From 008bc34d7967f2c9ec2257be3fc2daff7318bacc Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 24 Jul 2023 16:33:07 +0400 Subject: [PATCH] Implement `AcquiringRequestBuilderTests` --- .../Client/AcquiringRequestBuilder.swift | 4 +- .../Implementations/AttachCardRequest.swift | 4 +- .../Check3DSVersionRequest.swift | 4 +- .../FinishAuthorizeRequest.swift | 4 +- .../Utils/CardDataFormatter.swift | 7 +- .../Extensions/FinishAuthorizeData+Fake.swift | 15 + .../Extensions/PaymentInitData+Fake.swift | 15 + .../Mocks/CardDataFormatterMock.swift | 60 ++++ .../EnvironmentParametersProviderMock.swift | 13 + .../Mocks/IPAddressProviderMock.swift | 14 + .../Mocks/PublicKeyProviderMock.swift | 19 ++ .../Mocks/RSAEncryptorMock.swift | 60 ++++ .../AcquiringRequestBuilderTests.swift | 277 ++++++++++++++++++ 13 files changed, 487 insertions(+), 9 deletions(-) create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/FinishAuthorizeData+Fake.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/PaymentInitData+Fake.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/CardDataFormatterMock.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/EnvironmentParametersProviderMock.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/IPAddressProviderMock.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/PublicKeyProviderMock.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/RSAEncryptorMock.swift create mode 100644 TinkoffASDKCore/TinkoffASDKCoreTests/TestCases/AcquiringRequestBuilderTests.swift diff --git a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Client/AcquiringRequestBuilder.swift b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Client/AcquiringRequestBuilder.swift index df2f88e24..5d97d9cc7 100644 --- a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Client/AcquiringRequestBuilder.swift +++ b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Client/AcquiringRequestBuilder.swift @@ -31,7 +31,7 @@ final class AcquiringRequestBuilder: IAcquiringRequestBuilder { private let baseURLProvider: IURLProvider private let publicKeyProvider: IPublicKeyProvider private let terminalKeyProvider: IStringProvider - private let cardDataFormatter: CardDataFormatter + private let cardDataFormatter: ICardDataFormatter private let rsaEncryptor: IRSAEncryptor private let ipAddressProvider: IIPAddressProvider private let environmentParametersProvider: IEnvironmentParametersProvider @@ -40,7 +40,7 @@ final class AcquiringRequestBuilder: IAcquiringRequestBuilder { baseURLProvider: IURLProvider, publicKeyProvider: IPublicKeyProvider, terminalKeyProvider: IStringProvider, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, rsaEncryptor: IRSAEncryptor, ipAddressProvider: IIPAddressProvider, environmentParametersProvider: IEnvironmentParametersProvider diff --git a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/AttachCardRequest.swift b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/AttachCardRequest.swift index 4b4521f7c..c3e0a6e0a 100644 --- a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/AttachCardRequest.swift +++ b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/AttachCardRequest.swift @@ -30,7 +30,7 @@ struct AttachCardRequest: AcquiringRequest { init( data: AttachCardData, encryptor: IRSAEncryptor, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, publicKey: SecKey, baseURL: URL ) { @@ -50,7 +50,7 @@ private extension HTTPParameters { static func parameters( requestData: AttachCardData, encryptor: IRSAEncryptor, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, publicKey: SecKey ) -> HTTPParameters { var parameters: HTTPParameters = [Constants.Keys.requestKey: requestData.requestKey] diff --git a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/Check3DSVersionRequest.swift b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/Check3DSVersionRequest.swift index e57df4490..8ef505ace 100644 --- a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/Check3DSVersionRequest.swift +++ b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/Check3DSVersionRequest.swift @@ -30,7 +30,7 @@ struct Check3DSVersionRequest: AcquiringRequest { init( check3DSRequestData: Check3DSVersionData, encryptor: IRSAEncryptor, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, publicKey: SecKey, baseURL: URL ) { @@ -50,7 +50,7 @@ private extension HTTPParameters { static func create( requestData: Check3DSVersionData, encryptor: IRSAEncryptor, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, publicKey: SecKey ) -> HTTPParameters { var parameters: HTTPParameters = [Constants.Keys.paymentId: requestData.paymentId] diff --git a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/FinishAuthorizeRequest.swift b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/FinishAuthorizeRequest.swift index 0db40fd9a..c2fc1e84f 100644 --- a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/FinishAuthorizeRequest.swift +++ b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Requests/Implementations/FinishAuthorizeRequest.swift @@ -30,7 +30,7 @@ struct FinishAuthorizeRequest: AcquiringRequest { init( requestData: FinishAuthorizeData, encryptor: IRSAEncryptor, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, ipAddressProvider: IIPAddressProvider, environmentParametersProvider: IEnvironmentParametersProvider, publicKey: SecKey, @@ -54,7 +54,7 @@ private extension HTTPParameters { static func parameters( requestData: FinishAuthorizeData, encryptor: IRSAEncryptor, - cardDataFormatter: CardDataFormatter, + cardDataFormatter: ICardDataFormatter, ipAddressProvider: IIPAddressProvider, environmentParametersProvider: IEnvironmentParametersProvider, publicKey: SecKey diff --git a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Utils/CardDataFormatter.swift b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Utils/CardDataFormatter.swift index 95bc38ef3..eee26645b 100644 --- a/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Utils/CardDataFormatter.swift +++ b/TinkoffASDKCore/TinkoffASDKCore/Domain/AcquiringAPI/Utils/CardDataFormatter.swift @@ -19,7 +19,12 @@ import Foundation -struct CardDataFormatter { +protocol ICardDataFormatter { + func formatCardData(cardNumber: String, expDate: String, cvv: String) -> String + func formatCardData(cardId: String, cvv: String?) -> String +} + +struct CardDataFormatter: ICardDataFormatter { func formatCardData(cardNumber: String, expDate: String, cvv: String) -> String { return "\(Constants.Keys.cardNumber)=\(cardNumber);\(Constants.Keys.cardExpDate)=\(expDate);\(Constants.Keys.cardCVV)=\(cvv)" } diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/FinishAuthorizeData+Fake.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/FinishAuthorizeData+Fake.swift new file mode 100644 index 000000000..42b20bbe4 --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/FinishAuthorizeData+Fake.swift @@ -0,0 +1,15 @@ +// +// FinishAuthorizeData+Fake.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +extension FinishAuthorizeData { + static func fake() -> FinishAuthorizeData { + FinishAuthorizeData(paymentId: "id", paymentSource: .savedCard(cardId: "123", cvv: "213")) + } +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/PaymentInitData+Fake.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/PaymentInitData+Fake.swift new file mode 100644 index 000000000..83795f4e2 --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Extensions/PaymentInitData+Fake.swift @@ -0,0 +1,15 @@ +// +// PaymentInitData+Fake.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +extension PaymentInitData { + static func fake() -> PaymentInitData { + PaymentInitData(amount: Int64(5000), orderId: "order_id", customerKey: "key") + } +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/CardDataFormatterMock.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/CardDataFormatterMock.swift new file mode 100644 index 000000000..61ce8c7ed --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/CardDataFormatterMock.swift @@ -0,0 +1,60 @@ +// +// CardDataFormatterMock.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +final class CardDataFormatterMock: ICardDataFormatter { + + // MARK: - formatCardDataCardNumberExpDate + + typealias FormatCardDataCardNumberExpDateArguments = (cardNumber: String, expDate: String, cvv: String) + + var formatCardDataCardNumberExpDateCallsCount = 0 + var formatCardDataCardNumberExpDateReceivedArguments: FormatCardDataCardNumberExpDateArguments? + var formatCardDataCardNumberExpDateReceivedInvocations: [FormatCardDataCardNumberExpDateArguments?] = [] + var formatCardDataCardNumberExpDateReturnValue: String! + + func formatCardData(cardNumber: String, expDate: String, cvv: String) -> String { + formatCardDataCardNumberExpDateCallsCount += 1 + let arguments = (cardNumber, expDate, cvv) + formatCardDataCardNumberExpDateReceivedArguments = arguments + formatCardDataCardNumberExpDateReceivedInvocations.append(arguments) + return formatCardDataCardNumberExpDateReturnValue + } + + // MARK: - formatCardDataCardIdCvv + + typealias FormatCardDataCardIdCvvArguments = (cardId: String, cvv: String?) + + var formatCardDataCardIdCvvCallsCount = 0 + var formatCardDataCardIdCvvReceivedArguments: FormatCardDataCardIdCvvArguments? + var formatCardDataCardIdCvvReceivedInvocations: [FormatCardDataCardIdCvvArguments?] = [] + var formatCardDataCardIdCvvReturnValue: String! + + func formatCardData(cardId: String, cvv: String?) -> String { + formatCardDataCardIdCvvCallsCount += 1 + let arguments = (cardId, cvv) + formatCardDataCardIdCvvReceivedArguments = arguments + formatCardDataCardIdCvvReceivedInvocations.append(arguments) + return formatCardDataCardIdCvvReturnValue + } +} + +// MARK: - Resets + +extension CardDataFormatterMock { + func fullReset() { + formatCardDataCardNumberExpDateCallsCount = 0 + formatCardDataCardNumberExpDateReceivedArguments = nil + formatCardDataCardNumberExpDateReceivedInvocations = [] + + formatCardDataCardIdCvvCallsCount = 0 + formatCardDataCardIdCvvReceivedArguments = nil + formatCardDataCardIdCvvReceivedInvocations = [] + } +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/EnvironmentParametersProviderMock.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/EnvironmentParametersProviderMock.swift new file mode 100644 index 000000000..b620ba03f --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/EnvironmentParametersProviderMock.swift @@ -0,0 +1,13 @@ +// +// File.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +final class EnvironmentParametersProviderMock: IEnvironmentParametersProvider { + var environmentParameters: [String: String] = [:] +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/IPAddressProviderMock.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/IPAddressProviderMock.swift new file mode 100644 index 000000000..202ccec0c --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/IPAddressProviderMock.swift @@ -0,0 +1,14 @@ +// +// IPAddressProviderMock.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +public final class IPAddressProviderMock: IIPAddressProvider { + public init() {} + public var ipAddress: IPAddress? +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/PublicKeyProviderMock.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/PublicKeyProviderMock.swift new file mode 100644 index 000000000..778c721ff --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/PublicKeyProviderMock.swift @@ -0,0 +1,19 @@ +// +// PublicKeyProviderMock.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +final class PublicKeyProviderMock: IPublicKeyProvider { + + var publicKey: SecKey { + get { return underlyingPublicKey } + set(value) { underlyingPublicKey = value } + } + + var underlyingPublicKey: SecKey! +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/RSAEncryptorMock.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/RSAEncryptorMock.swift new file mode 100644 index 000000000..b975342ea --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/Infrastructure/Mocks/RSAEncryptorMock.swift @@ -0,0 +1,60 @@ +// +// RSAEncryptorMock.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +import Foundation +@testable import TinkoffASDKCore + +final class RSAEncryptorMock: IRSAEncryptor { + + // MARK: - createPublicSecKey + + typealias CreatePublicSecKeyArguments = String + + var createPublicSecKeyCallsCount = 0 + var createPublicSecKeyReceivedArguments: CreatePublicSecKeyArguments? + var createPublicSecKeyReceivedInvocations: [CreatePublicSecKeyArguments?] = [] + var createPublicSecKeyReturnValue: SecKey? + + func createPublicSecKey(publicKey: String) -> SecKey? { + createPublicSecKeyCallsCount += 1 + let arguments = publicKey + createPublicSecKeyReceivedArguments = arguments + createPublicSecKeyReceivedInvocations.append(arguments) + return createPublicSecKeyReturnValue + } + + // MARK: - encrypt + + typealias EncryptArguments = (string: String, publicKey: SecKey) + + var encryptCallsCount = 0 + var encryptReceivedArguments: EncryptArguments? + var encryptReceivedInvocations: [EncryptArguments?] = [] + var encryptReturnValue: String? + + func encrypt(string: String, publicKey: SecKey) -> String? { + encryptCallsCount += 1 + let arguments = (string, publicKey) + encryptReceivedArguments = arguments + encryptReceivedInvocations.append(arguments) + return encryptReturnValue + } +} + +// MARK: - Resets + +extension RSAEncryptorMock { + func fullReset() { + createPublicSecKeyCallsCount = 0 + createPublicSecKeyReceivedArguments = nil + createPublicSecKeyReceivedInvocations = [] + + encryptCallsCount = 0 + encryptReceivedArguments = nil + encryptReceivedInvocations = [] + } +} diff --git a/TinkoffASDKCore/TinkoffASDKCoreTests/TestCases/AcquiringRequestBuilderTests.swift b/TinkoffASDKCore/TinkoffASDKCoreTests/TestCases/AcquiringRequestBuilderTests.swift new file mode 100644 index 000000000..990d093df --- /dev/null +++ b/TinkoffASDKCore/TinkoffASDKCoreTests/TestCases/AcquiringRequestBuilderTests.swift @@ -0,0 +1,277 @@ +// +// AcquiringRequestBuilderTests.swift +// TinkoffASDKCore-Unit-Tests +// +// Created by Никита Васильев on 21.07.2023. +// + +@testable import TinkoffASDKCore +import XCTest + +final class AcquiringRequestBuilderTests: XCTestCase { + // MARK: Properties + + private var baseURLProvider: URLProviderMock! + private var publicKeyProviderMock: PublicKeyProviderMock! + private var terminalKeyProvider: StringProviderMock! + private var cardDataFormatterMock: CardDataFormatterMock! + private var rsaEncryptorMock: RSAEncryptorMock! + private var ipAddressProviderMock: IPAddressProviderMock! + private var environmentParametersProviderMock: EnvironmentParametersProviderMock! + private var sut: AcquiringRequestBuilder! + + // MARK: Initialization + + override func setUp() { + super.setUp() + baseURLProvider = URLProviderMock() + publicKeyProviderMock = PublicKeyProviderMock() + terminalKeyProvider = StringProviderMock() + cardDataFormatterMock = CardDataFormatterMock() + rsaEncryptorMock = RSAEncryptorMock() + ipAddressProviderMock = IPAddressProviderMock() + environmentParametersProviderMock = EnvironmentParametersProviderMock() + sut = AcquiringRequestBuilder( + baseURLProvider: baseURLProvider, + publicKeyProvider: publicKeyProviderMock, + terminalKeyProvider: terminalKeyProvider, + cardDataFormatter: cardDataFormatterMock, + rsaEncryptor: rsaEncryptorMock, + ipAddressProvider: ipAddressProviderMock, + environmentParametersProvider: environmentParametersProviderMock + ) + } + + override func tearDown() { + baseURLProvider = nil + publicKeyProviderMock = nil + terminalKeyProvider = nil + cardDataFormatterMock = nil + rsaEncryptorMock = nil + ipAddressProviderMock = nil + environmentParametersProviderMock = nil + sut = nil + super.tearDown() + } + + // MARK: Tests + + func test_initRequest() throws { + // given + let params = ["key": "value"] + let data = PaymentInitData.fake() + + baseURLProvider.underlyingUrl = .doesNotMatter + environmentParametersProviderMock.environmentParameters = params + + // when + let request = sut.initRequest(data: data) + + // then + let initRequest = try XCTUnwrap(request as? InitRequest) + let dataField = try XCTUnwrap(extractDataField(from: initRequest)) + XCTAssertEqual(initRequest.baseURL, .doesNotMatter) + XCTAssertEqual(initRequest.parameters["Amount"] as? Int64, data.amount) + XCTAssertEqual(initRequest.parameters["OrderId"] as? String, data.orderId) + XCTAssertEqual(initRequest.parameters["CustomerKey"] as? String, data.customerKey) + XCTAssertEqual(dataField, params) + } + + func test_submit3DSAuthorizationV2() throws { + // given + let data = CresData(cres: "cres") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.submit3DSAuthorizationV2(data: data) + + // then + let authRequest = try XCTUnwrap(request as? Submit3DSAuthorizationV2Request) + XCTAssertEqual(authRequest.parameters["cres"] as? String, data.cres) + } + + func test_getPaymentState() throws { + // given + let data = GetPaymentStateData(paymentId: "id") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.getPaymentState(data: data) + + // then + let stateRequest = try XCTUnwrap(request as? GetPaymentStateRequest) + XCTAssertEqual(stateRequest.parameters["PaymentId"] as? String, data.paymentId) + } + + func test_charge() throws { + // given + let chargeData = ChargeData(paymentId: "id", rebillId: "rebill_id") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.charge(data: chargeData) + + // when + let chargeRequest = try XCTUnwrap(request as? ChargePaymentRequest) + XCTAssertEqual(chargeRequest.baseURL, .doesNotMatter) + XCTAssertEqual(chargeRequest.parameters["PaymentId"] as? String, chargeData.paymentId) + XCTAssertEqual(chargeRequest.parameters["RebillId"] as? String, chargeData.rebillId) + } + + func test_getCardList() throws { + // given + let data = GetCardListData(customerKey: "key") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.getCardList(data: data) + + // then + let cardListRequest = try XCTUnwrap(request as? GetCardListRequest) + XCTAssertEqual(cardListRequest.parameters["CustomerKey"] as? String, data.customerKey) + } + + func test_addCard() throws { + // given + let data = AddCardData(with: .check3DS, customerKey: "key") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.addCard(data: data) + + // then + let cardListRequest = try XCTUnwrap(request as? AddCardRequest) + XCTAssertEqual(cardListRequest.parameters["CustomerKey"] as? String, data.customerKey) + } + + func test_getAddCardState() throws { + // given + let data = GetAddCardStateData(requestKey: "key") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.getAddCardState(data: data) + + // then + let addCardRequest = try XCTUnwrap(request as? GetAddCardStateRequest) + XCTAssertEqual(addCardRequest.parameters["RequestKey"] as? String, data.requestKey) + } + + func test_submitRandomAmount() throws { + // given + let data = SubmitRandomAmountData(amount: 60, requestKey: "key") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.submitRandomAmount(data: data) + + // then + let amountRequest = try XCTUnwrap(request as? SubmitRandomAmountRequest) + XCTAssertEqual(amountRequest.parameters["RequestKey"] as? String, data.requestKey) + XCTAssertEqual(amountRequest.parameters["Amount"] as? Int, Int(data.amount)) + } + + func test_removeCard() throws { + // given + let data = RemoveCardData(cardId: "id", customerKey: "key") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.removeCard(data: data) + + // then + let removeCardRequest = try XCTUnwrap(request as? RemoveCardRequest) + XCTAssertEqual(removeCardRequest.parameters["CustomerKey"] as? String, data.customerKey) + XCTAssertEqual(removeCardRequest.parameters["CardId"] as? String, data.cardId) + } + + func test_getQR() throws { + // given + let data = GetQRData(paymentId: "id") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.getQR(data: data) + + // then + let qrRequest = try XCTUnwrap(request as? GetQRRequest) + XCTAssertEqual(qrRequest.parameters["PaymentId"] as? String, data.paymentId) + } + + func test_getStaticQR() throws { + // given + let data = GetQRDataType.imageSVG + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.getStaticQR(data: data) + + // then + let staticRequest = try XCTUnwrap(request as? GetStaticQRRequest) + XCTAssertEqual(staticRequest.parameters[Constants.Keys.dataType] as? String, data.rawValue) + } + + func test_getTinkoffPayStatus() throws { + // given + let terminalKey = "2.0" + baseURLProvider.underlyingUrl = .doesNotMatter + terminalKeyProvider.stubbedValue = terminalKey + + // when + let request = sut.getTinkoffPayStatus() + + // then + let statusRequest = try XCTUnwrap(request as? GetTinkoffPayStatusRequest) + XCTAssertEqual(statusRequest.path, "v2/TinkoffPay/terminals/\(terminalKey)/status") + } + + func test_getTinkoffPayLink() throws { + // given + let data = GetTinkoffLinkData(paymentId: "id", version: "2.0") + + baseURLProvider.underlyingUrl = .doesNotMatter + + // when + let request = sut.getTinkoffPayLink(data: data) + + // then + let linkRequest = try XCTUnwrap(request as? GetTinkoffLinkRequest) + XCTAssertEqual( + linkRequest.path, + "v2/TinkoffPay/transactions/\(data.paymentId)/versions/\(data.version)/link" + ) + } + + func test_getTerminalPayMethods() throws { + // given + let terminalKey = "2.0" + + baseURLProvider.underlyingUrl = .doesNotMatter + terminalKeyProvider.stubbedValue = terminalKey + + // when + let request = sut.getTerminalPayMethods() + + // then + let linkRequest = try XCTUnwrap(request as? GetTerminalPayMethodsRequest) + XCTAssertEqual(linkRequest.queryItems.count, 2) + XCTAssertEqual(linkRequest.queryItems[0].value, terminalKey) + XCTAssertEqual(linkRequest.queryItems[1].value, "SDK") + } + + // MARK: Private + + private func extractDataField(from request: AcquiringRequest) -> [String: String]? { + request.parameters["DATA"] as? [String: String] + } +}