Skip to content

Commit 26b6249

Browse files
committed
Add remaining methods to CouponStoreMethods
1 parent 835331a commit 26b6249

File tree

6 files changed

+365
-244
lines changed

6 files changed

+365
-244
lines changed

.swiftlint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
swiftlint_version: 0.54.0
1+
swiftlint_version: 0.55.1
22

33
excluded:
44
- DerivedData

Yosemite/Yosemite.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
012848DC2D9ED55B00A9C69B /* SettingStoreMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012848DB2D9ED55700A9C69B /* SettingStoreMethods.swift */; };
11+
012848DE2D9EDAC100A9C69B /* MockCouponStoreMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012848DD2D9EDAC100A9C69B /* MockCouponStoreMethods.swift */; };
1112
0139C2B02D91D1C600C78FDE /* POSCart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0139C2AF2D91D1C400C78FDE /* POSCart.swift */; };
1213
016A776B2D9D30C90004FCD6 /* PointOfSaleCouponServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016A776A2D9D30C10004FCD6 /* PointOfSaleCouponServiceTests.swift */; };
1314
016A89D82D9D6DB50004FCD6 /* CouponStoreMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016A89D72D9D6DAE0004FCD6 /* CouponStoreMethods.swift */; };
@@ -558,6 +559,7 @@
558559

