Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge feature/button to master #272

Merged
merged 112 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
359aacc
Add swiftlint warning directive
nesevis Jul 8, 2021
20051c4
Add V3 implementation to Example app
nesevis Jul 13, 2021
f3d7b4e
Add `api-plus` to set of valid hosts
nesevis Jul 13, 2021
84bce2e
Make CheckoutResult success case polymorphic
nesevis Jul 13, 2021
d27a831
Add ObjcWrapper for new ApiError
nesevis Jul 13, 2021
3f1fd8b
Remove V2 cart options for V3 purposes
nesevis Jul 13, 2021
5981219
Add AfterPay.presentCheckoutV3Modally method
nesevis Jul 13, 2021
f4763be
Clean up example code
nesevis Jul 13, 2021
6e0b515
Add V3 models and view controller
nesevis Jul 13, 2021
5620f02
Update project file
nesevis Jul 13, 2021
265a93c
Remove CancellationReason.apiError
nesevis Jul 13, 2021
f694936
Extract request convenience methods from Checkout VC
nesevis Jul 13, 2021
be3ef15
Extract Amount model from CheckoutV3.Request
nesevis Jul 13, 2021
892f373
Add Codable support to Configuration model
nesevis Jul 13, 2021
73e8ed0
Add fetchMerchantConfiguration function
nesevis Jul 13, 2021
db0cbd8
Fix formatting
nesevis Jul 13, 2021
10b23cd
Move ApiV3 up one level
nesevis Jul 13, 2021
82e4990
Update README with v3 functionality
nesevis Jul 13, 2021
ac8fcf0
Use provided currencyCode rather than what is returned from the API
nesevis Jul 13, 2021
5cbc548
Remove Amount in favour of Money
nesevis Jul 13, 2021
98d89c0
Add documentation and properties to CheckoutV3 protocols
nesevis Jul 13, 2021
f02965d
Add newline to comment
nesevis Jul 14, 2021
9dca600
Add shipping and billing options to V3 checkout
nesevis Jul 14, 2021
59f6759
Change button text; re-add options on cart screen
nesevis Jul 14, 2021
3e82f0a
Add ApiV3.request overload that returns a Void result
nesevis Jul 14, 2021
d469d51
Extract V3 Checkout result from V1/2 CheckoutResults model
nesevis Jul 14, 2021
839a893
Add support for cancellation and merchant reference updates
nesevis Jul 14, 2021
ad12428
Remove unused types
nesevis Jul 14, 2021
1d4184a
Use same ID for display in Example controller
nesevis Jul 14, 2021
e892778
Add Checkout support for shipping and tax amounts
nesevis Jul 14, 2021
aa37c41
Conform V3Config currency formatter to ISO 4217
nesevis Jul 14, 2021
9ae69dc
Add test for Region formatter Decimal -> String
nesevis Jul 14, 2021
da139a4
Make V3 Request shippingAmount and taxAmount optional
nesevis Jul 14, 2021
67e0326
Tweak formatting and documentation
nesevis Jul 14, 2021
d9785e9
Add items to Example app checkout
nesevis Jul 14, 2021
192b9db
Move public V3 protocols into separate file
nesevis Jul 14, 2021
c09a258
Make VirtualCard an enum representing a Card or a tokenized Card
nesevis Jul 14, 2021
1bccb81
Change Checkout amount to use OrderTotal’s new `total` property
nesevis Jul 14, 2021
61a6e85
Add V3 support for buyNow flag during checkout
nesevis Jul 15, 2021
1fcf296
Remove button to cancel virtual card
nesevis Jul 15, 2021
3af63f6
Remove V3 functionality to cancel virtual cards
nesevis Jul 15, 2021
52b36fa
Remove V3references to `merchantPublicKey`
nesevis Jul 15, 2021
0ff0178
Make shopDirectoryId hard coded for sandbox and production
nesevis Jul 15, 2021
ab52fd4
Set Afterpay.configuration
nesevis Jul 15, 2021
4353634
Make `OrderTotal` explicit about passing in the full amount as `total`
nesevis Jul 15, 2021
4843320
Rename updateMerchantReference to updateMerchantReferenceV3
nesevis Jul 15, 2021
922ad82
Remove most express options from cart
nesevis Jul 20, 2021
110edc0
Replace failing retry url from V3 Checkout
nesevis Jul 20, 2021
afcffe2
Update instruction text on SingleUseCardResultViewController
nesevis Jul 20, 2021
d7deca2
Rename PaymentButton.configuration to avoid name collision
nesevis Aug 16, 2021
13b2938
Update `TokenizedCard` model to match API
nesevis Aug 16, 2021
097bc8a
Update Response.PaymentDetails model to support different keys
nesevis Aug 16, 2021
54ce28f
Add missing return statement to CheckoutV3Card
nesevis Aug 16, 2021
9531de7
Merge remote-tracking branch 'public/master' into feature/button
nesevis Aug 19, 2021
96a7694
Add support for Canadian locale to Button API
nesevis Aug 26, 2021
121ae1e
Update unit test relying on server configuration
nesevis Aug 26, 2021
4f50ae9
fixed issue where SWXMLHash was being updated for cocoapods users abo…
apederson94 Sep 29, 2021
9e31fcf
Merge pull request #177 from apederson94/feature/button
ScottAntonacAP Sep 30, 2021
a47d36b
bump Afterpay version to 3.0.5
ScottAntonacAP Oct 1, 2021
679522f
fix readme typo
ScottAntonacAP Sep 30, 2021
cd8dad2
Update GitHub Actions Xcode to 12.5.1
huwr Oct 1, 2021
95035a4
Bump simulator version to 14.5
huwr Oct 1, 2021
bad4f44
Merge branch 'master' into maintenance/update-feature-button-to-latest
ScottAntonacAP Mar 17, 2022
9f27ef0
update package.resolved
ScottAntonacAP Mar 17, 2022
06e9a43
Merge pull request #206 from afterpay/maintenance/update-feature-butt…
ScottAntonacAP Mar 23, 2022
f5d2a6a
Merge branch 'master' into maintenance/merge-master-to-feature-button
ScottAntonacAP Apr 6, 2022
237adcf
update package resolved with version 1
ScottAntonacAP Apr 6, 2022
2a6273e
Merge pull request #210 from afterpay/maintenance/merge-master-to-fea…
ScottAntonacAP Apr 6, 2022
9bd0d92
Merge branch 'master' into maintenance/merge-master-to-feature-button
ScottAntonacAP Apr 11, 2022
731212f
Merge pull request #214 from afterpay/maintenance/merge-master-to-fea…
ScottAntonacAP Apr 11, 2022
84e8080
Merge branch 'master' into maintenance/merge-master-to-feature-button
ScottAntonacAP Apr 14, 2022
3726667
Merge pull request #217 from afterpay/maintenance/merge-master-to-fea…
ScottAntonacAP Apr 14, 2022
58266bf
Merge branch 'master' into maintenance/merge-master-4.5.2-to-feature-…
ScottAntonacAP Apr 22, 2022
5f8caf2
Merge pull request #220 from afterpay/maintenance/merge-master-4.5.2-…
ScottAntonacAP Apr 22, 2022
a552c4a
remove grouping separator in sent amount for v3
ScottAntonacAP Apr 25, 2022
4cdd1c7
Merge pull request #221 from afterpay/fix/feature-button-remove-group…
ScottAntonacAP Apr 26, 2022
1433d50
Merge branch 'master' into maintenance/merge-master-5.0.0-to-feature-…
ScottAntonacAP Jul 25, 2022
2fd2f07
change naming of locales
ScottAntonacAP Jul 25, 2022
11b814d
Merge pull request #224 from afterpay/maintenance/merge-master-5.0.0-…
ScottAntonacAP Jul 25, 2022
d7dfe96
Merge branch 'master' into maintenance/merge-master-5.1.0-to-feature-…
ScottAntonacAP Sep 8, 2022
0852ba6
docs: add v3 specifics to readme.md
ScottAntonacAP Sep 8, 2022
8ae8240
Merge pull request #233 from afterpay/maintenance/merge-master-5.1.0-…
ScottAntonacAP Sep 9, 2022
901e659
Merge branch 'master' into maintenance/merge-master-5.2.0-to-feature-…
ScottAntonacAP Oct 28, 2022
90136c5
Merge pull request #239 from afterpay/maintenance/merge-master-5.2.0-…
ScottAntonacAP Oct 31, 2022
6b69241
Merge branch 'master' into maintenance/merge-master-5.3.0-to-feature-…
ScottAntonacAP Mar 10, 2023
47e5b96
Merge pull request #248 from afterpay/maintenance/merge-master-5.3.0-…
ScottAntonacAP Mar 10, 2023
6017449
Merge branch 'master' into maintenance/merge-master-5.4.0-to-feature-…
ScottAntonacAP Jul 5, 2023
7edf9f5
fix missing import
ScottAntonacAP Jul 5, 2023
d84ddc2
Merge pull request #257 from afterpay/maintenance/merge-master-5.4.0-…
ScottAntonacAP Jul 6, 2023
62d3048
Merge branch 'master' into maintenance/merge-master-5.5.0-to-feature-…
ScottAntonacAP Mar 1, 2024
75fe447
Merge branch 'master' into maintenance/merge-master-5.6.0-to-feature-…
ScottAntonacAP Apr 26, 2024
682173f
Merge pull request #265 from afterpay/maintenance/merge-master-5.6.0-…
ScottAntonacAP Apr 26, 2024
a82b764
Merge branch 'master' into maintenance/merge-master-5.6.1-to-feature-…
ScottAntonacAP Apr 29, 2024
0a504ab
Merge pull request #269 from afterpay/maintenance/merge-master-5.6.1-…
ScottAntonacAP Apr 29, 2024
4f68396
Button with Cash App Pay
mmroz May 31, 2024
38d4d4a
Added tests for Afterpay
mmroz Jun 3, 2024
459d48b
method naming
mmroz Jun 3, 2024
01a9ae1
Added example code
mmroz Jun 3, 2024
75cae89
updated picker
mmroz Jun 4, 2024
211f56a
Merge pull request #271 from afterpay/markmroz/button
mmroz Jun 6, 2024
ac75afb
Use V3 checkout configs for Cash App Pay checkout
mmroz Jun 12, 2024
a7bffd9
Updated from comments
mmroz Jun 13, 2024
3ffeada
added tests for Cash App Pay
mmroz Jun 13, 2024
383d8a4
fix button webview
mmroz Jun 17, 2024
ceb7a38
Merge pull request #273 from afterpay/markmroz/button-configs
mmroz Jun 17, 2024
3fcad6f
docs: add checkout diagrams
ScottAntonacAP May 27, 2024
5ccb1fd
Updated parchase login for CAP
mmroz Jun 17, 2024
a39b231
default to V2 for example app
mmroz Jun 17, 2024
25714c3
use 0.6.1 for Cash App Pay
mmroz Jun 17, 2024
53d047e
use version 2
mmroz Jun 17, 2024
ba3dd11
Merge branch 'master' into markmroz/feature-button-master
mmroz Jun 17, 2024
71e9b1d
merged master
mmroz Jun 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions Afterpay.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

