Skip to content

Commit 11c718f

Browse files
authored
Merge branch 'trunk' into issue/7766-suggestion-connect-jectpack-wpcom
2 parents 54ad5d7 + a75994f commit 11c718f

File tree

40 files changed

+1512
-69
lines changed

40 files changed

+1512
-69
lines changed

Experiments/Experiments/DefaultFeatureFlagService.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
3333
return true
3434
case .promptToEnableCodInIppOnboarding:
3535
return true
36+
case .searchProductsBySKU:
37+
return buildConfig == .localDeveloper || buildConfig == .alpha
3638
case .orderCreationSearchCustomers:
3739
return buildConfig == .localDeveloper || buildConfig == .alpha
3840
default:

Experiments/Experiments/FeatureFlag.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ public enum FeatureFlag: Int {
7070
///
7171
case promptToEnableCodInIppOnboarding
7272

73+
/// Enables searching products by partial SKU for WC version 6.6+.
74+
///
75+
case searchProductsBySKU
76+
7377
/// Enables the Search Customers functionality in the Order Creation screen
7478
///
7579
case orderCreationSearchCustomers

Networking/Networking.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
025CA2C4238EBC4300B05C81 /* ProductShippingClassRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 025CA2C3238EBC4300B05C81 /* ProductShippingClassRemote.swift */; };
3131
025CA2C6238F4F3500B05C81 /* ProductShippingClassRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 025CA2C5238F4F3500B05C81 /* ProductShippingClassRemoteTests.swift */; };
3232
025CA2C8238F4FF400B05C81 /* product-shipping-classes-load-all.json in Resources */ = {isa = PBXBuildFile; fileRef = 025CA2C7238F4FF400B05C81 /* product-shipping-classes-load-all.json */; };
33+
0261F5A928D4641500B7AC72 /* products-sku-search.json in Resources */ = {isa = PBXBuildFile; fileRef = 0261F5A828D4641500B7AC72 /* products-sku-search.json */; };
3334
02698CF624C17FC1005337C4 /* product-alternative-types.json in Resources */ = {isa = PBXBuildFile; fileRef = 02698CF524C17FC1005337C4 /* product-alternative-types.json */; };
3435
02698CF824C183A5005337C4 /* ProductVariationListMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02698CF724C183A5005337C4 /* ProductVariationListMapperTests.swift */; };
3536
02698CFA24C188E9005337C4 /* product-variations-load-all-alternative-types.json in Resources */ = {isa = PBXBuildFile; fileRef = 02698CF924C188E8005337C4 /* product-variations-load-all-alternative-types.json */; };
@@ -727,6 +728,7 @@
727728
025CA2C3238EBC4300B05C81 /* ProductShippingClassRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductShippingClassRemote.swift; sourceTree = "<group>"; };
728729
025CA2C5238F4F3500B05C81 /* ProductShippingClassRemoteTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductShippingClassRemoteTests.swift; sourceTree = "<group>"; };
729730
025CA2C7238F4FF400B05C81 /* product-shipping-classes-load-all.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-shipping-classes-load-all.json"; sourceTree = "<group>"; };
731+
0261F5A828D4641500B7AC72 /* products-sku-search.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "products-sku-search.json"; sourceTree = "<group>"; };
730732
02698CF524C17FC1005337C4 /* product-alternative-types.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-alternative-types.json"; sourceTree = "<group>"; };
731733
02698CF724C183A5005337C4 /* ProductVariationListMapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductVariationListMapperTests.swift; sourceTree = "<group>"; };
732734
02698CF924C188E8005337C4 /* product-variations-load-all-alternative-types.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-variations-load-all-alternative-types.json"; sourceTree = "<group>"; };
@@ -1999,6 +2001,7 @@
19992001
451274A525276C82009911FF /* product-variation.json */,
20002002
CE0A0F1E223998A00075ED8D /* products-load-all.json */,
20012003
0282DD90233A120A006A5FDB /* products-search-photo.json */,
2004+
0261F5A828D4641500B7AC72 /* products-sku-search.json */,
20022005
45D685F923D0C3CF005F87D0 /* product-search-sku.json */,
20032006
4599FC5B24A6276F0056157A /* product-tags-all.json */,
20042007
45AF57A824AB42CD0088E2F7 /* product-tags-extra.json */,
@@ -2518,6 +2521,7 @@
25182521
D865CE5F278CA183002C8520 /* stripe-payment-intent-requires-action.json in Resources */,
25192522
CCF48B2C2628AE160034EA83 /* shipping-label-account-settings.json in Resources */,
25202523
31A451D927863A2E00FE81AA /* stripe-account-live-test.json in Resources */,
2524+
0261F5A928D4641500B7AC72 /* products-sku-search.json in Resources */,
25212525
09885C8027C3FFD200910A62 /* product-variations-bulk-update.json in Resources */,
25222526
31054734262E36AB00C5C02B /* wcpay-payment-intent-error.json in Resources */,
25232527
02AF07EE27493AE700B2D81E /* media-upload-to-wordpress-site.json in Resources */,

