Skip to content

Commit 5eb0b26

Browse files
authored
Merge pull request #2 from Reaverart/tests
Tests
2 parents 1f040ec + 379e5f8 commit 5eb0b26

File tree

2 files changed

+228
-2
lines changed

2 files changed

+228
-2
lines changed

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"clean": "rimraf lib",
99
"lint": "eslint src",
1010
"prepublish": "npm run lint && npm run clean && npm run build",
11-
"test": "echo \"Error: no test specified\" && exit 1"
11+
"test": "babel-node test/index.js"
1212
},
1313
"keywords": [
1414
"redux",
@@ -36,7 +36,9 @@
3636
"eslint": "^3.13.1",
3737
"eslint-config-airbnb-base": "^11.0.1",
3838
"eslint-plugin-import": "^2.2.0",
39-
"rimraf": "^2.5.4"
39+
"rimraf": "^2.5.4",
40+
"sinon": "^5.0.10",
41+
"tape": "^4.9.0"
4042
},
4143
"files": [
4244
"README.md",

test/index.js

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
import test from 'tape';
2+
import sinon from 'sinon';
3+
import createApiMiddleware, {
4+
CALL_API,
5+
CALL_API_PHASE,
6+
callApiPhases,
7+
} from '../src/index';
8+
9+
function makeSleep(ms, shouldResolve, response) {
10+
return () =>
11+
new Promise((resolve, reject) => (
12+
setTimeout(() => (
13+
shouldResolve ? resolve(response) : reject(response)
14+
), ms)
15+
)
16+
);
17+
}
18+
19+
test('Calls fetch function with given endpoint and options', (t) => {
20+
const spy = sinon.spy();
21+
const apiMiddleware = createApiMiddleware({ callApi: spy });
22+
const doGetState = () => {};
23+
const doDispatch = () => {};
24+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
25+
const doNext = () => {};
26+
const actionHandler = nextHandler(doNext);
27+
const ENDPOINT = 'ENDPOINT';
28+
const OPTIONS = {};
29+
actionHandler({
30+
[CALL_API]: {
31+
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
32+
endpoint: ENDPOINT,
33+
options: OPTIONS,
34+
},
35+
});
36+
t.true(spy.calledOnce);
37+
t.true(spy.calledWith(ENDPOINT, OPTIONS));
38+
t.end();
39+
});
40+
41+
test('Calls fetch function and makes endpoint and options', (t) => {
42+
const spy = sinon.spy();
43+
const apiMiddleware = createApiMiddleware({ callApi: spy });
44+
const doGetState = () => {};
45+
const doDispatch = () => {};
46+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
47+
const doNext = () => {};
48+
const actionHandler = nextHandler(doNext);
49+
const ENDPOINT = 'ENDPOINT';
50+
const OPTIONS = {};
51+
actionHandler({
52+
[CALL_API]: {
53+
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
54+
endpoint: () => ENDPOINT,
55+
options: () => OPTIONS,
56+
},
57+
});
58+
t.true(spy.calledOnce);
59+
t.true(spy.calledWith(ENDPOINT, OPTIONS));
60+
t.end();
61+
});
62+
63+
test('Calls batch requests', (t) => {
64+
const spy = sinon.spy();
65+
const apiMiddleware = createApiMiddleware({ callApi: spy });
66+
const doGetState = () => {};
67+
const doDispatch = () => {};
68+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
69+
const doNext = () => {};
70+
const actionHandler = nextHandler(doNext);
71+
const ENDPOINT = 'ENDPOINT';
72+
const OPTIONS = {};
73+
actionHandler({
74+
[CALL_API]: {
75+
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
76+
batch: [
77+
{
78+
endpoint: () => ENDPOINT,
79+
options: () => OPTIONS,
80+
},
81+
{
82+
endpoint: () => ENDPOINT,
83+
options: () => OPTIONS,
84+
},
85+
],
86+
},
87+
});
88+
t.true(spy.calledTwice);
89+
t.true(spy.firstCall.calledWith(ENDPOINT, OPTIONS));
90+
t.true(spy.secondCall.calledWith(ENDPOINT, OPTIONS));
91+
t.end();
92+
});
93+
94+
test('Dispatches request action', (t) => {
95+
const apiMiddleware = createApiMiddleware({ callApi: makeSleep(0, true, {}) });
96+
const doGetState = () => {};
97+
const doDispatch = sinon.spy();
98+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
99+
const doNext = () => {};
100+
const actionHandler = nextHandler(doNext);
101+
actionHandler({
102+
[CALL_API]: {
103+
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
104+
endpoint: 'endpoint',
105+
options: {},
106+
},
107+
}).then(() => {
108+
t.true(doDispatch.firstCall.calledWith({
109+
type: 'REQUEST',
110+
}));
111+
t.true(doDispatch.calledTwice);
112+
t.end();
113+
});
114+
});
115+
116+
test('Dispatches success action', (t) => {
117+
const RESPONSE = 'RESPONSE';
118+
const apiMiddleware = createApiMiddleware({ callApi: makeSleep(0, true, RESPONSE) });
119+
const doGetState = () => {};
120+
const doDispatch = sinon.spy();
121+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
122+
const doNext = () => {};
123+
const actionHandler = nextHandler(doNext);
124+
actionHandler({
125+
[CALL_API]: {
126+
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
127+
endpoint: 'endpoint',
128+
options: {},
129+
},
130+
}).then(() => {
131+
t.true(doDispatch.secondCall.calledWith({
132+
type: 'SUCCESS',
133+
payload: RESPONSE,
134+
}));
135+
t.true(doDispatch.calledTwice);
136+
t.end();
137+
});
138+
});
139+
140+
test('Dispatches failure action', (t) => {
141+
const RESPONSE = new Error();
142+
const apiMiddleware = createApiMiddleware({ callApi: makeSleep(0, false, RESPONSE) });
143+
const doGetState = () => {};
144+
const doDispatch = sinon.spy();
145+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
146+
const doNext = () => {};
147+
const actionHandler = nextHandler(doNext);
148+
actionHandler({
149+
[CALL_API]: {
150+
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
151+
endpoint: 'endpoint',
152+
options: {},
153+
},
154+
}).then(() => {
155+
t.true(doDispatch.secondCall.calledWith({
156+
type: 'FAILURE',
157+
payload: RESPONSE,
158+
error: true,
159+
}));
160+
t.true(doDispatch.calledTwice);
161+
t.end();
162+
});
163+
});
164+
165+
test('Dispatches single typed action with request and success action phase', (t) => {
166+
const ACTION_TYPE = 'ACTION_TYPE';
167+
const RESPONSE = 'RESPONSE';
168+
const apiMiddleware = createApiMiddleware({ callApi: makeSleep(0, true, RESPONSE) });
169+
const doGetState = () => {};
170+
const doDispatch = sinon.spy();
171+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
172+
const doNext = () => {};
173+
const actionHandler = nextHandler(doNext);
174+
actionHandler({
175+
[CALL_API]: {
176+
type: ACTION_TYPE,
177+
endpoint: 'endpoint',
178+
options: {},
179+
},
180+
}).then(() => {
181+
t.true(doDispatch.firstCall.calledWith({
182+
type: ACTION_TYPE,
183+
[CALL_API_PHASE]: callApiPhases.REQUEST,
184+
}));
185+
t.true(doDispatch.secondCall.calledWith({
186+
type: ACTION_TYPE,
187+
[CALL_API_PHASE]: callApiPhases.SUCCESS,
188+
payload: RESPONSE,
189+
}));
190+
t.true(doDispatch.calledTwice);
191+
t.end();
192+
});
193+
});
194+
195+
test('Dispatches single typed action with request and failure action phase', (t) => {
196+
const ACTION_TYPE = 'ACTION_TYPE';
197+
const RESPONSE = new Error();
198+
const apiMiddleware = createApiMiddleware({ callApi: makeSleep(0, false, RESPONSE) });
199+
const doGetState = () => {};
200+
const doDispatch = sinon.spy();
201+
const nextHandler = apiMiddleware({ getState: doGetState, dispatch: doDispatch });
202+
const doNext = () => {};
203+
const actionHandler = nextHandler(doNext);
204+
actionHandler({
205+
[CALL_API]: {
206+
type: ACTION_TYPE,
207+
endpoint: 'endpoint',
208+
options: {},
209+
},
210+
}).then(() => {
211+
t.true(doDispatch.firstCall.calledWith({
212+
type: ACTION_TYPE,
213+
[CALL_API_PHASE]: callApiPhases.REQUEST,
214+
}));
215+
t.true(doDispatch.secondCall.calledWith({
216+
type: ACTION_TYPE,
217+
[CALL_API_PHASE]: callApiPhases.FALIURE,
218+
payload: RESPONSE,
219+
error: true,
220+
}));
221+
t.true(doDispatch.calledTwice);
222+
t.end();
223+
});
224+
});

0 commit comments

Comments
 (0)