32 changes: 0 additions & 32 deletions Afterpay.xcworkspace/xcshareddata/swiftpm/Package.resolved

This file was deleted.

177 changes: 177 additions & 0 deletions AfterpayTests/AfterpayV3Tests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
//
// AfterpayV3Tests.swift
// AfterpayTests
//
// Created by Mark Mroz on 2024-06-03.
// Copyright © 2024 Afterpay. All rights reserved.
//

import XCTest
@testable import Afterpay

final class AfterpayV3Tests: XCTestCase {

private var v3Configuration: CheckoutV3Configuration!

override func setUpWithError() throws {
try super.setUpWithError()
v3Configuration = CheckoutV3Configuration(
shopDirectoryMerchantId: "merchant_id",
region: .US,
environment: .production
)

Afterpay.setV3Configuration(v3Configuration)
}

override func tearDown() {
v3Configuration = nil
Afterpay.setV3Configuration(nil)
super.tearDown()
}

func testCheckoutV3WithCashAppPay() throws {
let checkoutV3Expectation = self.expectation(description: "Checkout V3")
let checkoutHandler: URLRequestHandler = { (request, response) in
URLSessionMock(dataTaskHandler: { url in
XCTAssertEqual(url.absoluteString, "https://api-plus.us.afterpay.com/v3/button")
return (Fixtures.checkoutV3WithCashAppPayResponse, nil, nil)
}).dataTask(with: request.url!) { data, urlResponse, error in
checkoutV3Expectation.fulfill()
response(data, urlResponse, error)
}
}

let signTokenExpectation = self.expectation(description: "Sign Token")
let signHandler = URLSessionMock(requestDataTaskHandler: { request in
XCTAssertEqual(request.url?.absoluteString, "https://api-plus.us.afterpay.com/v2/payments/sign-payment")
signTokenExpectation.fulfill()
return (Fixtures.signPaymentResponse, HTTPURLResponse(), nil)
})

let checkoutExpectation = self.expectation(description: "Completed Checkout")
Afterpay.checkoutV3WithCashAppPay(
consumer: Consumer(email: "[email protected]"),
orderTotal: OrderTotal(total: 10, shipping: 0, tax: 0),
items: [Product(name: "Coffee", quantity: 1, price: 10)],
configuration: v3Configuration,
urlSession: signHandler,
requestHandler: checkoutHandler
) { result in
switch result {
case .success(let data):
XCTAssertEqual(data.singleUseCardToken, "AQI")
XCTAssertEqual(data.token, "002.x")
XCTAssertEqual(data.cashAppSigningData.amount, 5000)
XCTAssertEqual(data.cashAppSigningData.brandId, "BRAND_ID")
XCTAssertEqual(data.cashAppSigningData.merchantId, "MMI_6nvgu9voweagwt5dn0kdteaio")
XCTAssertEqual(
data.cashAppSigningData.redirectUri.absoluteString,
"https://static-us.afterpay.com/javascript/button/index.html"
)
case .cancelled, .failure:
XCTFail("Expected success")
}
checkoutExpectation.fulfill()
}
waitForExpectations(timeout: 0.5)
}

func testCheckoutV3ConfirmForCashAppPay() {

let confirmRequestExpectation = self.expectation(description: "Confirmed")
let checkoutHandler: URLRequestHandler = { (request, response) in
URLSessionMock(dataTaskHandler: { url in
XCTAssertEqual(url.absoluteString, "https://api-plus.us.afterpay.com/v3/button/confirm")
return (Fixtures.confirmResponse, nil, nil)
}).dataTask(with: request.url!) { data, urlResponse, error in
confirmRequestExpectation.fulfill()
response(data, urlResponse, error)
}
}

let confirmExpectation = self.expectation(description: "Confirmed")
Afterpay.checkoutV3ConfirmForCashAppPay(
token: "002.x",
singleUseCardToken: "AQI",
cashAppPayCustomerID: "CUST_ID",
cashAppPayGrantID: "GRR_ID",
jwt: "JWT",
configuration: v3Configuration,
requestHandler: checkoutHandler
) { result in
switch result {
case .success(let data):
XCTAssertEqual(data.paymentDetails.virtualCard?.cardType, "VISA")
XCTAssertEqual(data.paymentDetails.virtualCard?.cardNumber, "4111111111111111")
XCTAssertEqual(data.paymentDetails.virtualCard?.cvc, "737")
XCTAssertEqual(data.paymentDetails.virtualCard?.expiryMonth, 3)
XCTAssertEqual(data.paymentDetails.virtualCard?.expiryYear, 30)
XCTAssertNotNil(data.cardValidUntil)
case .failure:
XCTFail("Expected success")
}

confirmExpectation.fulfill()
}

waitForExpectations(timeout: 0.5)
}

func testCashAppClientIdForV3() {
XCTAssertEqual(Afterpay.checkoutV3CashAppClientId, "CA-CI_AFTERPAY")
}
}

