Skip to content

Commit 9b2b8ee

Browse files
committed
Merge branch 'trunk' into issue/7976-products-onboarding-banner-ui
2 parents 92e7282 + 1d7fc6f commit 9b2b8ee

File tree

26 files changed

+530
-76
lines changed

26 files changed

+530
-76
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<!--
22
Contains editorialized release notes. Raw release notes should go into `RELEASE-NOTES.txt`.
33
-->
4+
## 11.0
5+
Even though this release doesn’t have any surprising new features, we still put a lot of love into it! We fixed a few bugs and made several improvements to make your experience smoother.
6+
47
## 10.9
58
This release includes a lot more stability fixes to help you log in much easier. You can now connect your WordPress.com account with Jetpack and access your store that much faster. We've also updated our app to support devices with iOS 15+ only. Please update your device to iOS 15 to continue to use the app.
69

Gemfile.lock

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,20 @@ GEM
1717
ast (2.4.2)
1818
atomos (0.1.3)
1919
aws-eventstream (1.2.0)
20-
aws-partitions (1.631.0)
21-
aws-sdk-core (3.148.0)
20+
aws-partitions (1.653.0)
21+
aws-sdk-core (3.166.0)
2222
aws-eventstream (~> 1, >= 1.0.2)
23-
aws-partitions (~> 1, >= 1.525.0)
24-
aws-sigv4 (~> 1.1)
23+
aws-partitions (~> 1, >= 1.651.0)
24+
aws-sigv4 (~> 1.5)
2525
jmespath (~> 1, >= 1.6.1)
26-
aws-sdk-kms (1.58.0)
27-
aws-sdk-core (~> 3, >= 3.127.0)
26+
aws-sdk-kms (1.59.0)
27+
aws-sdk-core (~> 3, >= 3.165.0)
2828
aws-sigv4 (~> 1.1)
29-
aws-sdk-s3 (1.114.0)
30-
aws-sdk-core (~> 3, >= 3.127.0)
29+
aws-sdk-s3 (1.117.1)
30+
aws-sdk-core (~> 3, >= 3.165.0)
3131
aws-sdk-kms (~> 1)
3232
aws-sigv4 (~> 1.4)
33-
aws-sigv4 (1.5.1)
33+
aws-sigv4 (1.5.2)
3434
aws-eventstream (~> 1, >= 1.0.2)
3535
babosa (1.0.4)
3636
bigdecimal (1.4.4)
@@ -94,7 +94,7 @@ GEM
9494
escape (0.0.4)
9595
ethon (0.15.0)
9696
ffi (>= 1.15.0)
97-
excon (0.92.4)
97+
excon (0.93.1)
9898
faraday (1.10.2)
9999
faraday-em_http (~> 1.0)
100100
faraday-em_synchrony (~> 1.0)
@@ -124,7 +124,7 @@ GEM
124124
faraday_middleware (1.2.0)
125125
faraday (~> 1.0)
126126
fastimage (2.2.6)
127-
fastlane (2.210.0)
127+
fastlane (2.210.1)
128128
CFPropertyList (>= 2.3, < 4.0.0)
129129
addressable (>= 2.8, < 3.0.0)
130130
artifactory (~> 3.0)
@@ -164,8 +164,9 @@ GEM
164164
xcpretty (~> 0.3.0)
165165
xcpretty-travis-formatter (>= 0.0.3)
166166
fastlane-plugin-appcenter (1.11.1)
167-
fastlane-plugin-sentry (1.11.1)
168-
fastlane-plugin-wpmreleasetoolkit (5.5.0)
167+
fastlane-plugin-sentry (1.14.0)
168+
os (~> 1.1, >= 1.1.4)
169+
fastlane-plugin-wpmreleasetoolkit (5.6.0)
169170
activesupport (~> 5)
170171
bigdecimal (~> 1.4)
171172
buildkit (~> 1.5)
@@ -188,9 +189,9 @@ GEM
188189
git (1.12.0)
189190
addressable (~> 2.8)
190191
rchardet (~> 1.8)
191-
google-apis-androidpublisher_v3 (0.26.0)
192-
google-apis-core (>= 0.7, < 2.a)
193-
google-apis-core (0.7.2)
192+
google-apis-androidpublisher_v3 (0.29.0)
193+
google-apis-core (>= 0.9.0, < 2.a)
194+
google-apis-core (0.9.1)
194195
addressable (~> 2.5, >= 2.5.1)
195196
googleauth (>= 0.16.2, < 2.a)
196197
httpclient (>= 2.8.1, < 3.a)
@@ -199,27 +200,27 @@ GEM
199200
retriable (>= 2.0, < 4.a)
200201
rexml
201202
webrick
202-
google-apis-iamcredentials_v1 (0.13.0)
203-
google-apis-core (>= 0.7, < 2.a)
204-
google-apis-playcustomapp_v1 (0.10.0)
205-
google-apis-core (>= 0.7, < 2.a)
206-
google-apis-storage_v1 (0.17.0)
207-
google-apis-core (>= 0.7, < 2.a)
203+
google-apis-iamcredentials_v1 (0.15.0)
204+
google-apis-core (>= 0.9.0, < 2.a)
205+
google-apis-playcustomapp_v1 (0.12.0)
206+
google-apis-core (>= 0.9.1, < 2.a)
207+
google-apis-storage_v1 (0.19.0)
208+
google-apis-core (>= 0.9.0, < 2.a)
208209
google-cloud-core (1.6.0)
209210
google-cloud-env (~> 1.0)
210211
google-cloud-errors (~> 1.0)
211212
google-cloud-env (1.6.0)
212213
faraday (>= 0.17.3, < 3.0)
213214
google-cloud-errors (1.3.0)
214-
google-cloud-storage (1.40.0)
215+
google-cloud-storage (1.43.0)
215216
addressable (~> 2.8)
216217
digest-crc (~> 0.4)
217218
google-apis-iamcredentials_v1 (~> 0.1)
218-
google-apis-storage_v1 (~> 0.17.0)
219+
google-apis-storage_v1 (~> 0.19.0)
219220
google-cloud-core (~> 1.6)
220221
googleauth (>= 0.16.2, < 2.a)
221222
mini_mime (~> 1.0)
222-
googleauth (1.2.0)
223+
googleauth (1.3.0)
223224
faraday (>= 0.17.3, < 3.a)
224225
jwt (>= 1.4, < 3.0)
225226
memoist (~> 0.16)
@@ -250,10 +251,10 @@ GEM
250251
nap (1.1.0)
251252
naturally (2.2.1)
252253
netrc (0.11.0)
253-
nokogiri (1.13.8)
254+
nokogiri (1.13.9)
254255
mini_portile2 (~> 2.8.0)
255256
racc (~> 1.4)
256-
nokogiri (1.13.8-x86_64-darwin)
257+
nokogiri (1.13.9-x86_64-darwin)
257258
racc (~> 1.4)
258259
octokit (4.25.1)
259260
faraday (>= 1, < 3)

