Skip to content

Commit

Permalink
Merge branch 'master' into bn/cvv-recapture-drop-in
Browse files Browse the repository at this point in the history
  • Loading branch information
borisprimer authored and BorisNikolic committed Apr 3, 2024
2 parents 8f61ef3 + 730c082 commit 19933e1
Show file tree
Hide file tree
Showing 30 changed files with 1,029 additions and 731 deletions.
2 changes: 1 addition & 1 deletion .cz.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.commitizen]
version_scheme = "semver"
version = "2.24.0"
version = "2.25.0"
version_files = [
"Sources/PrimerSDK/Classes/version.swift:let PrimerSDKVersion",
"PrimerSDK.podspec:s.version"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_test_upload.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
- name: Select Xcode Version
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
xcode-version: '15.1'
xcode-version: '14.3.1'
- name: Install SSH key
uses: shimataro/ssh-key-action@d4fffb50872869abe2d9a9098a6d9c5aa7d16be4 #v2.7.0
with:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.25.0 (2024-03-28)

### Feat

- Klarna Drop-IN Reskin (#822)

## 2.24.0 (2024-03-18)

### Feat
Expand Down
4 changes: 2 additions & 2 deletions Debug App/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PODS:
- IQKeyboardManagerSwift (7.0.1)
- Primer3DS (2.3.0)
- Primer3DS (2.3.1)
- PrimerIPay88MYSDK (0.1.7)
- PrimerKlarnaSDK (1.1.0)
- PrimerNolPaySDK (1.0.1)
Expand Down Expand Up @@ -30,7 +30,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
IQKeyboardManagerSwift: 7f6b1b1d1497855d2beea7f2f10ffcc6978525b1
Primer3DS: c70e939120c0e37aa968f89ecb59d5add5497720
Primer3DS: 1caa7f7c764c9e94d5e122755ffc56343a771991
PrimerIPay88MYSDK: 436ee0be7e2c97e4e81456ccddee20175e9e3c4d
PrimerKlarnaSDK: 83e9a1357a7247bf8fa2836fc945cf97644d601d
PrimerNolPaySDK: 08b140ed39b378a0b33b4f8746544a402175c0cc
Expand Down
4 changes: 4 additions & 0 deletions Debug App/Primer.io Debug App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
876141082B8346650058CA8C /* MerchantHeadlessKlarnaInitializationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 876141072B8346650058CA8C /* MerchantHeadlessKlarnaInitializationView.swift */; };
8761410A2B8355920058CA8C /* MerchantHeadlessKlarnaInitializationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 876141092B8355920058CA8C /* MerchantHeadlessKlarnaInitializationViewModel.swift */; };
8761410C2B849A250058CA8C /* MerchantHeadlessKlarnaInitializationView+Elements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8761410B2B849A250058CA8C /* MerchantHeadlessKlarnaInitializationView+Elements.swift */; };
87DF3EC72BA871BD00162100 /* PrimerKlarnaCategoriesViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87DF3EC62BA871BD00162100 /* PrimerKlarnaCategoriesViewControllerTests.swift */; };
8B5CB0C992DBAB293D378FAD /* MockModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EA7D2BB0AC0A1877DB2E6CE /* MockModule.swift */; };
91FAC91E687B6981268E677E /* DateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA0B2BEE5C389FD13E210847 /* DateTests.swift */; };
9263BD762EC26F6AA986F0C9 /* MockAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17476BFBED51F389FCE82F16 /* MockAPIClient.swift */; };
Expand Down Expand Up @@ -264,6 +265,7 @@
876141072B8346650058CA8C /* MerchantHeadlessKlarnaInitializationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessKlarnaInitializationView.swift; sourceTree = "<group>"; };
876141092B8355920058CA8C /* MerchantHeadlessKlarnaInitializationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantHeadlessKlarnaInitializationViewModel.swift; sourceTree = "<group>"; };
8761410B2B849A250058CA8C /* MerchantHeadlessKlarnaInitializationView+Elements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MerchantHeadlessKlarnaInitializationView+Elements.swift"; sourceTree = "<group>"; };
87DF3EC62BA871BD00162100 /* PrimerKlarnaCategoriesViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimerKlarnaCategoriesViewControllerTests.swift; sourceTree = "<group>"; };
8A23886804B13FA754E775D0 /* MockPaymentMethodTokenizationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPaymentMethodTokenizationViewModel.swift; sourceTree = "<group>"; };
8A3FDC6FE0EB5AB5828D4D80 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
8C7C082270CF1C6B7810F9B3 /* RawDataManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawDataManagerTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -592,6 +594,7 @@
876140E12B66F89D0058CA8C /* KlarnaHeadlessManagerTests.swift */,
876140F32B70FBFE0058CA8C /* KlarnaTokenizationComponentTests.swift */,
876140F52B716E060058CA8C /* KlarnaTokenizationManagerTests.swift */,
87DF3EC62BA871BD00162100 /* PrimerKlarnaCategoriesViewControllerTests.swift */,
);
path = Klarna;
sourceTree = "<group>";
Expand Down Expand Up @@ -1101,6 +1104,7 @@
042ED1622AF0F5600027833F /* MockBINDataAPIClient.swift in Sources */,
5976CCA261F0811F5D7707DA /* TokenizationService.swift in Sources */,
583EBAA90902121CEA479416 /* VaultService.swift in Sources */,
87DF3EC72BA871BD00162100 /* PrimerKlarnaCategoriesViewControllerTests.swift in Sources */,
961B5D18058EF4CFCD0185AE /* MockVaultCheckoutViewModel.swift in Sources */,
622A605DDEA98D981670B53F /* DropInUI_TokenizationViewModelTests.swift in Sources */,
F03699592AC2E63700E4179D /* (null) in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
"state": {
"branch": null,
"revision": "f13260c24a900f28e21bafd213c22191e6280e86",
"version": "1.0.4"
"version": "1.1.0"
}
},
{
"package": "Primer3DS",
"repositoryURL": "https://github.com/primer-io/primer-sdk-3ds-ios",
"state": {
"branch": null,
"revision": "e1ec345543e1d7583dd574cecfb488b47b681936",
"version": "2.3.0"
"revision": "e400363648a3217501fffc283bc009e7919d782b",
"version": "2.3.1"
}
}
]
Expand Down
19 changes: 16 additions & 3 deletions Debug App/Tests/Unit Tests/Primer/Klarna/KlarnaTestsMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ class KlarnaTestsMocks {
diagnosticsId: UUID().uuidString
)

static let primerPaymentMethodTokenData = PrimerPaymentMethodTokenData(
analyticsId: "mock_analytics_id",
id: "mock_payment_method_token_data_id",
isVaulted: false,
isAlreadyVaulted: false,
paymentInstrumentType: .klarnaCustomerToken,
paymentMethodType: "KLARNA",
paymentInstrumentData: nil,
threeDSecureAuthentication: nil,
token: "mock_payment_method_token",
tokenType: .singleUse,
vaultData: nil)

static var extraMerchantData: [String: Any] = [
"subscription": [
[
Expand Down Expand Up @@ -73,9 +86,9 @@ class KlarnaTestsMocks {

static func getMockPrimerApiConfiguration(clientSession: ClientSession.APIResponse) -> Response.Body.Configuration {
return Response.Body.Configuration(
coreUrl: "https://primer.io/core",
pciUrl: "https://primer.io/pci",
binDataUrl: "https://bindata.url",
coreUrl: "https://core.primer.io",
pciUrl: "https://pci.primer.io",
binDataUrl: "https://primer.io/bindata",
assetsUrl: "https://assets.staging.core.primer.io",
clientSession: clientSession,
paymentMethods: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,104 +12,170 @@ import XCTest

final class KlarnaTokenizationManagerTests: XCTestCase {

// var tokenizationComponent: KlarnaTokenizationComponent!
//
// override func setUp() {
// super.setUp()
// prepareConfigurations()
// }
//
// override func tearDown() {
// restartPrimerConfiguration()
// super.tearDown()
// }
//
// func test_tokenize_success() {
// let finalizePaymentData = KlarnaTestsMocks.getMockFinalizeKlarnaPaymentSession(isValid: true)
// let expectation = XCTestExpectation(description: "Successful Tokenize Klarna Payment Session")
//
// firstly {
// tokenizationComponent.tokenize(customerToken: finalizePaymentData, offSessionAuthorizationId: finalizePaymentData.customerTokenId)
// }
// .done { tokenData in
// XCTAssertNotNil(tokenData, "Result should not be nil")
// expectation.fulfill()
// }
// .catch { _ in
// expectation.fulfill()
// }
//
// wait(for: [expectation], timeout: 10.0)
// }
//
// func test_tokenize_failure() {
// let finalizePaymentData = KlarnaTestsMocks.getMockFinalizeKlarnaPaymentSession(isValid: false)
// let expectation = XCTestExpectation(description: "Failure Tokenize Klarna Payment Session")
//
// firstly {
// tokenizationComponent.tokenize(customerToken: finalizePaymentData, offSessionAuthorizationId: finalizePaymentData.customerTokenId)
// }
// .done { tokenData in
// XCTFail("Result should be nil")
// expectation.fulfill()
// }
// .catch { error in
// XCTAssertNotNil(error, "Error should not be nil")
// expectation.fulfill()
// }
//
// wait(for: [expectation], timeout: 10.0)
// }
var tokenizationManager: MockKlarnaTokenizationManager!

override func setUp() {
super.setUp()
prepareConfigurations()
}

override func tearDown() {
restartPrimerConfiguration()
super.tearDown()
}

func test_tokenizeHeadless_success() {
let finalizePaymentData = KlarnaTestsMocks.getMockFinalizeKlarnaPaymentSession(isValid: true)
let expectation = XCTestExpectation(description: "Successful Tokenize Klarna Payment Session")
tokenizationManager.mockedSuccessValue = true

firstly {
tokenizationManager.tokenizeHeadless(customerToken: finalizePaymentData, offSessionAuthorizationId: finalizePaymentData.customerTokenId)
}
.done { tokenData in
XCTAssertNotNil(tokenData, "Result should not be nil")
expectation.fulfill()
}
.catch { _ in
XCTFail("Result should be nil")
expectation.fulfill()
}

wait(for: [expectation], timeout: 10.0)
}

func test_tokenizeHeadless_failure() {
let finalizePaymentData = KlarnaTestsMocks.getMockFinalizeKlarnaPaymentSession(isValid: false)
let expectation = XCTestExpectation(description: "Failure Tokenize Klarna Payment Session")
tokenizationManager.mockedSuccessValue = false

firstly {
tokenizationManager.tokenizeHeadless(customerToken: finalizePaymentData, offSessionAuthorizationId: finalizePaymentData.customerTokenId)
}
.done { tokenData in
XCTFail("Result should be nil")
expectation.fulfill()
}
.catch { error in
XCTAssertNotNil(error, "Error should not be nil")
expectation.fulfill()
}

wait(for: [expectation], timeout: 10.0)
}

func test_tokenizeDropIn_success() {
let finalizePaymentData = KlarnaTestsMocks.getMockFinalizeKlarnaPaymentSession(isValid: true)
let expectation = XCTestExpectation(description: "Successful Tokenize Klarna Payment Session")
tokenizationManager.mockedSuccessValue = true

firstly {
tokenizationManager.tokenizeDropIn(customerToken: finalizePaymentData, offSessionAuthorizationId: finalizePaymentData.customerTokenId)
}
.done { tokenData in
XCTAssertNotNil(tokenData, "Result should not be nil")
expectation.fulfill()
}
.catch { _ in
XCTFail("Result should be nil")
expectation.fulfill()
}

wait(for: [expectation], timeout: 10.0)
}

func test_tokenizeDropIn_failure() {
let finalizePaymentData = KlarnaTestsMocks.getMockFinalizeKlarnaPaymentSession(isValid: false)
let expectation = XCTestExpectation(description: "Failure Tokenize Klarna Payment Session")
tokenizationManager.mockedSuccessValue = false

firstly {
tokenizationManager.tokenizeDropIn(customerToken: finalizePaymentData, offSessionAuthorizationId: finalizePaymentData.customerTokenId)
}
.done { tokenData in
XCTFail("Result should be nil")
expectation.fulfill()
}
.catch { error in
XCTAssertNotNil(error, "Error should not be nil")
expectation.fulfill()
}

wait(for: [expectation], timeout: 10.0)
}

}

// extension KlarnaTokenizationManagerTests {
// private func setupPrimerConfiguration(paymentMethod: PrimerPaymentMethod, apiConfiguration: PrimerAPIConfiguration) {
// let mockApiClient = MockPrimerAPIClient()
// mockApiClient.fetchConfigurationWithActionsResult = (apiConfiguration, nil)
// mockApiClient.mockSuccessfulResponses()
//
// AppState.current.clientToken = KlarnaTestsMocks.clientToken
// PrimerAPIConfigurationModule.apiClient = mockApiClient
// PrimerAPIConfigurationModule.clientToken = KlarnaTestsMocks.clientToken
// PrimerAPIConfigurationModule.apiConfiguration = apiConfiguration
//
// tokenizationComponent = KlarnaTokenizationComponent(paymentMethod: paymentMethod)
// }
//
// private func prepareConfigurations() {
// PrimerInternal.shared.intent = .checkout
// let clientSession = KlarnaTestsMocks.getClientSession()
// let successApiConfiguration = KlarnaTestsMocks.getMockPrimerApiConfiguration(clientSession: clientSession)
// successApiConfiguration.paymentMethods?[0].baseLogoImage = PrimerTheme.BaseImage(colored: UIImage(), light: nil, dark: nil)
// setupPrimerConfiguration(paymentMethod: Mocks.PaymentMethods.klarnaPaymentMethod, apiConfiguration: successApiConfiguration)
// }
//
// private func restartPrimerConfiguration() {
// AppState.current.clientToken = nil
// PrimerAPIConfigurationModule.clientToken = nil
// PrimerAPIConfigurationModule.apiConfiguration = nil
// PrimerAPIConfigurationModule.apiClient = nil
// tokenizationComponent = nil
// }
//
// private func getInvalidTokenError() -> PrimerError {
// let error = PrimerError.invalidClientToken(
// userInfo: self.getErrorUserInfo(),
// diagnosticsId: UUID().uuidString
// )
// ErrorHandler.handle(error: error)
// return error
// }
//
// private func getErrorUserInfo() -> [String: String] {
// return [
// "file": #file,
// "class": "\(Self.self)",
// "function": #function,
// "line": "\(#line)"
// ]
// }
// }
extension KlarnaTokenizationManagerTests {
private func setupPrimerConfiguration(paymentMethod: PrimerPaymentMethod, apiConfiguration: PrimerAPIConfiguration) {
let mockApiClient = MockPrimerAPIClient()
mockApiClient.fetchConfigurationWithActionsResult = (apiConfiguration, nil)
mockApiClient.mockSuccessfulResponses()

AppState.current.clientToken = KlarnaTestsMocks.clientToken
PrimerAPIConfigurationModule.apiClient = mockApiClient
PrimerAPIConfigurationModule.clientToken = KlarnaTestsMocks.clientToken
PrimerAPIConfigurationModule.apiConfiguration = apiConfiguration

tokenizationManager = MockKlarnaTokenizationManager()
}

private func prepareConfigurations() {
PrimerInternal.shared.intent = .checkout
let clientSession = KlarnaTestsMocks.getClientSession()
let successApiConfiguration = KlarnaTestsMocks.getMockPrimerApiConfiguration(clientSession: clientSession)
successApiConfiguration.paymentMethods?[0].baseLogoImage = PrimerTheme.BaseImage(colored: UIImage(), light: nil, dark: nil)
setupPrimerConfiguration(paymentMethod: Mocks.PaymentMethods.klarnaPaymentMethod, apiConfiguration: successApiConfiguration)
}

private func restartPrimerConfiguration() {
AppState.current.clientToken = nil
PrimerAPIConfigurationModule.clientToken = nil
PrimerAPIConfigurationModule.apiConfiguration = nil
PrimerAPIConfigurationModule.apiClient = nil
tokenizationManager = nil
}

private func getInvalidTokenError() -> PrimerError {
let error = PrimerError.invalidClientToken(
userInfo: self.getErrorUserInfo(),
diagnosticsId: UUID().uuidString
)
ErrorHandler.handle(error: error)
return error
}

private func getErrorUserInfo() -> [String: String] {
return [
"file": #file,
"class": "\(Self.self)",
"function": #function,
"line": "\(#line)"
]
}
}

class MockKlarnaTokenizationManager: KlarnaTokenizationManagerProtocol {
var mockedSuccessValue: Bool = false

let primerError = PrimerError.paymentFailed(paymentMethodType: "KLARNA", description: "payment_failed", userInfo: nil, diagnosticsId: UUID().uuidString)

func tokenizeHeadless(customerToken: PrimerSDK.Response.Body.Klarna.CustomerToken?, offSessionAuthorizationId: String?) -> PrimerSDK.Promise<PrimerSDK.PrimerCheckoutData> {
return Promise { seal in

let primerCheckoutData = PrimerCheckoutData(payment: PrimerCheckoutDataPayment(id: "mock-id", orderId: "ios-mock-id", paymentFailureReason: nil))

mockedSuccessValue ? seal.fulfill(primerCheckoutData) : seal.reject(primerError)
}
}

func tokenizeDropIn(customerToken: PrimerSDK.Response.Body.Klarna.CustomerToken?, offSessionAuthorizationId: String?) -> PrimerSDK.Promise<PrimerSDK.PrimerPaymentMethodTokenData> {
return Promise { seal in

let tokenData = KlarnaTestsMocks.primerPaymentMethodTokenData
mockedSuccessValue ? seal.fulfill(tokenData) : seal.reject(primerError)
}
}
}

#endif
Loading

0 comments on commit 19933e1

Please sign in to comment.