diff --git a/__tests__/components/__snapshots__/components.test.js.snap b/__tests__/components/__snapshots__/components.test.js.snap index ad718fd..53f6bc9 100644 --- a/__tests__/components/__snapshots__/components.test.js.snap +++ b/__tests__/components/__snapshots__/components.test.js.snap @@ -26,6 +26,7 @@ exports[`test Collect And Reveal Elements Components test CardHolderNameElement /> `; @@ -89,6 +90,7 @@ exports[`test Collect And Reveal Elements Components test CardNumberElement comp `; @@ -121,6 +123,7 @@ exports[`test Collect And Reveal Elements Components test CvvElement component 1 /> `; @@ -153,6 +156,7 @@ exports[`test Collect And Reveal Elements Components test ExpirationDateElement /> `; @@ -185,6 +189,7 @@ exports[`test Collect And Reveal Elements Components test ExpirationMonthElement /> `; @@ -217,6 +222,7 @@ exports[`test Collect And Reveal Elements Components test ExpirationYearElement /> `; @@ -247,6 +253,7 @@ exports[`test Collect And Reveal Elements Components test InputFieldElement comp /> `; @@ -279,6 +286,7 @@ exports[`test Collect And Reveal Elements Components test PinElement component 1 /> `; @@ -298,6 +306,7 @@ Array [ , , ] `; diff --git a/__tests__/core-utils/collect.test.js b/__tests__/core-utils/collect.test.js index e223c7e..48eca10 100644 --- a/__tests__/core-utils/collect.test.js +++ b/__tests__/core-utils/collect.test.js @@ -1,7 +1,7 @@ /* Copyright (c) 2022 Skyflow, Inc. */ -import { tokenize } from '../../src/core-utils/collect'; +import { tokenize, getElementValueToInsert } from '../../src/core-utils/collect'; import CollectElement from '../../src/core/CollectElement'; import Skyflow from '../../src/core/Skyflow'; import { ElementType, Env, LogLevel } from '../../src/utils/constants'; @@ -525,3 +525,31 @@ describe('test collect utils class', () => { }); }); + +describe('getVaultInsertValue', () => { + class MockCollectElement { + constructor(type, value) { + this.type = type; + this.value = value; + } + getClientState() { + return { elementType: this.type }; + } + getUnformattedValue() { + return this.value.replace(/[\s-]/g, ''); + } + getInternalState() { + return { value: this.value }; + } + } + + test('returns unformatted value for CARD_NUMBER', () => { + const element = new MockCollectElement(ElementType.CARD_NUMBER, '4111 1111 1111 1111'); + expect(getElementValueToInsert(element)).toBe('4111111111111111'); + }); + + test('returns value as is for non-CARD_NUMBER', () => { + const element = new MockCollectElement(ElementType.CVV, '123'); + expect(getElementValueToInsert(element)).toBe('123'); + }); +}); diff --git a/__tests__/core/collectElement.test.js b/__tests__/core/collectElement.test.js index 185c480..34433e8 100644 --- a/__tests__/core/collectElement.test.js +++ b/__tests__/core/collectElement.test.js @@ -517,4 +517,16 @@ describe('test Collect Element class', () => { cardNumberElement.onChangeElement('', true); expect(cardNumberElement.getClientState().selectedCardScheme).toEqual('DISCOVER'); }) + + it('should remove spaces from value', () => { + const elementInput = { + table: 'cards', + column: 'number', + type: ElementType.CARD_NUMBER, + containerType: ContainerType.COLLECT, + }; + const collectElement = new CollectElement(elementInput, {}, context); + collectElement.updateValue('4111 1111 1111 1111'); + expect(collectElement.getUnformattedValue()).toBe('4111111111111111'); + }); }); \ No newline at end of file diff --git a/src/components/CardHolderNameElement/index.tsx b/src/components/CardHolderNameElement/index.tsx index e9ec317..8bd1307 100644 --- a/src/components/CardHolderNameElement/index.tsx +++ b/src/components/CardHolderNameElement/index.tsx @@ -49,6 +49,7 @@ const CardHolderNameElement: React.FC = ({ container, optio ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text) setElementValue(element.getInternalState().value) @@ -75,7 +76,7 @@ const CardHolderNameElement: React.FC = ({ container, optio { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); diff --git a/src/components/CardNumberElement/index.tsx b/src/components/CardNumberElement/index.tsx index de3b8b3..0ce2ba4 100644 --- a/src/components/CardNumberElement/index.tsx +++ b/src/components/CardNumberElement/index.tsx @@ -109,6 +109,7 @@ const CardNumberElement: React.FC = ({ container, options, ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text) setElementValue(element.getInternalState().value) @@ -141,7 +142,7 @@ const CardNumberElement: React.FC = ({ container, options, { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/CvvElement/index.tsx b/src/components/CvvElement/index.tsx index dddbe8d..5754c7a 100644 --- a/src/components/CvvElement/index.tsx +++ b/src/components/CvvElement/index.tsx @@ -49,6 +49,7 @@ const CvvElement: React.FC = ({ container, options = { requ ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text); setElementValue(element.getInternalState().value) @@ -76,7 +77,7 @@ const CvvElement: React.FC = ({ container, options = { requ { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/ExpirationDateElement/index.tsx b/src/components/ExpirationDateElement/index.tsx index 04cd240..af9c071 100644 --- a/src/components/ExpirationDateElement/index.tsx +++ b/src/components/ExpirationDateElement/index.tsx @@ -54,6 +54,7 @@ const ExpirationDateElement: React.FC = ({ container, optio ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text); setElementValue(element.getInternalState().value) @@ -84,7 +85,7 @@ const ExpirationDateElement: React.FC = ({ container, optio { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/ExpirationMonthElement/index.tsx b/src/components/ExpirationMonthElement/index.tsx index 8092770..6e61fe7 100644 --- a/src/components/ExpirationMonthElement/index.tsx +++ b/src/components/ExpirationMonthElement/index.tsx @@ -49,6 +49,7 @@ const ExpirationMonthElement: React.FC = ({ container, opti ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text); setElementValue(element.getInternalState().value) @@ -79,7 +80,7 @@ const ExpirationMonthElement: React.FC = ({ container, opti { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/ExpirationYearElement/index.tsx b/src/components/ExpirationYearElement/index.tsx index c21439e..adba727 100644 --- a/src/components/ExpirationYearElement/index.tsx +++ b/src/components/ExpirationYearElement/index.tsx @@ -55,6 +55,7 @@ const ExpirationYearElement: React.FC = ({ container, optio ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text); setElementValue(element.getInternalState().value) @@ -85,7 +86,7 @@ const ExpirationYearElement: React.FC = ({ container, optio { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/InputFieldElement/index.tsx b/src/components/InputFieldElement/index.tsx index 0825173..35e85ae 100644 --- a/src/components/InputFieldElement/index.tsx +++ b/src/components/InputFieldElement/index.tsx @@ -51,6 +51,7 @@ const InputFieldElement: React.FC = ({ container, options = ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text); setElementValue(element.getInternalState().value) @@ -76,7 +77,7 @@ const InputFieldElement: React.FC = ({ container, options = { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/PinElement/index.tsx b/src/components/PinElement/index.tsx index 6bab3dc..79576a6 100644 --- a/src/components/PinElement/index.tsx +++ b/src/components/PinElement/index.tsx @@ -49,6 +49,7 @@ const PinElement: React.FC = ({ container, options = { requ ref={textInputRef} value={elementValue} placeholder={rest.placeholder} + testID={rest?.testID} onChangeText={(text) => { element?.onChangeElement(text) setElementValue(element.getInternalState().value) @@ -76,7 +77,7 @@ const PinElement: React.FC = ({ container, options = { requ { container && container?.type === ContainerType.COLLECT && - {errorText} + {errorText} } ); } diff --git a/src/components/RevealElement/index.tsx b/src/components/RevealElement/index.tsx index d08872a..5aa885a 100644 --- a/src/components/RevealElement/index.tsx +++ b/src/components/RevealElement/index.tsx @@ -27,8 +27,8 @@ const RevealElement: React.FC = ({ container, label, ...rest return <> {label} - {value} - {errorText} + {value} + {errorText} } diff --git a/src/core-utils/collect/index.ts b/src/core-utils/collect/index.ts index 5d2cc3d..5280bfa 100644 --- a/src/core-utils/collect/index.ts +++ b/src/core-utils/collect/index.ts @@ -7,7 +7,7 @@ import _ from 'lodash'; import Skyflow from '../../core/Skyflow'; import SkyflowError from '../../utils/skyflow-error'; import SKYFLOW_ERROR_CODE from '../../utils/skyflow-error-code'; -import { IInsertRecord, IInsertResponse } from '../../../src/utils/constants'; +import { ElementType, IInsertRecord, IInsertResponse } from '../../../src/utils/constants'; import omit from 'lodash/omit'; const set = require('set-value'); @@ -184,6 +184,12 @@ export const constructElementsInsertReq = (req: any, options: any) => { return { records }; }; +export function getElementValueToInsert(element: CollectElement) { + return element.getClientState().elementType === ElementType.CARD_NUMBER + ? element.getUnformattedValue() + : element.getInternalState().value; +} + export const tokenize = ( skyflowClient: Skyflow, elementList: CollectElement[], @@ -223,14 +229,14 @@ export const tokenize = ( set( elementsUpdateData[skyflowID], column, - currentElement.getInternalState().value, + getElementValueToInsert(currentElement), ); } else { elementsUpdateData[skyflowID] = {}; set( elementsUpdateData[skyflowID], column, - currentElement.getInternalState().value, + getElementValueToInsert(currentElement), ); set( elementsUpdateData[skyflowID], @@ -240,10 +246,10 @@ export const tokenize = ( } } else if (elementsData[table]) { - set(elementsData[table], column, currentElement.getInternalState().value); + set(elementsData[table], column, getElementValueToInsert(currentElement)); } else { elementsData[table] = {}; - set(elementsData[table], column, currentElement.getInternalState().value); + set(elementsData[table], column, getElementValueToInsert(currentElement)); } }); diff --git a/src/core/CollectElement/index.ts b/src/core/CollectElement/index.ts index 68f79bf..53c0405 100644 --- a/src/core/CollectElement/index.ts +++ b/src/core/CollectElement/index.ts @@ -136,6 +136,10 @@ class CollectElement extends SkyflowElement { return this.#state; } + getUnformattedValue() { + return this.#state.value.trim().replace(/[\s-]/g, ''); + } + getElementInput() { return this.#elementInput; } diff --git a/src/core/constants/index.ts b/src/core/constants/index.ts index 0924bcd..111c708 100644 --- a/src/core/constants/index.ts +++ b/src/core/constants/index.ts @@ -163,7 +163,7 @@ export const DEFAULT_CARD_INPUT_MAX_LENGTH = 23; export const REVEAL_ELEMENT_ERROR_TEXT = 'Invalid Token'; -export const DEFAULT_COLLECT_ELEMENT_ERROR_TEXT = 'Invalid Value'; +export const DEFAULT_COLLECT_ELEMENT_ERROR_TEXT = 'Invalid value'; export const DEFAULT_VALIDATION_ERROR_TEXT = 'Validation Failed'; diff --git a/src/utils/constants/index.ts b/src/utils/constants/index.ts index 97bc0b5..ab507ad 100644 --- a/src/utils/constants/index.ts +++ b/src/utils/constants/index.ts @@ -55,6 +55,7 @@ export interface CollectElementProps { errorTextStyles?: StylesBaseVariant; containerMethods?: Record; skyflowID?: string; + testID?: string; } export enum ElementType { @@ -114,6 +115,7 @@ export interface RevealElementProps { labelStyles?: StylesBaseVariant; errorTextStyles?: StylesBaseVariant; redaction?: RedactionType; + testID?: string; } export enum MessageType {