light-sentry-sdk/tests/identity.test.ts

169 lines
5.5 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import {
getAnonymousId,
setAnonymousId,
clearAnonymousId,
isAnonymousTrackingEnabled,
} from '../src/utils/identity';
const ANONYMOUS_ID_KEY = 'light_sentry_aid';
describe('identity utils', () => {
beforeEach(() => {
localStorage.clear();
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('getAnonymousId', () => {
it('should generate and store a new anonymous ID when none exists', () => {
const id = getAnonymousId();
expect(id).toBeTruthy();
expect(typeof id).toBe('string');
expect(id!.length).toBeGreaterThan(0);
const stored = localStorage.getItem(ANONYMOUS_ID_KEY);
expect(stored).toBe(id);
});
it('should return the same ID on subsequent calls', () => {
const id1 = getAnonymousId();
const id2 = getAnonymousId();
expect(id1).toBe(id2);
});
it('should return existing ID from localStorage', () => {
localStorage.setItem(ANONYMOUS_ID_KEY, 'existing-id-123');
const id = getAnonymousId();
expect(id).toBe('existing-id-123');
});
it('should return null when localStorage is not available', () => {
const originalLocalStorage = (global as any).localStorage;
delete (global as any).localStorage;
const id = getAnonymousId();
expect(id).toBeNull();
(global as any).localStorage = originalLocalStorage;
});
it('should return null when localStorage throws', () => {
const getItemSpy = vi.spyOn(Storage.prototype, 'getItem').mockImplementation(() => {
throw new Error('Storage error');
});
const id = getAnonymousId();
expect(id).toBeNull();
getItemSpy.mockRestore();
});
it('should generate UUID format (32 hex chars without hyphens)', () => {
const id = getAnonymousId();
expect(id).toMatch(/^[a-f0-9]{32}$/i);
});
});
describe('setAnonymousId', () => {
it('should set custom anonymous ID', () => {
const result = setAnonymousId('custom-id-123');
expect(result).toBe(true);
expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBe('custom-id-123');
});
it('should override existing ID', () => {
localStorage.setItem(ANONYMOUS_ID_KEY, 'old-id');
setAnonymousId('new-id');
expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBe('new-id');
});
it('should return false when localStorage is not available', () => {
const originalLocalStorage = (global as any).localStorage;
delete (global as any).localStorage;
const result = setAnonymousId('test-id');
expect(result).toBe(false);
(global as any).localStorage = originalLocalStorage;
});
it('should return false when localStorage throws', () => {
const setItemSpy = vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => {
throw new Error('Storage error');
});
const result = setAnonymousId('test-id');
expect(result).toBe(false);
setItemSpy.mockRestore();
});
it('should set empty string ID', () => {
const result = setAnonymousId('');
expect(result).toBe(true);
expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBe('');
});
});
describe('clearAnonymousId', () => {
it('should clear existing anonymous ID', () => {
localStorage.setItem(ANONYMOUS_ID_KEY, 'existing-id');
const result = clearAnonymousId();
expect(result).toBe(true);
expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBeNull();
});
it('should return true even when no ID exists', () => {
const result = clearAnonymousId();
expect(result).toBe(true);
});
it('should return false when localStorage is not available', () => {
const originalLocalStorage = (global as any).localStorage;
delete (global as any).localStorage;
const result = clearAnonymousId();
expect(result).toBe(false);
(global as any).localStorage = originalLocalStorage;
});
it('should return false when localStorage throws', () => {
const removeItemSpy = vi.spyOn(Storage.prototype, 'removeItem').mockImplementation(() => {
throw new Error('Storage error');
});
const result = clearAnonymousId();
expect(result).toBe(false);
removeItemSpy.mockRestore();
});
});
describe('isAnonymousTrackingEnabled', () => {
it('should return true when trackAnonymousUsers is undefined', () => {
expect(isAnonymousTrackingEnabled({})).toBe(true);
});
it('should return true when trackAnonymousUsers is true', () => {
expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: true })).toBe(true);
});
it('should return false when trackAnonymousUsers is false', () => {
expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: false })).toBe(false);
});
it('should return true for other truthy values', () => {
expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: 1 as any })).toBe(true);
expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: 'yes' as any })).toBe(true);
});
});
describe('integration: full lifecycle', () => {
it('should handle set -> get -> clear flow', () => {
const id1 = getAnonymousId();
expect(id1).toBeTruthy();
setAnonymousId('custom-user-id');
const id2 = getAnonymousId();
expect(id2).toBe('custom-user-id');
clearAnonymousId();
const id3 = getAnonymousId();
expect(id3).toBeTruthy();
expect(id3).not.toBe('custom-user-id');
expect(id3).not.toBe(id1);
});
});
});