|
|
|
|
@ -607,7 +607,7 @@ struct SyncDataAccessTests { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test func testMatchSharingThenTournamentDelete() async throws { |
|
|
|
|
@Test func testMatchSharingThenRevoking() async throws { |
|
|
|
|
guard let userId1 = StoreCenter.main.userId else { |
|
|
|
|
throw TestError.notAuthenticated |
|
|
|
|
} |
|
|
|
|
@ -618,12 +618,12 @@ struct SyncDataAccessTests { |
|
|
|
|
// Setup tournament |
|
|
|
|
let tournamentColA: SyncedCollection<Tournament> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() |
|
|
|
|
let eventColA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() |
|
|
|
|
try await tournamentColA.deleteAsync(contentOfs: tournamentColA) |
|
|
|
|
|
|
|
|
|
let event = Event(creator: userId1) |
|
|
|
|
try await eventColA.addOrUpdateAsync(instance: event) |
|
|
|
|
|
|
|
|
|
let tournament = Tournament(event: event.id, name: "test_data_access_children") |
|
|
|
|
tournament.relatedUser = userId1 |
|
|
|
|
let tournament = Tournament(event: event.id, name: "testMatchSharingThenTournamentDelete") |
|
|
|
|
try await tournamentColA.addOrUpdateAsync(instance: tournament) |
|
|
|
|
|
|
|
|
|
let tourStoreA = try StoreCenter.main.store(identifier: tournament.id) |
|
|
|
|
@ -644,12 +644,91 @@ struct SyncDataAccessTests { |
|
|
|
|
try await playerRegColA.addOrUpdateAsync(contentOfs: [pr11, pr12, pr21, pr22]) |
|
|
|
|
|
|
|
|
|
let round = Round(tournament: tournament.id) |
|
|
|
|
try await roundColA.addOrUpdateAsync(instance: round) |
|
|
|
|
|
|
|
|
|
let match = Match(round: round.id) |
|
|
|
|
try await matchColA.addOrUpdateAsync(instance: match) |
|
|
|
|
|
|
|
|
|
let ts1 = TeamScore(match: match.id, team: tr1) |
|
|
|
|
let ts2 = TeamScore(match: match.id, team: tr2) |
|
|
|
|
try await teamScoreColA.addOrUpdateAsync(contentOfs: [ts1, ts2]) |
|
|
|
|
|
|
|
|
|
try await StoreCenter.main.setAuthorizedUsersAsync(for: match, users: [userId2]) |
|
|
|
|
|
|
|
|
|
let data = try await self.storeCenterB.testSynchronizeOnceAsync() |
|
|
|
|
let syncData = try SyncData(data: data, storeCenter: self.storeCenterB) |
|
|
|
|
|
|
|
|
|
let tournamentColB: SyncedCollection<Tournament> = await self.storeCenterB.mainStore.asyncLoadingSynchronizedCollection() |
|
|
|
|
|
|
|
|
|
#expect(syncData.shared.count == 1) |
|
|
|
|
#expect(tournamentColB.count == 1) |
|
|
|
|
|
|
|
|
|
let tourStoreB = try self.storeCenterB.store(identifier: tournament.id) |
|
|
|
|
let matchColB: SyncedCollection<Match> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
let playerRegColB: SyncedCollection<PlayerRegistration> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
let teamRegColB: SyncedCollection<TeamRegistration> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
|
|
|
|
|
#expect(matchColB.count == 1) |
|
|
|
|
#expect(playerRegColB.count == 4) |
|
|
|
|
#expect(teamRegColB.count == 2) |
|
|
|
|
|
|
|
|
|
try await StoreCenter.main.setAuthorizedUsersAsync(for: match, users: []) |
|
|
|
|
|
|
|
|
|
let data2 = try await self.storeCenterB.testSynchronizeOnceAsync() |
|
|
|
|
let syncData2 = try SyncData(data: data2, storeCenter: self.storeCenterB) |
|
|
|
|
|
|
|
|
|
#expect(syncData2.revocations.count > 0) |
|
|
|
|
|
|
|
|
|
#expect(matchColB.count == 0) |
|
|
|
|
#expect(playerRegColB.count == 0) |
|
|
|
|
#expect(teamRegColB.count == 0) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test func testMatchSharingThenTournamentDelete() async throws { |
|
|
|
|
guard let userId1 = StoreCenter.main.userId else { |
|
|
|
|
throw TestError.notAuthenticated |
|
|
|
|
} |
|
|
|
|
guard let userId2 = self.storeCenterB.userId else { |
|
|
|
|
throw TestError.notAuthenticated |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Setup tournament |
|
|
|
|
let tournamentColA: SyncedCollection<Tournament> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() |
|
|
|
|
let eventColA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() |
|
|
|
|
try await tournamentColA.deleteAsync(contentOfs: tournamentColA) |
|
|
|
|
|
|
|
|
|
let event = Event(creator: userId1) |
|
|
|
|
try await eventColA.addOrUpdateAsync(instance: event) |
|
|
|
|
|
|
|
|
|
let tournament = Tournament(event: event.id, name: "testMatchSharingThenTournamentDelete") |
|
|
|
|
try await tournamentColA.addOrUpdateAsync(instance: tournament) |
|
|
|
|
|
|
|
|
|
let tourStoreA = try StoreCenter.main.store(identifier: tournament.id) |
|
|
|
|
let teamRegColA: SyncedCollection<TeamRegistration> = await tourStoreA.asyncLoadingSynchronizedCollection() |
|
|
|
|
let playerRegColA: SyncedCollection<PlayerRegistration> = await tourStoreA.asyncLoadingSynchronizedCollection() |
|
|
|
|
let roundColA: SyncedCollection<Round> = await tourStoreA.asyncLoadingSynchronizedCollection() |
|
|
|
|
let matchColA: SyncedCollection<Match> = await tourStoreA.asyncLoadingSynchronizedCollection() |
|
|
|
|
let teamScoreColA: SyncedCollection<TeamScore> = await tourStoreA.asyncLoadingSynchronizedCollection() |
|
|
|
|
|
|
|
|
|
let tr1 = TeamRegistration(tournament: tournament.id) |
|
|
|
|
let pr11 = PlayerRegistration(teamRegistration: tr1.id, firstName: "f1", lastName: "l1") |
|
|
|
|
let pr12 = PlayerRegistration(teamRegistration: tr1.id, firstName: "f2", lastName: "l2") |
|
|
|
|
let tr2 = TeamRegistration(tournament: tournament.id) |
|
|
|
|
let pr21 = PlayerRegistration(teamRegistration: tr2.id, firstName: "f21", lastName: "l21") |
|
|
|
|
let pr22 = PlayerRegistration(teamRegistration: tr2.id, firstName: "f22", lastName: "l22") |
|
|
|
|
|
|
|
|
|
try await teamRegColA.addOrUpdateAsync(contentOfs: [tr1, tr2]) |
|
|
|
|
try await playerRegColA.addOrUpdateAsync(contentOfs: [pr11, pr12, pr21, pr22]) |
|
|
|
|
|
|
|
|
|
let round = Round(tournament: tournament.id) |
|
|
|
|
try await roundColA.addOrUpdateAsync(instance: round) |
|
|
|
|
|
|
|
|
|
let match = Match(round: round.id) |
|
|
|
|
try await matchColA.addOrUpdateAsync(instance: match) |
|
|
|
|
|
|
|
|
|
let ts1 = TeamScore(match: match.id, team: tr1) |
|
|
|
|
let ts2 = TeamScore(match: match.id, team: tr2) |
|
|
|
|
try await teamScoreColA.addOrUpdateAsync(contentOfs: [ts1, ts2]) |
|
|
|
|
|
|
|
|
|
try await StoreCenter.main.setAuthorizedUsersAsync(for: match, users: [userId2]) |
|
|
|
|
@ -657,35 +736,44 @@ struct SyncDataAccessTests { |
|
|
|
|
let data = try await self.storeCenterB.testSynchronizeOnceAsync() |
|
|
|
|
let syncData = try SyncData(data: data, storeCenter: self.storeCenterB) |
|
|
|
|
|
|
|
|
|
#expect(syncData.shared.count == 1) |
|
|
|
|
|
|
|
|
|
let tournamentColB: SyncedCollection<Tournament> = await self.storeCenterB.mainStore.asyncLoadingSynchronizedCollection() |
|
|
|
|
|
|
|
|
|
#expect(syncData.shared.count == 1) |
|
|
|
|
#expect(tournamentColB.count == 1) |
|
|
|
|
|
|
|
|
|
let tourStoreB = try self.storeCenterB.store(identifier: tournament.id) |
|
|
|
|
let matchColB: SyncedCollection<Match> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
let playerRegColB: SyncedCollection<PlayerRegistration> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
let teamRegColB: SyncedCollection<TeamRegistration> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
let teamScoreColB: SyncedCollection<TeamScore> = await tourStoreB.asyncLoadingSynchronizedCollection() |
|
|
|
|
|
|
|
|
|
#expect(matchColB.count == 1) |
|
|
|
|
#expect(playerRegColB.count == 4) |
|
|
|
|
#expect(teamRegColB.count == 2) |
|
|
|
|
#expect(teamScoreColB.count == 2) |
|
|
|
|
|
|
|
|
|
try await tournamentColA.deleteAsync(instance: tournament) |
|
|
|
|
let tournaments: [Tournament] = try await StoreCenter.main.service().get() |
|
|
|
|
#expect(tournaments.count == 0) |
|
|
|
|
|
|
|
|
|
#expect(tournamentColA.count == 0) |
|
|
|
|
try await roundColA.deleteAsync(instance: round) |
|
|
|
|
#expect(roundColA.count == 0) |
|
|
|
|
|
|
|
|
|
try await Task.sleep(nanoseconds: 1_000_000_000) // wait for cascading deletes to be finished |
|
|
|
|
|
|
|
|
|
let data2 = try await self.storeCenterB.testSynchronizeOnceAsync() |
|
|
|
|
let syncData2 = try SyncData(data: data2, storeCenter: self.storeCenterB) |
|
|
|
|
|
|
|
|
|
#expect(tournamentColB.count == 0) |
|
|
|
|
|
|
|
|
|
for deletion in syncData2.deletions { |
|
|
|
|
print(">>> deletion type = \(deletion.type), count = \(deletion.items.count)") |
|
|
|
|
} |
|
|
|
|
for revocation in syncData2.revocations { |
|
|
|
|
print(">>> revocation type = \(revocation.type), count = \(revocation.items.count)") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#expect(syncData2.deletions.count > 0) |
|
|
|
|
#expect(syncData2.revocations.count > 0) |
|
|
|
|
|
|
|
|
|
#expect(matchColB.count == 0) |
|
|
|
|
#expect(teamScoreColB.count == 0) |
|
|
|
|
|
|
|
|
|
// the delete of round deletes the match, which should revoke granted objects like player/teams |
|
|
|
|
#expect(playerRegColB.count == 0) |
|
|
|
|
#expect(teamRegColB.count == 0) |
|
|
|
|
|
|
|
|
|
@ -894,7 +982,7 @@ extension GroupStage { |
|
|
|
|
matches.append(newMatch) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
for match in self.matches() { |
|
|
|
|
for match in self._matches() { |
|
|
|
|
match.resetTeamScores(outsideOf: []) |
|
|
|
|
teamScores.append(contentsOf: match.createTeamScores()) |
|
|
|
|
} |
|
|
|
|
|