Merge branch 'test-for-data'

This commit is contained in:
Arunoda Susiripala 2016-03-28 15:09:31 +05:30
commit e8cbf9989d
4 changed files with 176 additions and 13 deletions

View File

@ -52,7 +52,8 @@
"eslint-config-airbnb": "^6.2.0",
"eslint-plugin-babel": "^3.1.0",
"eslint-plugin-react": "^4.2.3",
"mocha": "^2.4.5"
"mocha": "^2.4.5",
"sinon": "^1.17.3"
},
"main": "dist/client/index.js",
"bin": {

View File

@ -0,0 +1,6 @@
export function setWindow(search) {
global.window = {
location: { search },
addEventListener: () => {},
};
}

View File

@ -0,0 +1,159 @@
const { describe, it } = global;
import UUID from 'uuid';
import sinon from 'sinon';
import { expect } from 'chai';
import { setWindow } from './_utils';
const currentDataId = UUID.v4();
setWindow(`?dataId=${currentDataId}`);
const dataModule = require('../data');
describe('data', () => {
// TODO: We can't find a way to reset the module cache.
// Once we do that, we can test for this case as well.
// describe('normal mode', () => {
// it('should set the `iframeMode` as false', () => {
// const data = dataModule.getData();
// expect(data.iframeMode).to.be.equal(false);
// });
// it('should set a random Id to dataId', () => {
// const data = dataModule.getData();
// expect(typeof data.dataId).to.be.equal('string');
// });
// });
describe('iframe mode', () => {
it('should get the dataId from the URL', () => {
const data = dataModule.getData();
expect(data.dataId).to.be.equal(currentDataId);
});
it('should set the iframeMode as true', () => {
const data = dataModule.getData();
expect(data.iframeMode).to.be.equal(true);
});
});
describe('watchData', () => {
it('should add the handler to handlers', () => {
const fn = () => {};
dataModule.watchData(fn);
const fnStored = dataModule.handlers.pop();
expect(fnStored).to.be.equal(fn);
});
it('should remove the handler when the return function called', () => {
const stop = dataModule.watchData(() => {});
const countStart = dataModule.handlers.length;
stop();
const countEnd = dataModule.handlers.length;
expect(countStart - countEnd).to.be.equal(1);
});
});
describe('setData', () => {
it('should emit data to the pageBus', () => {
const kkr = UUID.v4();
const originalEmit = dataModule.bus.emit;
dataModule.bus.emit = sinon.stub();
dataModule.setData({ kkr });
const data = dataModule.getData();
const sentString = dataModule.bus.emit.args[0][1];
const sentJSON = JSON.parse(sentString);
expect(sentJSON).to.deep.equal(data);
dataModule.bus.emit = originalEmit;
});
it('should update existing data', () => {
const kkr = UUID.v4();
const originalEmit = dataModule.bus.emit;
dataModule.bus.emit = sinon.stub();
const previousKKR = dataModule.getData().kkr;
dataModule.setData({ kkr });
const data = dataModule.getData();
expect(data.kkr).not.to.be.equal(previousKKR);
dataModule.bus.emit = originalEmit;
});
it('should run all handlers with the data', (done) => {
const kkr = UUID.v4();
const stop = dataModule.watchData((data) => {
stop();
expect(data.kkr).to.be.equal(kkr);
done();
});
const originalEmit = dataModule.bus.emit;
dataModule.bus.emit = sinon.stub();
dataModule.setData({ kkr });
dataModule.bus.emit = originalEmit;
});
it('should add a property with __lastUpdated with Date.now()', () => {
const now = UUID.v4();
const originalEmit = dataModule.bus.emit;
dataModule.bus.emit = sinon.stub();
const originalNow = Date.now;
Date.now = () => (now);
dataModule.setData({ aa: 10 });
const data = dataModule.getData();
expect(data.__lastUpdated).to.be.equal(now);
Date.now = originalNow;
dataModule.bus.emit = originalEmit;
});
});
describe('receiveData', () => {
it('should set received data as the new data', () => {
const previousData = dataModule.getData();
const newData = { kkr: UUID.v4() };
dataModule.onData(JSON.stringify(newData));
const updatedData = dataModule.getData();
delete updatedData.iframeMode;
expect(updatedData).to.deep.equal(newData);
expect(previousData).not.to.deep.equal(newData);
});
it('should run all handlers with data', (done) => {
const newData = { kkr: UUID.v4() };
const stop = dataModule.watchData((data) => {
stop();
const updatedData = { ...data };
delete updatedData.iframeMode;
expect(updatedData).to.deep.equal(newData);
done();
});
dataModule.onData(JSON.stringify(newData));
});
it('should set the local iframeMode to data', () => {
const newData = {
kkr: UUID.v4(),
iframeMode: UUID.v4(),
};
const oldIframeMode = dataModule.getData().iframeMode;
dataModule.onData(JSON.stringify(newData));
const newIframeMode = dataModule.getData().iframeMode;
expect(newIframeMode).to.be.deep.equal(oldIframeMode);
});
});
describe('getDataKey', () => {
it('should get the data key prefixed with the current dataId', () => {
const dataId = dataModule.getData().dataId;
const dataKey = dataModule.getDataKey();
expect(dataKey).to.be.equal(`data-${dataId}`);
});
});
});

View File

@ -1,6 +1,7 @@
import createPageBus from 'page-bus';
import stringify from 'json-stringify-safe';
import QS from 'query-string';
import UUID from 'uuid';
const parsedQs = QS.parse(window.location.search);
// We need to check whether we are inside a iframe or not.
@ -13,20 +14,16 @@ const iframeMode = Boolean(parsedQs.dataId);
// We create a new UUID if this is main page. Then, this is used by UI to
// create queryString param when creating the iframe.
// If we are in the iframe, we'll get it from the queryString.
const dataId = iframeMode ? parsedQs.dataId : window.dataId;
const dataId = iframeMode ? parsedQs.dataId : UUID.v4();
let data = { iframeMode, dataId };
const handlers = [];
const bus = createPageBus();
export const handlers = [];
export const bus = createPageBus();
export function getDataKey() {
return `data-${data.dataId}`;
}
export function getRequestKey() {
return `data-request-${data.dataId}`;
}
export function getData() {
return { ...data };
}
@ -38,12 +35,11 @@ export function setData(fields) {
data[key] = fields[key];
});
data.__lastUpdated = Date.now();
// In page-bus, we must send non-identical data.
// Otherwise, it'll cache and won't trigger.
// That's why we are setting the __lastUpdated value here.
const __lastUpdated = Date.now();
const newData = { ...data, __lastUpdated };
bus.emit(getDataKey(), stringify(newData));
bus.emit(getDataKey(), stringify(getData()));
handlers.forEach(handler => handler(getData()));
}
@ -55,14 +51,15 @@ export function watchData(fn) {
};
}
bus.on(getDataKey(), function (dataString) {
export function onData(dataString) {
const d = JSON.parse(dataString);
data = { ...d, iframeMode };
handlers.forEach(handler => {
handler(getData());
});
});
}
bus.on(getDataKey(), onData);
// do initial render
handlers.forEach(handler => handler(getData()));