diff --git a/src/Rokt-Kit.ts b/src/Rokt-Kit.ts index 52beb8f..1d6b599 100644 --- a/src/Rokt-Kit.ts +++ b/src/Rokt-Kit.ts @@ -28,7 +28,6 @@ import { PageEvent, PAGE_VIEWS_MAX_COUNT, buildPageEvents, - migrateLegacyPageViewStorage, loadPageViews, writePageViews, clearPageViews, @@ -881,7 +880,7 @@ class RoktKit implements KitInterface { try { pageUrl = sanitizeUrl(window.location.href); - const pageViews = loadPageViews(this.loggingService); + const pageViews = loadPageViews(); const pageView = buildPageEvent(event); pageViews.push(pageView); @@ -1263,7 +1262,6 @@ class RoktKit implements KitInterface { } if (event.EventDataType === MESSAGE_TYPE_SESSION_END) { - migrateLegacyPageViewStorage(this.loggingService); clearPageViews(); } } @@ -1483,7 +1481,7 @@ class RoktKit implements KitInterface { const filteredUserIdentities = this.returnUserIdentities(filteredUser); const sessionAttributes = this.returnLocalSessionAttributes(); - const pageEvents = buildPageEvents(loadPageViews(this.loggingService)); + const pageEvents = buildPageEvents(loadPageViews()); const mpSessionId = this.readMpSessionId(); const mpDeviceId = this.readMpDeviceId(); diff --git a/src/pageViewStorage.ts b/src/pageViewStorage.ts index 81396f6..f1e164c 100644 --- a/src/pageViewStorage.ts +++ b/src/pageViewStorage.ts @@ -1,10 +1,8 @@ -import type { LoggingService } from './Rokt-Kit'; -import { readJSON, removeKey, readNamespacedField, writeNamespacedField, removeNamespacedField } from './storage'; +import { readNamespacedField, writeNamespacedField, removeNamespacedField } from './storage'; import { sanitizeUrl } from './utils'; const LS_NAMESPACE_KEY = 'mp-rokt-kit'; const LS_PAGE_VIEWS_FIELD = 'pageViews'; -const LEGACY_PAGE_VIEWS_KEY = 'mpPageViews'; export const PAGE_VIEWS_MAX_COUNT = 25; export interface PageEvent { @@ -21,34 +19,7 @@ function capPageViews(views: PageEvent[]): PageEvent[] { return views.slice(-PAGE_VIEWS_MAX_COUNT); } -export function migrateLegacyPageViewStorage(loggingService: LoggingService | null): void { - const legacyViews = readJSON(LEGACY_PAGE_VIEWS_KEY); - if (legacyViews === null) { - return; - } - - const alreadyMigrated = readNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD) !== undefined; - const needsMigration = !alreadyMigrated && Array.isArray(legacyViews); - - if (needsMigration) { - loggingService?.log({ - message: 'Rokt Kit: Migrating legacy page-view storage', - code: 'PAGE_VIEW_LEGACY_MIGRATION', - }); - const migrated = writeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD, legacyViews); - if (!migrated) { - loggingService?.log({ - message: 'Rokt Kit: Failed to migrate legacy page-view storage [reason: migration_retry]', - code: 'PAGE_VIEW_CAPTURE_FAILED', - }); - } - } - - removeKey(LEGACY_PAGE_VIEWS_KEY); -} - -export function loadPageViews(loggingService: LoggingService | null): PageEvent[] { - migrateLegacyPageViewStorage(loggingService); +export function loadPageViews(): PageEvent[] { const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD); return Array.isArray(stored) ? (stored as PageEvent[]) : []; } diff --git a/test/src/pageViewStorage.spec.ts b/test/src/pageViewStorage.spec.ts index 049c76a..d492635 100644 --- a/test/src/pageViewStorage.spec.ts +++ b/test/src/pageViewStorage.spec.ts @@ -1,17 +1,9 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { readJSON, writeNamespacedField } from '../../src/storage'; -import { - migrateLegacyPageViewStorage, - loadPageViews, - writePageViews, - clearPageViews, - buildPageEvents, -} from '../../src/pageViewStorage'; -import type { LoggingService } from '../../src/Rokt-Kit'; +import { loadPageViews, writePageViews, clearPageViews, buildPageEvents } from '../../src/pageViewStorage'; const NAMESPACE_KEY = 'mp-rokt-kit'; const PAGE_VIEWS_FIELD = 'pageViews'; -const LEGACY_PAGE_VIEWS_KEY = 'mpPageViews'; const pageView = (id: string) => ({ pageUrl: 'https://example.com/' + id, sourceMessageId: id, timestamp: 1 }); @@ -25,102 +17,32 @@ describe('pageViewStorage', () => { window.localStorage.clear(); }); - describe('migrateLegacyPageViewStorage', () => { - it('is a no-op when the legacy key is absent', () => { - migrateLegacyPageViewStorage(null); - expect(readJSON(NAMESPACE_KEY)).toBeNull(); - }); - - it('moves a legacy array into the namespaced field and removes the legacy key', () => { - window.localStorage.setItem(LEGACY_PAGE_VIEWS_KEY, JSON.stringify([pageView('home')])); - migrateLegacyPageViewStorage(null); - - expect(readJSON(NAMESPACE_KEY)).toEqual({ [PAGE_VIEWS_FIELD]: [pageView('home')] }); - expect(window.localStorage.getItem(LEGACY_PAGE_VIEWS_KEY)).toBeNull(); - }); - - it('does not overwrite an already-migrated field, but still clears the legacy key', () => { - writeNamespacedField(NAMESPACE_KEY, PAGE_VIEWS_FIELD, [pageView('current')]); - window.localStorage.setItem(LEGACY_PAGE_VIEWS_KEY, JSON.stringify([pageView('stale')])); - - migrateLegacyPageViewStorage(null); - - expect(readJSON(NAMESPACE_KEY)).toEqual({ [PAGE_VIEWS_FIELD]: [pageView('current')] }); - expect(window.localStorage.getItem(LEGACY_PAGE_VIEWS_KEY)).toBeNull(); - }); - - it('logs PAGE_VIEW_LEGACY_MIGRATION when the migration path is taken', () => { - window.localStorage.setItem(LEGACY_PAGE_VIEWS_KEY, JSON.stringify([pageView('home')])); - const logger = { log: vi.fn() } as unknown as LoggingService; - - migrateLegacyPageViewStorage(logger); - - expect(logger.log).toHaveBeenCalledWith(expect.objectContaining({ code: 'PAGE_VIEW_LEGACY_MIGRATION' })); - }); - - it('removes the legacy key and logs when the migrating write fails', () => { - window.localStorage.setItem(LEGACY_PAGE_VIEWS_KEY, JSON.stringify([pageView('home')])); - const logger = { log: vi.fn() } as unknown as LoggingService; - vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => { - throw new DOMException('quota', 'QuotaExceededError'); - }); - - migrateLegacyPageViewStorage(logger); - - // Legacy key is removed even on failure — prevents the infinite retry loop. - expect(window.localStorage.getItem(LEGACY_PAGE_VIEWS_KEY)).toBeNull(); - expect(logger.log).toHaveBeenCalledWith(expect.objectContaining({ code: 'PAGE_VIEW_CAPTURE_FAILED' })); - }); - - it('does not log PAGE_VIEW_CAPTURE_FAILED on a second call after a failed migration', () => { - window.localStorage.setItem(LEGACY_PAGE_VIEWS_KEY, JSON.stringify([pageView('home')])); - const logger = { log: vi.fn() } as unknown as LoggingService; - vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => { - throw new DOMException('quota', 'QuotaExceededError'); - }); - - migrateLegacyPageViewStorage(logger); // first call: fails, legacy key removed - vi.restoreAllMocks(); - logger.log.mockClear(); - - migrateLegacyPageViewStorage(logger); // second call: legacy key gone, no-op - - expect(logger.log).not.toHaveBeenCalled(); - }); - }); - describe('loadPageViews', () => { it('returns an empty array when nothing is stored', () => { - expect(loadPageViews(null)).toEqual([]); + expect(loadPageViews()).toEqual([]); }); it('returns the stored page views', () => { writeNamespacedField(NAMESPACE_KEY, PAGE_VIEWS_FIELD, [pageView('home'), pageView('about')]); - expect(loadPageViews(null)).toEqual([pageView('home'), pageView('about')]); + expect(loadPageViews()).toEqual([pageView('home'), pageView('about')]); }); it('returns an empty array when the stored value is not an array', () => { writeNamespacedField(NAMESPACE_KEY, PAGE_VIEWS_FIELD, { not: 'an array' }); - expect(loadPageViews(null)).toEqual([]); - }); - - it('migrates the legacy key before reading', () => { - window.localStorage.setItem(LEGACY_PAGE_VIEWS_KEY, JSON.stringify([pageView('legacy')])); - expect(loadPageViews(null)).toEqual([pageView('legacy')]); - expect(window.localStorage.getItem(LEGACY_PAGE_VIEWS_KEY)).toBeNull(); + expect(loadPageViews()).toEqual([]); }); }); describe('writePageViews', () => { it('persists the page views and returns the stored count', () => { expect(writePageViews([pageView('home')])).toBe(1); - expect(loadPageViews(null)).toEqual([pageView('home')]); + expect(loadPageViews()).toEqual([pageView('home')]); }); it('keeps only the 25 most-recent views when given more than 25', () => { const views = Array.from({ length: 40 }, (_, i) => pageView('page-' + i)); expect(writePageViews(views)).toBe(25); - const stored = loadPageViews(null); + const stored = loadPageViews(); expect(stored).toHaveLength(25); expect(stored[0].sourceMessageId).toBe('page-15'); expect(stored[24].sourceMessageId).toBe('page-39'); @@ -136,7 +58,7 @@ describe('pageViewStorage', () => { }); expect(writePageViews(views)).toBe(4); - const stored = loadPageViews(null); + const stored = loadPageViews(); expect(stored).toHaveLength(4); expect(stored[0].sourceMessageId).toBe('page-1'); expect(stored[3].sourceMessageId).toBe('page-4'); @@ -152,7 +74,7 @@ describe('pageViewStorage', () => { }); expect(writePageViews(views)).toBe(2); - const stored = loadPageViews(null); + const stored = loadPageViews(); expect(stored).toHaveLength(2); expect(stored[0].sourceMessageId).toBe('page-3'); expect(stored[1].sourceMessageId).toBe('page-4'); @@ -171,7 +93,7 @@ describe('pageViewStorage', () => { }); expect(writePageViews(updated)).toBe(5); - const stored = loadPageViews(null); + const stored = loadPageViews(); expect(stored).toHaveLength(5); expect(stored[0].sourceMessageId).toBe('existing-1'); expect(stored[4].sourceMessageId).toBe('new');