Networking/Networking.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@
164164
2670C3FE270F4E6A002FE931 /* sites-malformed.json in Resources */ = {isa = PBXBuildFile; fileRef = 2670C3FD270F4E6A002FE931 /* sites-malformed.json */; };
165165
267313312559CC930026F7EF /* PaymentGateway.swift in Sources */ = {isa = PBXBuildFile; fileRef = 267313302559CC930026F7EF /* PaymentGateway.swift */; };
166166
26731337255ACA850026F7EF /* PaymentGatewayListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26731336255ACA850026F7EF /* PaymentGatewayListMapper.swift */; };
167+
2676F4CE290AE6BB00C7A15B /* EntityIDMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2676F4CD290AE6BB00C7A15B /* EntityIDMapper.swift */; };
168+
2676F4D0290B0EC800C7A15B /* product-id-only.json in Resources */ = {isa = PBXBuildFile; fileRef = 2676F4CF290B0EC700C7A15B /* product-id-only.json */; };
167169
2683D70E24456DB8002A1589 /* categories-empty.json in Resources */ = {isa = PBXBuildFile; fileRef = 2683D70D24456DB7002A1589 /* categories-empty.json */; };
168170
2683D71024456EE4002A1589 /* categories-extra.json in Resources */ = {isa = PBXBuildFile; fileRef = 2683D70F24456EE4002A1589 /* categories-extra.json */; };
169171
2685C0D2263B069500D9EE97 /* AddOnGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2685C0D1263B069500D9EE97 /* AddOnGroup.swift */; };
@@ -887,6 +889,8 @@
887889
2670C3FD270F4E6A002FE931 /* sites-malformed.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "sites-malformed.json"; sourceTree = "<group>"; };
888890
267313302559CC930026F7EF /* PaymentGateway.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentGateway.swift; sourceTree = "<group>"; };
889891
26731336255ACA850026F7EF /* PaymentGatewayListMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentGatewayListMapper.swift; sourceTree = "<group>"; };
892+
2676F4CD290AE6BB00C7A15B /* EntityIDMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityIDMapper.swift; sourceTree = "<group>"; };
893+
2676F4CF290B0EC700C7A15B /* product-id-only.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-id-only.json"; sourceTree = "<group>"; };
890894
2683D70D24456DB7002A1589 /* categories-empty.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "categories-empty.json"; sourceTree = "<group>"; };
891895
2683D70F24456EE4002A1589 /* categories-extra.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "categories-extra.json"; sourceTree = "<group>"; };
892896
2685C0D1263B069500D9EE97 /* AddOnGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOnGroup.swift; sourceTree = "<group>"; };
@@ -2083,6 +2087,7 @@
20832087
09885C7F27C3FFD200910A62 /* product-variations-bulk-update.json */,
20842088
451274A525276C82009911FF /* product-variation.json */,
20852089
CE0A0F1E223998A00075ED8D /* products-load-all.json */,
2090+
2676F4CF290B0EC700C7A15B /* product-id-only.json */,
20862091
CCF434652906C2A400B4475A /* products-ids-only.json */,
20872092
CCF434692906C9C300B4475A /* products-ids-only-empty.json */,
20882093
0282DD90233A120A006A5FDB /* products-search-photo.json */,
@@ -2215,6 +2220,7 @@
22152220
DE2095BE279583A100171F1C /* CouponReportListMapper.swift */,
22162221
45150A9D26836A57006922EA /* CountryListMapper.swift */,
22172222
B524193E21AC5FE400D6FC0A /* DotcomDeviceMapper.swift */,
2223+
2676F4CD290AE6BB00C7A15B /* EntityIDMapper.swift */,
22182224
24F98C572502EA8800F49B68 /* FeatureFlagMapper.swift */,
22192225
DE50295C28C6068B00551736 /* JetpackUserMapper.swift */,
22202226
AEF9458A27297FF6001DCCFB /* IgnoringResponseMapper.swift */,
@@ -2821,6 +2827,7 @@
28212827
68CB801628D8A39700E169F8 /* customer.json in Resources */,
28222828
03EB99982907F4AA00F06A39 /* just-in-time-message-list-multiple.json in Resources */,
28232829
451A97DE260B59870059D135 /* shipping-label-packages-success.json in Resources */,
2830+
2676F4D0290B0EC800C7A15B /* product-id-only.json in Resources */,
28242831
31D27C8F2602B553002EDB1D /* plugins.json in Resources */,
28252832
261CF1B4255AD6B30090D8D3 /* payment-gateway-list.json in Resources */,
28262833
268B68FB24C87384007EBF1D /* leaderboards-products.json in Resources */,
@@ -3240,6 +3247,7 @@
32403247
029BA53B255DFABD006171FD /* ShippingLabelPrintDataMapper.swift in Sources */,
32413248
0359EA0D27AAC5F80048DE2D /* WCPayChargeStatus.swift in Sources */,
32423249
CE430674234BA6AD0073CBFF /* RefundMapper.swift in Sources */,
3250+
2676F4CE290AE6BB00C7A15B /* EntityIDMapper.swift in Sources */,
32433251
CE0A0F1B223989670075ED8D /* ProductsRemote.swift in Sources */,
32443252
0359EA1527AAC7460048DE2D /* WCPayCardBrand.swift in Sources */,
32453253
2665032E261F4FBF0079A159 /* ProductAddOnOption.swift in Sources */,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Foundation
2+
3+
/// Mapper: Single Entity ID
4+
///
5+
struct EntityIDMapper: Mapper {
6+
7+
/// (Attempts) to convert an instance of Data into an into an ID
8+
///
9+
func map(response: Data) throws -> Int64 {
10+
let decoder = JSONDecoder()
11+
12+
return try decoder.decode(EntityIDEnvelope.self, from: response).id
13+
}
14+
}
15+
16+
/// Disposable Entity:
17+
/// Allows us to parse a product ID with JSONDecoder.
18+
///
19+
private struct EntityIDEnvelope: Decodable {
20+
private let data: [String: Int64]
21+
22+
// Extracts the entity ID from the underlying data
23+
var id: Int64 {
24+
data["id"] ?? .zero
25+
}
26+
27+
private enum CodingKeys: String, CodingKey {
28+
case data = "data"
29+
}
30+
}

