Skip to content

Commit

Permalink
No longer mock window API
Browse files Browse the repository at this point in the history
This makes tests compatible with Node 7
  • Loading branch information
ovidiuch committed Jan 25, 2017
1 parent 4964ceb commit 891f387
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 126 deletions.
135 changes: 72 additions & 63 deletions packages/react-cosmos/src/components/__tests__/Loader.jsx
@@ -1,25 +1,6 @@
import React from 'react';
import { mount } from 'enzyme';

let origAddEventListener;
let origRemoveEventListener;
let origParentPostMessage;

const stubWindowApi = () => {
origParentPostMessage = parent.postMessage;
parent.postMessage = jest.fn();
origAddEventListener = window.addEventListener;
window.addEventListener = jest.fn();
origRemoveEventListener = window.removeEventListener;
window.removeEventListener = jest.fn();
};

const revertWindowApi = () => {
parent.postMessage = origParentPostMessage;
window.addEventListener = origAddEventListener;
window.removeEventListener = origRemoveEventListener;
};

const mockProxyNext = {};
const mockFirstProxy = {
value: () => <span />,
Expand All @@ -44,6 +25,7 @@ const Loader = require('../Loader').default;

const Proxy = jest.fn();
const FooBarComponent = () => {};
const FooBarBarComponent = () => {};
const baseFixture = {};

let wrapper;
Expand All @@ -55,60 +37,83 @@ const init = () => {
proxies={[Proxy]}
components={{
FooBar: FooBarComponent,
FooBarBar: FooBarBarComponent,
}}
fixtures={{
FooBar: {
base: baseFixture,
},
FooBarBar: {
base: baseFixture,
},
}}
/>,
);
instance = wrapper.instance();
};

let pendingPromiseResolve;
const waitForPostMessage = () => new Promise((resolve) => {
pendingPromiseResolve = resolve;
});

const parentMessageListener = (e) => {
pendingPromiseResolve(e.data);
};

beforeAll(() => {
stubWindowApi();
parent.addEventListener('message', parentMessageListener, false);
init();
});

afterAll(() => {
revertWindowApi();
parent.removeEventListener('message', parentMessageListener);
});

test('renders nothing at first', () => {
expect(wrapper.html()).toBe(null);
});

test('subscribes to message events', () => {
const { onMessage } = instance;
expect(window.addEventListener).toHaveBeenLastCalledWith('message', onMessage, false);
});

test('notifies parent frames on load', () => {
expect(parent.postMessage).toHaveBeenLastCalledWith({ type: 'frameReady' }, '*');
});
test('notifies parent frames on load', () =>
waitForPostMessage().then((data) => {
expect(data).toEqual({ type: 'frameReady' });
}),
);

test('creates linked list from proxy list', () => {
expect(mockGetLinkedList).toHaveBeenLastCalledWith([Proxy]);
});

test('publishes message to parent on fixture update', () => {
const { onFixtureUpdate } = instance;
const updatedFixture = {};
onFixtureUpdate(updatedFixture);

return waitForPostMessage().then((data) => {
expect(data).toEqual({
type: 'fixtureUpdate',
fixtureBody: updatedFixture,
});
});
});

