@@ -2,15 +2,18 @@ import Foundation
2
2
import Testing
3
3
@testable import Networking
4
4
@testable import Yosemite
5
+ @testable import Storage
5
6
6
7
struct POSCatalogIncrementalSyncServiceTests {
7
8
private let sut : POSCatalogIncrementalSyncService
8
9
private let mockSyncRemote : MockPOSCatalogSyncRemote
10
+ private let mockPersistenceService : MockPOSCatalogPersistenceService
9
11
private let sampleSiteID : Int64 = 134
10
12
11
13
init ( ) {
12
14
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)
14
17
}
15
18
16
19
// MARK: - Basic Incremental Sync Tests
@@ -32,6 +35,7 @@ struct POSCatalogIncrementalSyncServiceTests {
32
35
#expect( mockSyncRemote. loadIncrementalProductVariationsCallCount == 2 )
33
36
#expect( mockSyncRemote. lastIncrementalProductsModifiedAfter == lastFullSyncDate)
34
37
#expect( mockSyncRemote. lastIncrementalVariationsModifiedAfter == lastFullSyncDate)
38
+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 1 )
35
39
}
36
40
37
41
@Test func startIncrementalSync_uses_last_incremental_sync_date_as_modifiedAfter_date_when_available( ) async throws {
@@ -73,6 +77,8 @@ struct POSCatalogIncrementalSyncServiceTests {
73
77
74
78
// Then
75
79
#expect( mockSyncRemote. loadIncrementalProductsCallCount == 4 )
80
+ let persistedCatalog = try #require( mockPersistenceService. persistIncrementalCatalogDataLastPersistedCatalog)
81
+ #expect( persistedCatalog. products. count == 3 )
76
82
}
77
83
78
84
@Test func startIncrementalSync_handles_paginated_variations_correctly( ) async throws {
@@ -92,6 +98,8 @@ struct POSCatalogIncrementalSyncServiceTests {
92
98
93
99
// Then
94
100
#expect( mockSyncRemote. loadIncrementalProductVariationsCallCount == 2 )
101
+ let persistedCatalog = try #require( mockPersistenceService. persistIncrementalCatalogDataLastPersistedCatalog)
102
+ #expect( persistedCatalog. variations. count == 2 )
95
103
}
96
104
97
105
// MARK: - Error Handling Tests
@@ -108,13 +116,39 @@ struct POSCatalogIncrementalSyncServiceTests {
108
116
await #expect( throws: expectedError) {
109
117
try await sut. startIncrementalSync ( for: sampleSiteID, lastFullSyncDate: lastFullSyncDate)
110
118
}
119
+ #expect( mockPersistenceService. persistIncrementalCatalogDataCallCount == 0 )
111
120
112
121
// When attempting a second sync
113
122
mockSyncRemote. setIncrementalProductResult ( pageNumber: 1 , result: . success( PagedItems ( items: [ ] , hasMorePages: false , totalItems: 0 ) ) )
114
123
try await sut. startIncrementalSync ( for: sampleSiteID, lastFullSyncDate: lastFullSyncDate)
115
124
116
125
// Then it uses lastFullSyncDate since no incremental date was stored due to previous failure
117
126
#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 )
118
152
}
119
153
120
154
// MARK: - Per-Site Behavior Tests
@@ -140,3 +174,23 @@ struct POSCatalogIncrementalSyncServiceTests {
140
174
#expect( site2ModifiedAfter == lastFullSyncDate)
141
175
}
142
176
}
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