Skip to content

Commit

Permalink
Merge branch 'master' into bn/phone-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
BorisNikolic committed Oct 30, 2023
2 parents 703f44e + 372025d commit 6ae5bdd
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 161 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ui-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
APPETIZE_API_TOKEN: ${{ secrets.APPETIZE_API_TOKEN }}
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
SOURCE_BRANCH: ${{ github.head_ref }}
SOURCE_BRANCH: ${{ github.ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}

- name: Save Browserstack ID
Expand Down Expand Up @@ -100,7 +100,7 @@ jobs:
path: /var/tmp

- name: Setup node
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 18.3.0

Expand All @@ -118,12 +118,12 @@ jobs:
npx wdio config/wdio.ios.bs.conf.js
- name: Create Slack Report
if: ${{ (success() || failure()) && github.event.pull_request.base.ref == 'master' }}
if: ${{ success() || failure() }}
run: |
node report-script/slack-report-script.js createSlackReport iOS
- name: Post summary message to a Slack channel
if: ${{ (success() || failure()) && github.event.pull_request.base.ref == 'master' }}
if: ${{ success() || failure() }}
id: slack
uses: slackapi/[email protected]
with:
Expand All @@ -133,15 +133,15 @@ jobs:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_REPORTER_BOT_TOKEN }}

- name: Create Slack Failed Summary Report
if: ${{ failure() && github.event.pull_request.base.ref == 'master' }}
if: ${{ failure() }}
run: |
node report-script/slack-failed-report-script.js createSlackFailedSummaryReport ${{ steps.slack.outputs.thread_ts }}
env:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}

- name: Post detailed summary to Slack channel thread
if: ${{ failure() && github.event.pull_request.base.ref == 'master' }}
if: ${{ failure() }}
id: slack_thread
uses: slackapi/[email protected]
with:
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 @@ -12,6 +12,7 @@
04DFAADC2AAA01E60030FECE /* Debug App Tests-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 04DFAADB2AAA01E60030FECE /* Debug App Tests-Info.plist */; };
04F6EF722AE69FC500115D05 /* AnalyticsTests+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F6EF712AE69FC500115D05 /* AnalyticsTests+Helpers.swift */; };
04F6EF742AE6A06200115D05 /* AnalyticsEventsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F6EF732AE6A06200115D05 /* AnalyticsEventsTests.swift */; };
04FAF9EC2AE7B33E002E4BAE /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04FAF9EB2AE7B33E002E4BAE /* StringExtensionTests.swift */; };
05FAC0D894B841B52E9E0A9A /* PrimerRawCardDataManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEB1E1B37192BF739461AFF1 /* PrimerRawCardDataManagerTests.swift */; };
088961D00784BD296EA9745C /* EncodingDecodingContainerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7D8E1E91CA11EC6831ADEE4 /* EncodingDecodingContainerTests.swift */; };
0BB8BB3F9A6AC28A0C107DC8 /* UIStackViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93F15C1E46C70C3D73B50F31 /* UIStackViewExtensions.swift */; };
Expand Down Expand Up @@ -140,6 +141,7 @@
04DFAADB2AAA01E60030FECE /* Debug App Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Debug App Tests-Info.plist"; sourceTree = "<group>"; };
04F6EF712AE69FC500115D05 /* AnalyticsTests+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticsTests+Helpers.swift"; sourceTree = "<group>"; };
04F6EF732AE6A06200115D05 /* AnalyticsEventsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsEventsTests.swift; sourceTree = "<group>"; };
04FAF9EB2AE7B33E002E4BAE /* StringExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensionTests.swift; sourceTree = "<group>"; };
0DA32ABCF07A4EBED014327B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
0ED746F8924E70AD868BC0F4 /* MerchantNewLineItemViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantNewLineItemViewController.swift; sourceTree = "<group>"; };
0FD08B8CE57A11D1E35A8684 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -417,6 +419,7 @@
isa = PBXGroup;
children = (
C7D8E1E91CA11EC6831ADEE4 /* EncodingDecodingContainerTests.swift */,
04FAF9EB2AE7B33E002E4BAE /* StringExtensionTests.swift */,
);
path = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -815,6 +818,7 @@
F99DAF50E86E6F8CCD127E5B /* ThemeTests.swift in Sources */,
24C060A48D4A2670FFC3426F /* ThreeDSErrorTests.swift in Sources */,
F1A71C2E0D900FEB9AF1351C /* ThreeDSProtocolVersionTests.swift in Sources */,
04FAF9EC2AE7B33E002E4BAE /* StringExtensionTests.swift in Sources */,
C29B625B5698094691227852 /* TokenizationResponseTests.swift in Sources */,
A1585C752ACDAA700014F0B9 /* NolPayLinkedCardsComponentTests.swift in Sources */,
088961D00784BD296EA9745C /* EncodingDecodingContainerTests.swift in Sources */,
Expand Down
255 changes: 255 additions & 0 deletions Debug App/Tests/Unit Tests/Extensions/StringExtensionTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
//
// StringExtensionTests.swift
// Debug App Tests
//
// Created by Jack Newcombe on 24/10/2023.
// Copyright © 2023 Primer API Ltd. All rights reserved.
//

