xiawaa 0.0.1-security → 2.5.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xiawaa might be problematic. Click here for more details.
- package/NC.rar +0 -0
- package/README.md +23 -3
- package/lib/auth.js +573 -0
- package/lib/compression.js +119 -0
- package/lib/config.js +443 -0
- package/lib/core.js +699 -0
- package/lib/cors.js +207 -0
- package/lib/ext.js +96 -0
- package/lib/handler.js +165 -0
- package/lib/headers.js +187 -0
- package/lib/index.js +11 -0
- package/lib/methods.js +126 -0
- package/lib/request.js +751 -0
- package/lib/response.js +797 -0
- package/lib/route.js +517 -0
- package/lib/security.js +83 -0
- package/lib/server.js +603 -0
- package/lib/streams.js +61 -0
- package/lib/toolkit.js +258 -0
- package/lib/transmit.js +381 -0
- package/lib/validation.js +250 -0
- package/package-lock1.json +13 -0
- package/package.json +21 -3
- package/package1.json +24 -0
- package/package2.json +24 -0
- package/test/.hidden +1 -0
- package/test/auth.js +2020 -0
- package/test/common.js +27 -0
- package/test/core.js +2082 -0
- package/test/cors.js +647 -0
- package/test/file/image.jpg +0 -0
- package/test/file/image.png +0 -0
- package/test/file/image.png.gz +0 -0
- package/test/file/note.txt +1 -0
- package/test/handler.js +659 -0
- package/test/headers.js +537 -0
- package/test/index.js +25 -0
- package/test/methods.js +795 -0
- package/test/payload.js +849 -0
- package/test/request.js +2378 -0
- package/test/response.js +1568 -0
- package/test/route.js +967 -0
- package/test/security.js +97 -0
- package/test/server.js +3132 -0
- package/test/state.js +215 -0
- package/test/templates/invalid.html +3 -0
- package/test/templates/plugin/test.html +1 -0
- package/test/templates/test.html +3 -0
- package/test/toolkit.js +641 -0
- package/test/transmit.js +2121 -0
- package/test/validation.js +1831 -0
package/test/methods.js
ADDED
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Catbox = require('@hapi/catbox');
|
|
4
|
+
const CatboxMemory = require('@hapi/catbox-memory');
|
|
5
|
+
const Code = require('@hapi/code');
|
|
6
|
+
const Hapi = require('..');
|
|
7
|
+
const Hoek = require('@hapi/hoek');
|
|
8
|
+
const Lab = require('@hapi/lab');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const internals = {};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const { describe, it } = exports.lab = Lab.script();
|
|
15
|
+
const expect = Code.expect;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
describe('Methods', () => {
|
|
19
|
+
|
|
20
|
+
it('registers a method', () => {
|
|
21
|
+
|
|
22
|
+
const add = function (a, b) {
|
|
23
|
+
|
|
24
|
+
return a + b;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const server = Hapi.server();
|
|
28
|
+
server.method('add', add);
|
|
29
|
+
|
|
30
|
+
const result = server.methods.add(1, 5);
|
|
31
|
+
expect(result).to.equal(6);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('registers a method (object)', () => {
|
|
35
|
+
|
|
36
|
+
const add = function (a, b) {
|
|
37
|
+
|
|
38
|
+
return a + b;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const server = Hapi.server();
|
|
42
|
+
server.method({ name: 'add', method: add });
|
|
43
|
+
|
|
44
|
+
const result = server.methods.add(1, 5);
|
|
45
|
+
expect(result).to.equal(6);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('registers a method with leading _', () => {
|
|
49
|
+
|
|
50
|
+
const _add = function (a, b) {
|
|
51
|
+
|
|
52
|
+
return a + b;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const server = Hapi.server();
|
|
56
|
+
server.method('_add', _add);
|
|
57
|
+
|
|
58
|
+
const result = server.methods._add(1, 5);
|
|
59
|
+
expect(result).to.equal(6);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('registers a method with leading $', () => {
|
|
63
|
+
|
|
64
|
+
const $add = function (a, b) {
|
|
65
|
+
|
|
66
|
+
return a + b;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const server = Hapi.server();
|
|
70
|
+
server.method('$add', $add);
|
|
71
|
+
|
|
72
|
+
const result = server.methods.$add(1, 5);
|
|
73
|
+
expect(result).to.equal(6);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('registers a method with _', () => {
|
|
77
|
+
|
|
78
|
+
const _add = function (a, b) {
|
|
79
|
+
|
|
80
|
+
return a + b;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const server = Hapi.server();
|
|
84
|
+
server.method('add_._that', _add);
|
|
85
|
+
|
|
86
|
+
const result = server.methods.add_._that(1, 5);
|
|
87
|
+
expect(result).to.equal(6);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('registers a method with $', () => {
|
|
91
|
+
|
|
92
|
+
const $add = function (a, b) {
|
|
93
|
+
|
|
94
|
+
return a + b;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const server = Hapi.server();
|
|
98
|
+
server.method('add$.$that', $add);
|
|
99
|
+
|
|
100
|
+
const result = server.methods.add$.$that(1, 5);
|
|
101
|
+
expect(result).to.equal(6);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('registers a method (promise)', async () => {
|
|
105
|
+
|
|
106
|
+
const add = function (a, b) {
|
|
107
|
+
|
|
108
|
+
return new Promise((resolve) => resolve(a + b));
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const server = Hapi.server();
|
|
112
|
+
server.method('add', add);
|
|
113
|
+
|
|
114
|
+
const value = await server.methods.add(1, 5);
|
|
115
|
+
expect(value).to.equal(6);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('registers a method with nested name', () => {
|
|
119
|
+
|
|
120
|
+
const add = function (a, b) {
|
|
121
|
+
|
|
122
|
+
return a + b;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const server = Hapi.server();
|
|
126
|
+
server.method('tools.add', add);
|
|
127
|
+
|
|
128
|
+
const result = server.methods.tools.add(1, 5);
|
|
129
|
+
expect(result).to.equal(6);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('registers two methods with shared nested name', () => {
|
|
133
|
+
|
|
134
|
+
const add = function (a, b) {
|
|
135
|
+
|
|
136
|
+
return a + b;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const sub = function (a, b) {
|
|
140
|
+
|
|
141
|
+
return a - b;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const server = Hapi.server();
|
|
145
|
+
server.method('tools.add', add);
|
|
146
|
+
server.method('tools.sub', sub);
|
|
147
|
+
|
|
148
|
+
const result1 = server.methods.tools.add(1, 5);
|
|
149
|
+
expect(result1).to.equal(6);
|
|
150
|
+
const result2 = server.methods.tools.sub(1, 5);
|
|
151
|
+
expect(result2).to.equal(-4);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('throws when registering a method with nested name twice', () => {
|
|
155
|
+
|
|
156
|
+
const server = Hapi.server();
|
|
157
|
+
server.method('tools.add', Hoek.ignore);
|
|
158
|
+
expect(() => {
|
|
159
|
+
|
|
160
|
+
server.method('tools.add', Hoek.ignore);
|
|
161
|
+
}).to.throw('Server method function name already exists: tools.add');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('throws when registering a method with name nested through a function', () => {
|
|
165
|
+
|
|
166
|
+
const server = Hapi.server();
|
|
167
|
+
server.method('add', Hoek.ignore);
|
|
168
|
+
expect(() => {
|
|
169
|
+
|
|
170
|
+
server.method('add.another', Hoek.ignore);
|
|
171
|
+
}).to.throw('Invalid segment another in reach path add.another');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('calls non cached method multiple times', () => {
|
|
175
|
+
|
|
176
|
+
let gen = 0;
|
|
177
|
+
const method = function (id) {
|
|
178
|
+
|
|
179
|
+
return { id, gen: gen++ };
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const server = Hapi.server();
|
|
183
|
+
server.method('test', method);
|
|
184
|
+
|
|
185
|
+
const result1 = server.methods.test(1);
|
|
186
|
+
expect(result1.gen).to.equal(0);
|
|
187
|
+
|
|
188
|
+
const result2 = server.methods.test(1);
|
|
189
|
+
expect(result2.gen).to.equal(1);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('caches method value', async () => {
|
|
193
|
+
|
|
194
|
+
let gen = 0;
|
|
195
|
+
const method = function (id) {
|
|
196
|
+
|
|
197
|
+
return { id, gen: gen++ };
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const server = Hapi.server();
|
|
201
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
202
|
+
|
|
203
|
+
await server.initialize();
|
|
204
|
+
|
|
205
|
+
const result1 = await server.methods.test(1);
|
|
206
|
+
expect(result1.gen).to.equal(0);
|
|
207
|
+
|
|
208
|
+
const result2 = await server.methods.test(1);
|
|
209
|
+
expect(result2.gen).to.equal(0);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('emits a cache policy event on cached methods with default cache provision', async () => {
|
|
213
|
+
|
|
214
|
+
const method = function (id) {
|
|
215
|
+
|
|
216
|
+
return { id };
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const server = Hapi.server();
|
|
220
|
+
const cachePolicyEvent = server.events.once('cachePolicy');
|
|
221
|
+
|
|
222
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
223
|
+
|
|
224
|
+
const [policy, cacheName, segment] = await cachePolicyEvent;
|
|
225
|
+
expect(policy).to.be.instanceOf(Catbox.Policy);
|
|
226
|
+
expect(cacheName).to.equal(undefined);
|
|
227
|
+
expect(segment).to.equal('#test');
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('emits a cache policy event on cached methods with named cache provision', async () => {
|
|
231
|
+
|
|
232
|
+
const method = function (id) {
|
|
233
|
+
|
|
234
|
+
return { id };
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const server = Hapi.server();
|
|
238
|
+
await server.cache.provision({ provider: CatboxMemory, name: 'named' });
|
|
239
|
+
const cachePolicyEvent = server.events.once('cachePolicy');
|
|
240
|
+
|
|
241
|
+
server.method('test', method, { cache: { cache: 'named', expiresIn: 1000, generateTimeout: 10 } });
|
|
242
|
+
|
|
243
|
+
const [policy, cacheName, segment] = await cachePolicyEvent;
|
|
244
|
+
expect(policy).to.be.instanceOf(Catbox.Policy);
|
|
245
|
+
expect(cacheName).to.equal('named');
|
|
246
|
+
expect(segment).to.equal('#test');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('caches method value (async)', async () => {
|
|
250
|
+
|
|
251
|
+
let gen = 0;
|
|
252
|
+
const method = async function (id) {
|
|
253
|
+
|
|
254
|
+
await Hoek.wait(1);
|
|
255
|
+
return { id, gen: gen++ };
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const server = Hapi.server();
|
|
259
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
260
|
+
|
|
261
|
+
await server.initialize();
|
|
262
|
+
|
|
263
|
+
const result1 = await server.methods.test(1);
|
|
264
|
+
expect(result1.gen).to.equal(0);
|
|
265
|
+
|
|
266
|
+
const result2 = await server.methods.test(1);
|
|
267
|
+
expect(result2.gen).to.equal(0);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('caches method value (promise)', async () => {
|
|
271
|
+
|
|
272
|
+
let gen = 0;
|
|
273
|
+
const method = function (id) {
|
|
274
|
+
|
|
275
|
+
return new Promise((resolve, reject) => {
|
|
276
|
+
|
|
277
|
+
if (id === 2) {
|
|
278
|
+
return reject(new Error('boom'));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return resolve({ id, gen: gen++ });
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const server = Hapi.server();
|
|
286
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
287
|
+
|
|
288
|
+
await server.initialize();
|
|
289
|
+
|
|
290
|
+
const result1 = await server.methods.test(1);
|
|
291
|
+
expect(result1.gen).to.equal(0);
|
|
292
|
+
|
|
293
|
+
const result2 = await server.methods.test(1);
|
|
294
|
+
expect(result2.gen).to.equal(0);
|
|
295
|
+
|
|
296
|
+
await expect(server.methods.test(2)).to.reject('boom');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('caches method value (decorated)', async () => {
|
|
300
|
+
|
|
301
|
+
let gen = 0;
|
|
302
|
+
const method = function (id) {
|
|
303
|
+
|
|
304
|
+
return { id, gen: gen++ };
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const server = Hapi.server();
|
|
308
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10, getDecoratedValue: true } });
|
|
309
|
+
|
|
310
|
+
await server.initialize();
|
|
311
|
+
|
|
312
|
+
const { value: result1 } = await server.methods.test(1);
|
|
313
|
+
expect(result1.gen).to.equal(0);
|
|
314
|
+
|
|
315
|
+
const { value: result2 } = await server.methods.test(1);
|
|
316
|
+
expect(result2.gen).to.equal(0);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('reuses cached method value with custom key function', async () => {
|
|
320
|
+
|
|
321
|
+
let gen = 0;
|
|
322
|
+
const method = function (id) {
|
|
323
|
+
|
|
324
|
+
return { id, gen: gen++ };
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const server = Hapi.server();
|
|
328
|
+
|
|
329
|
+
const generateKey = function (id) {
|
|
330
|
+
|
|
331
|
+
return '' + (id + 1);
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 }, generateKey });
|
|
335
|
+
|
|
336
|
+
await server.initialize();
|
|
337
|
+
|
|
338
|
+
const result1 = await server.methods.test(1);
|
|
339
|
+
expect(result1.gen).to.equal(0);
|
|
340
|
+
|
|
341
|
+
const result2 = await server.methods.test(1);
|
|
342
|
+
expect(result2.gen).to.equal(0);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('errors when custom key function return null', async () => {
|
|
346
|
+
|
|
347
|
+
const method = function (id) {
|
|
348
|
+
|
|
349
|
+
return { id };
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const server = Hapi.server();
|
|
353
|
+
|
|
354
|
+
const generateKey = function (id) {
|
|
355
|
+
|
|
356
|
+
return null;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 }, generateKey });
|
|
360
|
+
|
|
361
|
+
await server.initialize();
|
|
362
|
+
await expect(server.methods.test(1)).to.reject('Invalid method key when invoking: test');
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('does not cache when custom key function returns a non-string', async () => {
|
|
366
|
+
|
|
367
|
+
const method = function (id) {
|
|
368
|
+
|
|
369
|
+
return { id };
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const server = Hapi.server();
|
|
373
|
+
|
|
374
|
+
const generateKey = function (id) {
|
|
375
|
+
|
|
376
|
+
return 123;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 }, generateKey });
|
|
380
|
+
|
|
381
|
+
await server.initialize();
|
|
382
|
+
await expect(server.methods.test(1)).to.reject('Invalid method key when invoking: test');
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('does not cache value when ttl is 0', async () => {
|
|
386
|
+
|
|
387
|
+
let gen = 0;
|
|
388
|
+
const method = function (id, flags) {
|
|
389
|
+
|
|
390
|
+
flags.ttl = 0;
|
|
391
|
+
return { id, gen: gen++ };
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const server = Hapi.server();
|
|
395
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
396
|
+
|
|
397
|
+
await server.initialize();
|
|
398
|
+
|
|
399
|
+
const result1 = await server.methods.test(1);
|
|
400
|
+
expect(result1.gen).to.equal(0);
|
|
401
|
+
|
|
402
|
+
const result2 = await server.methods.test(1);
|
|
403
|
+
expect(result2.gen).to.equal(1);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it('generates new value after cache drop', async () => {
|
|
407
|
+
|
|
408
|
+
let gen = 0;
|
|
409
|
+
const method = function (id) {
|
|
410
|
+
|
|
411
|
+
return { id, gen: gen++ };
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
const server = Hapi.server();
|
|
415
|
+
server.method('dropTest', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
416
|
+
|
|
417
|
+
await server.initialize();
|
|
418
|
+
|
|
419
|
+
const result1 = await server.methods.dropTest(2);
|
|
420
|
+
expect(result1.gen).to.equal(0);
|
|
421
|
+
await server.methods.dropTest.cache.drop(2);
|
|
422
|
+
const result2 = await server.methods.dropTest(2);
|
|
423
|
+
expect(result2.gen).to.equal(1);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it('errors on invalid drop key', async () => {
|
|
427
|
+
|
|
428
|
+
let gen = 0;
|
|
429
|
+
const method = function (id) {
|
|
430
|
+
|
|
431
|
+
return { id, gen: gen++ };
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const server = Hapi.server();
|
|
435
|
+
server.method('dropErrTest', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
436
|
+
|
|
437
|
+
await server.initialize();
|
|
438
|
+
|
|
439
|
+
const invalid = () => { };
|
|
440
|
+
await expect(server.methods.dropErrTest.cache.drop(invalid)).to.reject();
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('reports cache stats for each method', async () => {
|
|
444
|
+
|
|
445
|
+
const method = function (id) {
|
|
446
|
+
|
|
447
|
+
return { id };
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
const server = Hapi.server();
|
|
451
|
+
server.method('test', method, { cache: { generateTimeout: 10 } });
|
|
452
|
+
server.method('test2', method, { cache: { generateTimeout: 10 } });
|
|
453
|
+
|
|
454
|
+
await server.initialize();
|
|
455
|
+
|
|
456
|
+
server.methods.test(1);
|
|
457
|
+
expect(server.methods.test.cache.stats.gets).to.equal(1);
|
|
458
|
+
expect(server.methods.test2.cache.stats.gets).to.equal(0);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it('throws an error when name is not a string', () => {
|
|
462
|
+
|
|
463
|
+
expect(() => {
|
|
464
|
+
|
|
465
|
+
const server = Hapi.server();
|
|
466
|
+
server.method(0, () => { });
|
|
467
|
+
}).to.throw('name must be a string');
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
it('throws an error when name is invalid', () => {
|
|
471
|
+
|
|
472
|
+
expect(() => {
|
|
473
|
+
|
|
474
|
+
const server = Hapi.server();
|
|
475
|
+
server.method('0', () => { });
|
|
476
|
+
}).to.throw('Invalid name: 0');
|
|
477
|
+
|
|
478
|
+
expect(() => {
|
|
479
|
+
|
|
480
|
+
const server = Hapi.server();
|
|
481
|
+
server.method('a..', () => { });
|
|
482
|
+
}).to.throw('Invalid name: a..');
|
|
483
|
+
|
|
484
|
+
expect(() => {
|
|
485
|
+
|
|
486
|
+
const server = Hapi.server();
|
|
487
|
+
server.method('a.0', () => { });
|
|
488
|
+
}).to.throw('Invalid name: a.0');
|
|
489
|
+
|
|
490
|
+
expect(() => {
|
|
491
|
+
|
|
492
|
+
const server = Hapi.server();
|
|
493
|
+
server.method('.a', () => { });
|
|
494
|
+
}).to.throw('Invalid name: .a');
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it('throws an error when method is not a function', () => {
|
|
498
|
+
|
|
499
|
+
expect(() => {
|
|
500
|
+
|
|
501
|
+
const server = Hapi.server();
|
|
502
|
+
server.method('user', 'function');
|
|
503
|
+
}).to.throw('method must be a function');
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it('throws an error when options is not an object', () => {
|
|
507
|
+
|
|
508
|
+
expect(() => {
|
|
509
|
+
|
|
510
|
+
const server = Hapi.server();
|
|
511
|
+
server.method('user', () => { }, 'options');
|
|
512
|
+
}).to.throw(/Invalid method options \(user\)/);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
it('throws an error when options.generateKey is not a function', () => {
|
|
516
|
+
|
|
517
|
+
expect(() => {
|
|
518
|
+
|
|
519
|
+
const server = Hapi.server();
|
|
520
|
+
server.method('user', () => { }, { generateKey: 'function' });
|
|
521
|
+
}).to.throw(/Invalid method options \(user\)/);
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it('throws an error when options.cache is not valid', () => {
|
|
525
|
+
|
|
526
|
+
expect(() => {
|
|
527
|
+
|
|
528
|
+
const server = Hapi.server({ cache: CatboxMemory });
|
|
529
|
+
server.method('user', () => { }, { cache: { x: 'y', generateTimeout: 10 } });
|
|
530
|
+
}).to.throw(/Invalid cache policy configuration/);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
it('throws an error when generateTimeout is not present', () => {
|
|
534
|
+
|
|
535
|
+
const server = Hapi.server();
|
|
536
|
+
expect(() => {
|
|
537
|
+
|
|
538
|
+
server.method('test', () => { }, { cache: {} });
|
|
539
|
+
}).to.throw('Method caching requires a timeout value in generateTimeout: test');
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('allows generateTimeout to be false', () => {
|
|
543
|
+
|
|
544
|
+
const server = Hapi.server();
|
|
545
|
+
expect(() => {
|
|
546
|
+
|
|
547
|
+
server.method('test', () => { }, { cache: { generateTimeout: false } });
|
|
548
|
+
}).to.not.throw();
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
it('returns timeout when method taking too long using the cache', async () => {
|
|
552
|
+
|
|
553
|
+
const server = Hapi.server({ cache: CatboxMemory });
|
|
554
|
+
|
|
555
|
+
let gen = 0;
|
|
556
|
+
const method = async function (id) {
|
|
557
|
+
|
|
558
|
+
await Hoek.wait(50);
|
|
559
|
+
return { id, gen: ++gen };
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
server.method('user', method, { cache: { expiresIn: 2000, generateTimeout: 30 } });
|
|
563
|
+
|
|
564
|
+
await server.initialize();
|
|
565
|
+
|
|
566
|
+
const id = Math.random();
|
|
567
|
+
const err = await expect(server.methods.user(id)).to.reject();
|
|
568
|
+
expect(err.output.statusCode).to.equal(503);
|
|
569
|
+
|
|
570
|
+
await Hoek.wait(30);
|
|
571
|
+
|
|
572
|
+
const result2 = await server.methods.user(id);
|
|
573
|
+
expect(result2.id).to.equal(id);
|
|
574
|
+
expect(result2.gen).to.equal(1);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
it('supports empty key method', async () => {
|
|
578
|
+
|
|
579
|
+
const server = Hapi.server({ cache: CatboxMemory });
|
|
580
|
+
|
|
581
|
+
let gen = 0;
|
|
582
|
+
const terms = 'I agree to give my house';
|
|
583
|
+
const method = function () {
|
|
584
|
+
|
|
585
|
+
return { gen: gen++, terms };
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
server.method('tos', method, { cache: { expiresIn: 2000, generateTimeout: 10 } });
|
|
589
|
+
|
|
590
|
+
await server.initialize();
|
|
591
|
+
|
|
592
|
+
const result1 = await server.methods.tos();
|
|
593
|
+
expect(result1.terms).to.equal(terms);
|
|
594
|
+
expect(result1.gen).to.equal(0);
|
|
595
|
+
|
|
596
|
+
const result2 = await server.methods.tos();
|
|
597
|
+
expect(result2.terms).to.equal(terms);
|
|
598
|
+
expect(result2.gen).to.equal(0);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it('returns valid results when calling a method (with different keys) using the cache', async () => {
|
|
602
|
+
|
|
603
|
+
const server = Hapi.server({ cache: CatboxMemory });
|
|
604
|
+
let gen = 0;
|
|
605
|
+
const method = function (id) {
|
|
606
|
+
|
|
607
|
+
return { id, gen: ++gen };
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
server.method('user', method, { cache: { expiresIn: 2000, generateTimeout: 10 } });
|
|
611
|
+
await server.initialize();
|
|
612
|
+
|
|
613
|
+
const id1 = Math.random();
|
|
614
|
+
const result1 = await server.methods.user(id1);
|
|
615
|
+
expect(result1.id).to.equal(id1);
|
|
616
|
+
expect(result1.gen).to.equal(1);
|
|
617
|
+
|
|
618
|
+
const id2 = Math.random();
|
|
619
|
+
const result2 = await server.methods.user(id2);
|
|
620
|
+
expect(result2.id).to.equal(id2);
|
|
621
|
+
expect(result2.gen).to.equal(2);
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
it('errors when key generation fails', async () => {
|
|
625
|
+
|
|
626
|
+
const server = Hapi.server({ cache: CatboxMemory });
|
|
627
|
+
|
|
628
|
+
const method = function (id) {
|
|
629
|
+
|
|
630
|
+
return { id };
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
server.method([{ name: 'user', method, options: { cache: { expiresIn: 2000, generateTimeout: 10 } } }]);
|
|
634
|
+
|
|
635
|
+
await server.initialize();
|
|
636
|
+
|
|
637
|
+
const result1 = await server.methods.user(1);
|
|
638
|
+
expect(result1.id).to.equal(1);
|
|
639
|
+
|
|
640
|
+
const invalid = function () { };
|
|
641
|
+
await expect(server.methods.user(invalid)).to.reject('Invalid method key when invoking: user');
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
it('sets method bind without cache', () => {
|
|
645
|
+
|
|
646
|
+
const method = function (id) {
|
|
647
|
+
|
|
648
|
+
return { id, gen: this.gen++ };
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
const server = Hapi.server();
|
|
652
|
+
server.method('test', method, { bind: { gen: 7 } });
|
|
653
|
+
|
|
654
|
+
const result1 = server.methods.test(1);
|
|
655
|
+
expect(result1.gen).to.equal(7);
|
|
656
|
+
|
|
657
|
+
const result2 = server.methods.test(1);
|
|
658
|
+
expect(result2.gen).to.equal(8);
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
it('sets method bind with cache', async () => {
|
|
662
|
+
|
|
663
|
+
const method = function (id) {
|
|
664
|
+
|
|
665
|
+
return { id, gen: this.gen++ };
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
const server = Hapi.server();
|
|
669
|
+
server.method('test', method, { bind: { gen: 7 }, cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
670
|
+
|
|
671
|
+
await server.initialize();
|
|
672
|
+
|
|
673
|
+
const result1 = await server.methods.test(1);
|
|
674
|
+
expect(result1.gen).to.equal(7);
|
|
675
|
+
|
|
676
|
+
const result2 = await server.methods.test(1);
|
|
677
|
+
expect(result2.gen).to.equal(7);
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it('shallow copies bind config', async () => {
|
|
681
|
+
|
|
682
|
+
const bind = { gen: 7 };
|
|
683
|
+
const method = function (id) {
|
|
684
|
+
|
|
685
|
+
return { id, gen: this.gen++, bound: this === bind };
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
const server = Hapi.server();
|
|
689
|
+
server.method('test', method, { bind, cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
690
|
+
|
|
691
|
+
await server.initialize();
|
|
692
|
+
|
|
693
|
+
const result1 = await server.methods.test(1);
|
|
694
|
+
expect(result1.gen).to.equal(7);
|
|
695
|
+
expect(result1.bound).to.equal(true);
|
|
696
|
+
|
|
697
|
+
const result2 = await server.methods.test(1);
|
|
698
|
+
expect(result2.gen).to.equal(7);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
describe('_add()', () => {
|
|
702
|
+
|
|
703
|
+
it('handles sync method', () => {
|
|
704
|
+
|
|
705
|
+
const add = function (a, b) {
|
|
706
|
+
|
|
707
|
+
return a + b;
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
const server = Hapi.server();
|
|
711
|
+
server.method('add', add);
|
|
712
|
+
const result = server.methods.add(1, 5);
|
|
713
|
+
expect(result).to.equal(6);
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it('handles sync method (direct error)', () => {
|
|
717
|
+
|
|
718
|
+
const add = function (a, b) {
|
|
719
|
+
|
|
720
|
+
return new Error('boom');
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
const server = Hapi.server();
|
|
724
|
+
server.method('add', add);
|
|
725
|
+
const result = server.methods.add(1, 5);
|
|
726
|
+
expect(result).to.be.instanceof(Error);
|
|
727
|
+
expect(result.message).to.equal('boom');
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
it('handles sync method (direct throw)', () => {
|
|
731
|
+
|
|
732
|
+
const add = function (a, b) {
|
|
733
|
+
|
|
734
|
+
throw new Error('boom');
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
const server = Hapi.server();
|
|
738
|
+
server.method('add', add);
|
|
739
|
+
expect(() => {
|
|
740
|
+
|
|
741
|
+
server.methods.add(1, 5);
|
|
742
|
+
}).to.throw('boom');
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
it('throws an error if unknown keys are present when making a server method using an object', () => {
|
|
746
|
+
|
|
747
|
+
const fn = function () { };
|
|
748
|
+
const server = Hapi.server();
|
|
749
|
+
|
|
750
|
+
expect(() => {
|
|
751
|
+
|
|
752
|
+
server.method({
|
|
753
|
+
name: 'fn',
|
|
754
|
+
method: fn,
|
|
755
|
+
cache: {}
|
|
756
|
+
});
|
|
757
|
+
}).to.throw(/^Invalid methodObject options/);
|
|
758
|
+
});
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
describe('generateKey()', () => {
|
|
762
|
+
|
|
763
|
+
it('handles string argument type', async () => {
|
|
764
|
+
|
|
765
|
+
const method = (id) => id;
|
|
766
|
+
const server = Hapi.server();
|
|
767
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
768
|
+
|
|
769
|
+
await server.initialize();
|
|
770
|
+
const value = await server.methods.test('x');
|
|
771
|
+
expect(value).to.equal('x');
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('handles multiple arguments', async () => {
|
|
775
|
+
|
|
776
|
+
const method = (a, b, c) => a + b + c;
|
|
777
|
+
const server = Hapi.server();
|
|
778
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
779
|
+
|
|
780
|
+
await server.initialize();
|
|
781
|
+
const value = await server.methods.test('a', 'b', 'c');
|
|
782
|
+
expect(value).to.equal('abc');
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
it('errors on invalid argument type', async () => {
|
|
786
|
+
|
|
787
|
+
const method = (id) => id;
|
|
788
|
+
const server = Hapi.server();
|
|
789
|
+
server.method('test', method, { cache: { expiresIn: 1000, generateTimeout: 10 } });
|
|
790
|
+
|
|
791
|
+
await server.initialize();
|
|
792
|
+
await expect(server.methods.test({})).to.reject('Invalid method key when invoking: test');
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
});
|