Skip to content

Commit 1e17c24

Browse files
committed
Store toggle setting for cellular catalog sync
1 parent d128552 commit 1e17c24

File tree

4 files changed

+135
-17
lines changed

4 files changed

+135
-17
lines changed

Modules/Sources/PointOfSale/Presentation/Settings/POSSettingsLocalCatalogViewModel.swift

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

56
@Observable
67
final class POSSettingsLocalCatalogViewModel {
@@ -14,21 +15,31 @@ final class POSSettingsLocalCatalogViewModel {
1415
private let siteID: Int64
1516
private let catalogSettingsService: POSCatalogSettingsServiceProtocol
1617
private let catalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol
18+
private let siteSettings: SiteSpecificAppSettingsStoreMethodsProtocol
1719
private let dateFormatter: RelativeDateTimeFormatter = {
1820
let formatter = RelativeDateTimeFormatter()
1921
formatter.dateTimeStyle = .named
2022
formatter.unitsStyle = .full
2123
return formatter
2224
}()
2325

24-
var allowFullSyncOnCellular: Bool = true
26+
var allowFullSyncOnCellular: Bool {
27+
get {
28+
siteSettings.getPOSLocalCatalogCellularDataAllowed(siteID: siteID)
29+
}
30+
set {
31+
siteSettings.setPOSLocalCatalogCellularDataAllowed(siteID: siteID, allowed: newValue)
32+
}
33+
}
2534

2635
init(siteID: Int64,
2736
catalogSettingsService: POSCatalogSettingsServiceProtocol,
28-
catalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol) {
37+
catalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol,
38+
siteSettings: SiteSpecificAppSettingsStoreMethodsProtocol? = nil) {
2939
self.siteID = siteID
3040
self.catalogSettingsService = catalogSettingsService
3141
self.catalogSyncCoordinator = catalogSyncCoordinator
42+
self.siteSettings = siteSettings ?? SiteSpecificAppSettingsStoreMethods(fileStorage: PListFileStorage())
3243
}
3344

3445
@MainActor

Modules/Sources/Yosemite/Stores/Helpers/SiteSpecificAppSettingsStoreMethods.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public protocol SiteSpecificAppSettingsStoreMethodsProtocol {
2525

2626
/// Methods for managing site-specific app settings
2727
///
28-
struct SiteSpecificAppSettingsStoreMethods: SiteSpecificAppSettingsStoreMethodsProtocol {
28+
public struct SiteSpecificAppSettingsStoreMethods: SiteSpecificAppSettingsStoreMethodsProtocol {
2929
private let fileStorage: FileStorage
3030
private let generalStoreSettingsFileURL: URL
3131

@@ -44,7 +44,7 @@ struct SiteSpecificAppSettingsStoreMethods: SiteSpecificAppSettingsStoreMethodsP
4444

4545
// MARK: - Store Settings
4646
extension SiteSpecificAppSettingsStoreMethods {
47-
func getStoreSettings(for siteID: Int64) -> GeneralStoreSettings {
47+
public func getStoreSettings(for siteID: Int64) -> GeneralStoreSettings {
4848
guard let existingData: GeneralStoreSettingsBySite = try? fileStorage.data(for: generalStoreSettingsFileURL),
4949
let storeSettings = existingData.storeSettingsBySite[siteID] else {
5050
return GeneralStoreSettings()
@@ -53,7 +53,7 @@ extension SiteSpecificAppSettingsStoreMethods {
5353
return storeSettings
5454
}
5555

56-
func setStoreSettings(settings: GeneralStoreSettings, for siteID: Int64, onCompletion: ((Result<Void, Error>) -> Void)? = nil) {
56+
public func setStoreSettings(settings: GeneralStoreSettings, for siteID: Int64, onCompletion: ((Result<Void, Error>) -> Void)? = nil) {
5757
var storeSettingsBySite: [Int64: GeneralStoreSettings] = [:]
5858
if let existingData: GeneralStoreSettingsBySite = try? fileStorage.data(for: generalStoreSettingsFileURL) {
5959
storeSettingsBySite = existingData.storeSettingsBySite
@@ -70,35 +70,35 @@ extension SiteSpecificAppSettingsStoreMethods {
7070
}
7171
}
7272

73-
func resetStoreSettings() {
73+
public func resetStoreSettings() {
7474
do {
7575
try fileStorage.deleteFile(at: generalStoreSettingsFileURL)
7676
} catch {
7777
DDLogError("⛔️ Deleting store settings file failed. Error: \(error)")
7878
}
7979
}
8080

81-
func setStoreID(siteID: Int64, id: String?) {
81+
public func setStoreID(siteID: Int64, id: String?) {
8282
let storeSettings = getStoreSettings(for: siteID)
8383
let updatedSettings = storeSettings.copy(storeID: id)
8484
setStoreSettings(settings: updatedSettings, for: siteID)
8585
}
8686

87-
func getStoreID(siteID: Int64, onCompletion: (String?) -> Void) {
87+
public func getStoreID(siteID: Int64, onCompletion: (String?) -> Void) {
8888
let storeSettings = getStoreSettings(for: siteID)
8989
onCompletion(storeSettings.storeID)
9090
}
9191
}
9292

9393
// MARK: - Search History
9494
extension SiteSpecificAppSettingsStoreMethods {
95-
func getSearchTerms(for itemType: POSItemType, siteID: Int64) -> [String] {
95+
public func getSearchTerms(for itemType: POSItemType, siteID: Int64) -> [String] {
9696
let storeSettings = getStoreSettings(for: siteID)
9797
let key = itemType.storedSearchHistoryKey
9898
return storeSettings.searchTermsByKey[key] ?? []
9999
}
100100

101-
func setSearchTerms(_ terms: [String], for itemType: POSItemType, siteID: Int64) {
101+
public func setSearchTerms(_ terms: [String], for itemType: POSItemType, siteID: Int64) {
102102
let storeSettings = getStoreSettings(for: siteID)
103103
let key = itemType.storedSearchHistoryKey
104104
var updatedSearchTermsByKey = storeSettings.searchTermsByKey
@@ -110,21 +110,21 @@ extension SiteSpecificAppSettingsStoreMethods {
110110

111111
// MARK: - POS sync eligibility tracking
112112
extension SiteSpecificAppSettingsStoreMethods{
113-
func getPOSLastOpenedDate(siteID: Int64) -> Date? {
113+
public func getPOSLastOpenedDate(siteID: Int64) -> Date? {
114114
getStoreSettings(for: siteID).lastPOSOpenedDate
115115
}
116116

117-
func setPOSLastOpenedDate(siteID: Int64, date: Date) {
117+
public func setPOSLastOpenedDate(siteID: Int64, date: Date) {
118118
let storeSettings = getStoreSettings(for: siteID)
119119
let updatedSettings = storeSettings.copy(lastPOSOpenedDate: date)
120120
setStoreSettings(settings: updatedSettings, for: siteID)
121121
}
122122

123-
func getFirstPOSCatalogSyncDate(siteID: Int64) -> Date? {
123+
public func getFirstPOSCatalogSyncDate(siteID: Int64) -> Date? {
124124
getStoreSettings(for: siteID).firstPOSCatalogSyncDate
125125
}
126126

127-
func setFirstPOSCatalogSyncDate(siteID: Int64, date: Date) {
127+
public func setFirstPOSCatalogSyncDate(siteID: Int64, date: Date) {
128128
let storeSettings = getStoreSettings(for: siteID)
129129
let updatedSettings = storeSettings.copy(firstPOSCatalogSyncDate: date)
130130
setStoreSettings(settings: updatedSettings, for: siteID)
@@ -133,13 +133,13 @@ extension SiteSpecificAppSettingsStoreMethods{
133133

134134
// MARK: - POS local catalog cellular data
135135
extension SiteSpecificAppSettingsStoreMethods {
136-
func setPOSLocalCatalogCellularDataAllowed(siteID: Int64, allowed: Bool) {
136+
public func setPOSLocalCatalogCellularDataAllowed(siteID: Int64, allowed: Bool) {
137137
let storeSettings = getStoreSettings(for: siteID)
138138
let updatedSettings = storeSettings.copy(syncPOSCatalogOverCellular: allowed)
139139
setStoreSettings(settings: updatedSettings, for: siteID)
140140
}
141141

142-
func getPOSLocalCatalogCellularDataAllowed(siteID: Int64) -> Bool {
142+
public func getPOSLocalCatalogCellularDataAllowed(siteID: Int64) -> Bool {
143143
getStoreSettings(for: siteID).syncPOSCatalogOverCellular
144144
}
145145
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
@testable import Yosemite
2+
import Foundation
3+
import Storage
4+
5+
/// Minimal mock for SiteSpecificAppSettingsStoreMethodsProtocol
6+
/// Only implements the methods needed for POS local catalog tests
7+
final class MockSiteSpecificAppSettingsStoreMethods: SiteSpecificAppSettingsStoreMethodsProtocol {
8+
var currentSiteID: Int64 = 1
9+
10+
// POS local catalog cellular data properties
11+
var getPOSLocalCatalogCellularDataAllowedCalled = false
12+
var setPOSLocalCatalogCellularDataAllowedCalled = false
13+
var mockPOSLocalCatalogCellularDataAllowed: Bool?
14+
15+
// Implement only the methods we actually use
16+
func setPOSLocalCatalogCellularDataAllowed(siteID: Int64, allowed: Bool) {
17+
setPOSLocalCatalogCellularDataAllowedCalled = true
18+
mockPOSLocalCatalogCellularDataAllowed = allowed
19+
}
20+
21+
func getPOSLocalCatalogCellularDataAllowed(siteID: Int64) -> Bool {
22+
getPOSLocalCatalogCellularDataAllowedCalled = true
23+
return mockPOSLocalCatalogCellularDataAllowed ?? false
24+
}
25+
26+
// Protocol requirements - minimal implementations
27+
func getStoreSettings(for siteID: Int64) -> GeneralStoreSettings {
28+
GeneralStoreSettings()
29+
}
30+
31+
func setStoreSettings(settings: GeneralStoreSettings, for siteID: Int64, onCompletion: ((Result<Void, Error>) -> Void)?) {
32+
onCompletion?(.success(()))
33+
}
34+
35+
func resetStoreSettings() {}
36+
37+
func setStoreID(siteID: Int64, id: String?) {}
38+
39+
func getStoreID(siteID: Int64, onCompletion: (String?) -> Void) {
40+
onCompletion(nil)
41+
}
42+
43+
func getSearchTerms(for itemType: POSItemType, siteID: Int64) -> [String] {
44+
[]
45+
}
46+
47+
func setSearchTerms(_ terms: [String], for itemType: POSItemType, siteID: Int64) {}
48+
49+
func getPOSLastOpenedDate(siteID: Int64) -> Date? {
50+
nil
51+
}
52+
53+
func setPOSLastOpenedDate(siteID: Int64, date: Date) {}
54+
55+
func getFirstPOSCatalogSyncDate(siteID: Int64) -> Date? {
56+
nil
57+
}
58+
59+
func setFirstPOSCatalogSyncDate(siteID: Int64, date: Date) {}
60+
}

Modules/Tests/PointOfSaleTests/Presentation/Settings/POSSettingsLocalCatalogViewModelTests.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ struct POSSettingsLocalCatalogViewModelTests {
88
private let sut: POSSettingsLocalCatalogViewModel
99
private let catalogSettingsService: MockPOSCatalogSettingsService
1010
private let catalogSyncCoordinator: MockPOSCatalogSyncCoordinator
11+
private let siteSettings: MockSiteSpecificAppSettingsStoreMethods
1112

1213
init() {
1314
self.catalogSettingsService = MockPOSCatalogSettingsService()
1415
self.catalogSyncCoordinator = MockPOSCatalogSyncCoordinator()
16+
self.siteSettings = MockSiteSpecificAppSettingsStoreMethods()
17+
self.siteSettings.currentSiteID = sampleSiteID
1518
self.sut = POSSettingsLocalCatalogViewModel(
1619
siteID: sampleSiteID,
1720
catalogSettingsService: catalogSettingsService,
18-
catalogSyncCoordinator: catalogSyncCoordinator
21+
catalogSyncCoordinator: catalogSyncCoordinator,
22+
siteSettings: siteSettings
1923
)
2024
}
2125

@@ -199,6 +203,49 @@ struct POSSettingsLocalCatalogViewModelTests {
199203
#expect(sut.isRefreshingCatalog == false)
200204
#expect(catalogSyncCoordinator.performFullSyncInvocationCount == 1)
201205
}
206+
207+
// MARK: - allowFullSyncOnCellular Tests
208+
209+
@Test func allowFullSyncOnCellular_returns_default_value_from_site_settings() async throws {
210+
// Given
211+
siteSettings.mockPOSLocalCatalogCellularDataAllowed = false
212+
213+
// When
214+
let isAllowed = sut.allowFullSyncOnCellular
215+
216+
// Then
217+
#expect(isAllowed == false)
218+
#expect(siteSettings.getPOSLocalCatalogCellularDataAllowedCalled == true)
219+
}
220+
221+
@Test func allowFullSyncOnCellular_setter_updates_site_settings() async throws {
222+
// When
223+
sut.allowFullSyncOnCellular = true
224+
225+
// Then
226+
#expect(siteSettings.setPOSLocalCatalogCellularDataAllowedCalled == true)
227+
#expect(siteSettings.mockPOSLocalCatalogCellularDataAllowed == true)
228+
}
229+
230+
@Test func allowFullSyncOnCellular_getter_and_setter_work_as_two_way_binding() async throws {
231+
// Given - Initially false
232+
siteSettings.mockPOSLocalCatalogCellularDataAllowed = false
233+
#expect(sut.allowFullSyncOnCellular == false)
234+
235+
// When - Set to true
236+
sut.allowFullSyncOnCellular = true
237+
238+
// Then - Value is persisted and can be retrieved
239+
#expect(siteSettings.mockPOSLocalCatalogCellularDataAllowed == true)
240+
#expect(sut.allowFullSyncOnCellular == true)
241+
242+
// When - Set to false
243+
sut.allowFullSyncOnCellular = false
244+
245+
// Then - Value is persisted and can be retrieved
246+
#expect(siteSettings.mockPOSLocalCatalogCellularDataAllowed == false)
247+
#expect(sut.allowFullSyncOnCellular == false)
248+
}
202249
}
203250

204251
private enum MockError: Error {

0 commit comments

Comments
 (0)