Repository navigation
Expand file tree
/
Copy pathauthResultStore.test.js
More file actions
71 lines (64 loc) · 3.02 KB
/
Copy pathauthResultStore.test.js
File metadata and controls
71 lines (64 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const assert = require('node:assert/strict');
const test = require('node:test');
const { createAuthResultStore } = require('../../services/authResultStore');
function fixture({ failWrite = false, hitOnRead } = {}) {
const values = new Map();
const operations = [];
let reads = 0;
const store = createAuthResultStore({
dataStore: {
async set(key, value) {
operations.push(['set', key, value]);
if (failWrite) throw new Error('write failed');
values.set(key, value);
},
async get(key) {
operations.push(['get', key]);
reads++;
if (reads === hitOnRead) values.set(key, { state: key });
return values.get(key);
},
},
delay: async ms => { operations.push(['delay', ms]); },
});
return { store, values, operations };
}
test('stores formatted result then raw userinfo without changing or consuming them', async () => {
const { store, values, operations } = fixture();
await store.saveResult('s', { userInfo: '<pre>phone</pre>' }, { phone: '+12025550123' });
assert.deepEqual(operations, [
['set', 's', { userInfo: '<pre>phone</pre>' }],
['set', 's-user-info', { phone: '+12025550123' }],
]);
assert.deepEqual(values.get('s'), { userInfo: '<pre>phone</pre>' });
assert.deepEqual(await store.getUserInfo('s'), { phone: '+12025550123' });
assert.deepEqual(await store.getUserInfo('s'), { phone: '+12025550123' });
});
test('does not write userinfo after the first result write fails', async () => {
const { store, operations } = fixture({ failWrite: true });
await assert.rejects(store.saveResult('s', { state: 's' }, {}), /write failed/);
assert.deepEqual(operations, [['set', 's', { state: 's' }]]);
});
test('returns an immediate result without sleeping', async () => {
const { store, values, operations } = fixture();
values.set('s', { state: 's' });
assert.deepEqual(await store.waitForResult('s'), { state: 's' });
assert.deepEqual(operations, [['get', 's']]);
});
test('returns a delayed result after exactly two sleeps when read three succeeds', async () => {
const { store, operations } = fixture({ hitOnRead: 3 });
assert.deepEqual(await store.waitForResult('s'), { state: 's' });
assert.deepEqual(operations, [['get', 's'], ['delay', 1000], ['get', 's'], ['delay', 1000], ['get', 's']]);
});
for (const state of ['missing', undefined]) {
test(`preserves five reads and five sleeps for missing result (${state})`, async () => {
const { store, operations } = fixture();
assert.equal(await store.waitForResult(state), undefined);
assert.deepEqual(operations, Array.from({ length: 5 }, () => [['get', state || ''], ['delay', 1000]]).flat());
});
}
test('propagates cache read errors without sleeping or retrying', async () => {
const store = createAuthResultStore({ dataStore: { get: async () => { throw new Error('read failed'); } }, delay: async () => { assert.fail('unexpected delay'); } });
await assert.rejects(store.waitForResult('s'), /read failed/);
await assert.rejects(store.getUserInfo('s'), /read failed/);
});