import { fireEvent } from '@testing-library/dom' import CommunicationHandler from './CommunicationHandler' describe('CommunicationHandler', () => { describe('send()', () => { it('should send message through postMessage when referrer is valid', () => { window.parent.postMessage = jest.fn() // mock the referrer const originalReferrer = document.referrer Object.defineProperty(document, 'referrer', { value: 'https://secure.helpscout.net', configurable: true, }) const commsHandler = new CommunicationHandler() commsHandler.send('SHOW_NOTIFICATION', { value: 'This is a noty!' }) expect(window.parent.postMessage).toHaveBeenCalledTimes(1) expect(window.parent.postMessage).toHaveBeenCalledWith( { appId: '', iframeId: '', value: 'This is a noty!', type: 'SHOW_NOTIFICATION', }, 'https://secure.helpscout.net' ) // set referrer back to original value Object.defineProperty(document, 'referrer', { value: originalReferrer }) }) it('should not send message through postMessage when referrer is invalid', () => { window.parent.postMessage = jest.fn() // mock the referrer const originalReferrer = document.referrer Object.defineProperty(document, 'referrer', { value: 'http://thisisnotvalid.net', configurable: true, }) const commsHandler = new CommunicationHandler() commsHandler.send('SHOW_NOTIFICATION', { value: 'This is a noty!' }) expect(window.parent.postMessage).not.toHaveBeenCalled() // set referrer back to original value Object.defineProperty(document, 'referrer', { value: originalReferrer }) }) }) describe('receive()', () => { it('should receive message when origin is allowed', () => { const commsHandler = new CommunicationHandler() const eventListener = commsHandler.receive('SEND_APP_CONTEXT') fireEvent( window, new MessageEvent('message', { data: { type: 'SEND_APP_CONTEXT', conversation: 'MOCK_CONVERSATION', customer: 'MOCK_CUSTOMER', }, origin: 'https://secure.helpscout.net', }) ) return eventListener.then(data => { expect(data).toMatchObject({ conversation: 'MOCK_CONVERSATION', customer: 'MOCK_CUSTOMER', }) }) }) it('should ignore message when origin is unknown', () => { const commsHandler = new CommunicationHandler() const eventListener = commsHandler.receive('SEND_APP_CONTEXT') fireEvent( window, new MessageEvent('message', { data: { type: 'SEND_APP_CONTEXT', conversation: 'FAKE_CONVERSATION', customer: 'FAKE_CUSTOMER', }, origin: 'http://thisisnotvalid.net', }) ) fireEvent( window, new MessageEvent('message', { data: { type: 'SEND_APP_CONTEXT', conversation: 'MOCK_CONVERSATION', customer: 'MOCK_CUSTOMER', }, origin: 'https://secure.helpscout.net', }) ) return eventListener.then(data => { expect(data).toMatchObject({ conversation: 'MOCK_CONVERSATION', customer: 'MOCK_CUSTOMER', }) }) }) }) describe('listen()', () => { it('should listen to messages when origin is allowed', () => { const listener = jest.fn() const commsHandler = new CommunicationHandler() commsHandler.listen('SEND_APP_CONTEXT', listener) fireEvent( window, new MessageEvent('message', { data: { type: 'SEND_APP_CONTEXT', conversation: 'MOCK_CONVERSATION', customer: 'MOCK_CUSTOMER', }, origin: 'https://secure.helpscout.net', }) ) fireEvent( window, new MessageEvent('message', { data: { type: 'SEND_APP_CONTEXT', conversation: 'MOCK_CONVERSATION_NEW', customer: 'MOCK_CUSTOMER_NEW', }, origin: 'https://secure.helpscout.net', }) ) expect(listener).toHaveBeenCalledTimes(2) expect(listener).toHaveBeenNthCalledWith(1, { conversation: 'MOCK_CONVERSATION', customer: 'MOCK_CUSTOMER', }) expect(listener).toHaveBeenNthCalledWith(2, { conversation: 'MOCK_CONVERSATION_NEW', customer: 'MOCK_CUSTOMER_NEW', }) }) it('should ignore message when origin is unknown', () => { const listener = jest.fn() const commsHandler = new CommunicationHandler() commsHandler.listen('SEND_APP_CONTEXT', listener) fireEvent( window, new MessageEvent('message', { data: { type: 'SEND_APP_CONTEXT', conversation: 'FAKE_CONVERSATION', customer: 'FAKE_CUSTOMER', }, origin: 'http://thisisnotvalid.net', }) ) expect(listener).not.toHaveBeenCalled() }) }) })