Skip to content

Commit 13183f8

Browse files
committed
Add more tests for ChannelStore
1 parent d0b748a commit 13183f8

File tree

2 files changed

+187
-7
lines changed

2 files changed

+187
-7
lines changed

src/ChannelStore.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ export default class ChannelStore {
2020
this.initData = initData;
2121
this.isPanel = isPanel;
2222
this.id = storyId;
23+
24+
this.store = {
25+
[GLOBAL]: { init: this.initData || {}, over: {} },
26+
};
2327
}
2428

25-
store = {
26-
[GLOBAL]: { init: this.initData || {}, over: {} },
27-
};
29+
2830
selectorId = null;
2931

3032
subscriber = () => {};
@@ -138,6 +140,7 @@ export default class ChannelStore {
138140
};
139141

140142
createGlobalAction = reducer => this._createAction(reducer, () => GLOBAL);
143+
141144
createLocalAction = reducer =>
142145
this._createAction(reducer, () => this.selectorId || this.id);
143146

@@ -154,6 +157,6 @@ export default class ChannelStore {
154157
let singleStore;
155158

156159
export const getSingleStore = (...args) => {
157-
singleStore = singleStore || new ChannelStore(...args)
160+
singleStore = singleStore || new ChannelStore(...args);
158161
return singleStore;
159162
};

src/__tests__/ChannelStore.test.js

Lines changed: 180 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import ChannelStore, { getSingleStore } from '../ChannelStore';
22
import { getConfig } from '../config';
33

44
jest.mock('@storybook/addons', () => {
5-
const initMockinfo = {
5+
const mockInfo = {
66
onEvent: jest.fn(),
7+
removeEvent: jest.fn(),
8+
emit: jest.fn(console.log),
79
reset() {
810
this.onEvent.mockReset();
11+
this.removeEvent.mockReset();
12+
this.emit.mockReset();
913
},
1014
};
1115
const channel = {
12-
on: (event, cb) => initMockinfo.onEvent([event, cb]),
13-
mock: () => initMockinfo,
16+
on: (event, cb) => mockInfo.onEvent([event, cb]),
17+
removeListener: (event, cb) => mockInfo.removeEvent([event, cb]),
18+
emit: (event, data) => mockInfo.emit([event, data]),
19+
mock: () => mockInfo,
1420
};
1521
return {
1622
getChannel: () => channel,
@@ -94,5 +100,176 @@ describe.each([{ isPanel: false }, { isPanel: true }])(
94100
]);
95101
}
96102
});
103+
104+
it(`should disconnect from channel on ${whatSide(isPanel)}`, () => {
105+
const store = new ChannelStore(configWith({ isPanel }));
106+
store.channel.mock().reset();
107+
store.connect();
108+
store.disconnect();
109+
110+
expect(store.channel.mock().removeEvent).toHaveBeenCalledTimes(2);
111+
112+
expect(store.channel.mock().removeEvent).toHaveBeenNthCalledWith(1, [
113+
store.EVENT_ID_INIT,
114+
store.onInitChannel,
115+
]);
116+
117+
expect(store.channel.mock().removeEvent).toHaveBeenNthCalledWith(2, [
118+
isPanel ? store.EVENT_ID_DATA : store.EVENT_ID_BACK,
119+
store.onDataChannel,
120+
]);
121+
});
122+
123+
describe.each([false, true])(
124+
'should receive and send data to channel (isGlobal: %s)',
125+
isGlobal => {
126+
const storyId = isGlobal
127+
? null
128+
: 'storybook-addon-development-kit--stories';
129+
let store;
130+
beforeEach(() => {
131+
store = new ChannelStore(configWith({ isPanel, storyId }));
132+
store.channel.mock().reset();
133+
store.connect();
134+
});
135+
136+
it('should trigger on init channel message', () => {
137+
const onData = jest.fn();
138+
store.onData(onData);
139+
const initData = {
140+
id: storyId,
141+
data: ['theme1', 'theme2', 'theme3'],
142+
};
143+
store.onInitChannel(initData);
144+
145+
expect(onData).toHaveBeenCalledTimes(1);
146+
147+
expect(store.channel.mock().emit).toHaveBeenCalledTimes(1);
148+
149+
expect(store.channel.mock().emit).toHaveBeenNthCalledWith(1, [
150+
isPanel ? store.EVENT_ID_BACK : store.EVENT_ID_DATA,
151+
{
152+
data: {
153+
global: { init: storyId ? {} : initData.data, over: {} },
154+
...(storyId && {
155+
[storyId]: {
156+
init: initData.data,
157+
over: {},
158+
},
159+
}),
160+
},
161+
id: storyId,
162+
},
163+
]);
164+
});
165+
166+
it('should trigger on data channel message', () => {
167+
const onData = jest.fn();
168+
store.onData(onData);
169+
170+
const initData = {
171+
id: storyId,
172+
data: ['theme1', 'theme2', 'theme3'],
173+
};
174+
store.onInitChannel(initData);
175+
176+
const newData = {
177+
id: storyId,
178+
data: ['T1', 'T2', 'T3'],
179+
};
180+
store.onDataChannel(newData);
181+
if (isPanel) {
182+
const storeData = {
183+
init: initData.data,
184+
over: newData.data,
185+
};
186+
expect(store.store).toEqual({
187+
global: isGlobal
188+
? storeData
189+
: {
190+
init: {},
191+
over: {},
192+
},
193+
...(!isGlobal && {
194+
[storyId]: storeData,
195+
}),
196+
});
197+
} else {
198+
expect(store.store).toEqual(newData.data);
199+
}
200+
});
201+
}
202+
);
97203
}
98204
);
205+
206+
describe('ChannelStore Actions', () => {
207+
let store;
208+
const initData = {
209+
index: 0,
210+
items: [
211+
'apple',
212+
'banana',
213+
'orange',
214+
'pear',
215+
'cherry',
216+
'tomato',
217+
'cucumber',
218+
],
219+
};
220+
const initWith = props => ({ ...initData, ...props });
221+
const onData = jest.fn();
222+
223+
beforeEach(() => {
224+
store = new ChannelStore(configWith({ isPanel: true, initData }));
225+
store.channel.mock().reset();
226+
onData.mockReset();
227+
store.onData(onData);
228+
store.connect();
229+
});
230+
231+
const reducer = (store, step) => ({
232+
...store,
233+
index: store.index + step,
234+
});
235+
236+
it('should create global action / call subscriber / send event', () => {
237+
const incAction = store.createGlobalAction(reducer);
238+
incAction(2);
239+
const newData = initWith({ index: 2 });
240+
const newStore = {
241+
global: {
242+
init: initData,
243+
over: newData,
244+
},
245+
};
246+
247+
expect(store.store).toEqual(newStore);
248+
249+
expect(onData).toHaveBeenCalledTimes(1);
250+
251+
expect(onData).toHaveBeenNthCalledWith(1, newData);
252+
253+
expect(store.channel.mock().emit).toHaveBeenCalledTimes(1);
254+
255+
expect(store.channel.mock().emit).toHaveBeenNthCalledWith(1, [
256+
store.EVENT_ID_BACK,
257+
{
258+
data: newStore,
259+
id: undefined,
260+
},
261+
]);
262+
});
263+
264+
test.todo('create action with default reducer');
265+
test.todo('create local action');
266+
});
267+
268+
describe('getSingleStore', () => {
269+
it('should create and refer to single store', () => {
270+
const panelStore = getSingleStore({ isPanel: true });
271+
const iconStore = getSingleStore();
272+
273+
expect(panelStore).toBe(iconStore);
274+
});
275+
});

0 commit comments

Comments
 (0)