// MARK: - Private

private extension AfterpayV3Tests {
struct Product: CheckoutV3Item {
let name: String
let quantity: UInt
let price: Decimal
let sku: String? = nil
let pageUrl: URL? = nil
let imageUrl: URL? = nil
let categories: [[String]]? = nil
let estimatedShipmentDate: String? = nil
}
}

// MARK: - Fixtures

extension AfterpayV3Tests {
// swiftlint:disable line_length indentation_width
enum Fixtures {
static let checkoutV3WithCashAppPayResponse = """
{
"token": "002.x",
"confirmMustBeCalledBefore": "2024-06-04T02:29:53.803Z",
"redirectCheckoutUrl": "https://portal.sandbox.afterpay.com/us/checkout/?token=002.x",
"singleUseCardToken": "AQI"
}
""".data(using: .utf8)

static let signPaymentResponse = """
{
"jwtToken": "eyJraWQiOiJrZXkxIiwiYWxnIjoiRVMyNTYiLCJ0dGwiOiIxNzE3NDM3Nzc1In0.eyJleHRlcm5hbE1lcmNoYW50SWQiOiJNTUlfNm52Z3U5dm93ZWFnd3Q1ZG4wa2R0ZWFpbyIsInRva2VuIjoiMDAyLmlscXFqZjJ1ZG11MnJwM3hjdTdjYjZtenVwNnRlZndiM2Q1eWs2Y3pyZnZqd3Nmb2NuIiwiYW1vdW50Ijp7ImFtb3VudCI6IjUwLjAwIiwiY3VycmVuY3kiOiJVU0QiLCJzeW1ib2wiOiIkIn0sInJlZGlyZWN0VXJsIjoiaHR0cHM6Ly9zdGF0aWMtdXMuYWZ0ZXJwYXkuY29tL2phdmFzY3JpcHQvYnV0dG9uL2luZGV4Lmh0bWwifQ.KRVxIHwrH_QPDTX2WF3Ei5wI7InE_v7xvPDDXFF2YBka2hUROkSX6ubdrFufIkE6yaFHyrlAGoQiS17VB80IDA",
"redirectUrl": "https://static-us.afterpay.com",
"externalBrandId": "BRAND_ID"
}
""".data(using: .utf8)

static let confirmResponse = """
{
"paymentDetails": {
"virtualCard": {
"cardType": "VISA",
"cardNumber": "4111111111111111",
"cvc": "737",
"expiry": "30-03"
}
},
"cardValidUntil": "2024-06-03T18:31:32.096071575Z"
}
""".data(using: .utf8)
}
}
42 changes: 42 additions & 0 deletions AfterpayTests/CashAppPayTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// CashAppPayTests.swift
// AfterpayTests
//
// Created by Mark Mroz on 2024-06-13.
// Copyright © 2024 Afterpay. All rights reserved.
//

