-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathvalidateCache.spec.ts
More file actions
135 lines (104 loc) · 6.8 KB
/
Copy pathvalidateCache.spec.ts
File metadata and controls
135 lines (104 loc) · 6.8 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { validateCache } from '../validateCache';
import { KeyBuilderCS } from '../../KeyBuilderCS';
import { fullSettings } from '../../../utils/settingsValidation/__tests__/settings.mocks';
import { SplitsCacheInLocal } from '../SplitsCacheInLocal';
import { nearlyEqual } from '../../../__tests__/testUtils';
import { MySegmentsCacheInLocal } from '../MySegmentsCacheInLocal';
import { RBSegmentsCacheInLocal } from '../RBSegmentsCacheInLocal';
import { storages, PREFIX } from './wrapper.mock';
const FULL_SETTINGS_HASH = 'dc1f9817';
describe.each(storages)('validateCache', (storage) => {
const keys = new KeyBuilderCS(PREFIX, 'user');
const logSpy = jest.spyOn(fullSettings.log, 'info');
const segments = new MySegmentsCacheInLocal(fullSettings.log, keys, storage);
const largeSegments = new MySegmentsCacheInLocal(fullSettings.log, keys, storage);
const splits = new SplitsCacheInLocal(fullSettings, keys, storage);
const rbSegments = new RBSegmentsCacheInLocal(fullSettings, keys, storage);
jest.spyOn(splits, 'getChangeNumber');
jest.spyOn(splits, 'clear');
jest.spyOn(rbSegments, 'clear');
jest.spyOn(segments, 'clear');
jest.spyOn(largeSegments, 'clear');
beforeEach(() => {
jest.clearAllMocks();
for (let i = 0; i < storage.length; i++) storage.removeItem(storage.key(i) as string);
});
test('if there is no cache, it should return false', async () => {
expect(await validateCache({}, storage, fullSettings, keys, splits, rbSegments, segments, largeSegments)).toBe(false);
expect(logSpy).not.toHaveBeenCalled();
expect(splits.clear).not.toHaveBeenCalled();
expect(rbSegments.clear).not.toHaveBeenCalled();
expect(segments.clear).not.toHaveBeenCalled();
expect(largeSegments.clear).not.toHaveBeenCalled();
expect(splits.getChangeNumber).toHaveBeenCalledTimes(1);
expect(storage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH);
expect(storage.getItem(keys.buildLastClear())).toBeNull();
});
test('if there is cache and it must not be cleared, it should return true', async () => {
storage.setItem(keys.buildSplitsTillKey(), '1');
storage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH);
expect(await validateCache({}, storage, fullSettings, keys, splits, rbSegments, segments, largeSegments)).toBe(true);
expect(logSpy).not.toHaveBeenCalled();
expect(splits.clear).not.toHaveBeenCalled();
expect(rbSegments.clear).not.toHaveBeenCalled();
expect(segments.clear).not.toHaveBeenCalled();
expect(largeSegments.clear).not.toHaveBeenCalled();
expect(splits.getChangeNumber).toHaveBeenCalledTimes(1);
expect(storage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH);
expect(storage.getItem(keys.buildLastClear())).toBeNull();
});
test('if there is cache and it has expired, it should clear cache and return false', async () => {
storage.setItem(keys.buildSplitsTillKey(), '1');
storage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH);
storage.setItem(keys.buildLastUpdatedKey(), Date.now() - 1000 * 60 * 60 * 24 * 2 + ''); // 2 days ago
expect(await validateCache({ expirationDays: 1 }, storage, fullSettings, keys, splits, rbSegments, segments, largeSegments)).toBe(false);
expect(logSpy).toHaveBeenCalledWith('storage:localstorage: Cache expired more than 1 days ago. Cleaning up cache');
expect(splits.clear).toHaveBeenCalledTimes(1);
expect(rbSegments.clear).toHaveBeenCalledTimes(1);
expect(segments.clear).toHaveBeenCalledTimes(1);
expect(largeSegments.clear).toHaveBeenCalledTimes(1);
expect(storage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH);
expect(nearlyEqual(parseInt(storage.getItem(keys.buildLastClear()) as string), Date.now())).toBe(true);
});
test('if there is cache and its hash has changed, it should clear cache and return false', async () => {
storage.setItem(keys.buildSplitsTillKey(), '1');
storage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH);
expect(await validateCache({}, storage, { ...fullSettings, core: { ...fullSettings.core, authorizationKey: 'another-sdk-key' } }, keys, splits, rbSegments, segments, largeSegments)).toBe(false);
expect(logSpy).toHaveBeenCalledWith('storage:localstorage: SDK key, flags filter criteria, or flags spec version has changed. Cleaning up cache');
expect(splits.clear).toHaveBeenCalledTimes(1);
expect(rbSegments.clear).toHaveBeenCalledTimes(1);
expect(segments.clear).toHaveBeenCalledTimes(1);
expect(largeSegments.clear).toHaveBeenCalledTimes(1);
expect(storage.getItem(keys.buildHashKey())).toBe('45c6ba5d');
expect(nearlyEqual(parseInt(storage.getItem(keys.buildLastClear()) as string), Date.now())).toBe(true);
});
test('if there is cache and clearOnInit is true, it should clear cache and return false', async () => {
// Older cache version (without last clear)
storage.setItem(keys.buildSplitsTillKey(), '1');
storage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH);
expect(await validateCache({ clearOnInit: true }, storage, fullSettings, keys, splits, rbSegments, segments, largeSegments)).toBe(false);
expect(logSpy).toHaveBeenCalledWith('storage:localstorage: clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache');
expect(splits.clear).toHaveBeenCalledTimes(1);
expect(rbSegments.clear).toHaveBeenCalledTimes(1);
expect(segments.clear).toHaveBeenCalledTimes(1);
expect(largeSegments.clear).toHaveBeenCalledTimes(1);
expect(storage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH);
const lastClear = storage.getItem(keys.buildLastClear());
expect(nearlyEqual(parseInt(lastClear as string), Date.now())).toBe(true);
// If cache is cleared, it should not clear again until a day has passed
logSpy.mockClear();
storage.setItem(keys.buildSplitsTillKey(), '1');
expect(await validateCache({ clearOnInit: true }, storage, fullSettings, keys, splits, rbSegments, segments, largeSegments)).toBe(true);
expect(logSpy).not.toHaveBeenCalled();
expect(storage.getItem(keys.buildLastClear())).toBe(lastClear); // Last clear should not have changed
// If a day has passed, it should clear again
storage.setItem(keys.buildLastClear(), (Date.now() - 1000 * 60 * 60 * 24 - 1) + '');
expect(await validateCache({ clearOnInit: true }, storage, fullSettings, keys, splits, rbSegments, segments, largeSegments)).toBe(false);
expect(logSpy).toHaveBeenCalledWith('storage:localstorage: clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache');
expect(splits.clear).toHaveBeenCalledTimes(2);
expect(rbSegments.clear).toHaveBeenCalledTimes(2);
expect(segments.clear).toHaveBeenCalledTimes(2);
expect(largeSegments.clear).toHaveBeenCalledTimes(2);
expect(nearlyEqual(parseInt(storage.getItem(keys.buildLastClear()) as string), Date.now())).toBe(true);
});
});