Networking/Networking/Model/Product/ProductStatus.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public enum ProductStatus: Codable, Hashable, GeneratedFakeable {
88
case draft
99
case pending
1010
case privateStatus // `private` is a reserved keyword
11+
case autoDraft
1112
case custom(String) // in case there are extensions modifying product statuses
1213
}
1314

@@ -28,6 +29,8 @@ extension ProductStatus: RawRepresentable {
2829
self = .pending
2930
case Keys.privateStatus:
3031
self = .privateStatus
32+
case Keys.autoDraft:
33+
self = .autoDraft
3134
default:
3235
self = .custom(rawValue)
3336
}
@@ -41,6 +44,7 @@ extension ProductStatus: RawRepresentable {
4144
case .draft: return Keys.draft
4245
case .pending: return Keys.pending
4346
case .privateStatus: return Keys.privateStatus
47+
case .autoDraft: return Keys.autoDraft
4448
case .custom(let payload): return payload
4549
}
4650
}
@@ -57,6 +61,8 @@ extension ProductStatus: RawRepresentable {
5761
return NSLocalizedString("Pending review", comment: "Display label for the product's pending status")
5862
case .privateStatus:
5963
return NSLocalizedString("Privately published", comment: "Display label for the product's private status")
64+
case .autoDraft:
65+
return "Auto Draft" // We don't need to localize this now.
6066
case .custom(let payload):
6167
return payload // unable to localize at runtime.
6268
}
@@ -71,4 +77,5 @@ private enum Keys {
7177
static let draft = "draft"
7278
static let pending = "pending"
7379
static let privateStatus = "private"
80+
static let autoDraft = "auto-draft"
7481
}