import XCTest
@testable import Afterpay

final class CashAppPayTests: XCTestCase {
func testSignCashAppOrderToken() {
let signingURL = "https://api-plus.us.afterpay.com/v2/payments/sign-payment"
let signTokenExpectation = self.expectation(description: "Sign Token")
let handle = URLSessionMock(requestDataTaskHandler: { request in
XCTAssertEqual(request.url?.absoluteString, signingURL)

return (Fixtures.signPaymentResponse, HTTPURLResponse(), nil)
})

CashAppPayCheckout.signCashAppOrderToken("Token", cashAppSigningURL: signingURL, urlSession: handle) { _ in
signTokenExpectation.fulfill()
}
waitForExpectations(timeout: 0.5)
}
}

// MARK: - Fixtures

extension CashAppPayTests {
// swiftlint:disable line_length indentation_width
enum Fixtures {
static let signPaymentResponse = """
{
"jwtToken": "eyJraWQiOiJrZXkxIiwiYWxnIjoiRVMyNTYiLCJ0dGwiOiIxNzE3NDM3Nzc1In0.eyJleHRlcm5hbE1lcmNoYW50SWQiOiJNTUlfNm52Z3U5dm93ZWFnd3Q1ZG4wa2R0ZWFpbyIsInRva2VuIjoiMDAyLmlscXFqZjJ1ZG11MnJwM3hjdTdjYjZtenVwNnRlZndiM2Q1eWs2Y3pyZnZqd3Nmb2NuIiwiYW1vdW50Ijp7ImFtb3VudCI6IjUwLjAwIiwiY3VycmVuY3kiOiJVU0QiLCJzeW1ib2wiOiIkIn0sInJlZGlyZWN0VXJsIjoiaHR0cHM6Ly9zdGF0aWMtdXMuYWZ0ZXJwYXkuY29tL2phdmFzY3JpcHQvYnV0dG9uL2luZGV4Lmh0bWwifQ.KRVxIHwrH_QPDTX2WF3Ei5wI7InE_v7xvPDDXFF2YBka2hUROkSX6ubdrFufIkE6yaFHyrlAGoQiS17VB80IDA",
"redirectUrl": "https://static-us.afterpay.com",
"externalBrandId": "BRAND_ID"
}
""".data(using: .utf8)
}
}
78 changes: 78 additions & 0 deletions AfterpayTests/CheckoutV3RequestTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// CheckoutV3RequestTests.swift
// AfterpayTests
//
// Created by Mark Mroz on 2024-06-16.
// Copyright © 2024 Afterpay. All rights reserved.
//

