-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.asyncCache.spec.ts
More file actions
116 lines (90 loc) · 4.82 KB
/
index.asyncCache.spec.ts
File metadata and controls
116 lines (90 loc) · 4.82 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import splitObject from './mocks/input.json';
import splitView from './mocks/output.json';
import { sdkManagerFactory } from '../index';
import { SplitsCacheInRedis } from '../../storages/inRedis/SplitsCacheInRedis';
import { SplitsCachePluggable } from '../../storages/pluggable/SplitsCachePluggable';
import { wrapperAdapter } from '../../storages/pluggable/wrapperAdapter';
import { KeyBuilderSS } from '../../storages/KeyBuilderSS';
import { ISdkReadinessManager } from '../../readiness/types';
import { loggerMock } from '../../logger/__tests__/sdkLogger.mock';
import { metadata } from '../../storages/__tests__/KeyBuilder.spec';
import { RedisAdapter } from '../../storages/inRedis/RedisAdapter';
import SplitIO from '../../../types/splitio';
// @ts-expect-error
const sdkReadinessManagerMock = {
readinessManager: {
isReady: jest.fn(() => true),
isDestroyed: jest.fn(() => false)
},
sdkStatus: jest.fn()
} as ISdkReadinessManager;
const keys = new KeyBuilderSS('prefix', metadata);
describe('Manager with async cache', () => {
afterEach(() => { loggerMock.mockClear(); });
test('returns the expected data from the cache', async () => {
/** Setup: create manager */
const connection = new RedisAdapter(loggerMock);
const cache = new SplitsCacheInRedis(loggerMock, keys, connection);
const manager = sdkManagerFactory({ mode: 'consumer', log: loggerMock }, cache, sdkReadinessManagerMock);
await cache.clear();
await cache.addSplit(splitObject as any);
/** List all splits */
const views = await manager.splits();
expect(views[0]).toEqual(splitView);
/** Read only one split by name */
const split = await manager.split(splitObject.name);
expect(split).toEqual(splitView);
/** List all the split names */
const names = await manager.names();
expect(names.indexOf(splitObject.name) !== -1).toBe(true);
/** Input Validation */
// control assertions to verify that the manager is connected with that cache.
expect((await manager.split(splitObject.name)) != null).toBe(true); // control assertion for split.
expect((await manager.splits()).length > 0).toBe(true); // control assertion for splits.
expect((await manager.names()).length > 0).toBe(true); // control assertion for names.
// @ts-expect-error
expect(await manager.split(undefined)).toBe(null); // If the split name is invalid, `manager.split(invalidName)` returns null.
// This is kind of tied to the implementation of the isOperational validator.
(sdkReadinessManagerMock.readinessManager.isDestroyed as jest.Mock).mockImplementation(() => true);
expect(await manager.split(splitObject.name)).toBe(null); // If the factory/client is destroyed, `manager.split(validName)` will return null either way since the storage is not valid.
expect(await manager.splits()).toEqual([]); // If the factory/client is destroyed, `manager.splits()` will return empty array either way since the storage is not valid.
expect(await manager.names()).toEqual([]); // If the factory/client is destroyed, `manager.names()` will return empty array either way since the storage is not valid.
/** Teardown */
await cache.removeSplit(splitObject.name);
await connection.disconnect();
});
test('handles storage errors', async () => {
// passing an empty object as wrapper, to make method calls of splits cache fail returning a rejected promise.
// @ts-expect-error
const cache = new SplitsCachePluggable(loggerMock, keys, wrapperAdapter(loggerMock, {}));
const manager = sdkManagerFactory({ mode: 'consumer_partial', log: loggerMock }, cache, sdkReadinessManagerMock);
expect(await manager.split('some_spplit')).toEqual(null);
expect(await manager.splits()).toEqual([]);
expect(await manager.names()).toEqual([]);
expect(loggerMock.error).toBeCalledTimes(3); // 3 error logs, one for each attempt to call a wrapper method
});
test('returns empty results when not operational', async () => {
// SDK is flagged as destroyed
const sdkReadinessManagerMock = {
readinessManager: {
isReady: () => true,
isReadyFromCache: () => true,
isDestroyed: () => true
},
sdkStatus: {}
};
// @ts-expect-error
const manager = sdkManagerFactory({ mode: 'consumer_partial', log: loggerMock }, {}, sdkReadinessManagerMock) as SplitIO.IAsyncManager;
function validateManager() {
expect(manager.split('some_spplit')).resolves.toBe(null);
expect(manager.splits()).resolves.toEqual([]);
expect(manager.names()).resolves.toEqual([]);
}
validateManager();
// SDK is not ready
sdkReadinessManagerMock.readinessManager.isReady = () => false;
sdkReadinessManagerMock.readinessManager.isReadyFromCache = () => false;
sdkReadinessManagerMock.readinessManager.isDestroyed = () => false;
validateManager();
});
});