Networking/Networking/Remote/ProductsRemote.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public protocol ProductsRemoteProtocol {
4242
func updateProduct(product: Product, completion: @escaping (Result<Product, Error>) -> Void)
4343
func updateProductImages(siteID: Int64, productID: Int64, images: [ProductImage], completion: @escaping (Result<Product, Error>) -> Void)
4444
func loadProductIDs(for siteID: Int64, pageNumber: Int, pageSize: Int, completion: @escaping (Result<[Int64], Error>) -> Void)
45+
func createTemplateProduct(for siteID: Int64, template: ProductsRemote.TemplateType, completion: @escaping (Result<Int64, Error>) -> Void)
4546
}
4647

4748
extension ProductsRemoteProtocol {
@@ -348,6 +349,19 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
348349

349350
enqueue(request, mapper: mapper, completion: completion)
350351
}
352+
353+
/// Creates a product using the provided template.
354+
/// Finishes with a completion block with the product ID.
355+
/// The created product has an `auto-draft` status.
356+
///
357+
public func createTemplateProduct(for siteID: Int64, template: ProductsRemote.TemplateType, completion: @escaping (Result<Int64, Error>) -> Void) {
358+
let parameters = [ParameterKey.templateName: template.rawValue]
359+
let path = Path.templateProducts
360+
let request = JetpackRequest(wooApiVersion: .wcAdmin, method: .post, siteID: siteID, path: path, parameters: parameters)
361+
let mapper = EntityIDMapper()
362+
363+
enqueue(request, mapper: mapper, completion: completion)
364+
}
351365
}
352366

