import * as React from 'react'; import CashierPaymentsWidget from './CashierPaymentsWidget'; import BaseDriver from '../../../test/BaseDriver'; import MockApi from '../../utils/mock-api'; import ConfigurationBuilder from '../../../test/builders/ConfigurationBuilder'; import SettingsBuilder from '../../../test/builders/SettingsBuilder'; import {ICashierPaymentsApi, ICashierPaymentsConfiguration, IChargeResponse} from '../../cashier-payments'; import * as sinon from 'sinon'; import Experiments from 'wix-experiments'; export default class CashierPaymentsDriver extends BaseDriver { private configuration: ICashierPaymentsConfiguration; private settings; private singlePaymentMethodSettings; private mockApi; private component; private onPaymentStart; private onPaymentComplete; private ccPostMessage; cashierPaymentsApi: ICashierPaymentsApi; private loggerMock; private mandatoryFields; private experimentsInstance; onPaymentMethodChanged: (pmId: string) => void; onApiInit: (cashierPaymentsApi: ICashierPaymentsApi) => void; constructor(component = null) { super(); this.mountedComponent = component; this.component = component; this.mockApi = new MockApi(); this.settings = new SettingsBuilder().build(); this.singlePaymentMethodSettings = new SettingsBuilder().buildSinglePaymentMethod(); this.onPaymentMethodChanged = sinon.spy(); this.onPaymentStart = sinon.spy(); this.onPaymentComplete = sinon.spy(); this.ccPostMessage = sinon.spy(); this.mandatoryFields = []; this.experimentsInstance = null; } given = { configuration: () => { this.configuration = new ConfigurationBuilder().build(); return this; }, cashierPaymentsApi: () => { this.onApiInit = (cashierPaymentsApi: ICashierPaymentsApi) => { this.cashierPaymentsApi = cashierPaymentsApi; }; return this; }, settingsResponse: () => { this.mockApi.settingsResponse(this.configuration, this.settings); return this; }, singlePaymentMethodSettingsResponse: () => { this.mockApi.settingsResponse(this.configuration, this.singlePaymentMethodSettings); return this; }, paymentDetails: () => { this.mockApi.paymentDetails(); return this; }, payOffline: () => { this.mockApi.payOffline(this.configuration.snapshotId); return this; }, charge: () => { this.mockApi.charge(this.configuration.snapshotId); return this; }, mandatoryFieldsRequest: () => { this.mockApi.mandatoryFields(this.configuration.snapshotId); return this; }, mandatoryFields: (mandatoryFields) => { this.mandatoryFields = mandatoryFields; return this; }, experiments: (experiments) => { this.experimentsInstance = new Experiments({ experiments }); }, }; when = { render: (props) => { this.loggerMock = { appLoaded: sinon.spy(), interactionStarted: sinon.spy(), interactionEnded: sinon.spy() }; this.component = this._render(); return this; }, mockRequests: () => { return this .given.settingsResponse() .given.paymentDetails() .given.payOffline() .given.mandatoryFieldsRequest() .given.charge(); }, errorSetted: (message) => { this.component.setState({generalErrorMessage: message}); return this; }, creditCardPaymentMethodItemSelected: () => { this.getPaymentMethodItemInput('creditCard').simulate('click'); return this; }, payPalPaymentMethodItemSelected: () => { this.getPaymentMethodItemInput('payPal').simulate('click'); return this; }, offlinePaymentMethodItemSelected: () => { this.getPaymentMethodItemInput('offline').simulate('click'); return this; }, validate: () => { return this.cashierPaymentsApi.validate(); }, collapse: () => { return this.cashierPaymentsApi.collapse(); }, expand: () => { return this.cashierPaymentsApi.expand(); }, submit: () => { return this.cashierPaymentsApi.submit(); }, initializePayment: () => { return this.cashierPaymentsApi.initializePayment(); }, updateProps: (props) => { this.component.setProps({...props}); return this; }, emulatePostMessageToIframe: (data) => { const iframe: any = this.getRootOfDom().querySelector('iframe'); if (iframe) { Object.defineProperty(iframe, 'contentWindow', { get: () => ( { postMessage: (request) => { setTimeout(() => { window.postMessage({ eventId: request.eventId, payload: { ...data } }, '*'); }, 100); } } ) }); } }, tokenize: () => this.cashierPaymentsApi.tokenize(), pay: () => this.cashierPaymentsApi.pay(), continuePayment: (chargeResponse: IChargeResponse) => this.cashierPaymentsApi.continuePayment(chargeResponse), localizeError: (errorCode, locale?: string) => this.cashierPaymentsApi.localizeError(errorCode, locale), goBack: () => { this.findByDataHook('wcn-back-button').simulate('click'); return this; } }; get = { cc: () => this.findByDataHook('cc-form').length, spinner: () => this.findByDataHook('cc-spinner').length, collapsedMessage: () => this.component.state().collapsedMessage, successPayedState: () => this.component.state().isPaymentSuccess, errorMessage: () => this.findByDataHook('general-error-message').text(), paymentMethodItems: () => this.findByDataHook('wcn-payment-method-item'), creditCardPaymentMethodItem: () => this.getPaymentMethodItemInput('creditCard'), payPalPaymentComponent: () => this.getPaymentMethodItemInput('payPal'), creditCardPaymentComponent: () => this.findByDataHook('cc-form'), paymentMethodChangedHandler: () => this.onPaymentMethodChanged, isMethodCollapsed: () => this.component.instance().state.isMethodCollapsed, submitButton: () => this.findByDataHook(`cashier-payments-method-pay-button`), termsInput: () => this.findByDataHook(`wcn-wallet-payment-terms-input`), mandatoryFields: () => this.component.instance().getAllMandatoryFields(), mandatoryFieldsItems: () => this.findByDataHook('cashier-payments-method-field'), mandatoryFieldsItemsLength: () => this.findByDataHook('cashier-payments-method-field').length, maxWidth: (maxWidth) => maxWidth ? this.component.html().indexOf(`style="max-width: ${maxWidth}px;"`) !== -1 : this.component.html().indexOf(`style="max-width: ${maxWidth}px;"`) === -1, stepTitle: () => this.findByDataHook('wcn-step-title').text() }; set = { mandatoryFields: (mandatoryFields) => this.component.instance().setMandatoryFields(mandatoryFields), }; fetch = { mandatoryFields: (country?: string) => this.component.instance().fetchMandatoryFields(country), }; is = { rtlClassName: () => this.component.hasClass('cashier-payments-widget-rtl'), paymentInProgress: () => this.component.state().isPaymentInProgress, onPaymentStartCalled: (method) => { return this.onPaymentStart.calledOnce && this.onPaymentStart.calledWith(method); }, onPaymentCompleteCalled: (method, data) => { return this.onPaymentComplete.calledOnce && this.onPaymentComplete.calledWith(method, data); }, appLoaded: () => this.loggerMock.appLoaded.calledOnce, interactionStarted: (method) => this.loggerMock.interactionStarted.calledWith(method), interactionEnded: (method) => this.loggerMock.interactionEnded.calledWith(method), renderedComponent: () => this.findByDataHook('wcn-payment-widget').length > 0, rendered: () => this.findByDataHook('wcn-payment-method-item').length > 0, mandatoryFieldsRendered: () => this.findByDataHook('cashier-payments-method-field').length > 0, collapsed: () => this.findByDataHook('wcn-collapsed-payment').exists(), renderedBackButton: () => this.findByDataHook('wcn-back-button').exists(), }; getPaymentMethodItemInput(pmId) { return this.findByDataHook(`wcn-payment-method-item-input-${pmId}`); } resetMock() { this.mockApi.reset(); } }