Networking/Networking/Remote/ProductsRemote.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public protocol ProductsRemoteProtocol {
3131
productCategory: ProductCategory?,
3232
excludedProductIDs: [Int64],
3333
completion: @escaping (Result<[Product], Error>) -> Void)
34+
func searchProductsBySKU(for siteID: Int64,
35+
keyword: String,
36+
pageNumber: Int,
37+
pageSize: Int,
38+
completion: @escaping (Result<[Product], Error>) -> Void)
3439
func searchSku(for siteID: Int64,
3540
sku: String,
3641
completion: @escaping (Result<String, Error>) -> Void)
@@ -238,6 +243,30 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
238243
enqueue(request, mapper: mapper, completion: completion)
239244
}
240245

246+
/// Retrieves all of the `Product`s that match the SKU. Partial SKU search is supported for WooCommerce version 6.6+, otherwise full SKU match is performed.
247+
/// - Parameters:
248+
/// - siteID: Site for which we'll fetch remote products
249+
/// - keyword: Search string that should be matched by the SKU (partial or full depending on the WC version).
250+
/// - pageNumber: Number of page that should be retrieved.
251+
/// - pageSize: Number of products to be retrieved per page.
252+
/// - completion: Closure to be executed upon completion.
253+
public func searchProductsBySKU(for siteID: Int64,
254+
keyword: String,
255+
pageNumber: Int,
256+
pageSize: Int,
257+
completion: @escaping (Result<[Product], Error>) -> Void) {
258+
let parameters = [
259+
ParameterKey.sku: keyword,
260+
ParameterKey.partialSKUSearch: keyword,
261+
ParameterKey.page: String(pageNumber),
262+
ParameterKey.perPage: String(pageSize)
263+
]
264+
let path = Path.products
265+
let request = JetpackRequest(wooApiVersion: .mark3, method: .get, siteID: siteID, path: path, parameters: parameters)
266+
let mapper = ProductListMapper(siteID: siteID)
267+
enqueue(request, mapper: mapper, completion: completion)
268+
}
269+
241270
/// Retrieves a product SKU if available.
242271
///
243272
/// - Parameters:
@@ -329,6 +358,7 @@ public extension ProductsRemote {
329358
static let orderBy: String = "orderby"
330359
static let order: String = "order"
331360
static let sku: String = "sku"
361+
static let partialSKUSearch: String = "search_sku"
332362
static let productStatus: String = "status"
333363
static let productType: String = "type"
334364
static let stockStatus: String = "stock_status"

Networking/NetworkingTests/Remote/ProductsRemoteTests.swift

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ final class ProductsRemoteTests: XCTestCase {
395395

396396
/// Verifies that searchProducts properly relays Networking Layer errors.
397397
///
398-
func test_searchProducts_properly_relays_netwoking_errors() {
398+
func test_searchProducts_properly_relays_networking_errors() {
399399
// Given
400400
let remote = ProductsRemote(network: network)
401401

@@ -413,6 +413,47 @@ final class ProductsRemoteTests: XCTestCase {
413413
XCTAssertTrue(result.isFailure)
414414
}
415415

416+
// MARK: - Search Products by SKU
417+
418+
func test_searchProductsBySKU_properly_returns_parsed_products() throws {
419+
// Given
420+
let remote = ProductsRemote(network: network)
421+
network.simulateResponse(requestUrlSuffix: "products", filename: "products-sku-search")
422+
423+
// When
424+
let result: Result<[Product], Error> = waitFor { promise in
425+
remote.searchProductsBySKU(for: self.sampleSiteID,
426+
keyword: "choco",
427+
pageNumber: 0,
428+
pageSize: 100) { result in
429+
promise(result)
430+
}
431+
}
432+
433+
// Then
434+
XCTAssertTrue(result.isSuccess)
435+
let products = try result.get()
436+
XCTAssertEqual(products.count, 1)
437+
}
438+
439+
func test_searchProductsBySKU_properly_relays_networking_errors() {
440+
// Given
441+
let remote = ProductsRemote(network: network)
442+
443+
// When
444+
let result: Result<[Product], Error> = waitFor { promise in
445+
remote.searchProductsBySKU(for: self.sampleSiteID,
446+
keyword: String(),
447+
pageNumber: 0,
448+
pageSize: 100) { result in
449+
promise(result)
450+
}
451+
}
452+
453+
// Then
454+
XCTAssertTrue(result.isFailure)
455+
}
456+
416457

417458
// MARK: - Search Product SKU tests
418459

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"data": [
3+
{
4+
"id": 2783,
5+
"name": "Chocolate bars",
6+
"slug": "variable-chocolate-bar",
7+
"permalink": "",
8+
"date_created": "2020-06-12T22:36:02",
9+
"date_created_gmt": "2020-06-12T14:36:02",
10+
"date_modified": "2021-02-23T10:46:54",
11+
"date_modified_gmt": "2021-02-23T02:46:54",
12+
"type": "variation",
13+
"status": "publish",
14+
"featured": false,
15+
"catalog_visibility": "visible",
16+
"description": "<p>Tasty!!</p>\n",
17+
"short_description": "",
18+
"sku": "chocobars",
19+
"price": "22",
20+
"regular_price": "999",
21+
"sale_price": "22",
22+
"date_on_sale_from": null,
23+
"date_on_sale_from_gmt": null,
24+
"date_on_sale_to": null,
25+
"date_on_sale_to_gmt": null,
26+
"on_sale": true,
27+
"purchasable": true,
28+
"total_sales": "0",
29+
"virtual": false,
30+
"downloadable": false,
31+
"downloads": [],
32+
"download_limit": -1,
33+
"download_expiry": -1,
34+
"external_url": "",
35+
"button_text": "",
36+
"tax_status": "taxable",
37+
"tax_class": "reduced-rate",
38+
"manage_stock": "parent",
39+
"stock_quantity": 7774,
40+
"backorders": "no",
41+
"backorders_allowed": false,
42+
"backordered": false,
43+
"low_stock_amount": null,
44+
"sold_individually": false,
45+
"weight": "67",
46+
"dimensions": {
47+
"length": "6",
48+
"width": "",
49+
"height": "1"
50+
},
51+
"shipping_required": true,
52+
"shipping_taxable": true,
53+
"shipping_class": "10-day-shipping",
54+
"shipping_class_id": 96987521,
55+
"reviews_allowed": false,
56+
"average_rating": "0.00",
57+
"rating_count": 0,
58+
"upsell_ids": [],
59+
"cross_sell_ids": [],
60+
"parent_id": 846,
61+
"purchase_note": "",
62+
"categories": [],
63+
"tags": [],
64+
"images": [],
65+
"attributes": [
66+
{
67+
"id": 0,
68+
"name": "Darkness",
69+
"option": "87%"
70+
}
71+
],
72+
"default_attributes": [],
73+
"variations": [],
74+
"grouped_products": [],
75+
"menu_order": 6,
76+
"related_ids": [],
77+
"meta_data": [],
78+
"stock_status": "instock",
79+
"has_options": false,
80+
}
81+
]
82+
}

RELEASE-NOTES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
- [*] Fixed a rare crash when selecting a store in the store picker. [https://github.com/woocommerce/woocommerce-ios/pull/7765]
77
- [*] Show suggestion for logging in to a WP.com site with a mismatched WP.com account. [https://github.com/woocommerce/woocommerce-ios/pull/7773]
8-
- [*] Help center: Added help center web page with FAQs for "Not a WooCommerce site" error screen. [https://github.com/woocommerce/woocommerce-ios/pull/7767]
8+
- [*] Help center: Added help center web page with FAQs for "Not a WooCommerce site" and "Wrong WordPress.com account" error screens. [https://github.com/woocommerce/woocommerce-ios/pull/7767, https://github.com/woocommerce/woocommerce-ios/pull/7769]
99

1010
10.5
1111
-----

Storage/Storage.xcodeproj/project.pbxproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@
243243
023FA29423316A4D008C1769 /* ProductSearchResults+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ProductSearchResults+CoreDataClass.swift"; sourceTree = "<group>"; };
244244
025CA2BB238EB86200B05C81 /* ProductShippingClass+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProductShippingClass+CoreDataClass.swift"; sourceTree = "<group>"; };
245245
025CA2BC238EB86200B05C81 /* ProductShippingClass+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProductShippingClass+CoreDataProperties.swift"; sourceTree = "<group>"; };
246+
027CE79D28D167D0001B8D0E /* Model 73.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Model 73.xcdatamodel"; sourceTree = "<group>"; };
246247
027D3E6D23A0EEA4007D91B0 /* StorageType+Deletions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StorageType+Deletions.swift"; sourceTree = "<group>"; };
247248
028296EE237D404F00E84012 /* ProductVariation+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProductVariation+CoreDataClass.swift"; sourceTree = "<group>"; };
248249
028296EF237D404F00E84012 /* ProductVariation+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProductVariation+CoreDataProperties.swift"; sourceTree = "<group>"; };
@@ -1789,6 +1790,7 @@
17891790
DEC51AA4275B41BE009F3DF4 /* WooCommerce.xcdatamodeld */ = {
17901791
isa = XCVersionGroup;
17911792
children = (
1793+
027CE79D28D167D0001B8D0E /* Model 73.xcdatamodel */,
17921794
0372D8B828AFD9530041028A /* Model 72.xcdatamodel */,
17931795
CC6A05402877012B002C144E /* Model 71.xcdatamodel */,
17941796
B963A5CA2853859400EFADA0 /* Model 70.xcdatamodel */,
@@ -1862,7 +1864,7 @@
18621864
DEC51ADE275B41BE009F3DF4 /* Model 47.xcdatamodel */,
18631865
DEC51ADF275B41BE009F3DF4 /* Model 19.xcdatamodel */,
18641866
);
1865-
currentVersion = 0372D8B828AFD9530041028A /* Model 72.xcdatamodel */;
1867+
currentVersion = 027CE79D28D167D0001B8D0E /* Model 73.xcdatamodel */;
18661868
path = WooCommerce.xcdatamodeld;
18671869
sourceTree = "<group>";
18681870
versionGroupType = wrapper.xcdatamodel;

Storage/Storage/Model/MIGRATIONS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
This file documents changes in the WCiOS Storage data model. Please explain any changes to the data model as well as any custom migrations.
44

5+
## Model 73 (Release 10.6.0.0)
6+
- @jaclync 2022-09-14
7+
- Added `filterKey` attribute to `ProductSearchResults` entity.
8+
59
## Model 71 (Release 9.6.0.0)
610
- @joshheald 2022-08-19
711
- Added `instructions` attribute to `PaymentGateway` entity.

Storage/Storage/Model/ProductSearchResults+CoreDataProperties.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ extension ProductSearchResults {
88
return NSFetchRequest<ProductSearchResults>(entityName: "ProductSearchResults")
99
}
1010

11+
@NSManaged public var filterKey: String?
1112
@NSManaged public var keyword: String?
1213
@NSManaged public var products: Set<Product>?
1314

@@ -29,3 +30,7 @@ extension ProductSearchResults {
2930
@NSManaged public func removeFromProducts(_ values: NSSet)
3031

3132
}
33+
34+
extension ProductSearchResults: Identifiable {
35+
36+
}

0 commit comments

Comments
 (0)