Skip to content

Commit 54c0c78

Browse files
committed
Always perform full sync if the site’s not stored
1 parent cbfea01 commit 54c0c78

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

Modules/Sources/Yosemite/Tools/POS/POSCatalogSyncCoordinator.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Foundation
22
import Storage
33
import CocoaLumberjackSwift
4+
import GRDB
45

56
public protocol POSCatalogSyncCoordinatorProtocol {
67
/// Performs a full catalog sync for the specified site
@@ -19,11 +20,14 @@ public protocol POSCatalogSyncCoordinatorProtocol {
1920
public final class POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol {
2021
private let syncService: POSCatalogFullSyncServiceProtocol
2122
private let settingsStore: SiteSpecificAppSettingsStoreMethodsProtocol
23+
private let grdbManager: GRDBManagerProtocol
2224

2325
public init(syncService: POSCatalogFullSyncServiceProtocol,
24-
settingsStore: SiteSpecificAppSettingsStoreMethodsProtocol? = nil) {
26+
settingsStore: SiteSpecificAppSettingsStoreMethodsProtocol? = nil,
27+
grdbManager: GRDBManagerProtocol) {
2528
self.syncService = syncService
2629
self.settingsStore = settingsStore ?? SiteSpecificAppSettingsStoreMethods(fileStorage: PListFileStorage())
30+
self.grdbManager = grdbManager
2731
}
2832

2933
public func performFullSync(for siteID: Int64) async throws -> POSCatalog {
@@ -39,6 +43,11 @@ public final class POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol
3943
}
4044

4145
public func shouldPerformFullSync(for siteID: Int64, maxAge: TimeInterval) -> Bool {
46+
if !siteExistsInDatabase(siteID: siteID) {
47+
DDLogInfo("📋 POSCatalogSyncCoordinator: Site \(siteID) not found in database, sync needed")
48+
return true
49+
}
50+
4251
guard let lastSyncDate = lastFullSyncDate(for: siteID) else {
4352
DDLogInfo("📋 POSCatalogSyncCoordinator: No previous sync found for site \(siteID), sync needed")
4453
return true
@@ -61,4 +70,16 @@ public final class POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol
6170
private func lastFullSyncDate(for siteID: Int64) -> Date? {
6271
return settingsStore.getPOSLastFullSyncDate(for: siteID)
6372
}
73+
74+
private func siteExistsInDatabase(siteID: Int64) -> Bool {
75+
do {
76+
return try grdbManager.databaseConnection.read { db in
77+
return try PersistedSite.filter(key: siteID).fetchCount(db) > 0
78+
}
79+
} catch {
80+
DDLogError("⛔️ POSCatalogSyncCoordinator: Error checking if site \(siteID) exists in database: \(error)")
81+
// On error, assume site exists to avoid unnecessary syncs
82+
return true
83+
}
84+
}
6485
}

Modules/Tests/YosemiteTests/Tools/POS/POSCatalogSyncCoordinatorTests.swift

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import Foundation
22
import Testing
33
@testable import Yosemite
4-
import Storage
4+
@testable import Storage
55

66
struct POSCatalogSyncCoordinatorTests {
77
private let mockSyncService: MockPOSCatalogFullSyncService
88
private let mockSettingsStore: MockSiteSpecificAppSettingsStoreMethods
9+
private let grdbManager: GRDBManager
910
private let sut: POSCatalogSyncCoordinator
1011
private let sampleSiteID: Int64 = 134
1112

12-
init() {
13+
init() throws {
1314
self.mockSyncService = MockPOSCatalogFullSyncService()
1415
self.mockSettingsStore = MockSiteSpecificAppSettingsStoreMethods()
16+
self.grdbManager = try GRDBManager()
1517
self.sut = POSCatalogSyncCoordinator(
1618
syncService: mockSyncService,
17-
settingsStore: mockSettingsStore
19+
settingsStore: mockSettingsStore,
20+
grdbManager: grdbManager
1821
)
1922
}
2023

@@ -128,17 +131,55 @@ struct POSCatalogSyncCoordinatorTests {
128131
#expect(shouldSyncB == true) // No previous sync
129132
}
130133

131-
@Test func shouldPerformFullSync_with_zero_maxAge_always_returns_true() {
134+
@Test func shouldPerformFullSync_with_zero_maxAge_always_returns_true() throws {
132135
// Given - previous sync was just now
133136
let justNow = Date()
134137
mockSettingsStore.storedDates[sampleSiteID] = justNow
138+
try createSiteInDatabase(siteID: sampleSiteID)
135139

136140
// When - max age is 0 (always sync)
137141
let shouldSync = sut.shouldPerformFullSync(for: sampleSiteID, maxAge: 0)
138142

139143
// Then
140144
#expect(shouldSync == true)
141145
}
146+
147+
// MARK: - Database Check Tests
148+
149+
@Test func shouldPerformFullSync_returns_true_when_site_not_in_database() {
150+
// Given - site does not exist in database, but has recent sync date
151+
let recentSyncDate = Date().addingTimeInterval(-30 * 60) // 30 minutes ago
152+
mockSettingsStore.storedDates[sampleSiteID] = recentSyncDate
153+
// Note: not creating site in database so it won't exist
154+
155+
// When - max age is 1 hour (normally wouldn't sync)
156+
let shouldSync = sut.shouldPerformFullSync(for: sampleSiteID, maxAge: 60 * 60)
157+
158+
// Then - should sync because site doesn't exist in database
159+
#expect(shouldSync == true)
160+
}
161+
162+
@Test func shouldPerformFullSync_respects_time_when_site_exists_in_database() throws {
163+
// Given - site exists in database with recent sync date
164+
let recentSyncDate = Date().addingTimeInterval(-30 * 60) // 30 minutes ago
165+
mockSettingsStore.storedDates[sampleSiteID] = recentSyncDate
166+
try createSiteInDatabase(siteID: sampleSiteID)
167+
168+
// When - max age is 1 hour
169+
let shouldSync = sut.shouldPerformFullSync(for: sampleSiteID, maxAge: 60 * 60)
170+
171+
// Then - should not sync because site exists and time hasn't passed
172+
#expect(shouldSync == false)
173+
}
174+
175+
// MARK: - Helper Methods
176+
177+
private func createSiteInDatabase(siteID: Int64) throws {
178+
try grdbManager.databaseConnection.write { db in
179+
let site = PersistedSite(id: siteID)
180+
try site.insert(db)
181+
}
182+
}
142183
}
143184

144185
// MARK: - Mock Services

WooCommerce/Classes/ViewRelated/MainTabBarController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ private extension MainTabBarController {
799799
return nil
800800
}
801801

802-
return POSCatalogSyncCoordinator(syncService: syncService)
802+
return POSCatalogSyncCoordinator(syncService: syncService, grdbManager: ServiceLocator.grdbManager)
803803
}
804804

805805
func triggerPOSCatalogSyncIfNeeded(for siteID: Int64) async {

0 commit comments

Comments
 (0)