559560
/* Begin PBXFileReference section */
560561
012848DB2D9ED55700A9C69B /* SettingStoreMethods.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingStoreMethods.swift; sourceTree = "<group>"; };
562+
012848DD2D9EDAC100A9C69B /* MockCouponStoreMethods.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCouponStoreMethods.swift; sourceTree = "<group>"; };
561563
0139C2AF2D91D1C400C78FDE /* POSCart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSCart.swift; sourceTree = "<group>"; };
562564
016A776A2D9D30C10004FCD6 /* PointOfSaleCouponServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleCouponServiceTests.swift; sourceTree = "<group>"; };
563565
016A89D72D9D6DAE0004FCD6 /* CouponStoreMethods.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponStoreMethods.swift; sourceTree = "<group>"; };
@@ -2001,6 +2003,7 @@
20012003
B5C9DE1D2087FF20006B910A /* Mocks */ = {
20022004
isa = PBXGroup;
20032005
children = (
2006+
012848DD2D9EDAC100A9C69B /* MockCouponStoreMethods.swift */,
20042007
20CF75B72CF4C3AD00ACCF4A /* MockPOSOrdersRemote.swift */,
20052008
6801E41B2D1007D000F9DF46 /* MockPOSReceiptsRemote.swift */,
20062009
207D2D1C2CFA0CEF00F79204 /* MockPOSOrderableItem.swift */,
@@ -2871,6 +2874,7 @@
28712874
748525AC218A45360036DF75 /* NotificationStoreTests.swift in Sources */,
28722875
26E5A09225A8A453000DF8F6 /* ProductAttributeTermStoreTests.swift in Sources */,
28732876
020C908124C7D71D001E2BEB /* MockProductVariationsRemote.swift in Sources */,
2877+
012848DE2D9EDAC100A9C69B /* MockCouponStoreMethods.swift in Sources */,
28742878
020C907D24C729D6001E2BEB /* MockProductVariation.swift in Sources */,
28752879
7499936820EFC0ED00CF01CD /* OrderNoteStoreTests.swift in Sources */,
28762880
578CE7972475FD8200492EBF /* MockProductReview.swift in Sources */,

Yosemite/Yosemite/Stores/CouponStore.swift

Lines changed: 17 additions & 224 deletions
Original file line numberDiff line numberDiff line change
@@ -57,238 +57,31 @@ public final class CouponStore: Store {
5757
pageSize: pageSize,
5858
onCompletion: onCompletion)
5959
case .deleteCoupon(let siteID, let couponID, let onCompletion):
60-
deleteCoupon(siteID: siteID, couponID: couponID, onCompletion: onCompletion)
60+
methods.deleteCoupon(siteID: siteID, couponID: couponID, onCompletion: onCompletion)
6161
case .updateCoupon(let coupon, let siteTimezone, let onCompletion):
62-
updateCoupon(coupon, siteTimezone: siteTimezone, onCompletion: onCompletion)
62+
methods.updateCoupon(coupon, siteTimezone: siteTimezone, onCompletion: onCompletion)
6363
case .createCoupon(let coupon, let siteTimezone, let onCompletion):
64-
createCoupon(coupon, siteTimezone: siteTimezone, onCompletion: onCompletion)
64+
methods.createCoupon(coupon, siteTimezone: siteTimezone, onCompletion: onCompletion)
6565
case .loadCouponReport(let siteID, let couponID, let startDate, let onCompletion):
66-
loadCouponReport(siteID: siteID, couponID: couponID, startDate: startDate, onCompletion: onCompletion)
66+
methods.loadCouponReport(siteID: siteID, couponID: couponID, startDate: startDate, onCompletion: onCompletion)
6767
case .loadMostActiveCoupons(let siteID, let numberOfCouponsToLoad, let timeRange, let siteTimezone, let onCompletion):
68-
loadMostActiveCoupons(siteID: siteID,
69-
numberOfCouponsToLoad: numberOfCouponsToLoad,
70-
timeRange: timeRange,
71-
siteTimezone: siteTimezone,
72-
onCompletion: onCompletion)
68+
methods.loadMostActiveCoupons(siteID: siteID,
69+
numberOfCouponsToLoad: numberOfCouponsToLoad,
70+
timeRange: timeRange,
71+
siteTimezone: siteTimezone,
72+
onCompletion: onCompletion)
7373
case .searchCoupons(let siteID, let keyword, let pageNumber, let pageSize, let onCompletion):
74-
searchCoupons(siteID: siteID,
75-
keyword: keyword,
76-
pageNumber: pageNumber,
77-
pageSize: pageSize,
78-
onCompletion: onCompletion)
74+
methods.searchCoupons(siteID: siteID,
75+
keyword: keyword,
76+
pageNumber: pageNumber,
77+
pageSize: pageSize,
78+
onCompletion: onCompletion)
7979
case .retrieveCoupon(let siteID, let couponID, let onCompletion):
80-
retrieveCoupon(siteID: siteID, couponID: couponID, onCompletion: onCompletion)
80+
methods.retrieveCoupon(siteID: siteID, couponID: couponID, onCompletion: onCompletion)
8181
case .validateCouponCode(let code, let siteID, let onCompletion):
82-
validateCouponCode(code: code, siteID: siteID, onCompletion: onCompletion)
82+
methods.validateCouponCode(code: code, siteID: siteID, onCompletion: onCompletion)
8383
case .loadCoupons(let siteID, let couponIDs, let onCompletion):
84-
loadCoupons(siteID: siteID, couponIDs: couponIDs, onCompletion: onCompletion)
84+
methods.loadCoupons(siteID: siteID, couponIDs: couponIDs, onCompletion: onCompletion)
8585
}
8686
}
8787
}
88-
89-
// MARK: - Services
90-
//
91-
private extension CouponStore {
92-
/// Deletes a coupon from a Site with what is persisted in the storage layer.
93-
/// After the API request succeeds, the stored coupon should be removed from the local storage.
94-
/// - Parameters:
95-
/// - siteID: The site that the deleted coupon belongs to.
96-
/// - couponID: The ID of the coupon to be deleted.
97-
/// - onCompletion: Closure to call after deletion is complete. Called on the main thread.
98-
///
99-
func deleteCoupon(siteID: Int64, couponID: Int64, onCompletion: @escaping (Result<Void, Error>) -> Void) {
100-
remote.deleteCoupon(for: siteID, couponID: couponID) { [weak self] result in
101-
guard let self = self else { return }
102-
switch result {
103-
case .failure(let error):
104-
onCompletion(.failure(error))
105-
case .success(let coupon):
106-
// This is unlikely to happen, but worth checking
107-
guard coupon.siteID == siteID, coupon.couponID == couponID else {
108-
onCompletion(.failure(CouponError.unexpectedCouponDeleted))
109-
DDLogError("⛔️ Unexpected coupon: Deleted couponID \(coupon.couponID) for site \(coupon.siteID) " +
110-
"while expecting couponID \(couponID) and site \(siteID)")
111-
return
112-
}
113-
self.methods.deleteStoredCoupon(siteID: siteID, couponID: couponID) {
114-
onCompletion(.success(()))
115-
}
116-
}
117-
}
118-
}
119-
120-
/// Updates a coupon given its details.
121-
/// After the API request succeeds, the stored coupon should be updated accordingly.
122-
/// - Parameters:
123-
/// - coupon: The coupon to be updated
124-
/// - siteTimezone: the timezone configured on the site (also know as local time of the site).
125-
/// - onCompletion: Closure to call after update is complete. Called on the main thread.
126-
///
127-
func updateCoupon(_ coupon: Coupon,
128-
siteTimezone: TimeZone? = nil,
129-
onCompletion: @escaping (Result<Coupon, Error>) -> Void) {
130-
remote.updateCoupon(coupon, siteTimezone: siteTimezone) { [weak self] result in
131-
guard let self = self else { return }
132-
switch result {
133-
case .failure(let error):
134-
onCompletion(.failure(error))
135-
case .success(let updatedCoupon):
136-
self.methods.upsertStoredCouponsInBackground(readOnlyCoupons: [updatedCoupon], siteID: updatedCoupon.siteID) {
137-
onCompletion(.success(updatedCoupon))
138-
}
139-
}
140-
}
141-
}
142-
143-
/// Creates a coupon given its details.
144-
/// After the API request succeeds, a new stored coupon should be inserted into the local storage.
145-
/// - Parameters:
146-
/// - coupon: The coupon to be created
147-
/// - siteTimezone: the timezone configured on the site (also know as local time of the site).
148-
/// - onCompletion: Closure to call after creation is complete. Called on the main thread.
149-
///
150-
func createCoupon(_ coupon: Coupon,
151-
siteTimezone: TimeZone? = nil,
152-
onCompletion: @escaping (Result<Coupon, Error>) -> Void) {
153-
remote.createCoupon(coupon, siteTimezone: siteTimezone) { [weak self] result in
154-
guard let self = self else { return }
155-
switch result {
156-
case .failure(let error):
157-
onCompletion(.failure(error))
158-
case .success(let createdCoupon):
159-
self.methods.upsertStoredCouponsInBackground(readOnlyCoupons: [createdCoupon], siteID: createdCoupon.siteID) {
160-
onCompletion(.success(createdCoupon))
161-
}
162-
}
163-
}
164-
}
165-
166-
/// Loads analytics report for a coupon with the specified coupon ID and site ID.
167-
///
168-
/// - Parameters:
169-
/// - siteID: ID of the site that the coupon belongs to.
170-
/// - couponID: ID of the coupon to load the analytics report for.
171-
/// - startDate: the start of the date range to load the analytics report for.
172-
/// - onCompletion: invoked when the creation finishes.
173-
///
174-
func loadCouponReport(siteID: Int64, couponID: Int64, startDate: Date, onCompletion: @escaping (Result<CouponReport, Error>) -> Void) {
175-
remote.loadCouponReport(for: siteID, couponID: couponID, from: startDate, completion: onCompletion)
176-
}
177-
178-
/// Loads top 3 most active coupons report within the specified time range and site ID.
179-
///
180-
/// - `siteID`: site ID.
181-
/// - `numberOfCouponsToLoad`: Number of coupons to load.
182-
/// - `timeRange`: Time range to fetch report for.
183-
/// - `siteTimezone`: site's timezone
184-
/// - `onCompletion`: invoked when the reports are fetched.
185-
///
186-
func loadMostActiveCoupons(siteID: Int64,
187-
numberOfCouponsToLoad: Int,
188-
timeRange: StatsTimeRangeV4,
189-
siteTimezone: TimeZone,
190-
onCompletion: @escaping (Result<[CouponReport], Error>) -> Void) {
191-
let to = timeRange.latestDate(currentDate: Date(), siteTimezone: siteTimezone)
192-
let from = timeRange.earliestDate(latestDate: to, siteTimezone: siteTimezone)
193-
remote.loadMostActiveCoupons(for: siteID,
194-
numberOfCouponsToLoad: numberOfCouponsToLoad,
195-
from: from,
196-
to: to,
197-
completion: onCompletion)
198-
}
199-
200-
/// Search coupons from a Site that match a specified keyword.
201-
/// Search results are persisted in the local storage to ensure
202-
/// good performance for future search of the same keyword.
203-
///
204-
/// - Parameters:
205-
/// - siteId: The site to search coupons for.
206-
/// - keyword: The string to match the results with.
207-
/// - pageNumber: Page number of coupons to fetch from the API
208-
/// - pageSize: Number of coupons per page to fetch from the API
209-
/// - onCompletion: Closure to call after the search is complete. Called on the main thread.
210-
///
211-
func searchCoupons(siteID: Int64,
212-
keyword: String,
213-
pageNumber: Int,
214-
pageSize: Int,
215-
onCompletion: @escaping (_ result: Result<Void, Error>) -> Void) {
216-
remote.searchCoupons(for: siteID,
217-
keyword: keyword,
218-
pageNumber: pageNumber,
219-
pageSize: pageSize) { [weak self] result in
220-
guard let self = self else { return }
221-
switch result {
222-
case .failure(let error):
223-
onCompletion(.failure(error))
224-
case .success(let coupons):
225-
self.methods.upsertSearchResultsInBackground(siteID: siteID,
226-
keyword: keyword,
227-
readOnlyCoupons: coupons) {
228-
onCompletion(.success(()))
229-
}
230-
}
231-
}
232-
}
233-
234-
/// Retrieve a coupon from a Site given.
235-
/// The fetched coupon is persisted to the local storage.
236-
///
237-
/// - Parameters:
238-
/// - siteID: The site to retrieve the coupon for.
239-
/// - couponID: ID of the coupon to be retrieved.
240-
/// - onCompletion: Closure to call upon completion. Called on the main thread.
241-
///
242-
func retrieveCoupon(siteID: Int64,
243-
couponID: Int64,
244-
onCompletion: @escaping (_ result: Result<Coupon, Error>) -> Void) {
245-
remote.retrieveCoupon(for: siteID,
246-
couponID: couponID) { [weak self] result in
247-
guard let self = self else { return }
248-
switch result {
249-
case .failure(let error):
250-
onCompletion(.failure(error))
251-
case .success(let coupon):
252-
self.methods.upsertStoredCouponsInBackground(readOnlyCoupons: [coupon], siteID: siteID) {
253-
onCompletion(.success(coupon))
254-
}
255-
}
256-
}
257-
}
258-
/// Loads the coupons for a site given all the coupon IDs
259-
///
260-
/// - `siteID`: the site for which coupons should be fetched.
261-
/// - `couponIDs`: IDs of the coupons to be retrieved.
262-
/// - `onCompletion`: invoked upon completion.
263-
///
264-
func loadCoupons(siteID: Int64,
265-
couponIDs: [Int64],
266-
onCompletion: @escaping (_ result: Result<[Coupon], Error>) -> Void) {
267-
remote.loadCoupons(for: siteID, by: couponIDs) { [weak self] result in
268-
guard let self = self else { return }
269-
switch result {
270-
case .failure(let error):
271-
onCompletion(.failure(error))
272-
case .success(let coupons):
273-
self.methods.upsertStoredCouponsInBackground(readOnlyCoupons: coupons, siteID: siteID) {
274-
onCompletion(.success(coupons))
275-
}
276-
}
277-
}
278-
}
279-
280-
func validateCouponCode(code: String, siteID: Int64, onCompletion: @escaping (Result<Bool, Error>) -> Void) {
281-
remote.searchCoupons(for: siteID, keyword: code, pageNumber: Remote.Default.firstPageNumber, pageSize: 25) { result in
282-
switch result {
283-
case let .success(coupons):
284-
onCompletion(.success(coupons.contains(where: { $0.code == code })))
285-
case let .failure(error):
286-
onCompletion(.failure(error))
287-
}
288-
}
289-
}
290-
}
291-
292-
public enum CouponError: Error {
293-
case unexpectedCouponDeleted
294-
}

0 commit comments

Comments
 (0)