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

249 lines
7.5 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { ConfigManager } from '../src/core/ConfigManager';
import type { LightConfig, SentryEvent, ErrorEvent } from '../src/types';
// Mock the env module
vi.mock('../src/utils/env', () => ({
getContexts: vi.fn(() => ({
browser: { name: 'c', version: '120' },
os: { name: 'm', version: '14' },
device: { type: 'desktop' },
})),
getContextId: vi.fn(() => 'test_context_id'),
getPageUrl: vi.fn(() => 'https://example.com/page'),
getReferrer: vi.fn(() => 'https://google.com'),
}));
describe('ConfigManager', () => {
let configManager: ConfigManager;
beforeEach(() => {
vi.clearAllMocks();
});
describe('constructor', () => {
it('should create ConfigManager with valid config', () => {
const config: LightConfig = {
dsn: 'https://proj_abc123@log.example.com/1001',
release: '1.0.0',
environment: 'production',
};
configManager = new ConfigManager(config);
expect(configManager).toBeDefined();
});
it('should use default values for optional config', () => {
const config: LightConfig = {
dsn: 'https://proj_abc123@log.example.com/1001',
};
configManager = new ConfigManager(config);
expect(configManager.get('enabled')).toBe(true);
expect(configManager.get('sampleRate')).toBe(1);
expect(configManager.get('environment')).toBe('production');
});
});
describe('get/set methods', () => {
beforeEach(() => {
configManager = new ConfigManager({
dsn: 'https://proj_abc123@log.example.com/1001',
});
});
it('should get configured value', () => {
expect(configManager.get('environment')).toBe('production');
});
it('should set and get value', () => {
configManager.set('environment', 'development');
expect(configManager.get('environment')).toBe('development');
});
it('should set user info', () => {
configManager.setUser({ id: '123', username: 'test' });
const config = configManager.getAll();
expect(config.user?.id).toBe('123');
});
it('should set single tag', () => {
configManager.setTag('page', 'home');
const config = configManager.getAll();
expect(config.tags?.page).toBe('home');
});
it('should set multiple tags', () => {
configManager.setTags({ page: 'home', version: '2.0' });
const config = configManager.getAll();
expect(config.tags?.page).toBe('home');
expect(config.tags?.version).toBe('2.0');
});
it('should set extra data', () => {
configManager.setExtra('order_id', '12345');
const config = configManager.getAll();
expect(config.extra?.order_id).toBe('12345');
});
});
describe('shouldSample', () => {
it('should return true when sampleRate is 1', () => {
configManager = new ConfigManager({
dsn: 'https://proj_abc123@log.example.com/1001',
sampleRate: 1,
});
expect(configManager.shouldSample()).toBe(true);
});
it('should return false when sampleRate is 0', () => {
configManager = new ConfigManager({
dsn: 'https://proj_abc123@log.example.com/1001',
sampleRate: 0,
});
expect(configManager.shouldSample()).toBe(false);
});
});
describe('isIgnoredError', () => {
beforeEach(() => {
configManager = new ConfigManager({
dsn: 'https://proj_abc123@log.example.com/1001',
ignoreErrors: [/^Script error/i, 'ResizeObserver'],
});
});
it('should ignore matching pattern', () => {
expect(configManager.isIgnoredError('Script error')).toBe(true);
});
it('should ignore matching regex', () => {
expect(configManager.isIgnoredError('Script error: something')).toBe(true);
});
it('should not ignore non-matching message', () => {
expect(configManager.isIgnoredError('TypeError: something')).toBe(false);
});
it('should handle string pattern', () => {
expect(configManager.isIgnoredError('Some ResizeObserver issue')).toBe(true);
});
});
describe('applyToEvent', () => {
beforeEach(() => {
configManager = new ConfigManager({
dsn: 'https://proj_abc123@log.example.com/1001',
release: '1.0.0',
environment: 'production',
user: { id: '123' },
tags: { page: 'home' },
});
});
it('should apply release to event', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.release).toBe('1.0.0');
});
it('should apply environment to event', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.environment).toBe('production');
});
it('should apply user to event', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.user?.id).toBe('123');
});
it('should apply and merge tags', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
tags: { custom: 'value' },
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.tags?.page).toBe('home');
expect(result.tags?.custom).toBe('value');
});
it('should add context_id to event', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.context_id).toBe('test_context_id');
});
it('should add contexts on first event', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.contexts).toBeDefined();
expect(result.contexts?.browser).toBeDefined();
});
it('should add request info to event', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.request?.url).toBe('https://example.com/page');
expect(result.request?.referrer).toBe('https://google.com');
});
it('should not overwrite existing request.url', () => {
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
request: { url: 'https://custom.com/api' },
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.request?.url).toBe('https://custom.com/api');
});
});
describe('markContextReported', () => {
beforeEach(() => {
configManager = new ConfigManager({
dsn: 'https://proj_abc123@log.example.com/1001',
});
});
it('should add contexts on first event', () => {
configManager.markContextReported();
const event: SentryEvent = {
type: 'error',
level: 'error',
timestamp: Date.now(),
} as ErrorEvent;
const result = configManager.applyToEvent(event);
expect(result.contexts).toBeUndefined();
expect(result.context_id).toBe('test_context_id');
});
});
});