describe('on `fixtureLoad` event', () => {
let firstProxyWrapper;
let firstProxyProps;
let firstProxyKey;

beforeAll(() => {
const { onMessage } = instance;
onMessage({
data: {
type: 'fixtureLoad',
component: 'FooBar',
fixture: 'base',
},
window.postMessage({
type: 'fixtureLoad',
component: 'FooBar',
fixture: 'base',
}, '*');

return waitForPostMessage().then(() => {
firstProxyWrapper = wrapper.find(mockFirstProxy.value);
firstProxyProps = firstProxyWrapper.props();
firstProxyKey = firstProxyWrapper.key();
});
firstProxyWrapper = wrapper.find(mockFirstProxy.value);
firstProxyProps = firstProxyWrapper.props();
firstProxyKey = firstProxyWrapper.key();
});

test('renders first proxy ', () => {
Expand Down Expand Up @@ -148,17 +153,17 @@ describe('on `fixtureLoad` event', () => {
};

beforeAll(() => {
const { onMessage } = instance;
onMessage({
data: {
type: 'fixtureLoad',
component: 'FooBar',
fixture: 'base',
fixtureBody,
},
window.postMessage({
type: 'fixtureLoad',
component: 'FooBar',
fixture: 'base',
fixtureBody,
}, '*');

return waitForPostMessage().then(() => {
firstProxyWrapper = wrapper.find(mockFirstProxy.value);
firstProxyProps = firstProxyWrapper.props();
});
firstProxyWrapper = wrapper.find(mockFirstProxy.value);
firstProxyProps = firstProxyWrapper.props();
});

test('includes body received in fixture sent to first proxy', () => {
Expand All @@ -172,20 +177,24 @@ describe('on `fixtureLoad` event', () => {
expect(firstProxyWrapper.key()).not.toEqual(firstProxyKey);
});
});
});

test('publishes message to parent on fixture update', () => {
const { onFixtureUpdate } = instance;
const updatedFixture = {};
onFixtureUpdate(updatedFixture);
expect(parent.postMessage).toHaveBeenLastCalledWith({
type: 'fixtureUpdate',
fixtureBody: updatedFixture,
}, '*');
});
describe('on unmount', () => {
beforeAll(() => {
wrapper.unmount();
});

test('unsubscribes from message events', () => {
instance.setState = jest.fn();

test('unsubscribes from message events on unmount', () => {
const { onMessage } = instance;
wrapper.unmount();
expect(window.removeEventListener).toHaveBeenLastCalledWith('message', onMessage);
window.postMessage({
type: 'fixtureLoad',
component: 'FooBarBar',
fixture: 'base',
}, '*');

return waitForPostMessage().then(() => {
expect(instance.setState).not.toHaveBeenCalled();
});
});
});
});
94 changes: 31 additions & 63 deletions packages/react-querystring-router/src/__tests__/router.js
Expand Up @@ -7,7 +7,9 @@ let getComponentClass;
let getComponentProps;

const onChange = jest.fn();
const mockUriLocation = 'mypage.com?component=List&dataUrl=users.json';
// window.location is mocked inside jest.config.json
const mockUriLocationInitial = 'http://foo.bar/';
const mockUriLocation = `${mockUriLocationInitial}?component=List&dataUrl=users.json`;
const mockUriParams = {
component: 'List',
dataUrl: 'users.json',
Expand All @@ -19,22 +21,6 @@ let Router;
let ReactDOM;
let routerInstance;

const nativeRefs = {};
const stubWindowApi = () => {
nativeRefs.addEventListener = window.addEventListener;
nativeRefs.removeEventListener = window.removeEventListener;
nativeRefs.historyPushState = window.history.pushState;

window.addEventListener = jest.fn();
window.removeEventListener = jest.fn();
window.history.pushState = jest.fn();
};
const restoreWindowApi = () => {
window.addEventListener = nativeRefs.addEventListener;
window.removeEventListener = nativeRefs.removeEventListener;
window.history.pushState = nativeRefs.historyPushState;
};

const initRouter = () => {
jest.resetModules();
jest.resetAllMocks();
Expand Down Expand Up @@ -109,43 +95,15 @@ const commonTests = () => {
});
};

const currentLocationTests = () => {
it('should unserialize current location', () => {
// window.location is mocked inside jest.config.json
expect(uri.parseLocation.mock.calls[0][0]).toBe('http://foo.bar/');
});
};

const pushLocationTests = () => {
it('should push new entry to browser history', () => {
expect(window.history.pushState.mock.calls[0][2]).toBe(mockUriLocation);
});
};

beforeAll(() => {
stubWindowApi();
});

afterAll(() => {
restoreWindowApi();
});

describe('initial location', () => {
beforeAll(() => {
initRouter();
});

commonTests();
currentLocationTests();

it('should add popstate event listener', () => {
expect(window.addEventListener.mock.calls[0]).toEqual(['popstate', routerInstance.onPopState]);
});

it('should remove popstate event listener on destroy', () => {
routerInstance.stop();
expect(window.removeEventListener.mock.calls[0]).toEqual(
['popstate', routerInstance.onPopState]);
it('should unserialize current location', () => {
expect(uri.parseLocation.mock.calls[0][0]).toBe(mockUriLocationInitial);
});
});

Expand All @@ -156,8 +114,15 @@ describe('.goTo method', () => {
routerInstance.goTo(mockUriLocation);
});

afterAll(() => {
window.history.pushState({}, '', mockUriLocationInitial);
});

commonTests();
pushLocationTests();

it('should push new entry to browser history', () => {
expect(window.location.href).toBe(mockUriLocation);
});
});

describe('.routeLink method', () => {
Expand All @@ -172,32 +137,35 @@ describe('.routeLink method', () => {
});
});

afterAll(() => {
window.history.pushState({}, '', mockUriLocationInitial);
});

commonTests();
pushLocationTests();

it('should push new entry to browser history', () => {
expect(window.location.href).toBe(mockUriLocation);
});
});

describe('PopState event', () => {
beforeAll(() => {
initRouter();

routerInstance.onPopState({
state: {},
});
window.history.pushState({}, '', mockUriLocation);
window.dispatchEvent(new Event('popstate'));
});

commonTests();
currentLocationTests();
});

describe('Empty PopState event', () => {
beforeEach(() => {
initRouter();

routerInstance.onPopState({
state: null,
});
it('should unserialize current location', () => {
expect(uri.parseLocation.mock.calls[1][0]).toBe(mockUriLocation);
});

commonTests();
currentLocationTests();
it('should remove popstate event listener on destroy', () => {
routerInstance.stop();
window.dispatchEvent(new Event('popstate'));

expect(uri.parseLocation.mock.calls.length).toEqual(2);
});
});

0 comments on commit 891f387

Please sign in to comment.