543 lines
21 KiB
Swift
543 lines
21 KiB
Swift
//
|
|
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import XCTest
|
|
@testable import Signal
|
|
@testable import SignalServiceKit
|
|
|
|
final class DonateViewControllerTest: SignalBaseTest {
|
|
typealias State = DonateViewController.State
|
|
|
|
// MARK: - One time fixtures
|
|
|
|
private struct OneTimeFixtures {
|
|
static let badge: ProfileBadge = try! ProfileBadge(jsonDictionary: [
|
|
"id": "BOOST",
|
|
"category": "donor",
|
|
"name": "A Boost",
|
|
"description": "A boost badge!",
|
|
"sprites6": ["ldpi.png", "mdpi.png", "hdpi.png", "xhdpi.png", "xxhdpi.png", "xxxhdpi.png"]
|
|
])
|
|
|
|
static let minimums: [Currency.Code: FiatMoney] = [
|
|
"USD": 10.as("USD"),
|
|
"AUD": 30.as("AUD")
|
|
]
|
|
|
|
static let presets: [Currency.Code: DonationUtilities.Preset] = [
|
|
"USD": .init(currencyCode: "USD", amounts: [10.as("USD"), 20.as("USD")]),
|
|
"AUD": .init(currencyCode: "AUD", amounts: [30.as("AUD"), 40.as("AUD")])
|
|
]
|
|
|
|
static func configWithDefaults(
|
|
level: UInt = 12,
|
|
badge: ProfileBadge = badge,
|
|
minimums: [Currency.Code: FiatMoney] = minimums,
|
|
presets: [Currency.Code: DonationUtilities.Preset] = presets
|
|
) -> State.OneTimeConfiguration {
|
|
.init(
|
|
level: level,
|
|
badge: badge,
|
|
presetAmounts: presets,
|
|
minimumAmountsByCurrency: minimums,
|
|
maximumAmountViaSepa: FiatMoney(currencyCode: "EUR", value: 10.000)
|
|
)
|
|
}
|
|
}
|
|
|
|
// MARK: - Monthly fixtures
|
|
|
|
private struct MonthlyFixtures {
|
|
static let badgeOne: ProfileBadge = try! .init(jsonDictionary: [
|
|
"id": "test-badge-1",
|
|
"category": "donor",
|
|
"name": "Test Badge 1",
|
|
"description": "First test badge",
|
|
"sprites6": ["ldpi.png", "mdpi.png", "hdpi.png", "xhdpi.png", "xxhdpi.png", "xxxhdpi.png"]
|
|
])
|
|
|
|
static let badgeTwo: ProfileBadge = try! .init(jsonDictionary: [
|
|
"id": "test-badge-2",
|
|
"category": "donor",
|
|
"name": "Test Badge 2",
|
|
"description": "Second test badge",
|
|
"sprites6": ["ldpi.png", "mdpi.png", "hdpi.png", "xhdpi.png", "xxhdpi.png", "xxxhdpi.png"]
|
|
])
|
|
|
|
static let amountsOne: [Currency.Code: FiatMoney] = [
|
|
"USD": 1.as("USD"),
|
|
"GBP": 2.as("GBP"),
|
|
"EUR": 3.as("EUR")
|
|
]
|
|
|
|
static let amountsTwo: [Currency.Code: FiatMoney] = [
|
|
"USD": 4.as("USD"),
|
|
"EUR": 5.as("EUR")
|
|
]
|
|
|
|
static func levelOneWithDefaults(
|
|
level: UInt = 1,
|
|
name: String = "First Level",
|
|
badge: ProfileBadge = badgeOne,
|
|
amounts: [Currency.Code: FiatMoney] = amountsOne
|
|
) -> DonationSubscriptionLevel {
|
|
.init(
|
|
level: level,
|
|
badge: badge,
|
|
amounts: amounts
|
|
)
|
|
}
|
|
|
|
static func levelTwoWithDefaults(
|
|
level: UInt = 2,
|
|
name: String = "Second Level",
|
|
badge: ProfileBadge = badgeTwo,
|
|
amounts: [Currency.Code: FiatMoney] = amountsTwo
|
|
) -> DonationSubscriptionLevel {
|
|
.init(
|
|
level: level,
|
|
badge: badge,
|
|
amounts: amounts
|
|
)
|
|
}
|
|
|
|
static let subscriptionLevels: [DonationSubscriptionLevel] = [
|
|
levelOneWithDefaults(),
|
|
levelTwoWithDefaults()
|
|
]
|
|
|
|
static func configWithDefaults(
|
|
subscriptionLevels: [DonationSubscriptionLevel] = subscriptionLevels
|
|
) -> State.MonthlyConfiguration {
|
|
.init(levels: subscriptionLevels)
|
|
}
|
|
}
|
|
|
|
// MARK: - Payment methods fixtures
|
|
|
|
private struct PaymentMethodsFixtures {
|
|
static let supportedPaymentMethodsByCurrency: [Currency.Code: Set<DonationPaymentMethod>] = [
|
|
"USD": [.applePay, .creditOrDebitCard, .paypal],
|
|
"AUD": [.applePay, .creditOrDebitCard, .paypal],
|
|
"EUR": [.applePay, .creditOrDebitCard]
|
|
]
|
|
|
|
static func configWithDefaults(
|
|
paymentMethods: [Currency.Code: Set<DonationPaymentMethod>] = supportedPaymentMethodsByCurrency
|
|
) -> State.PaymentMethodsConfiguration {
|
|
.init(supportedPaymentMethodsByCurrency: paymentMethods)
|
|
}
|
|
}
|
|
|
|
// MARK: - Subscription fixtures
|
|
|
|
private static func subscription(
|
|
at level: UInt,
|
|
isPaymentProcessing: Bool = false,
|
|
paymentMethod: String = "CARD"
|
|
) -> Subscription {
|
|
try! .init(
|
|
subscriptionDict: [
|
|
"level": level,
|
|
"currency": isPaymentProcessing ? "EUR" : "USD",
|
|
"amount": 12,
|
|
"endOfCurrentPeriod": TimeInterval(1234),
|
|
"billingCycleAnchor": TimeInterval(5678),
|
|
"active": true,
|
|
"cancelAtPeriodEnd": false,
|
|
"status": "active",
|
|
"processor": "STRIPE",
|
|
"paymentMethod": paymentMethod,
|
|
"paymentProcessing": isPaymentProcessing
|
|
],
|
|
chargeFailureDict: nil
|
|
)
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
private static let defaultOneTimeConfig = OneTimeFixtures.configWithDefaults()
|
|
private static let defaultMonthlyConfig = MonthlyFixtures.configWithDefaults()
|
|
private static let defaultPaymentMethodsConfig = PaymentMethodsFixtures.configWithDefaults()
|
|
|
|
private static var localNumber: String = "+17735550100"
|
|
|
|
private var initializing: State { .init(donateMode: .oneTime) }
|
|
|
|
private var loading: State { initializing.loading() }
|
|
|
|
private var loadFailed: State { loading.loadFailed() }
|
|
|
|
private var loadedWithoutSubscription: State {
|
|
loading.loaded(
|
|
oneTimeConfig: Self.defaultOneTimeConfig,
|
|
monthlyConfig: Self.defaultMonthlyConfig,
|
|
paymentMethodsConfig: Self.defaultPaymentMethodsConfig,
|
|
currentMonthlySubscription: nil,
|
|
subscriberID: nil,
|
|
previousMonthlySubscriptionCurrencyCode: nil,
|
|
previousMonthlySubscriptionPaymentMethod: nil,
|
|
oneTimeBoostReceiptCredentialRequestError: nil,
|
|
recurringSubscriptionReceiptCredentialRequestError: nil,
|
|
pendingIDEALOneTimeDonation: nil,
|
|
pendingIDEALSubscription: nil,
|
|
locale: Locale(identifier: "en-US"),
|
|
localNumber: Self.localNumber
|
|
)
|
|
}
|
|
|
|
private var loadedWithSubscription: State {
|
|
loading.loaded(
|
|
oneTimeConfig: Self.defaultOneTimeConfig,
|
|
monthlyConfig: Self.defaultMonthlyConfig,
|
|
paymentMethodsConfig: Self.defaultPaymentMethodsConfig,
|
|
currentMonthlySubscription: Self.subscription(at: 2),
|
|
subscriberID: Data([1, 2, 3]),
|
|
previousMonthlySubscriptionCurrencyCode: "USD",
|
|
previousMonthlySubscriptionPaymentMethod: .applePay,
|
|
oneTimeBoostReceiptCredentialRequestError: nil,
|
|
recurringSubscriptionReceiptCredentialRequestError: nil,
|
|
pendingIDEALOneTimeDonation: nil,
|
|
pendingIDEALSubscription: nil,
|
|
locale: Locale(identifier: "en-US"),
|
|
localNumber: Self.localNumber
|
|
)
|
|
}
|
|
|
|
func loadWithDefaults(
|
|
oneTimeConfig: State.OneTimeConfiguration = defaultOneTimeConfig,
|
|
monthlyConfig: State.MonthlyConfiguration = defaultMonthlyConfig,
|
|
paymentMethodsConfig: State.PaymentMethodsConfiguration = defaultPaymentMethodsConfig,
|
|
currentMonthlySubscription: Subscription? = subscription(at: 2),
|
|
subscriberID: Data? = Data([1, 2, 3]),
|
|
previousMonthlySubscriptionCurrencyCode: Currency.Code? = nil,
|
|
locale: Locale = Locale(identifier: "en-US")
|
|
) -> State {
|
|
loading.loaded(
|
|
oneTimeConfig: oneTimeConfig,
|
|
monthlyConfig: monthlyConfig,
|
|
paymentMethodsConfig: paymentMethodsConfig,
|
|
currentMonthlySubscription: currentMonthlySubscription,
|
|
subscriberID: subscriberID,
|
|
previousMonthlySubscriptionCurrencyCode: previousMonthlySubscriptionCurrencyCode,
|
|
previousMonthlySubscriptionPaymentMethod: .applePay,
|
|
oneTimeBoostReceiptCredentialRequestError: nil,
|
|
recurringSubscriptionReceiptCredentialRequestError: nil,
|
|
pendingIDEALOneTimeDonation: nil,
|
|
pendingIDEALSubscription: nil,
|
|
locale: locale,
|
|
localNumber: Self.localNumber
|
|
)
|
|
}
|
|
|
|
func loadWithPaymentsProcessing(
|
|
recurringProcessingViaSubscription: Bool,
|
|
recurringProcessingViaError: Bool
|
|
) -> State {
|
|
let recurringError: DonationReceiptCredentialRequestError? = {
|
|
guard recurringProcessingViaError else { return nil }
|
|
|
|
return DonationReceiptCredentialRequestError(
|
|
errorCode: .paymentStillProcessing,
|
|
chargeFailureCodeIfPaymentFailed: nil,
|
|
badge: MonthlyFixtures.badgeOne,
|
|
amount: FiatMoney(currencyCode: "EUR", value: 5),
|
|
paymentMethod: .sepa
|
|
)
|
|
}()
|
|
|
|
return loading.loaded(
|
|
oneTimeConfig: Self.defaultOneTimeConfig,
|
|
monthlyConfig: Self.defaultMonthlyConfig,
|
|
paymentMethodsConfig: Self.defaultPaymentMethodsConfig,
|
|
currentMonthlySubscription: Self.subscription(
|
|
at: 2,
|
|
isPaymentProcessing: recurringProcessingViaSubscription,
|
|
paymentMethod: "SEPA_DEBIT"
|
|
),
|
|
subscriberID: Data([1, 2, 3]),
|
|
previousMonthlySubscriptionCurrencyCode: nil,
|
|
previousMonthlySubscriptionPaymentMethod: .applePay,
|
|
oneTimeBoostReceiptCredentialRequestError: DonationReceiptCredentialRequestError(
|
|
errorCode: .paymentStillProcessing,
|
|
chargeFailureCodeIfPaymentFailed: nil,
|
|
badge: OneTimeFixtures.badge,
|
|
amount: FiatMoney(currencyCode: "EUR", value: 100),
|
|
paymentMethod: .sepa
|
|
),
|
|
recurringSubscriptionReceiptCredentialRequestError: recurringError,
|
|
pendingIDEALOneTimeDonation: nil,
|
|
pendingIDEALSubscription: nil,
|
|
locale: Locale(identifier: "en-US"),
|
|
localNumber: Self.localNumber
|
|
)
|
|
}
|
|
|
|
// MARK: - Initialization
|
|
|
|
func testInitialization() {
|
|
XCTAssertEqual(initializing.loadState, .initializing)
|
|
}
|
|
|
|
// MARK: - Top-level getters
|
|
|
|
func testOneTime() {
|
|
XCTAssertNil(initializing.oneTime)
|
|
XCTAssertNil(loading.oneTime)
|
|
XCTAssertNil(loadFailed.oneTime)
|
|
XCTAssertNotNil(loadedWithoutSubscription.oneTime)
|
|
}
|
|
|
|
func testMonthly() {
|
|
XCTAssertNil(initializing.monthly)
|
|
XCTAssertNil(loading.monthly)
|
|
XCTAssertNil(loadFailed.monthly)
|
|
XCTAssertNotNil(loadedWithoutSubscription.monthly)
|
|
}
|
|
|
|
func testSelectedCurrencyCode() {
|
|
XCTAssertNil(initializing.selectedCurrencyCode)
|
|
XCTAssertEqual(loadedWithoutSubscription.selectedCurrencyCode, "USD")
|
|
}
|
|
|
|
func testSupportedCurrencyCodes() {
|
|
XCTAssertTrue(initializing.supportedCurrencyCodes.isEmpty)
|
|
|
|
let onOneTime = loadedWithoutSubscription.selectDonateMode(.oneTime)
|
|
XCTAssertEqual(onOneTime.supportedCurrencyCodes, Set<Currency.Code>(["USD", "AUD"]))
|
|
|
|
let onMonthly = loadedWithoutSubscription.selectDonateMode(.monthly)
|
|
XCTAssertEqual(onMonthly.supportedCurrencyCodes, Set<Currency.Code>(["USD", "EUR"]))
|
|
}
|
|
|
|
func testSelectedProfileBadge() {
|
|
XCTAssertNil(initializing.selectedCurrencyCode)
|
|
|
|
let onOneTime = loadedWithoutSubscription.selectDonateMode(.oneTime)
|
|
XCTAssertEqual(onOneTime.selectedProfileBadge, Self.defaultOneTimeConfig.badge)
|
|
|
|
let onMonthly = loadedWithoutSubscription.selectDonateMode(.monthly)
|
|
let levels = Self.defaultMonthlyConfig.levels
|
|
let selectedSecond = onMonthly.selectSubscriptionLevel(levels.last!)
|
|
XCTAssertEqual(onMonthly.selectedProfileBadge, levels.first!.badge)
|
|
XCTAssertEqual(selectedSecond.selectedProfileBadge, levels.last!.badge)
|
|
}
|
|
|
|
func testLoadedDonateMode() {
|
|
XCTAssertNil(initializing.loadedDonateMode)
|
|
XCTAssertNil(loadFailed.loadedDonateMode)
|
|
|
|
let onOneTime = loadedWithoutSubscription.selectDonateMode(.oneTime)
|
|
XCTAssertEqual(onOneTime.loadedDonateMode, .oneTime)
|
|
|
|
let onMonthly = loadedWithoutSubscription.selectDonateMode(.monthly)
|
|
XCTAssertEqual(onMonthly.loadedDonateMode, .monthly)
|
|
}
|
|
|
|
// MARK: - Top-level state changes
|
|
|
|
func testLoading() {
|
|
XCTAssertEqual(loading.loadState, .loading)
|
|
}
|
|
|
|
func testLoadFailed() {
|
|
XCTAssertEqual(loadFailed.loadState, .loadFailed)
|
|
}
|
|
|
|
func testLoadedBoringSettingOfProperties() {
|
|
let oneTime = loadedWithSubscription.oneTime
|
|
let monthly = loadedWithSubscription.monthly
|
|
XCTAssertEqual(oneTime?.selectedPreset, Self.defaultOneTimeConfig.presetAmounts["USD"])
|
|
XCTAssertEqual(oneTime?.selectedAmount, .nothingSelected(currencyCode: "USD"))
|
|
XCTAssertEqual(oneTime?.profileBadge, Self.defaultOneTimeConfig.badge)
|
|
XCTAssertEqual(monthly?.subscriptionLevels, Self.defaultMonthlyConfig.levels)
|
|
XCTAssertEqual(monthly?.currentSubscription, Self.subscription(at: 2))
|
|
XCTAssertEqual(monthly?.subscriberID, Data([1, 2, 3]))
|
|
}
|
|
|
|
func testLoadedDefaultOneTimeCurrency() {
|
|
let american = loadWithDefaults(locale: Locale(identifier: "en-US"))
|
|
let australian = loadWithDefaults(locale: Locale(identifier: "en-AU"))
|
|
let spanish = loadWithDefaults(locale: Locale(identifier: "es-ES"))
|
|
let korean = loadWithDefaults(locale: Locale(identifier: "kr-KR"))
|
|
XCTAssertEqual(american.oneTime?.selectedCurrencyCode, "USD")
|
|
XCTAssertEqual(australian.oneTime?.selectedCurrencyCode, "AUD")
|
|
XCTAssertEqual(spanish.oneTime?.selectedCurrencyCode, "USD")
|
|
XCTAssertEqual(korean.oneTime?.selectedCurrencyCode, "USD")
|
|
}
|
|
|
|
func testLoadedDefaultMonthlyCurrency() {
|
|
let withPreviousCurrency = loadWithDefaults(previousMonthlySubscriptionCurrencyCode: "EUR")
|
|
XCTAssertEqual(withPreviousCurrency.monthly?.selectedCurrencyCode, "EUR")
|
|
|
|
let withSubscription = loadWithDefaults(locale: Locale(identifier: "kr-KR"))
|
|
XCTAssertEqual(withSubscription.monthly?.selectedCurrencyCode, "USD")
|
|
|
|
let withSupportedLocaleCurrency = loadWithDefaults(
|
|
currentMonthlySubscription: nil,
|
|
locale: Locale(identifier: "es-ES")
|
|
)
|
|
XCTAssertEqual(withSupportedLocaleCurrency.monthly?.selectedCurrencyCode, "EUR")
|
|
|
|
let withUnsupportedLocaleCurrency = loadWithDefaults(
|
|
currentMonthlySubscription: nil,
|
|
locale: Locale(identifier: "kr-KR")
|
|
)
|
|
XCTAssertEqual(withUnsupportedLocaleCurrency.monthly?.selectedCurrencyCode, "USD")
|
|
}
|
|
|
|
func testLoadedSubscriptionLevelWithNoSubscription() {
|
|
XCTAssertEqual(
|
|
loadedWithoutSubscription.monthly?.selectedSubscriptionLevel,
|
|
Self.defaultMonthlyConfig.levels.first!
|
|
)
|
|
}
|
|
|
|
func testLoadedSubscriptionLevelWithStillSupportedSubscription() {
|
|
XCTAssertEqual(
|
|
loadedWithSubscription.monthly?.selectedSubscriptionLevel,
|
|
Self.defaultMonthlyConfig.levels[1]
|
|
)
|
|
}
|
|
|
|
func testLoadedSubscriptionLevelWithSubscriptionTheServerNoLongerLists() {
|
|
let state = loadWithDefaults(currentMonthlySubscription: Self.subscription(at: 99))
|
|
XCTAssertEqual(
|
|
state.monthly?.selectedSubscriptionLevel,
|
|
Self.defaultMonthlyConfig.levels.first!
|
|
)
|
|
}
|
|
|
|
func testSelectCurrencyCode() {
|
|
let selectedUsd = loadedWithoutSubscription.selectCurrencyCode("USD")
|
|
XCTAssertEqual(selectedUsd.selectDonateMode(.oneTime).selectedCurrencyCode, "USD")
|
|
XCTAssertEqual(selectedUsd.selectDonateMode(.monthly).selectedCurrencyCode, "USD")
|
|
|
|
let triedToSelectEur = loadedWithoutSubscription.selectCurrencyCode("EUR")
|
|
XCTAssertEqual(triedToSelectEur.selectDonateMode(.oneTime).selectedCurrencyCode, "USD")
|
|
XCTAssertEqual(triedToSelectEur.selectDonateMode(.monthly).selectedCurrencyCode, "EUR")
|
|
|
|
let triedToSelectAud = loadedWithoutSubscription.selectCurrencyCode("AUD")
|
|
XCTAssertEqual(triedToSelectAud.selectDonateMode(.oneTime).selectedCurrencyCode, "AUD")
|
|
XCTAssertEqual(triedToSelectAud.selectDonateMode(.monthly).selectedCurrencyCode, "USD")
|
|
}
|
|
|
|
func testSupportedPaymentMethods() {
|
|
let oneTimeConfig = OneTimeFixtures.configWithDefaults(
|
|
minimums: [
|
|
"USD": 10.as("USD"),
|
|
"EUR": 200.as("EUR")
|
|
],
|
|
presets: [
|
|
"USD": .init(currencyCode: "USD", amounts: [10.as("USD"), 20.as("USD")]),
|
|
"EUR": .init(currencyCode: "EUR", amounts: [200.as("EUR"), 400.as("EUR")])
|
|
]
|
|
)
|
|
|
|
let monthlyConfig = MonthlyFixtures.configWithDefaults(
|
|
subscriptionLevels: [
|
|
MonthlyFixtures.levelOneWithDefaults(
|
|
amounts: [
|
|
"USD": 15.as("USD"),
|
|
"EUR": 250.as("EUR")
|
|
]
|
|
)
|
|
]
|
|
)
|
|
|
|
let paymentMethodsConfig = PaymentMethodsFixtures.configWithDefaults(
|
|
paymentMethods: [
|
|
"USD": [.paypal, .applePay],
|
|
"EUR": []
|
|
]
|
|
)
|
|
|
|
var state = loadWithDefaults(
|
|
oneTimeConfig: oneTimeConfig,
|
|
monthlyConfig: monthlyConfig,
|
|
paymentMethodsConfig: paymentMethodsConfig
|
|
)
|
|
|
|
// If a currency has no payment methods, it should not be supported.
|
|
|
|
state = state.selectDonateMode(.oneTime)
|
|
XCTAssertEqual(
|
|
state.supportedCurrencyCodes,
|
|
["USD"],
|
|
"Only USD should be supported for one-time, as only it has any payment methods!"
|
|
)
|
|
|
|
state = state.selectDonateMode(.monthly)
|
|
XCTAssertEqual(
|
|
state.supportedCurrencyCodes,
|
|
["USD"],
|
|
"Only USD should be supported for monthly, as only it has any payment methods!"
|
|
)
|
|
|
|
// If the selected currency has supported payment methods, payment
|
|
// requests should return them - unless they are disabled globally
|
|
// for that type of payment.
|
|
|
|
state = state.selectCurrencyCode("USD")
|
|
state = state.selectOneTimeAmount(.choseCustomAmount(amount: 123.as("USD")))
|
|
state = state.selectSubscriptionLevel(monthlyConfig.levels.first!)
|
|
|
|
let oneTimePaymentRequest = state.oneTime!.paymentRequest
|
|
switch oneTimePaymentRequest {
|
|
case let .canContinue(amount, supportedPaymentMethods):
|
|
XCTAssertEqual(amount, 123.as("USD"))
|
|
XCTAssertEqual(supportedPaymentMethods, [.paypal, .applePay])
|
|
default:
|
|
XCTFail("Unexpectedly invalid one-time payment request! \(oneTimePaymentRequest)")
|
|
}
|
|
|
|
let monthlyPaymentRequest = state.monthly!.paymentRequest!
|
|
XCTAssertEqual(monthlyPaymentRequest.amount, 15.as("USD"))
|
|
XCTAssertEqual(monthlyPaymentRequest.supportedPaymentMethods, [.paypal, .applePay])
|
|
}
|
|
|
|
func testPaymentProcessing() {
|
|
let oneTimeProcessing = loadWithPaymentsProcessing(
|
|
recurringProcessingViaSubscription: false,
|
|
recurringProcessingViaError: false
|
|
)
|
|
|
|
switch oneTimeProcessing.oneTime!.paymentRequest {
|
|
case let .alreadyHasPaymentProcessing(paymentMethod):
|
|
XCTAssertEqual(paymentMethod, .sepa)
|
|
case .noAmountSelected, .amountIsTooSmall, .canContinue, .awaitingIDEALAuthorization:
|
|
XCTFail("Should be payment processing!")
|
|
}
|
|
|
|
/// Simulates a payment that has not yet processed.
|
|
let recurringProcessingViaSubscription = loadWithPaymentsProcessing(
|
|
recurringProcessingViaSubscription: true,
|
|
recurringProcessingViaError: true
|
|
)
|
|
|
|
XCTAssertEqual(
|
|
recurringProcessingViaSubscription.monthly!.paymentMethodIfPaymentProcessing,
|
|
.sepa
|
|
)
|
|
|
|
/// Simulates a payment that has processed, but our client hasn't yet
|
|
/// redeemed a badge for it.
|
|
let recurringProcessingOnlyViaError = loadWithPaymentsProcessing(
|
|
recurringProcessingViaSubscription: false,
|
|
recurringProcessingViaError: true
|
|
)
|
|
|
|
XCTAssertEqual(
|
|
recurringProcessingOnlyViaError.monthly!.paymentMethodIfPaymentProcessing,
|
|
.sepa
|
|
)
|
|
}
|
|
}
|
|
|
|
fileprivate extension Int {
|
|
func `as`(_ currencyCode: Currency.Code) -> FiatMoney {
|
|
FiatMoney(currencyCode: currencyCode, value: Decimal(self))
|
|
}
|
|
}
|