Skip to content

Commit 32df2db

Browse files
committed
Update app version to 8.0.0.0 for testing.
Merge branch 'develop' into issue/5032-new-push-notification-payload # Conflicts: # config/Version.Public.xcconfig
2 parents f3b865f + 1ae6a14 commit 32df2db

File tree

71 files changed

+1020
-378
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1020
-378
lines changed

Hardware/Hardware/CardReader/CardReaderServiceError.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ public enum UnderlyingError: Error {
186186
/// The SDK will attempt to auto-disconnect for you and you should instruct your user to reconnect it.
187187
case readerSessionExpired
188188

189+
/// The underlying request returned an API error.
190+
case processorAPIError
191+
189192
/// Catch-all error case. Indicates there is something wrong with the
190193
/// internal state of the CardReaderService.
191194
case internalServiceError
@@ -305,6 +308,9 @@ updating the application or using a different reader
305308
case .readerSessionExpired:
306309
return NSLocalizedString("The card reader session has expired - please disconnect and reconnect the card reader and then try again",
307310
comment: "Error message when the card reader session has timed out.")
311+
case .processorAPIError:
312+
return NSLocalizedString("The payment can not be processed by the payment processor.",
313+
comment: "Error message when the payment can not be processed (i.e. order amount is below the minimum amount allowed.)")
308314
case .internalServiceError:
309315
return NSLocalizedString("Sorry, this payment couldn’t be processed",
310316
comment: "Error message when the card reader service experiences an unexpected internal service error.")

Hardware/Hardware/CardReader/StripeCardReader/UnderlyingError+Stripe.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ extension UnderlyingError {
7979
self = .requestTimedOut
8080
case ErrorCode.Code.sessionExpired.rawValue:
8181
self = .readerSessionExpired
82+
case ErrorCode.Code.stripeAPIError.rawValue:
83+
self = .processorAPIError
8284
default:
8385
self = .internalServiceError
8486
}

Hardware/HardwareTests/ErrorCodesTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ final class CardReaderServiceErrorTests: XCTestCase {
154154
XCTAssertEqual(.readerSessionExpired, domainError(stripeCode: 9060))
155155
}
156156

157+
func test_stripe_error_api_maps_to_stripeAPI() {
158+
XCTAssertEqual(.processorAPIError, domainError(stripeCode: 9020))
159+
}
160+
157161
func test_stripe_catch_all_error() {
158162
// Any error code not mapped to an specific error will be
159163
// mapped to `internalServiceError`

Networking/Networking.xcodeproj/project.pbxproj

Lines changed: 37 additions & 21 deletions
Large diffs are not rendered by default.

Networking/Networking/Mapper/SystemPluginsMapper.swift

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Foundation
2+
3+
/// Mapper: System Status
4+
///
5+
struct SystemStatusMapper: Mapper {
6+
7+
/// Site Identifier associated to the system plugins that will be parsed.
8+
/// We're injecting this field via `JSONDecoder.userInfo` because the remote endpoints don't return the SiteID in the system plugin endpoint.
9+
///
10+
let siteID: Int64
11+
12+
/// (Attempts) to convert a dictionary into [SystemPlugin].
13+
///
14+
func map(response: Data) throws -> [SystemPlugin] {
15+
let decoder = JSONDecoder()
16+
decoder.userInfo = [
17+
.siteID: siteID
18+
]
19+
20+
let systemStatus = try decoder.decode(SystemStatusEnvelope.self, from: response).systemStatus
21+
22+
/// For now, we're going to override the networkActivated Bool in each plugin to convey active or inactive -- in order to
23+
/// avoid a core data change to add a Bool for activated
24+
/// This will be undone in #5269
25+
let activePlugins = systemStatus.activePlugins.map {
26+
$0.overrideNetworkActivated(isNetworkActivated: true)
27+
}
28+
let inactivePlugins = systemStatus.inactivePlugins.map {
29+
$0.overrideNetworkActivated(isNetworkActivated: false)
30+
}
31+
32+
return activePlugins + inactivePlugins
33+
}
34+
}
35+
36+
/// System Status endpoint returns the requested account in the `data` key. This entity
37+
/// allows us to parse it with JSONDecoder.
38+
///
39+
private struct SystemStatusEnvelope: Decodable {
40+
let systemStatus: SystemStatus
41+
42+
private enum CodingKeys: String, CodingKey {
43+
case systemStatus = "data"
44+
}
45+
}

Networking/Networking/Model/Product/ProductCategory.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ public struct ProductCategory: Codable, Equatable, GeneratedFakeable {
2727
/// Public initializer for ProductCategory.
2828
///
2929
public init(from decoder: Decoder) throws {
30-
guard let siteID = decoder.userInfo[.siteID] as? Int64 else {
30+
let container = try decoder.container(keyedBy: CodingKeys.self)
31+
32+
guard let siteID = ProductCategory.siteID(from: decoder, container: container) else {
3133
throw ProductCategoryDecodingError.missingSiteID
3234
}
3335

34-
let container = try decoder.container(keyedBy: CodingKeys.self)
35-
3636
let categoryID = try container.decode(Int64.self, forKey: .categoryID)
3737
// Some product endpoints don't include the parent category ID
3838
let parentID = container.failsafeDecodeIfPresent(Int64.self, forKey: .parentID) ?? 0
@@ -48,6 +48,8 @@ public struct ProductCategory: Codable, Equatable, GeneratedFakeable {
4848
try container.encode(categoryID, forKey: .categoryID)
4949
try container.encode(name, forKey: .name)
5050
try container.encode(slug, forKey: .slug)
51+
try container.encode(siteID, forKey: .siteID)
52+
try container.encode(parentID, forKey: .parentID)
5153
}
5254
}
5355

@@ -56,13 +58,30 @@ public struct ProductCategory: Codable, Equatable, GeneratedFakeable {
5658
///
5759
private extension ProductCategory {
5860
enum CodingKeys: String, CodingKey {
61+
case siteID = "siteID"
5962
case categoryID = "id"
6063
case name = "name"
6164
case slug = "slug"
6265
case parentID = "parent"
6366
}
6467
}
6568

69+
private extension ProductCategory {
70+
/// Provides the siteID, that can be found as a encoded value or in the Decoder user info
71+
///
72+
private static func siteID(from decoder: Decoder, container: KeyedDecodingContainer<ProductCategory.CodingKeys>) -> Int64? {
73+
var siteID: Int64?
74+
75+
if let userInfoSiteID = decoder.userInfo[.siteID] as? Int64 {
76+
siteID = userInfoSiteID
77+
} else if let decodedSiteID = try? container.decode(Int64.self, forKey: .siteID) {
78+
siteID = decodedSiteID
79+
}
80+
81+
return siteID
82+
}
83+
}
84+
6685

6786
// MARK: - Comparable Conformance
6887
//

Networking/Networking/Model/SystemPlugin.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ public struct SystemPlugin: Decodable, GeneratedFakeable, GeneratedCopiable {
8888
}
8989
}
9090

91+
extension SystemPlugin {
92+
func overrideNetworkActivated(isNetworkActivated: Bool) -> SystemPlugin {
93+
SystemPlugin(
94+
siteID: self.siteID,
95+
plugin: self.plugin,
96+
name: self.name,
97+
version: self.version,
98+
versionLatest: self.versionLatest,
99+
url: self.url,
100+
authorName: self.authorName,
101+
authorUrl: self.authorUrl,
102+
networkActivated: isNetworkActivated
103+
)
104+
}
105+
}
106+
91107
/// Defines all of the SystemPlugin CodingKeys.
92108
///
93109
private extension SystemPlugin {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/// Represent a System Status.
2+
/// Note: We are only decoding the active and inactive plugins portions at the moment.
3+
///
4+
public struct SystemStatus: Decodable {
5+
let activePlugins: [SystemPlugin]
6+
let inactivePlugins: [SystemPlugin]
7+
8+
public init(
9+
activePlugins: [SystemPlugin],
10+
inactivePlugins: [SystemPlugin]
11+
) {
12+
self.activePlugins = activePlugins
13+
self.inactivePlugins = inactivePlugins
14+
}
15+
16+
/// The public initializer for System Status.
17+
///
18+
public init(from decoder: Decoder) throws {
19+
let container = try decoder.container(keyedBy: CodingKeys.self)
20+
let activePlugins = try container.decode([SystemPlugin].self, forKey: .activePlugins)
21+
let inactivePlugins = try container.decode([SystemPlugin].self, forKey: .inactivePlugins)
22+
23+
self.init(
24+
activePlugins: activePlugins,
25+
inactivePlugins: inactivePlugins
26+
)
27+
}
28+
}
29+
30+
private extension SystemStatus {
31+
enum CodingKeys: String, CodingKey {
32+
case activePlugins = "active_plugins"
33+
case inactivePlugins = "inactive_plugins"
34+
}
35+
}

Networking/Networking/Model/WCPayAccount.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ public struct WCPayAccount: Decodable {
44
public static let gatewayID = "woocommerce-payments"
55

66
public let status: WCPayAccountStatusEnum
7+
/// Indicates whether the payment gateway is a live account that can accept actual payments, or just a test/developer account.
8+
/// Not to be confused with "test mode" which is a separate concept (see `isInTestMode`)
9+
///
10+
public let isLiveAccount: Bool
11+
/// Indicates whether the payment gateway is currently in "Test" or "Debug" mode
12+
///
13+
public let isInTestMode: Bool
714
public let hasPendingRequirements: Bool
815
public let hasOverdueRequirements: Bool
916
public let currentDeadline: Date?
@@ -22,6 +29,8 @@ public struct WCPayAccount: Decodable {
2229

2330
public init(
2431
status: WCPayAccountStatusEnum,
32+
isLiveAccount: Bool,
33+
isInTestMode: Bool,
2534
hasPendingRequirements: Bool,
2635
hasOverdueRequirements: Bool,
2736
currentDeadline: Date?,
@@ -32,6 +41,8 @@ public struct WCPayAccount: Decodable {
3241
isCardPresentEligible: Bool
3342
) {
3443
self.status = status
44+
self.isLiveAccount = isLiveAccount
45+
self.isInTestMode = isInTestMode
3546
self.hasPendingRequirements = hasPendingRequirements
3647
self.hasOverdueRequirements = hasOverdueRequirements
3748
self.currentDeadline = currentDeadline
@@ -47,6 +58,8 @@ public struct WCPayAccount: Decodable {
4758
public init(from decoder: Decoder) throws {
4859
let container = try decoder.container(keyedBy: CodingKeys.self)
4960
let status = try container.decode(WCPayAccountStatusEnum.self, forKey: .status)
61+
let isLiveAccount = try container.decode(Bool.self, forKey: .isLive)
62+
let isInTestMode = try container.decode(Bool.self, forKey: .testMode)
5063
let hasPendingRequirements = try container.decode(Bool.self, forKey: .hasPendingRequirements)
5164
let hasOverdueRequirements = try container.decode(Bool.self, forKey: .hasOverdueRequirements)
5265
let currentDeadline = try container.decodeIfPresent(Date.self, forKey: .currentDeadline)
@@ -60,6 +73,8 @@ public struct WCPayAccount: Decodable {
6073

6174
self.init(
6275
status: status,
76+
isLiveAccount: isLiveAccount,
77+
isInTestMode: isInTestMode,
6378
hasPendingRequirements: hasPendingRequirements,
6479
hasOverdueRequirements: hasOverdueRequirements,
6580
currentDeadline: currentDeadline,
@@ -75,6 +90,8 @@ public struct WCPayAccount: Decodable {
7590
public extension WCPayAccount {
7691
static let noAccount = WCPayAccount(
7792
status: .noAccount,
93+
isLiveAccount: false,
94+
isInTestMode: false,
7895
hasPendingRequirements: false,
7996
hasOverdueRequirements: false,
8097
currentDeadline: nil,
@@ -89,17 +106,19 @@ public extension WCPayAccount {
89106
private extension WCPayAccount {
90107
enum CodingKeys: String, CodingKey {
91108
case status = "status"
109+
case isLive = "is_live"
110+
case testMode = "test_mode"
92111
case hasPendingRequirements = "has_pending_requirements"
93112
case hasOverdueRequirements = "has_overdue_requirements"
94113
case currentDeadline = "current_deadline"
95114
case statementDescriptor = "statement_descriptor"
96115
case storeCurrencies = "store_currencies"
97-
case country = "country"
116+
case country
98117
case cardPresentEligible = "card_present_eligible"
99118
}
100119

101120
enum CurrencyCodingKeys: String, CodingKey {
102121
case defaultCurrency = "default"
103-
case supported = "supported"
122+
case supported
104123
}
105124
}

0 commit comments

Comments
 (0)