diff options
| author | Erik Larkö <erik@mullvad.net> | 2017-06-30 10:14:36 +0200 |
|---|---|---|
| committer | Erik Larkö <erik@mullvad.net> | 2017-07-03 15:26:08 +0200 |
| commit | d06281eb566330a38b13a56bb9fdadbd7ef9aa99 (patch) | |
| tree | e1bc465e4e1b54b9ccbb8c500ad9b921fd2e16f9 /test/helpers | |
| parent | 005a6094aa48738f54e97d809de6e11f3b966da0 (diff) | |
| download | mullvadvpn-d06281eb566330a38b13a56bb9fdadbd7ef9aa99.tar.xz mullvadvpn-d06281eb566330a38b13a56bb9fdadbd7ef9aa99.zip | |
Add first login workflow test
Diffstat (limited to 'test/helpers')
| -rw-r--r-- | test/helpers/IpcChain.js | 84 | ||||
| -rw-r--r-- | test/helpers/ipc-helpers.js | 51 |
2 files changed, 135 insertions, 0 deletions
diff --git a/test/helpers/IpcChain.js b/test/helpers/IpcChain.js new file mode 100644 index 0000000000..247ea0526b --- /dev/null +++ b/test/helpers/IpcChain.js @@ -0,0 +1,84 @@ +// @flow + +import { expect } from 'chai'; +import { check, failFast } from './ipc-helpers'; + +export class IpcChain { + _expectedCalls: Array<string>; + _recordedCalls: Array<string>; + _mockIpc: {}; + _done: (*) => void; + + constructor(mockIpc: {}, done: (*) => void) { + this._expectedCalls = []; + this._recordedCalls = []; + this._mockIpc = mockIpc; + this._done = done; + } + + addRequiredStep(ipcCall: string): StepBuilder { + this._expectedCalls.push(ipcCall); + return new StepBuilder(ipcCall, this._addStep.bind(this)); + } + + _addStep(step: StepBuilder) { + const me = this; + this._mockIpc[step.ipcCall] = function() { + return new Promise(r => me._stepPromiseCallback(step, r, arguments)); + }; + } + + _stepPromiseCallback(step, resolve, args) { + this._registerCall(step.ipcCall); + + if (step.inputValidation) { + failFast(() => step.inputValidation(...args), this._done); + } + + if (this._isLastCall()) { + this._ensureChainCalledCorrectly(); + } + + resolve(step.returnValue); + } + + _isLastCall(): boolean { + return this._recordedCalls.length === this._expectedCalls.length; + } + + _ensureChainCalledCorrectly() { + check(() => { + expect(this._expectedCalls).to.deep.equal(this._recordedCalls); + }, this._done); + } + + _registerCall(ipcCall: string) { + this._recordedCalls.push(ipcCall); + } +} + +class StepBuilder { + ipcCall: string; + inputValidation: () => void; + returnValue: *; + _cb: (StepBuilder) => void; + + constructor(ipcCall: string, cb: (StepBuilder)=> void) { + this.ipcCall = ipcCall; + this._cb = cb; + } + + withInputValidation(iv: () => void): StepBuilder { + this.inputValidation = iv; + return this; + } + + withReturnValue(rv: *): StepBuilder { + this.returnValue = rv; + return this; + } + + done() { + this._cb(this); + } +} diff --git a/test/helpers/ipc-helpers.js b/test/helpers/ipc-helpers.js new file mode 100644 index 0000000000..39fc9fba06 --- /dev/null +++ b/test/helpers/ipc-helpers.js @@ -0,0 +1,51 @@ +// @flow + +import { Backend } from '../../app/lib/backend'; +import { newMockIpc } from '../mocks/ipc'; +import configureStore from '../../app/redux/store'; +import { createMemoryHistory } from 'history'; + +type DoneCallback = (?mixed) => void; +type Check = () => void; + +// Mock localStorage because redux-localstorage has no test helpers +// We use redux-localstorage when we setup the redux store to have the +// store persist when the application is shut down. +global.localStorage = {getItem: ()=>'{}', setItem: ()=>{}}; + +export function setupBackendAndStore() { + + const memoryHistory = createMemoryHistory(); + const store = configureStore(null, memoryHistory); + + const mockIpc = newMockIpc(); + + const backend = new Backend(store, mockIpc); + + return { store, mockIpc, backend }; +} + +// chai and async aren't the best of friends. To allow us +// to get the assertion error in the output of failed async +// tests we need to do this try-catch thing. +export function check(fn: Check, done: DoneCallback) { + try { + fn(); + done(); + } catch (e) { + done(e); + } +} + + +// In async tests where we want to test a chain of IPC messages +// we can only invoke `done` for the last message. This function +// is for the intermediate messages. +export function failFast(fn: Check, done: DoneCallback) { + try { + fn(); + } catch(e) { + done(e); + } +} + |
