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

feat: add type conversion when submitting element values #66

Merged
merged 3 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ internal protocol InternalElementProtocol {
func getMaskedValue() -> String?
}

public enum ElementValueType: String {
case int = "int"
case double = "double"
case bool = "bool"
case string = "string"
}

internal protocol ElementReferenceProtocol {
func getValue() -> String?
var getValueType: ElementValueType? { get set }
var isComplete: Bool? { get set }
var elementId: String { get set }
}
Expand All @@ -43,11 +51,13 @@ public class ElementValueReference: ElementReferenceProtocol {
var elementId: String
var valueMethod: (() -> String)?
var isComplete: Bool? = true
var getValueType: ElementValueType? = .string

init(elementId: String = UUID(uuid: UUID_NULL).uuidString, valueMethod: (() -> String)?, isComplete: Bool?) {
init(elementId: String = UUID(uuid: UUID_NULL).uuidString, valueMethod: (() -> String)?, isComplete: Bool?, getValueType: ElementValueType? = .string) {
self.valueMethod = valueMethod
self.isComplete = isComplete
self.elementId = elementId
self.getValueType = getValueType
}

func getValue() -> String? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,20 @@ final public class BasisTheoryElements {

throw TokenizingError.invalidInput
}
body[key] = textValue


switch (v.getValueType) {
case .int:
body[key] = Int(textValue!)
case .double:
body[key] = Double(textValue!)
case .bool:
body[key] = Bool(textValue!)
case .string:
body[key] = textValue
case .none:
body[key] = textValue
}

TelemetryLogging.info("Retrieving element value for API call", attributes: [
"elementId": v.elementId,
"endpoint": endpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ final public class CardExpirationDateUITextField: TextElementUITextField {
}

public func month() -> ElementValueReference {
let monthReference = ElementValueReference(elementId: self.elementId, valueMethod: getMonthValue, isComplete: self.isComplete)
let monthReference = ElementValueReference(elementId: self.elementId, valueMethod: getMonthValue, isComplete: self.isComplete, getValueType: .int)
return monthReference
}

public func year() -> ElementValueReference {
let yearReference = ElementValueReference(elementId: self.elementId, valueMethod: getYearValue, isComplete: self.isComplete)
let yearReference = ElementValueReference(elementId: self.elementId, valueMethod: getYearValue, isComplete: self.isComplete, getValueType: .int)
return yearReference
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ public struct TextElementOptions {
let validation: NSRegularExpression?
let enableCopy: Bool?
let copyIconColor: UIColor?
let getValueType: ElementValueType?

public init(mask: [Any]? = nil, transform: ElementTransform? = nil, validation: NSRegularExpression? = nil, enableCopy: Bool? = false, copyIconColor: UIColor? = nil) {
public init(mask: [Any]? = nil, transform: ElementTransform? = nil, validation: NSRegularExpression? = nil, enableCopy: Bool? = false, copyIconColor: UIColor? = nil, getValueType: ElementValueType? = .string) {
self.mask = mask
self.transform = transform
self.validation = validation
self.enableCopy = enableCopy
self.copyIconColor = copyIconColor
self.getValueType = getValueType
}
}

Expand All @@ -37,6 +39,7 @@ public class TextElementUITextField: UITextField, InternalElementProtocol, Eleme
var readOnly: Bool = false
var valueRef: TextElementUITextField?
var copyIconColor: UIColor?
var getValueType: ElementValueType? = .string
private var cancellables = Set<AnyCancellable>()
private var copyIconImageView: UIImageView = UIImageView()

Expand Down Expand Up @@ -190,6 +193,12 @@ public class TextElementUITextField: UITextField, InternalElementProtocol, Eleme
if ((options?.enableCopy) != nil && options?.enableCopy == true) {
setupCopy()
}

if (options?.getValueType != nil) {
self.getValueType = options?.getValueType
} else {
self.getValueType = .string
}
}

private func transform(text: String?) -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ final class CardExpirationDateUITextFieldTests: XCTestCase {
TokensAPI.getByIdWithRequestBuilder(id: createdToken["id"] as! String).addHeader(name: "BT-API-KEY", value: privateApiKey).execute { result in
do {
let token = try result.get().body.data!.value as! [String: Any]
XCTAssertEqual(token["monthRef"] as! String, String(self.formatMonth(month: self.getCurrentMonth())))
XCTAssertEqual(token["yearRef"] as! String, formattedYear)
XCTAssertEqual(token["monthRef"] as? Int, Int(self.formatMonth(month: self.getCurrentMonth())))
XCTAssertEqual(token["yearRef"] as? Int, Int(formattedYear))

idQueryExpectation.fulfill()
} catch {
Expand Down
64 changes: 64 additions & 0 deletions IntegrationTester/UnitTests/TextElementUITextFieldTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,68 @@ final class TextElementUITextFieldTests: XCTestCase {
// assert color
XCTAssertEqual(iconImageView?.tintColor, UIColor.red)
}

func testGetValueType() throws {
let textField = TextElementUITextField()
let intTextField = TextElementUITextField()
let doubleTextField = TextElementUITextField()
let boolTextField = TextElementUITextField()

let string: String = "string"
let int: Int = 10
let double: Double = 1.5
let bool: Bool = true

textField.insertText(string)
intTextField.insertText(String(int))
doubleTextField.insertText(String(double))
boolTextField.insertText(String(bool))

try! intTextField.setConfig(options: TextElementOptions(getValueType: .int))
try! doubleTextField.setConfig(options: TextElementOptions(getValueType: .double))
try! boolTextField.setConfig(options: TextElementOptions(getValueType: .bool))

let body: CreateToken = CreateToken(type: "token", data: [
"stringTextField": textField,
"intTextField": intTextField,
"doubleTextField": doubleTextField,
"boolTextField": boolTextField,

])

let apiKey = Configuration.getConfiguration().btApiKey!
let transformExpectation = self.expectation(description: "Get Value Types")

var createdToken: CreateTokenResponse? = nil
BasisTheoryElements.basePath = "https://api.flock-dev.com"
BasisTheoryElements.createToken(body: body, apiKey: apiKey) { data, error in
createdToken = data

XCTAssertNotNil(createdToken!.id)
XCTAssertEqual(createdToken!.type!, "token")
transformExpectation.fulfill()
}

waitForExpectations(timeout: 3)

let valueTypeQueryExpectation = self.expectation(description: "Query Token By ID to Test Value Types")
let privateApiKey = Configuration.getConfiguration().privateBtApiKey!
TokensAPI.getByIdWithRequestBuilder(id: createdToken!.id!).addHeader(name: "BT-API-KEY", value: privateApiKey).execute { result in
do {
let token = try result.get().body.data!.value as! [String: Any]

XCTAssertEqual(token["stringTextField"] as! String, string)
XCTAssertEqual(token["intTextField"] as! Int, int)
XCTAssertEqual(token["doubleTextField"] as! Double, double)
XCTAssertEqual(token["boolTextField"] as! Bool, bool)


valueTypeQueryExpectation.fulfill()
} catch {
print(error)
}
}

waitForExpectations(timeout: 3)
}
}