Improve sync tests

sync3
Laurent 6 months ago
parent 6f0ddb21d8
commit 7f843633a5
  1. 8
      PadelClubDataTests/PadelClubDataTests.swift
  2. 146
      PadelClubDataTests/SyncDataAccessTests.swift
  3. 91
      PadelClubDataTests/SynchronizationTests.swift

@ -41,7 +41,7 @@ struct PadelClubDataTests {
// Cleanup // Cleanup
let events = DataStore.shared.events let events = DataStore.shared.events
await DataStore.shared.events.deleteAsync(contentOfs: Array(events)) try await DataStore.shared.events.deleteAsync(contentOfs: Array(events))
try await DataStore.shared.events.loadDataFromServerIfAllowed(clear: true) try await DataStore.shared.events.loadDataFromServerIfAllowed(clear: true)
#expect(DataStore.shared.events.count == 0) #expect(DataStore.shared.events.count == 0)
@ -51,11 +51,11 @@ struct PadelClubDataTests {
// Create // Create
let event: Event = Event(creator: userId, club: nil, name: "test") let event: Event = Event(creator: userId, club: nil, name: "test")
await DataStore.shared.events.addOrUpdateAsync(instance: event) try await DataStore.shared.events.addOrUpdateAsync(instance: event)
let tournament: Tournament = Tournament.fake() let tournament: Tournament = Tournament.fake()
tournament.event = event.id tournament.event = event.id
await DataStore.shared.tournaments.addOrUpdateAsync(instance: tournament) try await DataStore.shared.tournaments.addOrUpdateAsync(instance: tournament)
// Test server content // Test server content
try await DataStore.shared.events.loadDataFromServerIfAllowed(clear: true) try await DataStore.shared.events.loadDataFromServerIfAllowed(clear: true)
@ -86,7 +86,7 @@ struct PadelClubDataTests {
secondStoreServer.tokenKeychain = MockKeychainStore(fileName: "token.json") secondStoreServer.tokenKeychain = MockKeychainStore(fileName: "token.json")
let events = DataStore.shared.events let events = DataStore.shared.events
await DataStore.shared.events.deleteAsync(contentOfs: Array(events)) try await DataStore.shared.events.deleteAsync(contentOfs: Array(events))
} }

@ -65,7 +65,12 @@ struct SyncDataAccessTests {
#expect(userId1 != userId2) #expect(userId1 != userId2)
} }
@Test func testDataAccess() async throws { /// In this test, the first user:
/// - creates an event and a tournament
/// - shares the tournament with a second user
/// - remove the sharing with the second user
/// We test that the data is properly received and removed upon the sharing actions
@Test func testTournamentSharing() async throws {
guard let userId1 = StoreCenter.main.userId else { guard let userId1 = StoreCenter.main.userId else {
throw TestError.notAuthenticated throw TestError.notAuthenticated
@ -81,11 +86,11 @@ struct SyncDataAccessTests {
let tournamentColB: SyncedCollection<Tournament> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection() let tournamentColB: SyncedCollection<Tournament> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
if let dataAccessCollection = StoreCenter.main.dataAccessCollection { if let dataAccessCollection = StoreCenter.main.dataAccessCollection {
await dataAccessCollection.deleteAsync(contentOfs: Array(dataAccessCollection)) try await dataAccessCollection.deleteAsync(contentOfs: Array(dataAccessCollection))
} }
await eventColA.deleteAsync(contentOfs: Array(eventColA)) try await eventColA.deleteAsync(contentOfs: Array(eventColA))
await tournamentColA.deleteAsync(contentOfs: Array(tournamentColA)) try await tournamentColA.deleteAsync(contentOfs: Array(tournamentColA))
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync() let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
@ -94,9 +99,9 @@ struct SyncDataAccessTests {
// Create // Create
let eventA = Event(creator: userId1) let eventA = Event(creator: userId1)
await eventColA.addOrUpdateAsync(instance: eventA) try await eventColA.addOrUpdateAsync(instance: eventA)
let tournamentA = Tournament(event: eventA.id, name: "P100") let tournamentA = Tournament(event: eventA.id, name: "P100")
await tournamentColA.addOrUpdateAsync(instance: tournamentA) try await tournamentColA.addOrUpdateAsync(instance: tournamentA)
// Share with user2 // Share with user2
try await StoreCenter.main.setAuthorizedUsersAsync(for: tournamentA, users: [userId2]) try await StoreCenter.main.setAuthorizedUsersAsync(for: tournamentA, users: [userId2])
@ -123,7 +128,134 @@ struct SyncDataAccessTests {
#expect(dataAccesses.count == 0) #expect(dataAccesses.count == 0)
} }
// tester les shared data, les relationship add/remove shared/ou non /// In this test, the first user:
/// - creates a club and 2 events in that club
/// - shares both events with a second user
/// - removes the sharing of 1 event
/// Here we want to test that the Club instance remains even if one event is removed from the second user
@Test func testSharedRelationship() async throws {
guard let userId1 = StoreCenter.main.userId else {
throw TestError.notAuthenticated
}
guard let userId2 = self.secondStoreCenter.userId else {
throw TestError.notAuthenticated
}
// Setup
let eventColA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
let clubColA: SyncedCollection<Club> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
let eventColB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
let clubColB: SyncedCollection<Club> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
if let dataAccessCollection = StoreCenter.main.dataAccessCollection {
try await dataAccessCollection.deleteAsync(contentOfs: Array(dataAccessCollection))
}
try await eventColA.deleteAsync(contentOfs: Array(eventColA))
try await clubColA.deleteAsync(contentOfs: Array(clubColA))
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
#expect(eventColB.count == 0)
#expect(clubColB.count == 0)
// Create
let clubA = Club(creator: userId1, name: "Club A", acronym: "CA")
try await clubColA.addOrUpdateAsync(instance: clubA)
let event1A = Event(creator: userId1, club: clubA.id, name: "event 1")
let event2A = Event(creator: userId1, club: clubA.id, name: "event 2")
try await eventColA.addOrUpdateAsync(contentOfs: [event1A, event2A])
// Share with user2
try await StoreCenter.main.setAuthorizedUsersAsync(for: event1A, users: [userId2])
try await StoreCenter.main.setAuthorizedUsersAsync(for: event2A, users: [userId2])
var dataB = try await self.secondStoreCenter.testSynchronizeOnceAsync()
var syncDataB = try SyncData(data: dataB, storeCenter: self.secondStoreCenter)
#expect(syncDataB.grants.count == 2)
let clubGrants = syncDataB.grants.first { $0.type == Club.self }
let eventGrants = syncDataB.grants.first { $0.type == Event.self }
#expect(clubGrants?.items.count == 1)
#expect(eventGrants?.items.count == 2)
#expect(eventColB.count == 2)
#expect(clubColB.count == 1)
// Remove sharing from user2
try await StoreCenter.main.setAuthorizedUsersAsync(for: event1A, users: [])
dataB = try await self.secondStoreCenter.testSynchronizeOnceAsync()
syncDataB = try SyncData(data: dataB, storeCenter: self.secondStoreCenter)
#expect(syncDataB.revocations.count == 1)
#expect(syncDataB.revocationParents.count == 1)
#expect(eventColB.count == 1)
#expect(clubColB.count == 1) // club remains because used in event2A
}
/// In this test, the first user:
/// - creates one event and 2 clubs
/// - shares the event with a second user
/// - changes the club on the event
/// Here we want to test that the first Club is removed and the second one is received
@Test func testRelationshipChange() async throws {
guard let userId1 = StoreCenter.main.userId else {
throw TestError.notAuthenticated
}
guard let userId2 = self.secondStoreCenter.userId else {
throw TestError.notAuthenticated
}
// Setup
let eventColA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
let clubColA: SyncedCollection<Club> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
let eventColB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
let clubColB: SyncedCollection<Club> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
if let dataAccessCollection = StoreCenter.main.dataAccessCollection {
try await dataAccessCollection.deleteAsync(contentOfs: Array(dataAccessCollection))
}
try await eventColA.deleteAsync(contentOfs: Array(eventColA))
try await clubColA.deleteAsync(contentOfs: Array(clubColA))
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
#expect(eventColB.count == 0)
#expect(clubColB.count == 0)
// Create
let club1A = Club(creator: userId1, name: "Club 1", acronym: "C1")
try await clubColA.addOrUpdateAsync(instance: club1A)
let club2A = Club(creator: userId1, name: "Club 2", acronym: "C2")
try await clubColA.addOrUpdateAsync(instance: club2A)
let eventA = Event(creator: userId1, club: club1A.id, name: "event 1")
try await eventColA.addOrUpdateAsync(instance: eventA)
// Share with user2
try await StoreCenter.main.setAuthorizedUsersAsync(for: eventA, users: [userId2])
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
#expect(eventColB.count == 1)
#expect(clubColB.count == 1)
// Change the club
eventA.club = club2A.id
try await eventColA.addOrUpdateAsync(instance: eventA)
let dataB = try await self.secondStoreCenter.testSynchronizeOnceAsync()
let syncDataB = try SyncData(data: dataB, storeCenter: self.secondStoreCenter)
#expect(syncDataB.sharedRelationshipSets.count == 1)
#expect(syncDataB.sharedRelationshipRemovals.count == 1)
#expect(eventColB.first?.club == club2A.id)
}
// trouver le moyen de tester les sous-Store et voir si on peut essayer de rendre ça propre sans passer par DataStore ou autre // trouver le moyen de tester les sous-Store et voir si on peut essayer de rendre ça propre sans passer par DataStore ou autre

@ -27,7 +27,7 @@ struct SynchronizationTests {
FileManager.default.deleteDirectoryInDocuments(directoryName: "storage-2") FileManager.default.deleteDirectoryInDocuments(directoryName: "storage-2")
self.secondStoreCenter = StoreCenter(directoryName: "storage-2") self.secondStoreCenter = StoreCenter(directoryName: "storage-2")
self.secondStoreCenter.configureURLs(secureScheme: false, domain: "127.0.0.1:8000", webSockets: false) self.secondStoreCenter.configureURLs(secureScheme: false, domain: "127.0.0.1:8000", webSockets: false, useSynchronization: true)
self.secondStoreCenter.tokenKeychain = MockKeychainStore(fileName: "storage-2/token.json") self.secondStoreCenter.tokenKeychain = MockKeychainStore(fileName: "storage-2/token.json")
self.secondStoreCenter.deviceKeychain = MockKeychainStore(fileName: "storage-2/device.json") self.secondStoreCenter.deviceKeychain = MockKeychainStore(fileName: "storage-2/device.json")
try self.secondStoreCenter.deviceKeychain.add(value: UUID().uuidString) try self.secondStoreCenter.deviceKeychain.add(value: UUID().uuidString)
@ -39,7 +39,7 @@ struct SynchronizationTests {
try await self.login(storeCenter: self.secondStoreCenter) try await self.login(storeCenter: self.secondStoreCenter)
} }
StoreCenter.main.configureURLs(secureScheme: false, domain: "127.0.0.1:8000", webSockets: false) StoreCenter.main.configureURLs(secureScheme: false, domain: "127.0.0.1:8000", webSockets: false, useSynchronization: true)
StoreCenter.main.tokenKeychain = MockKeychainStore(fileName: "storage/token.json") StoreCenter.main.tokenKeychain = MockKeychainStore(fileName: "storage/token.json")
StoreCenter.main.deviceKeychain = MockKeychainStore(fileName: "storage/device.json") StoreCenter.main.deviceKeychain = MockKeychainStore(fileName: "storage/device.json")
try StoreCenter.main.deviceKeychain.add(value: UUID().uuidString) try StoreCenter.main.deviceKeychain.add(value: UUID().uuidString)
@ -75,7 +75,7 @@ struct SynchronizationTests {
let eventCollection1: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() let eventCollection1: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
#expect(eventCollection1.hasLoaded == true) #expect(eventCollection1.hasLoaded == true)
await eventCollection1.deleteAsync(contentOfs: Array(eventCollection1)) try await eventCollection1.deleteAsync(contentOfs: Array(eventCollection1))
let eventCollection2: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection() let eventCollection2: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
#expect(eventCollection2.hasLoaded == true) #expect(eventCollection2.hasLoaded == true)
@ -86,7 +86,7 @@ struct SynchronizationTests {
// Create // Create
let event: Event = Event(creator: userId, club: nil, name: "test") let event: Event = Event(creator: userId, club: nil, name: "test")
await eventCollection1.addOrUpdateAsync(instance: event) try await eventCollection1.addOrUpdateAsync(instance: event)
let serverEvents: [Event] = try await StoreCenter.main.service().get() let serverEvents: [Event] = try await StoreCenter.main.service().get()
#expect(serverEvents.count == 1) #expect(serverEvents.count == 1)
@ -118,13 +118,13 @@ struct SynchronizationTests {
// Setup events collections // Setup events collections
let eventCollectionA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() let eventCollectionA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
await eventCollectionA.deleteAsync(contentOfs: Array(eventCollectionA)) try await eventCollectionA.deleteAsync(contentOfs: Array(eventCollectionA))
let eventCollectionB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection() let eventCollectionB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
eventCollectionB.clear() eventCollectionB.clear()
// Setup clubs collections // Setup clubs collections
let clubCollectionA: SyncedCollection<Club> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() let clubCollectionA: SyncedCollection<Club> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
await clubCollectionA.deleteAsync(contentOfs: Array(clubCollectionA)) try await clubCollectionA.deleteAsync(contentOfs: Array(clubCollectionA))
let clubCollectionB: SyncedCollection<Club> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection() let clubCollectionB: SyncedCollection<Club> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
clubCollectionB.clear() clubCollectionB.clear()
@ -133,7 +133,7 @@ struct SynchronizationTests {
// Create // Create
let eventA: Event = Event(creator: userId, club: nil, name: "test-b") let eventA: Event = Event(creator: userId, club: nil, name: "test-b")
await eventCollectionA.addOrUpdateAsync(instance: eventA) try await eventCollectionA.addOrUpdateAsync(instance: eventA)
// Retrieve Event // Retrieve Event
let dataB = try await self.secondStoreCenter.testSynchronizeOnceAsync() let dataB = try await self.secondStoreCenter.testSynchronizeOnceAsync()
@ -143,13 +143,13 @@ struct SynchronizationTests {
// Create club on 2nd StoreCenter // Create club on 2nd StoreCenter
let club = Club(creator: userId, name: "Padel Club", acronym: "PC") let club = Club(creator: userId, name: "Padel Club", acronym: "PC")
await clubCollectionB.addOrUpdateAsync(instance: club) try await clubCollectionB.addOrUpdateAsync(instance: club)
guard let eventB = eventCollectionB.findById(eventA.id) else { guard let eventB = eventCollectionB.findById(eventA.id) else {
throw SyncTestError.instanceNotFound(id: eventA.id) throw SyncTestError.instanceNotFound(id: eventA.id)
} }
eventB.club = club.id eventB.club = club.id
await eventCollectionB.addOrUpdateAsync(instance: eventB) try await eventCollectionB.addOrUpdateAsync(instance: eventB)
// Synchronize 1st StoreCenter // Synchronize 1st StoreCenter
let dataA = try await StoreCenter.main.testSynchronizeOnceAsync() let dataA = try await StoreCenter.main.testSynchronizeOnceAsync()
@ -182,7 +182,7 @@ struct SynchronizationTests {
// Setup TeamReg // Setup TeamReg
let teamRegColA: SyncedCollection<TeamRegistration> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() let teamRegColA: SyncedCollection<TeamRegistration> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
await teamRegColA.deleteAsync(contentOfs: Array(teamRegColA)) try await teamRegColA.deleteAsync(contentOfs: Array(teamRegColA))
let teamRegColB: SyncedCollection<TeamRegistration> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection() let teamRegColB: SyncedCollection<TeamRegistration> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
teamRegColB.clear() teamRegColB.clear()
@ -191,8 +191,8 @@ struct SynchronizationTests {
// Create // Create
let trA = TeamRegistration(tournament: tournament.id) let trA = TeamRegistration(tournament: tournament.id)
await teamRegColA.addOrUpdateAsync(instance: trA) try await teamRegColA.addOrUpdateAsync(instance: trA)
await teamRegColA.deleteAsync(instance: trA) try await teamRegColA.deleteAsync(instance: trA)
#expect(teamRegColA.count == 0) #expect(teamRegColA.count == 0)
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync() let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
@ -207,8 +207,10 @@ struct SynchronizationTests {
} }
// Setup events collections // Setup events collections
let eventCollectionA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection() let eventCollectionA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection(inMemory: true)
await eventCollectionA.deleteAsync(contentOfs: Array(eventCollectionA)) try await eventCollectionA.loadOnceAsync()
try await eventCollectionA.deleteAsync(contentOfs: Array(eventCollectionA))
let eventCollectionB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection() let eventCollectionB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
eventCollectionB.clear() eventCollectionB.clear()
@ -220,7 +222,7 @@ struct SynchronizationTests {
// Create // Create
let eventA: Event = Event(creator: userId, club: nil, name: "test-b") let eventA: Event = Event(creator: userId, club: nil, name: "test-b")
await eventCollectionA.addOrUpdateAsync(instance: eventA) try await eventCollectionA.addOrUpdateAsync(instance: eventA)
#expect(eventCollectionA.count == 1) #expect(eventCollectionA.count == 1)
let serverEvents: [Event] = try await StoreCenter.main.service().get() let serverEvents: [Event] = try await StoreCenter.main.service().get()
@ -236,12 +238,12 @@ struct SynchronizationTests {
throw SyncTestError.instanceNotFound(id: eventA.id) throw SyncTestError.instanceNotFound(id: eventA.id)
} }
eventA.name = "my event is nice" eventA.name = "my event is nice"
await eventCollectionA.addOrUpdateAsync(instance: eventA) try await eventCollectionA.addOrUpdateAsync(instance: eventA)
eventB.name = "my event is better" eventB.name = "my event is better"
await eventCollectionB.addOrUpdateAsync(instance: eventB) try await eventCollectionB.addOrUpdateAsync(instance: eventB)
await eventCollectionA.addOrUpdateAsync(instance: eventA) try await eventCollectionA.addOrUpdateAsync(instance: eventA)
let _ = try await StoreCenter.main.testSynchronizeOnceAsync() let _ = try await StoreCenter.main.testSynchronizeOnceAsync()
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync() let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
@ -254,4 +256,57 @@ struct SynchronizationTests {
} }
/// In this test, the first user:
/// - creates one event and 2 clubs
/// - shares the event with a second user
/// - changes the club on the event
/// Here we want to test that the first Club is removed and the second one is received
@Test func testRelationshipChange() async throws {
guard let userId = StoreCenter.main.userId else {
throw TestError.notAuthenticated
}
// Setup
let eventColA: SyncedCollection<Event> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
let clubColA: SyncedCollection<Club> = await StoreCenter.main.mainStore.asyncLoadingSynchronizedCollection()
let eventColB: SyncedCollection<Event> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
let clubColB: SyncedCollection<Club> = await self.secondStoreCenter.mainStore.asyncLoadingSynchronizedCollection()
if let dataAccessCollection = StoreCenter.main.dataAccessCollection {
try await dataAccessCollection.deleteAsync(contentOfs: Array(dataAccessCollection))
}
try await eventColA.deleteAsync(contentOfs: Array(eventColA))
try await clubColA.deleteAsync(contentOfs: Array(clubColA))
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
#expect(eventColB.count == 0)
#expect(clubColB.count == 0)
// Create
let club1A = Club(creator: userId, name: "Club 1", acronym: "C1")
try await clubColA.addOrUpdateAsync(instance: club1A)
let club2A = Club(creator: userId, name: "Club 2", acronym: "C2")
try await clubColA.addOrUpdateAsync(instance: club2A)
let eventA = Event(creator: userId, club: club1A.id, name: "event 1")
try await eventColA.addOrUpdateAsync(instance: eventA)
// Share with user2
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
#expect(eventColB.count == 1)
#expect(clubColB.count == 2)
// Change the club
eventA.club = club2A.id
try await eventColA.addOrUpdateAsync(instance: eventA)
let _ = try await self.secondStoreCenter.testSynchronizeOnceAsync()
#expect(eventColB.first?.club == eventA.club)
}
} }

Loading…
Cancel
Save