@@ -2,15 +2,18 @@ import Foundation
22import Testing
33@testable import Networking
44@testable import Yosemite
5+ @testable import Storage
56
67struct POSCatalogIncrementalSyncServiceTests {
78 private let sut : POSCatalogIncrementalSyncService
89 private let mockSyncRemote : MockPOSCatalogSyncRemote
10+ private let mockPersistenceService : MockPOSCatalogPersistenceService
911 private let sampleSiteID : Int64 = 134
1012
1113 init ( ) {
1214 self . mockSyncRemote = MockPOSCatalogSyncRemote ( )
13- self . sut = POSCatalogIncrementalSyncService ( syncRemote: mockSyncRemote, batchSize: 2 )
15+ self . mockPersistenceService = MockPOSCatalogPersistenceService ( )
16+ self . sut = POSCatalogIncrementalSyncService ( syncRemote: mockSyncRemote, batchSize: 2 , persistenceService: mockPersistenceService)
1417 }
1518
1619 // MARK: - Basic Incremental Sync Tests
@@ -32,6 +35,7 @@ struct POSCatalogIncrementalSyncServiceTests {
3235 #expect( mockSyncRemote. loadIncrementalProductVariationsCallCount == 2 )
3336 #expect( mockSyncRemote. lastIncrementalProductsModifiedAfter == lastFullSyncDate)
3437 #expect( mockSyncRemote. lastIncrementalVariationsModifiedAfter == lastFullSyncDate)
38+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 1 )
3539 }
3640
3741 @Test func startIncrementalSync_uses_last_incremental_sync_date_as_modifiedAfter_date_when_available( ) async throws {
@@ -73,6 +77,8 @@ struct POSCatalogIncrementalSyncServiceTests {
7377
7478 // Then
7579 #expect( mockSyncRemote. loadIncrementalProductsCallCount == 4 )
80+ let persistedCatalog = try #require( mockPersistenceService. persistIncrementalCatalogDataLastPersistedCatalog)
81+ #expect( persistedCatalog. products. count == 3 )
7682 }
7783
7884 @Test func startIncrementalSync_handles_paginated_variations_correctly( ) async throws {
@@ -92,6 +98,8 @@ struct POSCatalogIncrementalSyncServiceTests {
9298
9399 // Then
94100 #expect( mockSyncRemote. loadIncrementalProductVariationsCallCount == 2 )
101+ let persistedCatalog = try #require( mockPersistenceService. persistIncrementalCatalogDataLastPersistedCatalog)
102+ #expect( persistedCatalog. variations. count == 2 )
95103 }
96104
97105 // MARK: - Error Handling Tests
@@ -108,13 +116,39 @@ struct POSCatalogIncrementalSyncServiceTests {
108116 await #expect( throws: expectedError) {
109117 try await sut. startIncrementalSync ( for: sampleSiteID, lastFullSyncDate: lastFullSyncDate)
110118 }
119+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 0 )
111120
112121 // When attempting a second sync
113122 mockSyncRemote. setIncrementalProductResult ( pageNumber: 1 , result: . success( PagedItems ( items: [ ] , hasMorePages: false , totalItems: 0 ) ) )
114123 try await sut. startIncrementalSync ( for: sampleSiteID, lastFullSyncDate: lastFullSyncDate)
115124
116125 // Then it uses lastFullSyncDate since no incremental date was stored due to previous failure
117126 #expect( mockSyncRemote. lastIncrementalProductsModifiedAfter == lastFullSyncDate)
127+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 1 )
128+ }
129+
130+ @Test func startIncrementalSync_throws_error_when_persistence_fails( ) async throws {
131+ // Given
132+ let lastFullSyncDate = Date ( timeIntervalSince1970: 1000 )
133+ let expectedError = NSError ( domain: " persistence " , code: 500 , userInfo: nil )
134+
135+ mockSyncRemote. setIncrementalProductResult ( pageNumber: 1 , result: . success( PagedItems ( items: [ ] , hasMorePages: false , totalItems: 0 ) ) )
136+ mockSyncRemote. setIncrementalVariationResult ( pageNumber: 1 , result: . success( PagedItems ( items: [ ] , hasMorePages: false , totalItems: 0 ) ) )
137+ mockPersistenceService. persistIncrementalCatalogDataError = expectedError
138+
139+ // When/Then
140+ await #expect( throws: Error . self) {
141+ try await sut. startIncrementalSync ( for: sampleSiteID, lastFullSyncDate: lastFullSyncDate)
142+ }
143+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 1 )
144+
145+ // When attempting a second sync
146+ mockPersistenceService. persistIncrementalCatalogDataError = nil // Clear the error
147+ try await sut. startIncrementalSync ( for: sampleSiteID, lastFullSyncDate: lastFullSyncDate)
148+
149+ // Then it uses lastFullSyncDate since no incremental date was stored due to previous persistence failure
150+ #expect( mockSyncRemote. lastIncrementalProductsModifiedAfter == lastFullSyncDate)
151+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 2 )
118152 }
119153
120154 // MARK: - Per-Site Behavior Tests
@@ -140,3 +174,23 @@ struct POSCatalogIncrementalSyncServiceTests {
140174 #expect( site2ModifiedAfter == lastFullSyncDate)
141175 }
142176}
177+
178+ // MARK: - Mock Classes
179+
180+ private final class MockPOSCatalogPersistenceService : POSCatalogPersistenceServiceProtocol {
181+ private( set) var persistIncrementalCatalogDataCallCount = 0
182+ private( set) var persistIncrementalCatalogDataLastPersistedCatalog : POSCatalog ?
183+ private( set) var persistIncrementalCatalogDataLastPersistedSiteID : Int64 ?
184+ var persistIncrementalCatalogDataError : Error ?
185+
186+ func replaceAllCatalogData( _ catalog: POSCatalog , siteID: Int64 ) async throws { }
187+
188+ func persistIncrementalCatalogData( _ catalog: POSCatalog , siteID: Int64 ) async throws {
189+ persistIncrementalCatalogDataCallCount += 1
190+ persistIncrementalCatalogDataLastPersistedSiteID = siteID
191+ persistIncrementalCatalogDataLastPersistedCatalog = catalog
192+ if let error = persistIncrementalCatalogDataError {
193+ throw error
194+ }
195+ }
196+ }
0 commit comments