@testable import Afterpay
import XCTest

final class CheckoutV3RequestTests: XCTestCase {
func testEncodingWithCashAppIncludesEncodedKey() throws {
let customer = Customer(
email: "[email protected]",
givenNames: nil,
surname: nil,
phoneNumber: nil,
shippingInformation: nil,
billingInformation: nil
)
let request = CheckoutV3.Request(
consumer: customer,
orderTotal: OrderTotal(total: 1, shipping: 1, tax: 0),
items: [],
isCashAppPay: true,
configuration: CheckoutV3Configuration(shopDirectoryMerchantId: "", region: .US, environment: .production)
)
let encoded = try JSONEncoder().encode(request)
let stringData = try XCTUnwrap(String(data: encoded, encoding: .utf8))
XCTAssert(stringData.localizedCaseInsensitiveContains("isCashApp"))
}

func testEncodingWithoutCashAppDoesNotIncludeEncodedKey() throws {
let customer = Customer(
email: "[email protected]",
givenNames: nil,
surname: nil,
phoneNumber: nil,
shippingInformation: nil,
billingInformation: nil
)

let request = CheckoutV3.Request(
consumer: customer,
orderTotal: OrderTotal(total: 1, shipping: 1, tax: 0),
items: [],
isCashAppPay: false,
configuration: CheckoutV3Configuration(shopDirectoryMerchantId: "", region: .US, environment: .production)
)
let encoded = try JSONEncoder().encode(request)
let stringData = try XCTUnwrap(String(data: encoded, encoding: .utf8))
XCTAssertFalse(stringData.localizedCaseInsensitiveContains("isCashApp"))
}
}

