4b10d38965777c2372a4dadbc2fcd446d6af1e75
1 /* eslint-disable capitalized-comments */
5 const assert
= require('assert');
6 const sinon
= require('sinon'); // eslint-disable-line node/no-unpublished-require
7 const common
= require('../../lib/common');
10 describe('common', function () {
12 describe('generateETag', function () {
13 it('generates a tag from data', function () {
14 const expected
= '"RHUvNyculE/SyROjU0LqzN0arxibrlBnazAashP8UGE"';
15 const data
= 'example data';
16 const result
= common
.generateETag(undefined, undefined, data
);
17 assert
.strictEqual(result
, expected
);
19 it('generates a tag from data and stats', function () {
20 const expected
= '"mtI0qCyqXsZVfX0Pgi+G6mQM10y9yVyi1NZejXSYttk"';
22 mtimeMs: 1600113038270.2375,
24 const data
= 'example data';
25 const result
= common
.generateETag(undefined, stat
, data
);
26 assert
.strictEqual(result
, expected
);
30 describe('get', function () {
31 const def
= 'default';
32 it('covers missing obj', function () {
33 const result
= common
.get(undefined, undefined, def
);
34 assert
.strictEqual(result
, def
);
36 it('covers missing prop', function () {
37 const result
= common
.get({}, undefined, def
);
38 assert
.strictEqual(result
, def
);
40 it('covers default', function () {
41 const result
= common
.get({ k: 'v' }, 'x', def
);
42 assert
.strictEqual(result
, def
);
44 it('covers prop', function () {
45 const result
= common
.get({ k: 'v' }, 'k', def
);
46 assert
.strictEqual(result
, 'v');
50 describe('isClientCached', function () {
51 let req
, modifiedTimeMs
, eTag
;
52 const blueMoon
= 'Sat, 31 Oct 2020 07:51:00 GMT';
53 const blueMoonMs
= 1604130660000;
54 const oneDayMs
= 86400000;
55 const anotherETag
= '"RHUvNyculE/SyROjU0LqzN0arxibrlBnazAashP8UGE"';
56 beforeEach(function () {
58 getHeader: sinon
.stub(),
61 eTag
= '"mtI0qCyqXsZVfX0Pgi+G6mQM10y9yVyi1NZejXSYttk"';
63 it('no headers, not cached', function () {
64 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
65 assert
.strictEqual(result
, false);
67 it('modified header, not cached', function () {
68 req
.getHeader
.onCall(0).returns(blueMoon
);
69 modifiedTimeMs
= blueMoonMs
+ oneDayMs
;
70 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
71 assert
.strictEqual(result
, false);
73 it('modified header, cached', function () {
74 req
.getHeader
.onCall(0).returns(blueMoon
);
75 modifiedTimeMs
= blueMoonMs
- oneDayMs
;
76 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
77 assert
.strictEqual(result
, true);
79 it('match header, not matched', function () {
80 req
.getHeader
.onCall(1).returns(anotherETag
);
81 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
82 assert
.strictEqual(result
, false);
84 it('match header, matched', function () {
85 req
.getHeader
.onCall(1).returns(`${anotherETag}, ${eTag}, ${anotherETag}`);
86 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
87 assert
.strictEqual(result
, true);
89 it('match header any, matched', function () {
90 req
.getHeader
.onCall(1).returns('*');
91 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
92 assert
.strictEqual(result
, true);
94 it('modified header cached, match header not matched, not cached', function () {
95 req
.getHeader
.onCall(0).returns(blueMoon
);
96 modifiedTimeMs
= blueMoonMs
- oneDayMs
;
97 req
.getHeader
.onCall(1).returns(`${anotherETag}, ${anotherETag}`);
98 const result
= common
.isClientCached(req
, modifiedTimeMs
, eTag
);
99 assert
.strictEqual(result
, false);
101 }); // iscClientCached
103 describe('pick', function () {
104 it('picks', function () {
110 const result
= common
.pick(srcObj
, ['a', 'c', 'd']);
111 assert
.deepStrictEqual(result
, {
118 describe('setOptions', function () {
119 it('sets options', function () {
126 const defaultOptions
= {
135 common
.setOptions(target
, defaultOptions
, options
);
136 assert
.deepStrictEqual(target
, expected
);
140 describe('splitFirst', function () {
141 it('splits', function () {
142 const expected
= ['foo', 'awoo'];
143 const src
= 'foo?awoo';
146 const result
= common
.splitFirst(src
, delim
, fill
);
147 assert
.deepStrictEqual(result
, expected
);
149 it('fills', function () {
150 const expected
= ['foo', 'fill'];
154 const result
= common
.splitFirst(src
, delim
, fill
);
155 assert
.deepStrictEqual(result
, expected
);
159 describe('mergeEnum', function () {
160 it('merges enums', function () {
163 TextHTML: 'text/html',
168 errorMessage: 'Bad Request',
174 TextPlain: 'text/plain',
179 errorMessage: 'Unauthorized',
189 TextHTML: 'text/html',
190 TextPlain: 'text/plain',
195 errorMessage: 'Bad Request',
199 errorMessage: 'Unauthorized',
207 const result
= common
.mergeEnum(origEnum
, newEnum
);
208 assert
.deepStrictEqual(result
, mergedEnum
);
212 describe('requestId', function () {
213 it('returns a string', function () {
214 const id
= common
.requestId();
215 assert
.strictEqual(typeof id
, 'string');
216 assert(id
.length
> 0);
220 describe('httpStatusCodeClass', function () {
221 it('works', function () {
222 for (const [statusCode
, statusClassExpected
] of Object
.entries({
228 const statusClass
= common
.httpStatusCodeClass(statusCode
);
229 assert
.strictEqual(statusClass
, statusClassExpected
);
232 }); // ensureLoggerLevels
234 describe('mergeDeep', function () {
235 it('simple merge', function () {
250 const result
= common
.mergeDeep(o1
, o2
, o3
);
251 assert
.deepStrictEqual(result
, expected
);
253 it('deep merge', function () {
281 myList: ['fancy', 'pants'],
292 const result
= common
.mergeDeep(o1
, o2
, o3
);
293 assert
.deepStrictEqual(result
, expected
);
295 it('merged object is distinct', function () {
314 const result
= common
.mergeDeep(o1
, o2
);
315 assert
.deepStrictEqual(result
, expected
);
326 assert
.deepStrictEqual(result
, expected2
);
327 assert
.strictEqual(o1
.foo
.bar
, 3);
328 assert
.strictEqual(o2
.baz
.quux
, 4);
332 describe('unfoldHeaderLines', function () {
333 it('folds', function () {
335 'Normal-Header: some header data',
336 'Folded-Header: more data',
337 ' second line of data',
338 ' third line of data',
341 'Normal-Header: some header data',
342 'Folded-Header: more data second line of data third line of data',
344 const result
= common
.unfoldHeaderLines(lines
);
345 assert
.deepStrictEqual(result
, expected
);
347 it('covers no input', function () {
348 const lines
= undefined;
349 const result
= common
.unfoldHeaderLines();
350 assert
.deepStrictEqual(result
, lines
);
352 }); // unfoldHeaderLines
354 describe('addCookie', function () {
355 let res
, name
, value
;
356 beforeEach(function () {
358 appendHeader: sinon
.stub(),
360 name
= 'someCookieName';
361 value
= 'someCookieValue';
363 it('covers no options', function () {
364 common
.addCookie(res
, name
, value
, {});
365 assert(res
.appendHeader
.called
);
367 it('covers all options', function () {
368 common
.addCookie(res
, name
, value
, {
369 domain: 'example.com',
377 assert(res
.appendHeader
.called
);
379 it('covers invalid expires', function () {
380 assert
.throws(() => common
.addCookie(res
, name
, value
, { expires: 'never' }), TypeError
);
382 it('covers invalid sameSite', function () {
383 assert
.throws(() => common
.addCookie(res
, name
, value
, { sameSite: 'Whatever' }));
385 it('covers no options', function () {
386 common
.addCookie(res
, name
, value
);
387 assert(res
.appendHeader
.called
);