From 9ca290bd13f5604e40959a14928a74864234a7a6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 27 May 2025 15:53:15 +0200 Subject: [PATCH] Fix and add tests --- PadelClubData/Data/GroupStage.swift | 4 +- PadelClubDataTests/PadelClubDataTests.swift | 4 +- PadelClubDataTests/SyncDataAccessTests.swift | 80 ++++++++++++++++++- PadelClubDataTests/SynchronizationTests.swift | 5 +- 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/PadelClubData/Data/GroupStage.swift b/PadelClubData/Data/GroupStage.swift index 40c9fed..4c74d03 100644 --- a/PadelClubData/Data/GroupStage.swift +++ b/PadelClubData/Data/GroupStage.swift @@ -155,7 +155,7 @@ final public class GroupStage: BaseGroupStage, SideStorable { matches.append(newMatch) } } else { - for match in matches() { + for match in self.matches() { match.resetTeamScores(outsideOf: []) teamScores.append(contentsOf: match.createTeamScores()) } @@ -445,7 +445,7 @@ final public class GroupStage: BaseGroupStage, SideStorable { return teamsSorted.first == teamPosition } else { - if let matchIndex = combos.firstIndex(of: indexes), let match = matches().first(where: { $0.index == matchIndex }) { + if let matchIndex = combos.firstIndex(of: indexes), let match = self.matches().first(where: { $0.index == matchIndex }) { return teamPosition.id == match.losingTeamId } else { return false diff --git a/PadelClubDataTests/PadelClubDataTests.swift b/PadelClubDataTests/PadelClubDataTests.swift index 04ca9f9..545249d 100644 --- a/PadelClubDataTests/PadelClubDataTests.swift +++ b/PadelClubDataTests/PadelClubDataTests.swift @@ -76,8 +76,10 @@ struct PadelClubDataTests { @Test func dualStoreCenter() async throws { + let conf = Config.server + let secondStoreServer = StoreCenter() - secondStoreServer.configureURLs(secureScheme: false, domain: "127.0.0.1:8000") + secondStoreServer.configureURLs(secureScheme: conf.secure, domain: conf.domain) secondStoreServer.tokenKeychain = MockKeychainStore(fileName: "token.json") let _: CustomUser = try await secondStoreServer.service().login(username: self.username, password: self.password) diff --git a/PadelClubDataTests/SyncDataAccessTests.swift b/PadelClubDataTests/SyncDataAccessTests.swift index 366c86f..621ced2 100644 --- a/PadelClubDataTests/SyncDataAccessTests.swift +++ b/PadelClubDataTests/SyncDataAccessTests.swift @@ -29,6 +29,7 @@ struct SyncDataAccessTests { let dirB = "storageB" FileManager.default.deleteDirectoryInDocuments(directoryName: dir) + FileManager.default.deleteDirectoryInDocuments(directoryName: dirA) FileManager.default.deleteDirectoryInDocuments(directoryName: dirB) self.storeCenterA = StoreCenter(directoryName: dirA) @@ -279,13 +280,16 @@ struct SyncDataAccessTests { // Change the club eventA.club = club2A.id try await eventColA.addOrUpdateAsync(instance: eventA) + let dataB = try await self.storeCenterB.testSynchronizeOnceAsync() let syncDataB = try SyncData(data: dataB, storeCenter: self.storeCenterB) + #expect(syncDataB.updates.count == 1) // event update #expect(syncDataB.sharedRelationshipSets.count == 1) #expect(syncDataB.sharedRelationshipRemovals.count == 1) + print("club1A = \(club1A.id)") #expect(eventColB.first?.club == club2A.id) } @@ -418,7 +422,7 @@ struct SyncDataAccessTests { // Sync with 2nd store let data = try await self.storeCenterB.testSynchronizeOnceAsync() - let syncData = try SyncData(data: data, storeCenter: self.storeCenterB) + let _ = try SyncData(data: data, storeCenter: self.storeCenterB) #expect(gsColB.count == 2) #expect(roundColB.count == 15) @@ -426,6 +430,74 @@ struct SyncDataAccessTests { } + // needs to run on a postgreSQL, otherwise fails because of sqlite database locks + @Test func testDataAccessForChildren() async throws { + + guard let userId2 = self.storeCenterB.userId else { + throw TestError.notAuthenticated + } + // Setup tournament + let tournamentColA: SyncedCollection = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() + let tournamentColB: SyncedCollection = await self.storeCenterB.mainStore.asyncLoadingSynchronizedCollection() + + let tournament = Tournament(name: "test_data_access_children") + try await tournamentColA.addOrUpdateAsync(instance: tournament) + + let tourStoreA = try StoreCenter.main.store(identifier: tournament.id) + let teamRegColA: SyncedCollection = await tourStoreA.asyncLoadingSynchronizedCollection() + let playerRegColA: SyncedCollection = await tourStoreA.asyncLoadingSynchronizedCollection() + + // cleanup sync residues + let _ = try await self.storeCenterB.testSynchronizeOnceAsync() + + try await StoreCenter.main.setAuthorizedUsersAsync(for: tournament, users: [userId2]) + + var teamRegistrations: [TeamRegistration] = [] + var playerRegistrations: [PlayerRegistration] = [] + + let count = 5 + for i in (0.. = await tourStoreB.asyncLoadingSynchronizedCollection() + let playerRegColB: SyncedCollection = await tourStoreB.asyncLoadingSynchronizedCollection() + + #expect(tournamentColB.count == 1) + #expect(teamRegColB.count == count) + #expect(playerRegColB.count == count * 2) + + for team in teamRegistrations { + try await teamRegColA.deleteAsync(instance: team) + } + + try await Task.sleep(for: .milliseconds(100)) // without this, it looks like the sync date is smaller than the ModelLogs, so we don't get them all + + let data = try await self.storeCenterB.testSynchronizeOnceAsync() + let syncData = try SyncData(data: data, storeCenter: self.storeCenterB) + + #expect(syncData.deletions.count == 2) + + let teamRegDeletions = syncData.deletions.first(where: { $0.type == TeamRegistration.self }) + #expect(teamRegDeletions?.items.count == 5) + let playerRegDeletions = syncData.deletions.first(where: { $0.type == PlayerRegistration.self }) + #expect(playerRegDeletions?.items.count == 10) + + #expect(teamRegColB.count == 0) + #expect(playerRegColB.count == 0) + + } + } @@ -468,7 +540,7 @@ extension Tournament { } func buildGroupStagesAsync() async throws { - guard groupStages().isEmpty, let tournamentStore = self.tournamentStore else { + guard groupStages().isEmpty, let _ = self.tournamentStore else { return } @@ -555,13 +627,13 @@ extension GroupStage { _removeMatches() for i in 0..<_numberOfMatchesToBuild() { - let newMatch = self._createMatch(index: i) + let newMatch = self.createMatch(index: i) // let newMatch = Match(groupStage: self.id, index: i, matchFormat: self.matchFormat, name: localizedMatchUpLabel(for: i)) teamScores.append(contentsOf: newMatch.createTeamScores()) matches.append(newMatch) } } else { - for match in matches() { + for match in self.matches() { match.resetTeamScores(outsideOf: []) teamScores.append(contentsOf: match.createTeamScores()) } diff --git a/PadelClubDataTests/SynchronizationTests.swift b/PadelClubDataTests/SynchronizationTests.swift index 486ca66..5db05f9 100644 --- a/PadelClubDataTests/SynchronizationTests.swift +++ b/PadelClubDataTests/SynchronizationTests.swift @@ -311,6 +311,7 @@ struct SynchronizationTests { } + // needs to run on a postgreSQL, otherwise fails because of sqlite database locks @Test func testBuildEverything() async throws { // Cleanup @@ -325,7 +326,7 @@ struct SynchronizationTests { let tournament = Tournament() try await tournamentColA.addOrUpdateAsync(instance: tournament) - try await tournament.deleteAndBuildEverything() + try await tournament.deleteAndBuildEverythingAsync() let tourStore = try StoreCenter.main.store(identifier: tournament.id) let gsColA: SyncedCollection = try tourStore.syncedCollection() @@ -352,7 +353,7 @@ struct SynchronizationTests { tournament.groupStageCount = 2 tournament.teamCount = 20 try await tournamentColA.addOrUpdateAsync(instance: tournament) - try await tournament.deleteAndBuildEverything() + try await tournament.deleteAndBuildEverythingAsync() #expect(gsColA.count == 2) #expect(roundColA.count == 15)