private extension CheckoutV3RequestTests {
struct Customer: CheckoutV3Consumer {
let email: String
let givenNames: String?
let surname: String?
let phoneNumber: String?
let shippingInformation: CheckoutV3Contact?
let billingInformation: CheckoutV3Contact?
}

struct Contact: CheckoutV3Contact {
let name: String
let line1: String
let line2: String?
let area1: String?
let area2: String?
let region: String?
let postcode: String?
let countryCode: String
let phoneNumber: String?
}
}
15 changes: 15 additions & 0 deletions AfterpayTests/CurrencyFormatterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,19 @@ class CurrencyFormatterTests: XCTestCase {
let usd: CurrencyFormatter
}

func testOrderTotalDecimalToStringPerformsRounding() {
let region = CheckoutV3Configuration.Region.US

XCTAssertEqual(region.formatted(currency: 9), "9")
XCTAssertEqual(region.formatted(currency: 9.9), "9.9")
XCTAssertEqual(region.formatted(currency: 9.99), "9.99")
XCTAssertEqual(region.formatted(currency: 9.999), "10")
XCTAssertEqual(region.formatted(currency: 9.995), "9.99")
XCTAssertEqual(region.formatted(currency: 9.996), "10")
// This test was added to make sure that the grouping seperator
// was omitted from the formatted currency
// ie 1196.996 should not return 1,197 but 1197
XCTAssertEqual(region.formatted(currency: 1196.996), "1197")
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// KeyedEncodingContainerProtocolExtensionTests.swift
// AfterpayTests
//
// Created by Mark Mroz on 2024-06-16.
// Copyright © 2024 Afterpay. All rights reserved.
//

@testable import Afterpay
import XCTest

final class KeyedEncodingContainerProtocolTests: XCTestCase {
func testEncodeIfTrue() throws {
let encoder = JSONEncoder()

let params = Params(buyNow: true)
let data = try encoder.encode(params)
let paramsString = String(data: data, encoding: .utf8)
XCTAssertEqual(paramsString, "{\"buyNow\":true}")
}

func testDoesNotEncodeIfFalse() throws {
let encoder = JSONEncoder()

let params = Params(buyNow: false)
let data = try encoder.encode(params)
let paramsString = String(data: data, encoding: .utf8)
XCTAssertEqual(paramsString, "{}")
}
}

private extension KeyedEncodingContainerProtocolTests {
// swiftlint:disable nesting
struct Params: Encodable {
let buyNow: Bool

enum CodingKeys: CodingKey {
case buyNow
}

func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfTrue(self.buyNow, forKey: .buyNow)
}
}
}
Loading
Loading