diff --git a/src/core/external/collect/collect-container.ts b/src/core/external/collect/collect-container.ts index ea9d0c56..6647302f 100644 --- a/src/core/external/collect/collect-container.ts +++ b/src/core/external/collect/collect-container.ts @@ -270,6 +270,8 @@ class CollectContainer extends Container { try { validateInitConfig(this.#metaData.clientJSON.config); const collectElements = Object.values(this.#elements); + const elementIds = Object.keys(this.#elements) + .map((element) => ({ frameId: element, elementId: element })); collectElements.forEach((element) => { if (!element.isMounted()) { throw new SkyflowError(SKYFLOW_ERROR_CODE.ELEMENTS_NOT_MOUNTED, [], true); @@ -292,6 +294,7 @@ class CollectContainer extends Container { { ...options, tokens: options?.tokens !== undefined ? options.tokens : true, + elementIds, }, (data: any) => { if (!data || data?.error) { diff --git a/src/core/external/collect/collect-element.ts b/src/core/external/collect/collect-element.ts index b2df64f8..6f9302bc 100644 --- a/src/core/external/collect/collect-element.ts +++ b/src/core/external/collect/collect-element.ts @@ -208,17 +208,23 @@ class CollectElement extends SkyflowElement { const isComposable = this.#elements.length > 1; if (isComposable) { - this.#iframe.mount(domElement); + this.#iframe.mount(domElement, { + record: JSON.stringify({ record: this.#group }), + }); this.#bus.on(ELEMENT_EVENTS_TO_IFRAME.FRAME_READY + this.containerId, sub); } else { if (this.#readyToMount) { - this.#iframe.mount(domElement); + this.#iframe.mount(domElement, { + record: JSON.stringify({ record: this.#group }), + }); this.#bus.on(ELEMENT_EVENTS_TO_IFRAME.FRAME_READY + this.containerId, sub); return; } this.#groupEmitter?.on(ELEMENT_EVENTS_TO_CONTAINER.COLLECT_CONTAINER_MOUNTED, (data) => { if (data?.containerId === this.containerId) { - this.#iframe.mount(domElement); + this.#iframe.mount(domElement, { + record: JSON.stringify({ record: this.#group }), + }); this.#bus.on(ELEMENT_EVENTS_TO_IFRAME.FRAME_READY + this.containerId, sub); } }); diff --git a/src/core/external/collect/compose-collect-container.ts b/src/core/external/collect/compose-collect-container.ts index f89cc580..f4722507 100644 --- a/src/core/external/collect/compose-collect-container.ts +++ b/src/core/external/collect/compose-collect-container.ts @@ -353,7 +353,7 @@ class ComposableContainer extends Container { throw new SkyflowError(SKYFLOW_ERROR_CODE.ELEMENTS_NOT_MOUNTED, [], true); } }); - + const elementIds:{ frameId:string, elementId:string }[] = []; const collectElements = Object.values(this.#elements); collectElements.forEach((element) => { element.isValidElement(); @@ -368,6 +368,12 @@ class ComposableContainer extends Container { if (options?.upsert) { validateUpsertOptions(options?.upsert); } + this.#elementsList.forEach((element) => { + elementIds.push({ + frameId: this.#tempElements.elementName, + elementId: element.elementName, + }); + }); bus // .target(properties.IFRAME_SECURE_ORGIN) .emit( @@ -375,6 +381,7 @@ class ComposableContainer extends Container { { ...options, tokens: options?.tokens !== undefined ? options.tokens : true, + elementIds, }, (data: any) => { if (!data || data?.error) { diff --git a/src/core/external/common/iframe.ts b/src/core/external/common/iframe.ts index ff8b2017..ce04140f 100644 --- a/src/core/external/common/iframe.ts +++ b/src/core/external/common/iframe.ts @@ -27,7 +27,7 @@ export default class IFrame { setAttributes(this.iframe, { src: responseValue }); }; - mount = (domElement) => { + mount = (domElement, data?:any) => { this.unmount(); try { if (typeof domElement === 'string') { @@ -46,7 +46,7 @@ export default class IFrame { // throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_ELEMENT_SELECTOR, [], true); } - setAttributes(this.iframe, { src: getIframeSrc() }); + setAttributes(this.iframe, { src: `${getIframeSrc()}${data ? `?${btoa(data?.record)}` : ''}` }); this.container?.appendChild(this.iframe); }; diff --git a/src/core/external/reveal/reveal-element.ts b/src/core/external/reveal/reveal-element.ts index 38a687c2..60702608 100644 --- a/src/core/external/reveal/reveal-element.ts +++ b/src/core/external/reveal/reveal-element.ts @@ -127,7 +127,13 @@ class RevealElement extends SkyflowElement { }; if (this.#readyToMount) { - this.#iframe.mount(domElementSelector); + this.#iframe.mount(domElementSelector, { + record: JSON.stringify({ + ...this.#metaData, + record: this.#recordData, + context: this.#context, + }), + }); bus .target(properties.IFRAME_SECURE_ORGIN) .on(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY, sub); @@ -135,7 +141,13 @@ class RevealElement extends SkyflowElement { } this.#eventEmitter?.on(ELEMENT_EVENTS_TO_CONTAINER.REVEAL_CONTAINER_MOUNTED, (data) => { if (data?.containerId === this.#containerId) { - this.#iframe.mount(domElementSelector); + this.#iframe.mount(domElementSelector, { + record: JSON.stringify({ + ...this.#metaData, + record: this.#recordData, + context: this.#context, + }), + }); bus .target(properties.IFRAME_SECURE_ORGIN) .on(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY, sub); diff --git a/src/core/internal/frame-elements.ts b/src/core/internal/frame-elements.ts index e14cf5de..3d250136 100644 --- a/src/core/internal/frame-elements.ts +++ b/src/core/internal/frame-elements.ts @@ -63,18 +63,22 @@ export default class FrameElements { bus.emit( ELEMENT_EVENTS_TO_IFRAME.FRAME_READY + names[3], { name: window.name }, - (group: any) => { + () => { printLog(parameterizedString(logs.infoLogs.COLLECT_FRAME_READY_CB, CLASS_NAME, getElementName(window.name)), MessageType.LOG, logLevel); - FrameElements.group = group; - if (FrameElements.frameElements) { - printLog(parameterizedString(logs.infoLogs.SETUP_IN_START, CLASS_NAME), - MessageType.LOG, logLevel); - FrameElements.frameElements.setup(); // start the process - } }, ); + const url = window.location?.href; + const configIndex = url.indexOf('?'); + const encodedString = configIndex !== -1 ? decodeURIComponent(url.substring(configIndex + 1)) : ''; + const parsedRecord = encodedString ? JSON.parse(atob(encodedString)) : {}; + FrameElements.group = parsedRecord?.record; + if (FrameElements.frameElements) { + printLog(parameterizedString(logs.infoLogs.SETUP_IN_START, CLASS_NAME), + MessageType.LOG, logLevel); + FrameElements.frameElements.setup(); // start the process + } }; // called by IFrameForm diff --git a/src/core/internal/iframe-form/index.ts b/src/core/internal/iframe-form/index.ts index d70eaaf8..3dc1866a 100644 --- a/src/core/internal/iframe-form/index.ts +++ b/src/core/internal/iframe-form/index.ts @@ -945,25 +945,27 @@ export class IFrameForm { if (!this.client) throw new SkyflowError(SKYFLOW_ERROR_CODE.CLIENT_CONNECTION, [], true); const insertResponseObject: any = {}; const updateResponseObject: any = {}; - const formElements = Object.keys(this.iFrameFormElements); let errorMessage = ''; - for (let i = 0; i < formElements.length; i += 1) { - if ( - this.iFrameFormElements[formElements[i]].fieldType - !== ELEMENTS.FILE_INPUT.name - ) { - const { - state, doesClientHasError, clientErrorText, errorText, onFocusChange, - } = this.iFrameFormElements[formElements[i]]; - - if (state.isRequired || !state.isValid) { - onFocusChange(false); - } - - if (!state.isValid || !state.isComplete) { - if (doesClientHasError) { - errorMessage += `${state.name}:${clientErrorText}`; - } else { errorMessage += `${state.name}:${errorText} `; } + for (let i = 0; i < options.elementIds.length; i += 1) { + const Frame = window.parent.frames[`${options.elementIds[i].frameId}:${this.controllerId}:${this.logLevel}`]; + const inputElement = Frame.document + .getElementById(options.elementIds[i].elementId); + if (inputElement) { + if ( + inputElement.iFrameFormElement.fieldType + !== ELEMENTS.FILE_INPUT.name + ) { + const { + state, doesClientHasError, clientErrorText, errorText, onFocusChange, + } = inputElement.iFrameFormElement; + if (state.isRequired || !state.isValid) { + onFocusChange(false); + } + if (!state.isValid || !state.isComplete) { + if (doesClientHasError) { + errorMessage += `${state.name}:${clientErrorText}`; + } else { errorMessage += `${state.name}:${errorText} `; } + } } } } @@ -972,68 +974,73 @@ export class IFrameForm { return Promise.reject(new SkyflowError(SKYFLOW_ERROR_CODE.COMPLETE_AND_VALID_INPUTS, [`${errorMessage}`], true)); } - for (let i = 0; i < formElements.length; i += 1) { - const { - state, tableName, validations, skyflowID, - } = this.iFrameFormElements[formElements[i]]; - if (tableName) { - if ( - this.iFrameFormElements[formElements[i]].fieldType - !== ELEMENTS.FILE_INPUT.name - ) { + for (let i = 0; i < options.elementIds.length; i += 1) { + const Frame = window.parent.frames[`${options.elementIds[i].frameId}:${this.controllerId}:${this.logLevel}`]; + const inputElement = Frame.document + .getElementById(options.elementIds[i].elementId); + if (inputElement) { + const { + state, tableName, validations, skyflowID, + } = inputElement.iFrameFormElement; + if (tableName) { if ( - this.iFrameFormElements[formElements[i]].fieldType - === ELEMENTS.checkbox.name + inputElement.iFrameFormElement.fieldType + !== ELEMENTS.FILE_INPUT.name ) { - if (insertResponseObject[state.name]) { - insertResponseObject[state.name] = `${insertResponseObject[state.name]},${state.value - }`; - } else { - insertResponseObject[state.name] = state.value; - } - } else if (insertResponseObject[tableName] && !(skyflowID === '') && skyflowID === undefined) { - if (get(insertResponseObject[tableName], state.name) + if ( + inputElement.iFrameFormElement.fieldType + === ELEMENTS.checkbox.name + ) { + if (insertResponseObject[state.name]) { + insertResponseObject[state.name] = `${insertResponseObject[state.name]},${state.value + }`; + } else { + insertResponseObject[state.name] = state.value; + } + } else if (insertResponseObject[tableName] && !(skyflowID === '') && skyflowID === undefined) { + if (get(insertResponseObject[tableName], state.name) && !(validations && checkForElementMatchRule(validations))) { - return Promise.reject(new SkyflowError(SKYFLOW_ERROR_CODE.DUPLICATE_ELEMENT, - [state.name, tableName], true)); - } - set( - insertResponseObject[tableName], - state.name, - this.iFrameFormElements[formElements[i]].getUnformattedValue(), - ); - } else if (skyflowID || skyflowID === '') { - if (skyflowID === '' || skyflowID === null) { - return Promise.reject(new SkyflowError( - SKYFLOW_ERROR_CODE.EMPTY_SKYFLOW_ID_IN_ADDITIONAL_FIELDS, - )); - } - if (updateResponseObject[skyflowID]) { + return Promise.reject(new SkyflowError(SKYFLOW_ERROR_CODE.DUPLICATE_ELEMENT, + [state.name, tableName], true)); + } set( - updateResponseObject[skyflowID], + insertResponseObject[tableName], state.name, - this.iFrameFormElements[formElements[i]].getUnformattedValue(), + inputElement.iFrameFormElement.getUnformattedValue(), ); + } else if (skyflowID || skyflowID === '') { + if (skyflowID === '' || skyflowID === null) { + return Promise.reject(new SkyflowError( + SKYFLOW_ERROR_CODE.EMPTY_SKYFLOW_ID_IN_ADDITIONAL_FIELDS, + )); + } + if (updateResponseObject[skyflowID]) { + set( + updateResponseObject[skyflowID], + state.name, + inputElement.iFrameFormElement.getUnformattedValue(), + ); + } else { + updateResponseObject[skyflowID] = {}; + set( + updateResponseObject[skyflowID], + state.name, + inputElement.iFrameFormElement.getUnformattedValue(), + ); + set( + updateResponseObject[skyflowID], + 'table', + tableName, + ); + } } else { - updateResponseObject[skyflowID] = {}; + insertResponseObject[tableName] = {}; set( - updateResponseObject[skyflowID], + insertResponseObject[tableName], state.name, - this.iFrameFormElements[formElements[i]].getUnformattedValue(), - ); - set( - updateResponseObject[skyflowID], - 'table', - tableName, + inputElement.iFrameFormElement.getUnformattedValue(), ); } - } else { - insertResponseObject[tableName] = {}; - set( - insertResponseObject[tableName], - state.name, - this.iFrameFormElements[formElements[i]].getUnformattedValue(), - ); } } } @@ -1180,7 +1187,7 @@ export class IFrameForm { try { if ( - frame.location.href === window.location.href + frame.location.href.split('?')[0] === window.location.href && frame.name === frameGlobalName ) { frameInstance = frame; diff --git a/src/core/internal/index.ts b/src/core/internal/index.ts index c34923b3..737fb7cf 100644 --- a/src/core/internal/index.ts +++ b/src/core/internal/index.ts @@ -106,7 +106,8 @@ export class FrameElement { private domLabel?: HTMLLabelElement; - private domInput?: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLFormElement; + private domInput?: (HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLFormElement) + & { iFrameFormElement? : IFrameFormElement }; public domError?: HTMLSpanElement; @@ -153,7 +154,7 @@ export class FrameElement { this.domError = document.createElement('span'); - let type; + let type:'select' | 'textarea' | 'input' = 'input'; if (this.iFrameFormElement?.fieldType === ELEMENTS.dropdown.name) { type = 'select'; } else if (this.iFrameFormElement?.fieldType === ELEMENTS.textarea.name) { @@ -167,6 +168,7 @@ export class FrameElement { const inputElement = document.createElement(type); this.domInput = inputElement; + this.domInput.iFrameFormElement = this.iFrameFormElement; inputElement.setAttribute(CUSTOM_ROW_ID_ATTRIBUTE, this.htmlDivElement?.id?.split(':')[0] || ''); this.inputParent.append(inputElement); diff --git a/src/core/internal/reveal/reveal-frame.ts b/src/core/internal/reveal/reveal-frame.ts index cfde3786..77571ced 100644 --- a/src/core/internal/reveal/reveal-frame.ts +++ b/src/core/internal/reveal/reveal-frame.ts @@ -61,10 +61,13 @@ class RevealFrame { .emit( ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY, { name: window.name }, - (data: any) => { - RevealFrame.revealFrame = new RevealFrame(data.record, data.context); - }, + () => {}, ); + const url = window.location?.href; + const configIndex = url.indexOf('?'); + const encodedString = configIndex !== -1 ? decodeURIComponent(url.substring(configIndex + 1)) : ''; + const parsedRecord = encodedString ? JSON.parse(atob(encodedString)) : {}; + RevealFrame.revealFrame = new RevealFrame(parsedRecord.record, parsedRecord.context); } constructor(record, context) { diff --git a/tests/core/external/collect/composable-container.test.js b/tests/core/external/collect/composable-container.test.js index 12e44a05..b0b63ebd 100644 --- a/tests/core/external/collect/composable-container.test.js +++ b/tests/core/external/collect/composable-container.test.js @@ -28,13 +28,17 @@ jest.mock('../../../../src/libs/uuid', () => ({ const mockUnmount = jest.fn(); const updateMock = jest.fn(); jest.mock('../../../../src/core/external/collect/collect-element'); -CollectElement.mockImplementation(()=>({ +CollectElement.mockImplementation((_,tempElements)=>{ + tempElements.rows[0].elements.forEach((element)=>{ + element.isMounted = true; + }) + return { isMounted : ()=>(true), mount: jest.fn(), isValidElement: ()=>(true), unmount:mockUnmount, updateElement:updateMock -})) +}}) jest.mock('../../../../src/event-emitter'); const emitMock = jest.fn(); @@ -177,6 +181,10 @@ describe('test composable container class',()=>{ }); it('test collect',()=>{ + let readyCb; + on.mockImplementation((name,cb)=>{ + readyCb = cb; + }) const div = document.createElement('div'); div.id = 'composable' document.body.append(div); @@ -184,9 +192,13 @@ describe('test composable container class',()=>{ const element1 = container.create(cvvElement); const element2 = container.create(cardNumberElement); emitterSpy(); + readyCb({name:`${COLLECT_FRAME_CONTROLLER}1234`},jest.fn()) + container.mount('#composable'); container.collect(); + + on.mockImplementation((name,cb)=>{emitterSpy = cb}) }); it('test collect without mounting the container',(done)=>{ diff --git a/tests/core/internal/frame-controller.test.js b/tests/core/internal/frame-controller.test.js index f0eb1f60..85d6135d 100644 --- a/tests/core/internal/frame-controller.test.js +++ b/tests/core/internal/frame-controller.test.js @@ -34,6 +34,8 @@ const on = jest.fn(); const tableCol = btoa('table.col'); const collect_element = `element:CVV:${tableCol}`; +const collect_element_textarea = `element:${ELEMENTS.textarea.name}:${tableCol}`; +const collect_element_dropdown = `element:${ELEMENTS.dropdown.name}:${tableCol}`; const context = { logLevel: LogLevel.ERROR, @@ -220,6 +222,131 @@ describe('test frame controller', () => { element.setupInputField(); }); + test('FrameElement constructor : textarea', () => { + const div = document.createElement('div'); + + const formElement = new IFrameFormElement(collect_element_textarea, {}, context); + const element = new FrameElement(formElement, { + label: 'label', + inputStyles, + labelStyles, + errorTextStyles, + }, div); + + const inst = EventEmitter.mock.instances[0]; + const onSpy = inst.on.mock.calls; + + const focusCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_CLIENT.FOCUS); + + focusCb[0][1](state); + + const blurCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_CLIENT.BLUR); + + + blurCb[0][1](state); + + blurCb[0][1]({ + ...state, + isValid: false, + isEmpty: false, + }); + + const changeCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_CLIENT.CHANGE); + + changeCb[0][1](state); + + const setCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.SET_VALUE); + setCb[0][1]({ + options: { + label: 'updatedLabel', + inputStyles, + labelStyles, + errorTextStyles, + table:'updatedTable', + column:'updateColumn', + placeholder:'XX', + validations:[ + { + type:ValidationRuleType.LENGTH_MATCH_RULE, + params:{ + min:2, + } + } + ], + skyflowID: 'updated-skyflow-id', + }, + }); + + element.setupInputField(); + }); + + test('FrameElement constructor : dropdown', () => { + const div = document.createElement('div'); + + const formElement = new IFrameFormElement(collect_element_dropdown, {}, context); + const element = new FrameElement(formElement, { + label: 'label', + inputStyles, + labelStyles, + errorTextStyles, + options:["dummyOptions"] + }, div); + + const inst = EventEmitter.mock.instances[0]; + const onSpy = inst.on.mock.calls; + + const focusCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_CLIENT.FOCUS); + + focusCb[0][1](state); + + const blurCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_CLIENT.BLUR); + + + blurCb[0][1](state); + + blurCb[0][1]({ + ...state, + isValid: false, + isEmpty: false, + }); + + const changeCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_CLIENT.CHANGE); + + changeCb[0][1](state); + + const setCb = onSpy + .filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.SET_VALUE); + setCb[0][1]({ + options: { + label: 'updatedLabel', + inputStyles, + labelStyles, + errorTextStyles, + table:'updatedTable', + column:'updateColumn', + placeholder:'XX', + validations:[ + { + type:ValidationRuleType.LENGTH_MATCH_RULE, + params:{ + min:2, + } + } + ], + skyflowID: 'updated-skyflow-id', + }, + }); + + element.setupInputField(); + }); + test('card element FrameElement with card type', () => { const cardElement = `element:CARD_NUMBER:${tableCol}`; diff --git a/tests/core/internal/frame-elements.test.js b/tests/core/internal/frame-elements.test.js index f5a3da90..ceb8c256 100644 --- a/tests/core/internal/frame-elements.test.js +++ b/tests/core/internal/frame-elements.test.js @@ -78,11 +78,21 @@ describe('test frame elements', () => { windowSpy = jest.spyOn(global, 'window', 'get'); windowSpy.mockImplementation(() => ({ name: `${FRAME_ELEMENT}:CARD_NUMBER:${btoa('123')}:ERROR`, + location: { + href: `http://localhost/?${btoa(JSON.stringify({record:element}))}`, + } })); emitSpy = jest.spyOn(bus, 'emit'); }) - test('FrameElements constructor', () => { + + test('FrameElements constructor : empty path', () => { + windowSpy.mockImplementation(() => ({ + name: `${FRAME_ELEMENT}:CARD_NUMBER:${btoa('123')}:ERROR`, + location: { + href: `http://localhost`, + } + })) const onSpy = jest.spyOn(bus, 'on'); FrameElements.start() @@ -112,12 +122,40 @@ describe('test frame elements', () => { } }) const frameElement = new FrameElements(mockCreateElement, {}, 'ERROR') - const heigtEvent = onSpy.mock.calls[0][1]; - const cb = jest.fn(); - heigtEvent({},cb); - cb(); + }) + test('FrameElements constructor', () => { + const onSpy = jest.spyOn(bus, 'on'); + FrameElements.init(jest.fn().mockReturnValue({resetEvents:jest.fn(),on:jest.fn(),fieldType:'group',getStatus:jest.fn().mockReturnValue({}),state:{}}),{}) + + FrameElements.start() + + const emitEventName = emitSpy.mock.calls[0][0]; + const emitCb = emitSpy.mock.calls[0][2]; + expect(emitEventName.includes(ELEMENT_EVENTS_TO_IFRAME.FRAME_READY)).toBeTruthy() + emitCb(element); + + const mockCreateElement = jest.fn().mockImplementation(()=>{ + return { + resetEvents: jest.fn(), + on: jest.fn(), + getStatus: jest.fn(()=>({ + isFocused: false, + isValid: false, + isEmpty: true, + isComplete: false, + })), + fieldType: 'CARD_NUMBER', + state:{name:''}, + setValidation:jest.fn(), + setReplacePattern: jest.fn(), + setMask:jest.fn(), + getValue: jest.fn(), + setValue: jest.fn(), + } + }) + const frameElement = new FrameElements(mockCreateElement, {}, 'ERROR') }) }) @@ -129,6 +167,9 @@ describe('test composable frame elements', () => { windowSpy = jest.spyOn(global, 'window', 'get'); windowSpy.mockImplementation(() => ({ name: `${FRAME_ELEMENT}:group:${btoa('123')}:ERROR`, + location: { + href: `http://localhost/?${btoa(JSON.stringify({record:element}))}`, + } })); emitSpy = jest.spyOn(bus, 'emit'); diff --git a/tests/core/internal/iframe-form/iframe-form.test.js b/tests/core/internal/iframe-form/iframe-form.test.js index 0a47e7fa..73d72f42 100644 --- a/tests/core/internal/iframe-form/iframe-form.test.js +++ b/tests/core/internal/iframe-form/iframe-form.test.js @@ -14,6 +14,7 @@ import { parameterizedString } from '../../../../src/utils/logs-helper'; const tableCol = btoa('1234') const collect_element = `element:CVV:${tableCol}`; +const checkbox_element = `element:${ELEMENTS.checkbox.name}:${tableCol}` const file_element = `element:FILE_INPUT:${tableCol}`; const context = { @@ -144,11 +145,22 @@ describe('test iframeFormelement', () => { }) test('test tokenize error case', () => { const element = new IFrameFormElement(`element:EXPIRATION_MONTH:${tableCol}`, {}, context) - const form = new IFrameForm(element) + const form = new IFrameForm("controllerId","",'ERROR') + jest.spyOn(window,'parent','get').mockImplementation(()=>({ + frames:{ + [`element:EXPIRATION_MONTH:${tableCol}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + })) form.setClient(clientObj1) form.setClientMetadata(metaData) form.setContext(context) - expect(form.tokenize()).rejects.toThrow(SkyflowError) + expect(form.tokenize({elementIds:[{elemenId:`element:EXPIRATION_MONTH:${tableCol}`,frameId:`element:EXPIRATION_MONTH:${tableCol}`}]})).rejects.toThrow(SkyflowError) }) test('test setValue for expiration_date', () => { @@ -561,6 +573,95 @@ describe('test iframeForm collect method', () => { }); }); + test('initialize iframeform and submit collect with invalid input : client has error', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + form.setClient(clientObj) + form.setClientMetadata(metaData) + form.setContext(context) + + const frameReadyEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.FRAME_READY + 'controllerId'); + const frameReadyCb = frameReadyEvent[0][1]; + expect(() => { frameReadyCb({}) }).toThrow(SkyflowError) + + frameReadyCb({ name: COLLECT_FRAME_CONTROLLER }) + + expect(() => { frameReadyCb({ name: "element:type:aW52YWxpZA==" }) }).toThrow(SkyflowError) + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + + frameReadyCb({ name:collect_element}) + + const createFormElement = skyflowInit.mock.calls[0][0] + const element = createFormElement(collect_element,undefined,undefined,true) + + const setErrorEvent = on.mock.calls.filter((data)=>data[0]===ELEMENT_EVENTS_TO_IFRAME.COLLECT_ELEMENT_SET_ERROR) + console.log("setErrorEvent",setErrorEvent) + const setErrorCb = setErrorEvent[0][1] + + setErrorCb({isTriggerError:true,clientErrorText:"Error",name:collect_element}) + + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; + const cb2 = jest.fn(); + + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2) + + setTimeout(() => { + expect(cb2.mock.calls[0][0].error.message).toBeDefined() + done() + }, 1000) + + + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + }) + test('initialize iframeform and submit collect with invalid input', (done) => { const form = new IFrameForm("controllerId", "", "ERROR"); form.setClient(clientObj) @@ -602,7 +703,24 @@ describe('test iframeForm collect method', () => { const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); - tokenizationCb(data, cb2) + + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2) setTimeout(() => { expect(cb2.mock.calls[0][0].error.message).toBeDefined() @@ -610,7 +728,7 @@ describe('test iframeForm collect method', () => { element.setValue('123') const cb3 = jest.fn() - tokenizationCb(data, cb3) + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb3) setTimeout(() => { expect(cb3.mock.calls[0][0].records.length).toBe(2); @@ -631,7 +749,121 @@ describe('test iframeForm collect method', () => { col: '123' } }] + }, + elementIds:[{elementId:collect_element,frameId:collect_element}] + }, cb4) + + setTimeout(() => { + expect(cb4.mock.calls[0][0].error).toBeDefined() + done() + }, 1000) + + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + }) + + test('initialize iframeform and submit collect with invalid input and not required field', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + form.setClient(clientObj) + form.setClientMetadata(metaData) + form.setContext(context) + + const frameReadyEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.FRAME_READY + 'controllerId'); + const frameReadyCb = frameReadyEvent[0][1]; + + expect(() => { frameReadyCb({}) }).toThrow(SkyflowError) + + frameReadyCb({ name: COLLECT_FRAME_CONTROLLER }) + + expect(() => { frameReadyCb({ name: "element:type:aW52YWxpZA==" }) }).toThrow(SkyflowError) + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + + frameReadyCb({ name:collect_element}) + + const createFormElement = skyflowInit.mock.calls[0][0] + const element = createFormElement(collect_element) + + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; + const cb2 = jest.fn(); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' } + })); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2) + + setTimeout(() => { + expect(cb2.mock.calls[0][0].error.message).toBeDefined() + }, 1000) + + element.setValue('123') + const cb3 = jest.fn() + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb3) + + setTimeout(() => { + expect(cb3.mock.calls[0][0].records.length).toBe(2); + }, 1000) + + element.fieldName = 'col'; + element.tableName = 'table'; + element.state.name = 'col'; + + const cb4 = jest.fn() + tokenizationCb({ + ...data, + additionalFields: { + ...data.additionalFields, + records: [{ + table: 'table', + fields: { + col: '123' + } + }] + }, + elementIds:[{elementId:collect_element,frameId:collect_element}] }, cb4) setTimeout(() => { @@ -639,6 +871,22 @@ describe('test iframeForm collect method', () => { done() }, 1000) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) @@ -683,7 +931,23 @@ describe('test iframeForm collect method', () => { const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); - tokenizationCb(data, cb2) + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2) setTimeout(() => { expect(cb2.mock.calls[0][0].error.message).toBeDefined() @@ -691,7 +955,7 @@ describe('test iframeForm collect method', () => { element.setValue('123') const cb3 = jest.fn() - tokenizationCb(data, cb3) + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb3) setTimeout(() => { expect(cb3.mock.calls[0][0].records.length).toBe(2); @@ -712,7 +976,8 @@ describe('test iframeForm collect method', () => { col: '123' } }] - } + }, + elementIds:[{elementId:collect_element,frameId:collect_element}] }, cb4) setTimeout(() => { @@ -721,6 +986,22 @@ describe('test iframeForm collect method', () => { }, 1000) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) test('collect submit without client initializatiob', () => { @@ -745,26 +1026,96 @@ describe('test iframeForm collect method', () => { }) test('collect error second case', () => { const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(collect_element,"",{},context) + element.setValue("123") + let windowSpy = jest.spyOn(global, 'window', 'get'); + const skyflowInit = jest.fn(); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); form.setContext(context) form.setClient(clientObj1) - expect(form.tokenize(records)).rejects.toMatchObject({"error": {"code": 404, "description": "Not Found"}}); - }) - test('insert records with tokens as true', (done) => { - const form = new IFrameForm("controllerId", "", "ERROR"); - form.setClient(clientObj) - form.setClientMetadata(metaData) - form.setContext(context) - - const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); - const tokenizationCb = tokenizationEvent[0][1]; + expect(form.tokenize({...records,elementIds:[{elementId:collect_element,frameId:collect_element}]})).rejects.toMatchObject({"error": {"code": 404, "description": "Not Found"}}); + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + }));}) + test('insert records with tokens as true', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(collect_element,"",{},context) + form.setClient(clientObj) + form.setClientMetadata(metaData) + form.setContext(context) + element.setValue("123") + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); - tokenizationCb(data, cb2); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2); setTimeout(() => { expect(cb2.mock.calls[0][0].records.length).toBe(2); expect(cb2.mock.calls[0][0].records[0].table).toBe('table'); expect(Object.keys(cb2.mock.calls[0][0].records[0].fields).length).toBe(2); done() }, 1000) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) let clientObj1 = { config: {}, @@ -778,6 +1129,138 @@ describe('test iframeForm collect method', () => { } test('ererr', (done) => { const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(collect_element,"",{},context) + form.setClient(clientObj1) + form.setClientMetadata(metaData) + form.setContext(context) + + element.setValue("123") + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; + const cb2 = jest.fn(); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2); + setTimeout(() => { + expect(cb2.mock.calls[0][0].error).toBeDefined(); + done() + }, 1000) + form.tokenize({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}).then().catch( err => { + expect(err).toBeDefined(); + }) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + }) + test('inputElementNotFound', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(collect_element,"",{},context) + form.setClient(clientObj1) + form.setClientMetadata(metaData) + form.setContext(context) + + element.setValue("123") + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>(undefined) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; + const cb2 = jest.fn(); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2); + setTimeout(() => { + expect(cb2.mock.calls[0][0].error).toBeDefined(); + done() + }, 1000) + form.tokenize({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}).then().catch( err => { + expect(err).toBeDefined(); + }) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + }) + test('success with skyflowID', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(collect_element,"",{},context) + + element.setValue("123") + element.skyflowID = "testID" + element.tableName = "table" + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + form.setClient(clientObj1) form.setClientMetadata(metaData) form.setContext(context) @@ -785,17 +1268,114 @@ describe('test iframeForm collect method', () => { const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); - tokenizationCb(data, cb2); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2); setTimeout(() => { expect(cb2.mock.calls[0][0].error).toBeDefined(); done() }, 1000) - form.tokenize(data).then().catch( err => { + form.tokenize({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}).then().catch( err => { expect(err).toBeDefined(); }) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) + test('success', (done) => { const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(collect_element,"",{},context) + + element.setValue("123") + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + + form.setClient(clientObj1) + form.setClientMetadata(metaData) + form.setContext(context) + + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; + const cb2 = jest.fn(); + tokenizationCb({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}, cb2); + setTimeout(() => { + expect(cb2.mock.calls[0][0].error).toBeDefined(); + done() + }, 1000) + form.tokenize({...data,elementIds:[{elementId:collect_element,frameId:collect_element}]}).then().catch( err => { + expect(err).toBeDefined(); + }) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + }) + + + test('success : checkbox', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + const element = new IFrameFormElement(checkbox_element,"",{},context) + element.tableName = "tableName" + element.setValue(true) + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${checkbox_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + form.setClient(clientObj1) form.setClientMetadata(metaData) form.setContext(context) @@ -803,21 +1383,62 @@ describe('test iframeForm collect method', () => { const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); - tokenizationCb(data, cb2); + tokenizationCb({...data,elementIds:[{elementId:checkbox_element,frameId:checkbox_element}]}, cb2); setTimeout(() => { expect(cb2.mock.calls[0][0].error).toBeDefined(); done() }, 1000) - form.tokenize(data).then().catch( err => { + form.tokenize({...data,elementIds:[{elementId:checkbox_element,frameId:checkbox_element},{elementId:checkbox_element,frameId:checkbox_element}]}).then().catch( err => { expect(err).toBeDefined(); }) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) - test('insert records duplicate error', (done) => { + + test('skyflowID error', (done) => { const form = new IFrameForm("controllerId", "", "ERROR"); form.setClient(clientObj) form.setClientMetadata(metaData) form.setContext(context) + const element = new IFrameFormElement(collect_element,"",{},context) + + element.setValue("123") + element.tableName = "table" + element.state.name = collect_element + element.skyflowID = '' + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); @@ -830,12 +1451,95 @@ describe('test iframeForm collect method', () => { col: '123', } }] + }, + elementIds:[{elementId:collect_element,frameId:collect_element}] + }, cb2) + setTimeout(() => { + expect(cb2.mock.calls[0][0].error.message).toBeDefined() + done() + }, 1000) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); + }) + + test('insert records duplicate error', (done) => { + const form = new IFrameForm("controllerId", "", "ERROR"); + form.setClient(clientObj) + form.setClientMetadata(metaData) + form.setContext(context) + + const element = new IFrameFormElement(collect_element,"",{},context) + + element.setValue("123") + element.tableName = "table" + element.state.name = collect_element + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' } + })); + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); + const tokenizationCb = tokenizationEvent[0][1]; + const cb2 = jest.fn(); + tokenizationCb({ + additionalFields: { + records: [{ + table: 'table', + fields: { + col: '123', + col: '123', + } + }] + }, + elementIds:[{elementId:collect_element,frameId:collect_element},{elementId:collect_element,frameId:collect_element}] }, cb2) setTimeout(() => { expect(cb2.mock.calls[0][0].error.message).toBeDefined() done() }, 1000) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) test('insert records with tokens as false', (done) => { const form = new IFrameForm("controllerId", "", "ERROR"); @@ -843,15 +1547,55 @@ describe('test iframeForm collect method', () => { form.setClientMetadata(metaData) form.setContext(context) + const element = new IFrameFormElement(collect_element,"",{},context) + + element.setValue("123") + const skyflowInit = jest.fn(); + let windowSpy = jest.spyOn(global, 'window', 'get'); + windowSpy.mockImplementation(() => ({ + parent: { + frames: { + [`${collect_element}:controllerId:ERROR`]:{ + document:{ + getElementById:()=>({ + iFrameFormElement:element + }) + } + } + } + }, + location: { + href: 'http://iframe.html' + } + })); + const tokenizationEvent = on.mock.calls.filter((data) => data[0] === ELEMENT_EVENTS_TO_IFRAME.TOKENIZATION_REQUEST + 'controllerId'); const tokenizationCb = tokenizationEvent[0][1]; const cb2 = jest.fn(); - tokenizationCb(data2, cb2); + tokenizationCb({...data2, + elementIds:[{elementId:collect_element,frameId:collect_element}] + }, cb2); setTimeout(() => { expect(cb2.mock.calls[0][0].records[0].table).toBe('pii_fields'); expect(Object.keys(cb2.mock.calls[0][0].records[0]).length).toBe(2); done() }, 1000) + windowSpy.mockImplementation(() => ({ + parent: { + frames: [{ + name: collect_element, + location: { + href: 'http://iframe.html' + }, + Skyflow: { + init: skyflowInit + } + }] + }, + location: { + href: 'http://iframe.html' + } + })); }) }) diff --git a/tests/core/internal/reveal/reveal-frame.test.js b/tests/core/internal/reveal/reveal-frame.test.js index dd4a7cbc..4545b90e 100644 --- a/tests/core/internal/reveal/reveal-frame.test.js +++ b/tests/core/internal/reveal/reveal-frame.test.js @@ -42,6 +42,16 @@ const testRecord = { // expect(_on).toHaveBeenCalledTimes(2); // }); // }); +global.window = Object.create(window); +const defineUrl = (url) => { + Object.defineProperty(window, "location", { + value: { + href: url, + }, + writable: true, + }); +}; + const on = jest.fn(); const off = jest.fn(); describe("Reveal Frame Class",()=>{ @@ -57,9 +67,35 @@ describe("Reveal Frame Class",()=>{ }); }); + + test("init callback before reveal : without path",()=>{ + const data = { + record:{ + token:"1815-6223-1073-1425", + label:"Card Number", + altText:"xxxx-xxxx-xxxx-xxxx", + inputStyles:{ + base:{ + color:"red" + } + }, + labelStyles:{ + base:{ + color:"black" + } + } + }, + context: { logLevel: LogLevel.ERROR,env:Env.PROD} + } + defineUrl('http://localhost'); + try{ + RevealFrame.init() + }catch(e){ + expect(e).toBeDefined() + } + }); + test("init callback before reveal",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -78,16 +114,13 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; - const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); - emitCb(data); - }); test("init callback after reveal with response value",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -106,10 +139,12 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); - emitCb(data); + // emitCb(data); // reveal response ready const onRevealResponseName = on.mock.calls[0][0]; @@ -121,8 +156,6 @@ describe("Reveal Frame Class",()=>{ }); test("init callback after reveal with response value with mask value",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815", @@ -142,6 +175,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -157,8 +192,6 @@ describe("Reveal Frame Class",()=>{ }); test("init callback after reveal without value",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -182,6 +215,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -197,8 +232,6 @@ describe("Reveal Frame Class",()=>{ }); test("reveal set error",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -225,6 +258,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -243,8 +278,6 @@ describe("Reveal Frame Class",()=>{ }); test("reveal reset error",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -268,6 +301,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -285,8 +320,6 @@ describe("Reveal Frame Class",()=>{ }); test("reveal set token",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -310,6 +343,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -326,8 +361,6 @@ describe("Reveal Frame Class",()=>{ }); test("reveal set altText",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -351,6 +384,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -368,8 +403,6 @@ describe("Reveal Frame Class",()=>{ }); test("reveal clearAltText",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -393,6 +426,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -410,8 +445,6 @@ describe("Reveal Frame Class",()=>{ }); test("copy icon in reveal elements",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -444,6 +477,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY); @@ -451,8 +486,6 @@ describe("Reveal Frame Class",()=>{ }) test("global style variant in reveal elements",()=>{ - const testFrame = RevealFrame.init(); - // const onCb = jest.fn(); const data = { record:{ token:"1815-6223-1073-1425", @@ -486,6 +519,8 @@ describe("Reveal Frame Class",()=>{ }, context: { logLevel: LogLevel.ERROR,env:Env.PROD} } + defineUrl('http://localhost/?' + btoa(JSON.stringify(data))); + const testFrame = RevealFrame.init(); const emittedEventName = emitSpy.mock.calls[0][0]; const emitCb = emitSpy.mock.calls[0][2]; expect(emittedEventName).toBe(ELEMENT_EVENTS_TO_IFRAME.REVEAL_FRAME_READY);