Skip to content

Commit 86c308c

Browse files
authored
chore(utils): add utils tests (#675)
1 parent 6afd559 commit 86c308c

11 files changed

+753
-7
lines changed

src/middleware.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default function wrapper(context) {
7272
}
7373

7474
// Buffer
75-
content = handleRangeHeaders(content, req, res);
75+
content = handleRangeHeaders(context, content, req, res);
7676

7777
// send Buffer
7878
res.send(content);

src/utils/handleRangeHeaders.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import parseRange from 'range-parser';
22

3-
export default function handleRangeHeaders(content, req, res) {
3+
export default function handleRangeHeaders(context, content, req, res) {
44
// assumes express API. For other servers, need to add logic to access
55
// alternative header APIs
66
res.setHeader('Accept-Ranges', 'bytes');
@@ -13,11 +13,18 @@ export default function handleRangeHeaders(content, req, res) {
1313
res.setHeader('Content-Range', `bytes */${content.length}`);
1414
// eslint-disable-next-line no-param-reassign
1515
res.statusCode = 416;
16-
}
17-
18-
// valid (syntactically invalid/multiple ranges are treated as a
19-
// regular response)
20-
if (ranges !== -2 && ranges.length === 1) {
16+
} else if (ranges === -2) {
17+
// malformed header treated as regular response
18+
context.logger.error(
19+
'A malformed Range header was provided. A regular response will be sent for this request.'
20+
);
21+
} else if (ranges.length !== 1) {
22+
// multiple ranges treated as regular response
23+
context.logger.error(
24+
'A Range header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.'
25+
);
26+
} else {
27+
// valid range header
2128
const { length } = content;
2229

2330
// Content-Range

test/middleware.test.js

+11
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,17 @@ describe('middleware', () => {
229229
.expect(206, done);
230230
});
231231

232+
it('should return the "200" code for the "GET" request with malformed range header which is ignored', (done) => {
233+
request(app).get('/bundle.js').set('Range', 'abc').expect(200, done);
234+
});
235+
236+
it('should return the "200" code for the "GET" request with multiple range header which is ignored', (done) => {
237+
request(app)
238+
.get('/bundle.js')
239+
.set('Range', 'bytes=3000-3100,3200-3300')
240+
.expect(200, done);
241+
});
242+
232243
it('should return the "404" code for the "GET" request with to the non-public path', (done) => {
233244
request(app)
234245
.get('/nonpublic/')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`handleRangeHeaders should handle malformed range header 1`] = `
4+
Array [
5+
Array [
6+
"A malformed Range header was provided. A regular response will be sent for this request.",
7+
],
8+
]
9+
`;
10+
11+
exports[`handleRangeHeaders should handle malformed range header 2`] = `
12+
Array [
13+
Array [
14+
"Accept-Ranges",
15+
"bytes",
16+
],
17+
]
18+
`;
19+
20+
exports[`handleRangeHeaders should handle multiple ranges 1`] = `
21+
Array [
22+
Array [
23+
"A Range header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.",
24+
],
25+
]
26+
`;
27+
28+
exports[`handleRangeHeaders should handle multiple ranges 2`] = `
29+
Array [
30+
Array [
31+
"Accept-Ranges",
32+
"bytes",
33+
],
34+
]
35+
`;
36+
37+
exports[`handleRangeHeaders should handle unsatisfiable range 1`] = `
38+
Array [
39+
Array [
40+
"Accept-Ranges",
41+
"bytes",
42+
],
43+
Array [
44+
"Content-Range",
45+
"bytes */6",
46+
],
47+
]
48+
`;
49+
50+
exports[`handleRangeHeaders should return content in range with valid range header 1`] = `
51+
Array [
52+
Array [
53+
"Accept-Ranges",
54+
"bytes",
55+
],
56+
Array [
57+
"Content-Range",
58+
"bytes 1-4/6",
59+
],
60+
]
61+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`setupHooks handles multi compiler 1`] = `
4+
Array [
5+
Array [
6+
"Child \\"comp1\\": Failed to compile.",
7+
],
8+
Array [
9+
"Child \\"comp2\\": Compiled with warnings.",
10+
],
11+
]
12+
`;
13+
14+
exports[`setupHooks handles multi compiler 2`] = `
15+
Array [
16+
Array [
17+
"Child \\"comp1\\": statsString1",
18+
],
19+
]
20+
`;
21+
22+
exports[`setupHooks handles multi compiler 3`] = `
23+
Array [
24+
Array [
25+
"Child \\"comp2\\": statsString2",
26+
],
27+
]
28+
`;
29+
30+
exports[`setupHooks sets state, then logs stats and handles callbacks on nextTick from done hook 1`] = `
31+
Array [
32+
Array [
33+
"statsString",
34+
],
35+
Array [
36+
"Compiled successfully.",
37+
],
38+
]
39+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with mkdir error 1`] = `
4+
Array [
5+
Array [
6+
"Child \\"name\\": Unable to write \\"/target/path\\" directory to disk:
7+
error1",
8+
],
9+
]
10+
`;
11+
12+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with mkdir error 2`] = `Array []`;
13+
14+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with mkdir error 3`] = `
15+
Array [
16+
Array [
17+
"error1",
18+
],
19+
]
20+
`;
21+
22+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with no write errors 1`] = `Array []`;
23+
24+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with no write errors 2`] = `
25+
Array [
26+
Array [
27+
"Child \\"name\\": Asset written to disk: \\"/target/path/file\\"",
28+
],
29+
]
30+
`;
31+
32+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with no write errors 3`] = `
33+
Array [
34+
Array [],
35+
]
36+
`;
37+
38+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with writeFile error 1`] = `
39+
Array [
40+
Array [
41+
"Child \\"name\\": Unable to write \\"/target/path/file\\" asset to disk:
42+
error2",
43+
],
44+
]
45+
`;
46+
47+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with writeFile error 2`] = `Array []`;
48+
49+
exports[`setupWriteToDisk tries to create directories and write file if not filtered out with writeFile error 3`] = `
50+
Array [
51+
Array [
52+
"error2",
53+
],
54+
]
55+
`;

test/utils/handleRangeHeaders.test.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import handleRangeHeaders from '../../src/utils/handleRangeHeaders';
2+
3+
describe('handleRangeHeaders', () => {
4+
let context;
5+
6+
beforeEach(() => {
7+
context = {
8+
logger: {
9+
error: jest.fn(),
10+
},
11+
};
12+
});
13+
14+
it('should return content in range with valid range header', () => {
15+
const content = 'abcdef';
16+
const req = {
17+
headers: {
18+
range: 'bytes=1-4',
19+
},
20+
};
21+
22+
const res = {
23+
setHeader: jest.fn(),
24+
};
25+
26+
const contentRes = handleRangeHeaders(context, content, req, res);
27+
expect(contentRes).toEqual('bcde');
28+
expect(res.statusCode).toEqual(206);
29+
expect(res.setHeader.mock.calls).toMatchSnapshot();
30+
});
31+
32+
it('should handle malformed range header', () => {
33+
const content = 'abcdef';
34+
const req = {
35+
headers: {
36+
range: 'abc',
37+
},
38+
};
39+
40+
const res = {
41+
setHeader: jest.fn(),
42+
};
43+
44+
const contentRes = handleRangeHeaders(context, content, req, res);
45+
expect(contentRes).toEqual('abcdef');
46+
expect(context.logger.error.mock.calls).toMatchSnapshot();
47+
expect(res.statusCode).toBeUndefined();
48+
expect(res.setHeader.mock.calls).toMatchSnapshot();
49+
});
50+
51+
it('should handle unsatisfiable range', () => {
52+
const content = 'abcdef';
53+
const req = {
54+
headers: {
55+
range: 'bytes=10-20',
56+
},
57+
};
58+
59+
const res = {
60+
setHeader: jest.fn(),
61+
};
62+
63+
const contentRes = handleRangeHeaders(context, content, req, res);
64+
expect(contentRes).toEqual('abcdef');
65+
expect(res.statusCode).toEqual(416);
66+
expect(res.setHeader.mock.calls).toMatchSnapshot();
67+
});
68+
69+
it('should handle multiple ranges', () => {
70+
const content = 'abcdef';
71+
const req = {
72+
headers: {
73+
range: 'bytes=1-2,4-5',
74+
},
75+
};
76+
77+
const res = {
78+
setHeader: jest.fn(),
79+
};
80+
81+
const contentRes = handleRangeHeaders(context, content, req, res);
82+
expect(contentRes).toEqual('abcdef');
83+
expect(context.logger.error.mock.calls).toMatchSnapshot();
84+
expect(res.statusCode).toBeUndefined();
85+
expect(res.setHeader.mock.calls).toMatchSnapshot();
86+
});
87+
});

test/utils/ready.test.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import ready from '../../src/utils/ready';
2+
3+
describe('ready', () => {
4+
it('should call callback if state is true', () => {
5+
const cb = jest.fn();
6+
const context = {
7+
state: true,
8+
stats: 'stats',
9+
};
10+
ready(context, cb);
11+
12+
expect(cb.mock.calls.length).toEqual(1);
13+
expect(cb.mock.calls[0]).toEqual(['stats']);
14+
});
15+
16+
it('should save callback and log req.url if state is false with req.url set', () => {
17+
const cb = jest.fn();
18+
const context = {
19+
state: false,
20+
stats: 'stats',
21+
logger: {
22+
info: jest.fn(),
23+
},
24+
callbacks: [],
25+
};
26+
const req = {
27+
url: 'url',
28+
};
29+
ready(context, cb, req);
30+
31+
expect(cb).not.toBeCalled();
32+
expect(context.logger.info.mock.calls.length).toEqual(1);
33+
expect(context.logger.info.mock.calls[0]).toEqual([
34+
'wait until bundle finished: url',
35+
]);
36+
expect(context.callbacks).toEqual([cb]);
37+
});
38+
39+
it('should save callback and log callback.name if state is false with req.url not set', () => {
40+
const cb = jest.fn();
41+
const context = {
42+
state: false,
43+
stats: 'stats',
44+
logger: {
45+
info: jest.fn(),
46+
},
47+
callbacks: [],
48+
};
49+
ready(context, cb);
50+
51+
expect(cb).not.toBeCalled();
52+
expect(context.logger.info.mock.calls.length).toEqual(1);
53+
// mockConstructor is the name of the jest.fn() function
54+
expect(context.logger.info.mock.calls[0]).toEqual([
55+
'wait until bundle finished: mockConstructor',
56+
]);
57+
expect(context.callbacks).toEqual([cb]);
58+
});
59+
});

0 commit comments

Comments
 (0)