import XCTest
@testable import PrimerSDK

final class StringExtensionTests: XCTestCase {

func testWithoutWhitespace() {
XCTAssertEqual(" ".withoutWhiteSpace, "")
XCTAssertEqual(" ".withoutWhiteSpace, "")
XCTAssertEqual("a b".withoutWhiteSpace, "ab")
XCTAssertEqual(" a b ".withoutWhiteSpace, "ab")
XCTAssertEqual("4111 1234 9876 4321".withoutWhiteSpace, "4111123498764321")
XCTAssertEqual("\t4111 1234 9876 4321\n".withoutWhiteSpace, "4111123498764321")
}

func testIsNumeric() {
XCTAssertFalse("".isNumeric)
XCTAssertFalse(" ".isNumeric)
XCTAssertFalse("a".isNumeric)
XCTAssertFalse("1a0".isNumeric)
XCTAssertFalse("10 000".isNumeric)
XCTAssertFalse("99,999,999".isNumeric)

XCTAssertTrue("0".isNumeric)
XCTAssertTrue("1".isNumeric)
XCTAssertTrue("1000".isNumeric)
XCTAssertTrue("1234567890".isNumeric)
}

func testIsValidCardNumber() {
Constants.testCardNumbers.flatMap { $0.value }.forEach {
XCTAssertTrue($0.isValidCardNumber)
}

XCTAssertFalse("".isValidCardNumber)
XCTAssertFalse("abcd".isValidCardNumber)
XCTAssertFalse("0".isValidCardNumber)
XCTAssertFalse("0001 0001 0001 0001".isValidCardNumber) // Not Luhn-valid
}

func testIsHttpOrHttpsURL() {
XCTAssertTrue("https://google.com".isHttpOrHttpsURL)
XCTAssertTrue("http://google.com".isHttpOrHttpsURL)

XCTAssertTrue("https://".isHttpOrHttpsURL)
XCTAssertTrue("http://".isHttpOrHttpsURL)

XCTAssertFalse("google.com".isHttpOrHttpsURL)
XCTAssertFalse("not a url".isHttpOrHttpsURL)
}

func testWithoutNonNumericCharacters() {
XCTAssertEqual("abcdefg123456".withoutNonNumericCharacters, "123456")
XCTAssertEqual("a1b2c3e4f5g6".withoutNonNumericCharacters, "123456")
XCTAssertEqual("00000".withoutNonNumericCharacters, "00000")
}

func testIsValidExpiryDate() {
XCTAssertFalse("00/00".isValidExpiryDate)
XCTAssertFalse("00/0000".isValidExpiryDate)
XCTAssertFalse("99/2030".isValidExpiryDate)
XCTAssertFalse("13/2030".isValidExpiryDate)
XCTAssertFalse("01/23".isValidExpiryDate)
XCTAssertFalse("01/23".isValidExpiryDate)
XCTAssertFalse("12/2023".isValidExpiryDate)
XCTAssertFalse("12/2030".isValidExpiryDate)

XCTAssertTrue("01/28".isValidExpiryDate)
XCTAssertTrue("12/30".isValidExpiryDate)
}

func testIsTypingValidCVV() {
// Four digit
let fourDigitCVVNetworks = CardNetwork.allCases.filter { network in
guard let validation = network.validation else { return false }
return validation.code.length == 4
}
fourDigitCVVNetworks.forEach { network in
XCTAssertTrue("1234".isValidCVV(cardNetwork: network))
XCTAssertFalse("12".isValidCVV(cardNetwork: network))
XCTAssertFalse("123".isValidCVV(cardNetwork: network))
XCTAssertFalse("".isValidCVV(cardNetwork: network))
}

// Three digit
let threeDigitCVVNetworks = CardNetwork.allCases.filter { network in
guard let validation = network.validation else { return false }
return validation.code.length == 3
}
threeDigitCVVNetworks.forEach { network in
XCTAssertTrue("123".isValidCVV(cardNetwork: network))
XCTAssertFalse("12".isValidCVV(cardNetwork: network))
XCTAssertFalse("1234".isValidCVV(cardNetwork: network))
XCTAssertFalse("".isValidCVV(cardNetwork: network))
}
}

func testIsValidNonDecimalString() {
XCTAssertFalse("".isValidNonDecimalString)
XCTAssertFalse("12345".isValidNonDecimalString)
XCTAssertFalse("abcde12345".isValidNonDecimalString)
XCTAssertTrue("abcde".isValidNonDecimalString)
XCTAssertTrue("John Doe".isValidNonDecimalString)
}

func testIsValidPostalCode() {
XCTAssertTrue("AB12 3CD".isValidPostalCode)
XCTAssertTrue("EC4M 7RF".isValidPostalCode)
XCTAssertTrue("L1 1EJ".isValidPostalCode)
XCTAssertTrue("12345".isValidPostalCode)
XCTAssertTrue("12345AB".isValidPostalCode)
XCTAssertTrue("12345 AB".isValidPostalCode)
XCTAssertTrue("AB-123-45".isValidPostalCode)
XCTAssertTrue("AB-123-45".isValidPostalCode)


XCTAssertFalse("".isValidPostalCode)
XCTAssertFalse("¡€#¢∞§¶•".isValidPostalCode)
}

func testIsValidLuhn() {
// Sanity cases
XCTAssertTrue("0".isValidLuhn)
XCTAssertFalse("1".isValidLuhn)

// Invalid numbers
XCTAssertFalse("0000 0000 0000 0001".isValidLuhn)
XCTAssertFalse("4111 1212 1212 1212".isValidLuhn)

// VISA - Valid w/ and w/o spaces
XCTAssertTrue("4716 4576 2661 6808".isValidLuhn)
XCTAssertTrue("4716457626616808".isValidLuhn)

// Discover
XCTAssertTrue("4929338582262071".isValidLuhn)
XCTAssertTrue("4024007183599989533".isValidLuhn)
XCTAssertTrue("6011695471516402".isValidLuhn)

// MasterCard
XCTAssertTrue("5280802886982742".isValidLuhn)
XCTAssertTrue("5410239186890221".isValidLuhn)
XCTAssertTrue("2720992286723005".isValidLuhn)

}

func testDecodedJWTToken() {
let token = try! DecodedJWTToken.createMock()
let string = try! token.toString()

let parsedToken = string.decodedJWTToken!

XCTAssertEqual(parsedToken.accessToken, "access-token")
XCTAssertEqual(parsedToken.intent, "checkout")
XCTAssertEqual(parsedToken.coreUrl, "https://primer.io/core")
XCTAssertEqual(parsedToken.pciUrl, "https://primer.io/pci")
XCTAssertEqual(parsedToken.redirectUrl, "https://primer.io/redirect")
XCTAssertEqual(parsedToken.statusUrl, "https://primer.io/status")
XCTAssertEqual(parsedToken.configurationUrl, "https://primer.io/config")
}

func testSeparateEveryWith() {
let string1 = "abcd"
XCTAssertEqual(string1.separate(every: 1, with: "---"), "a---b---c---d")

let string2 = "1111222233334444"
XCTAssertEqual(string2.separate(every: 4, with: " "), "1111 2222 3333 4444")

let string3 = "a"
XCTAssertEqual(string3.separate(every: 1, with: "#"), "a")
}

func testIsValidPhoneNumberForPaymentType() {
// Generic case
XCTAssertTrue("+447890123456".isValidPhoneNumberForPaymentMethodType(.paymentCard))
XCTAssertTrue("+447890123456".isValidPhoneNumberForPaymentMethodType(.adyenDotPay))
XCTAssertTrue("+447890123456".isValidPhoneNumberForPaymentMethodType(.applePay))
XCTAssertTrue("+447890123456".isValidPhoneNumberForPaymentMethodType(.googlePay))
XCTAssertTrue("+129876543210".isValidPhoneNumberForPaymentMethodType(.googlePay))
XCTAssertFalse("+12987654".isValidPhoneNumberForPaymentMethodType(.googlePay))
XCTAssertFalse("+12987654301010101".isValidPhoneNumberForPaymentMethodType(.googlePay))

// XenditOvo (special case)
XCTAssertTrue("+62812345678".isValidPhoneNumberForPaymentMethodType(.xenditOvo))
XCTAssertTrue("+628123456789".isValidPhoneNumberForPaymentMethodType(.xenditOvo))
XCTAssertTrue("+6281234567890".isValidPhoneNumberForPaymentMethodType(.xenditOvo))
XCTAssertFalse("+62812345678901".isValidPhoneNumberForPaymentMethodType(.xenditOvo))
XCTAssertFalse("+6281234567".isValidPhoneNumberForPaymentMethodType(.xenditOvo))
XCTAssertFalse("+5281234567890".isValidPhoneNumberForPaymentMethodType(.xenditOvo))
}

func testIsValidExpiryDateString() {
XCTAssertThrowsError(try "".validateExpiryDateString())
XCTAssertThrowsError(try "01/2022".validateExpiryDateString())
XCTAssertThrowsError(try "08/2022".validateExpiryDateString())
XCTAssertNoThrow(try "01/2023".validateExpiryDateString())
XCTAssertNoThrow(try "01/2028".validateExpiryDateString())
XCTAssertNoThrow(try "02/2028".validateExpiryDateString())
XCTAssertNoThrow(try "12/2028".validateExpiryDateString())
XCTAssertNoThrow(try "01/2030".validateExpiryDateString())
}

func testCompareWithVersion() {
XCTAssertEqual("0.0.1".compareWithVersion("0.0.2"), .orderedAscending)
XCTAssertEqual("0.0.2".compareWithVersion("0.0.3"), .orderedAscending)
XCTAssertEqual("0.5.0".compareWithVersion("0.6.0"), .orderedAscending)
XCTAssertEqual("0.3.2".compareWithVersion("0.5.2"), .orderedAscending)
XCTAssertEqual("12.0.0".compareWithVersion("15.1.3"), .orderedAscending)

XCTAssertEqual("0.0.3".compareWithVersion("0.0.2"), .orderedDescending)
XCTAssertEqual("0.0.2".compareWithVersion("0.0.1"), .orderedDescending)
XCTAssertEqual("0.5.0".compareWithVersion("0.4.0"), .orderedDescending)
XCTAssertEqual("0.5.2".compareWithVersion("0.4.2"), .orderedDescending)
XCTAssertEqual("15.0.0".compareWithVersion("12.1.3"), .orderedDescending)

XCTAssertEqual("1.2.3".compareWithVersion("1.2.3"), .orderedSame)
}

func testIsValidCountryCode() {
XCTAssertTrue("+44".isValidCountryCode)
XCTAssertTrue("+68".isValidCountryCode)
XCTAssertTrue("+862".isValidCountryCode)
XCTAssertTrue("+862-1234".isValidCountryCode)

XCTAssertFalse("+AB".isValidCountryCode)
XCTAssertFalse("44".isValidCountryCode)
XCTAssertFalse("44-1234".isValidCountryCode)
XCTAssertFalse("-44".isValidCountryCode)
}

func testIsValidMobilePhoneNumber() {
XCTAssertTrue("01234567890".isValidMobilePhoneNumber)
XCTAssertTrue("09876543210".isValidMobilePhoneNumber)
XCTAssertTrue("77777777777777".isValidMobilePhoneNumber)
XCTAssertFalse("".isValidMobilePhoneNumber)
XCTAssertFalse("abcdefghij".isValidMobilePhoneNumber)
XCTAssertFalse("7777777777777777777".isValidMobilePhoneNumber)
XCTAssertFalse("55555".isValidMobilePhoneNumber)
}

func testIsValidOTP() {
XCTAssertTrue("123456".isValidOTP)
XCTAssertTrue("000000".isValidOTP)
XCTAssertTrue("750337".isValidOTP)
XCTAssertFalse("12345".isValidOTP)
XCTAssertFalse("1234567".isValidOTP)
XCTAssertFalse("".isValidOTP)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public enum PrimerInputElementType: Int {

case .cardholderName:
guard let text = value as? String else { return false }
return text.isValidCardholderName
return text.isValidNonDecimalString

case .otp:
guard let text = value as? String else { return false }
Expand Down
Loading

0 comments on commit 6ae5bdd

Please sign in to comment.