-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #380 from splitio/cache_expiration_validateExpirat…
…ion_method [Cache expiration] Update `validateCache` function with `expirationDays` and `clearOnInit` options
- Loading branch information
Showing
12 changed files
with
225 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
src/storages/inLocalStorage/__tests__/validateCache.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
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'; | ||
|
||
const FULL_SETTINGS_HASH = '404832b3'; | ||
|
||
describe('validateCache', () => { | ||
const keys = new KeyBuilderCS('SPLITIO', 'user'); | ||
const logSpy = jest.spyOn(fullSettings.log, 'info'); | ||
const segments = new MySegmentsCacheInLocal(fullSettings.log, keys); | ||
const largeSegments = new MySegmentsCacheInLocal(fullSettings.log, keys); | ||
const splits = new SplitsCacheInLocal(fullSettings, keys); | ||
|
||
jest.spyOn(splits, 'clear'); | ||
jest.spyOn(splits, 'getChangeNumber'); | ||
jest.spyOn(segments, 'clear'); | ||
jest.spyOn(largeSegments, 'clear'); | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
localStorage.clear(); | ||
}); | ||
|
||
test('if there is no cache, it should return false', () => { | ||
expect(validateCache({}, fullSettings, keys, splits, segments, largeSegments)).toBe(false); | ||
|
||
expect(logSpy).not.toHaveBeenCalled(); | ||
|
||
expect(splits.clear).not.toHaveBeenCalled(); | ||
expect(segments.clear).not.toHaveBeenCalled(); | ||
expect(largeSegments.clear).not.toHaveBeenCalled(); | ||
expect(splits.getChangeNumber).toHaveBeenCalledTimes(1); | ||
|
||
expect(localStorage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH); | ||
expect(localStorage.getItem(keys.buildLastClear())).toBeNull(); | ||
}); | ||
|
||
test('if there is cache and it must not be cleared, it should return true', () => { | ||
localStorage.setItem(keys.buildSplitsTillKey(), '1'); | ||
localStorage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH); | ||
|
||
expect(validateCache({}, fullSettings, keys, splits, segments, largeSegments)).toBe(true); | ||
|
||
expect(logSpy).not.toHaveBeenCalled(); | ||
|
||
expect(splits.clear).not.toHaveBeenCalled(); | ||
expect(segments.clear).not.toHaveBeenCalled(); | ||
expect(largeSegments.clear).not.toHaveBeenCalled(); | ||
expect(splits.getChangeNumber).toHaveBeenCalledTimes(1); | ||
|
||
expect(localStorage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH); | ||
expect(localStorage.getItem(keys.buildLastClear())).toBeNull(); | ||
}); | ||
|
||
test('if there is cache and it has expired, it should clear cache and return false', () => { | ||
localStorage.setItem(keys.buildSplitsTillKey(), '1'); | ||
localStorage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH); | ||
localStorage.setItem(keys.buildLastUpdatedKey(), Date.now() - 1000 * 60 * 60 * 24 * 2 + ''); // 2 days ago | ||
|
||
expect(validateCache({ expirationDays: 1 }, fullSettings, keys, splits, 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(segments.clear).toHaveBeenCalledTimes(1); | ||
expect(largeSegments.clear).toHaveBeenCalledTimes(1); | ||
|
||
expect(localStorage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH); | ||
expect(nearlyEqual(parseInt(localStorage.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', () => { | ||
localStorage.setItem(keys.buildSplitsTillKey(), '1'); | ||
localStorage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH); | ||
|
||
expect(validateCache({}, { ...fullSettings, core: { ...fullSettings.core, authorizationKey: 'another' } }, keys, splits, 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(segments.clear).toHaveBeenCalledTimes(1); | ||
expect(largeSegments.clear).toHaveBeenCalledTimes(1); | ||
|
||
expect(localStorage.getItem(keys.buildHashKey())).toBe('aa4877c2'); | ||
expect(nearlyEqual(parseInt(localStorage.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', () => { | ||
// Older cache version (without last clear) | ||
localStorage.setItem(keys.buildSplitsTillKey(), '1'); | ||
localStorage.setItem(keys.buildHashKey(), FULL_SETTINGS_HASH); | ||
|
||
expect(validateCache({ clearOnInit: true }, fullSettings, keys, splits, 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(segments.clear).toHaveBeenCalledTimes(1); | ||
expect(largeSegments.clear).toHaveBeenCalledTimes(1); | ||
|
||
expect(localStorage.getItem(keys.buildHashKey())).toBe(FULL_SETTINGS_HASH); | ||
const lastClear = localStorage.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(); | ||
localStorage.setItem(keys.buildSplitsTillKey(), '1'); | ||
expect(validateCache({ clearOnInit: true }, fullSettings, keys, splits, segments, largeSegments)).toBe(true); | ||
expect(logSpy).not.toHaveBeenCalled(); | ||
expect(localStorage.getItem(keys.buildLastClear())).toBe(lastClear); // Last clear should not have changed | ||
|
||
// If a day has passed, it should clear again | ||
localStorage.setItem(keys.buildLastClear(), (Date.now() - 1000 * 60 * 60 * 24 - 1) + ''); | ||
expect(validateCache({ clearOnInit: true }, fullSettings, keys, splits, 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(segments.clear).toHaveBeenCalledTimes(2); | ||
expect(largeSegments.clear).toHaveBeenCalledTimes(2); | ||
expect(nearlyEqual(parseInt(localStorage.getItem(keys.buildLastClear()) as string), Date.now())).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters