From 3dc3638150df006358395c1bc1f5fc38f02484a6 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 25 Feb 2022 19:20:53 -0300 Subject: [PATCH] localstorage update --- src/storages/KeyBuilderCS.ts | 14 +++++++- .../inLocalStorage/MySegmentsCacheInLocal.ts | 26 +++++++++++++-- .../__tests__/MySegmentsCacheInLocal.spec.ts | 32 +++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/storages/KeyBuilderCS.ts b/src/storages/KeyBuilderCS.ts index d4f9e902..58c19fbb 100644 --- a/src/storages/KeyBuilderCS.ts +++ b/src/storages/KeyBuilderCS.ts @@ -16,10 +16,22 @@ export class KeyBuilderCS extends KeyBuilder { * @override */ buildSegmentNameKey(segmentName: string) { - return `${this.matchingKey}.${this.prefix}.segment.${segmentName}`; + return `${this.prefix}.${this.matchingKey}.segment.${segmentName}`; } extractSegmentName(builtSegmentKeyName: string) { + const prefix = `${this.prefix}.${this.matchingKey}.segment.`; + + if (startsWith(builtSegmentKeyName, prefix)) + return builtSegmentKeyName.substr(prefix.length); + } + + // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3 + buildOldSegmentNameKey(segmentName: string) { + return `${this.matchingKey}.${this.prefix}.segment.${segmentName}`; + } + // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3 + extractOldSegmentKey(builtSegmentKeyName: string) { const prefix = `${this.matchingKey}.${this.prefix}.segment.`; if (startsWith(builtSegmentKeyName, prefix)) diff --git a/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts b/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts index 7bc6690a..627d1fcf 100644 --- a/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +++ b/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts @@ -67,9 +67,29 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync { // Scan current values from localStorage const storedSegmentNames = Object.keys(localStorage).reduce((accum, key) => { - const name = this.keys.extractSegmentName(key); - - if (name) accum.push(name); + let segmentName = this.keys.extractSegmentName(key); + + if (segmentName) { + accum.push(segmentName); + } else { + // @BREAKING: This is only to clean up "old" keys. Remove this whole else code block. + segmentName = this.keys.extractOldSegmentKey(key); + + if (segmentName) { // this was an old segment key, let's clean up. + const newSegmentKey = this.keys.buildSegmentNameKey(segmentName); + try { + // If the new format key is not there, create it. + if (!localStorage.getItem(newSegmentKey) && names.indexOf(segmentName) > -1) { + localStorage.setItem(newSegmentKey, DEFINED); + // we are migrating a segment, let's track it. + accum.push(segmentName); + } + localStorage.removeItem(key); // we migrated the current key, let's delete it. + } catch (e) { + this.log.error(e); + } + } + } return accum; }, [] as string[]); diff --git a/src/storages/inLocalStorage/__tests__/MySegmentsCacheInLocal.spec.ts b/src/storages/inLocalStorage/__tests__/MySegmentsCacheInLocal.spec.ts index 36072550..67c9efcc 100644 --- a/src/storages/inLocalStorage/__tests__/MySegmentsCacheInLocal.spec.ts +++ b/src/storages/inLocalStorage/__tests__/MySegmentsCacheInLocal.spec.ts @@ -17,3 +17,35 @@ test('SEGMENT CACHE / in LocalStorage', () => { expect(cache.isInSegment('mocked-segment') === false).toBe(true); }); + +// @BREAKING: REMOVE when removing this backwards compatibility. +test('SEGMENT CACHE / in LocalStorage migration for mysegments keys', () => { + + const keys = new KeyBuilderCS('LS_BC_test.SPLITIO', 'test_nico'); + const cache = new MySegmentsCacheInLocal(loggerMock, keys); + + const oldKey1 = 'test_nico.LS_BC_test.SPLITIO.segment.segment1'; + const oldKey2 = 'test_nico.LS_BC_test.SPLITIO.segment.segment2'; + const newKey1 = keys.buildSegmentNameKey('segment1'); + const newKey2 = keys.buildSegmentNameKey('segment2'); + + cache.clear(); // cleanup before starting. + + // Not adding a full suite for LS keys now, testing here + expect(oldKey1).toBe(keys.buildOldSegmentNameKey('segment1')); + expect('segment1').toBe(keys.extractOldSegmentKey(oldKey1)); + + // add two segments, one we don't want to send on reset, should only be cleared, other one will be migrated. + localStorage.setItem(oldKey1, '1'); + localStorage.setItem(oldKey2, '1'); + expect(localStorage.getItem(newKey1)).toBe(null); // control assertion + + cache.resetSegments(['segment1']); + + expect(localStorage.getItem(newKey1)).toBe('1'); // The segment key for segment1, as is part of the new list, should be migrated. + expect(localStorage.getItem(newKey2)).toBe(null); // The segment key for segment2 should not be migrated. + expect(localStorage.getItem(oldKey1)).toBe(null); // Old keys are removed. + expect(localStorage.getItem(oldKey2)).toBe(null); // Old keys are removed. + + cache.clear(); +});