353367

@@ -364,6 +378,16 @@ public extension ProductsRemote {
364378
case descending
365379
}
366380

381+
/// Supported types for creating a template product.
382+
///
383+
enum TemplateType: String {
384+
case physical
385+
case digital
386+
case variable
387+
case external
388+
case grouped
389+
}
390+
367391
enum Default {
368392
public static let pageSize: Int = 25
369393
public static let pageNumber: Int = Remote.Default.firstPageNumber
@@ -372,6 +396,7 @@ public extension ProductsRemote {
372396

373397
private enum Path {
374398
static let products = "products"
399+
static let templateProducts = "onboarding/tasks/create_product_from_template"
375400
}
376401

377402
private enum ParameterKey {
@@ -392,6 +417,7 @@ public extension ProductsRemote {
392417
static let fields: String = "_fields"
393418
static let images: String = "images"
394419
static let id: String = "id"
420+
static let templateName: String = "template_name"
395421
}
396422

397423
private enum ParameterValues {

Networking/Networking/Settings/WooAPIVersion.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public enum WooAPIVersion: String {
4343
///
4444
case wcTelemetry = "wc-telemetry"
4545

46+
/// WooCommerce Admin.
47+
///
48+
case wcAdmin = "wc-admin"
49+
4650
/// Returns the path for the current API Version
4751
///
4852
var path: String {

Networking/NetworkingTests/Remote/ProductsRemoteTests.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,23 @@ final class ProductsRemoteTests: XCTestCase {
620620
// Then
621621
XCTAssertTrue(result.isFailure)
622622
}
623+
624+
func test_create_template_product_returns_product_id() throws {
625+
// Given
626+
let remote = ProductsRemote(network: network)
627+
network.simulateResponse(requestUrlSuffix: "onboarding/tasks/create_product_from_template", filename: "product-id-only")
628+
629+
// When
630+
let result = waitFor { promise in
631+
remote.createTemplateProduct(for: self.sampleSiteID, template: .physical) { result in
632+
promise(result)
633+
}
634+
}
635+
636+
// Then
637+
let productID = try XCTUnwrap(result.get())
638+
XCTAssertEqual(productID, 3946)
639+
}
623640
}
624641

625642
// MARK: - Private Helpers
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"data": {
3+
"id": 3946
4+
}
5+
}

Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ target 'WooCommerce' do
6565
pod 'Gridicons', '~> 1.2.0'
6666

6767
# To allow pod to pick up beta versions use -beta. E.g., 1.1.7-beta.1
68-
pod 'WordPressAuthenticator', '~> 3.3.0-beta.2'
68+
pod 'WordPressAuthenticator', '~> 4.0.0'
6969
# pod 'WordPressAuthenticator', :git => 'https://github.com/wordpress-mobile/WordPressAuthenticator-iOS.git', :commit => ''
7070
# pod 'WordPressAuthenticator', :git => 'https://github.com/wordpress-mobile/WordPressAuthenticator-iOS.git', :branch => ''
7171
# pod 'WordPressAuthenticator', :path => '../WordPressAuthenticator-iOS'

0 commit comments

Comments
 (0)