@tinytapanalytics/sdk
Version:
Behavioral psychology platform that detects visitor frustration, predicts abandonment, and helps you save at-risk conversions in real-time
289 lines (251 loc) • 8.95 kB
text/typescript
/**
* Tests for core.ts - tree-shakeable exports and SDK factories
*/
import {
ErrorHandler,
NetworkManager,
PrivacyManager,
loadEnvironmentDetector,
loadEventQueue,
loadShadowDOMManager,
loadAutoTracking,
loadAdvancedAnalytics,
loadABTesting,
loadHeatmap,
loadPerformanceMonitoring,
loadAllFeatures,
createMinimalSDK,
createEnhancedSDK,
createFullSDK,
getBundleInfo,
} from '../core';
describe('Core Exports', () => {
describe('Direct Exports', () => {
it('should export ErrorHandler', () => {
expect(ErrorHandler).toBeDefined();
expect(typeof ErrorHandler).toBe('function');
});
it('should export NetworkManager', () => {
expect(NetworkManager).toBeDefined();
expect(typeof NetworkManager).toBe('function');
});
it('should export PrivacyManager', () => {
expect(PrivacyManager).toBeDefined();
expect(typeof PrivacyManager).toBe('function');
});
});
describe('Dynamic Imports', () => {
it('should load EnvironmentDetector', async () => {
const EnvironmentDetector = await loadEnvironmentDetector();
expect(EnvironmentDetector).toBeDefined();
expect(typeof EnvironmentDetector).toBe('function');
});
it('should load EventQueue', async () => {
const EventQueue = await loadEventQueue();
expect(EventQueue).toBeDefined();
expect(typeof EventQueue).toBe('function');
});
it('should load ShadowDOMManager', async () => {
const ShadowDOMManager = await loadShadowDOMManager();
expect(ShadowDOMManager).toBeDefined();
expect(typeof ShadowDOMManager).toBe('function');
});
it('should load AutoTracking', async () => {
const AutoTracking = await loadAutoTracking();
expect(AutoTracking).toBeDefined();
expect(typeof AutoTracking).toBe('function');
});
it('should load AdvancedAnalytics', async () => {
const AdvancedAnalytics = await loadAdvancedAnalytics();
expect(AdvancedAnalytics).toBeDefined();
expect(typeof AdvancedAnalytics).toBe('function');
});
it('should load ABTesting', async () => {
const ABTesting = await loadABTesting();
expect(ABTesting).toBeDefined();
expect(typeof ABTesting).toBe('function');
});
it('should load Heatmap', async () => {
const Heatmap = await loadHeatmap();
expect(Heatmap).toBeDefined();
expect(typeof Heatmap).toBe('function');
});
it('should load PerformanceMonitoring', async () => {
const PerformanceMonitoring = await loadPerformanceMonitoring();
expect(PerformanceMonitoring).toBeDefined();
expect(typeof PerformanceMonitoring).toBe('function');
});
it('should load all features at once', async () => {
const features = await loadAllFeatures();
expect(features).toBeDefined();
expect(features.EnvironmentDetector).toBeDefined();
expect(features.EventQueue).toBeDefined();
expect(features.ShadowDOMManager).toBeDefined();
expect(features.AutoTracking).toBeDefined();
expect(features.AdvancedAnalytics).toBeDefined();
expect(features.ABTesting).toBeDefined();
expect(features.Heatmap).toBeDefined();
expect(features.PerformanceMonitoring).toBeDefined();
});
});
describe('SDK Factory Functions', () => {
const mockConfig = {
apiKey: 'test-api-key',
endpoint: 'https://api.test.com',
};
beforeEach(() => {
// Mock navigator for browser APIs
Object.defineProperty(global, 'navigator', {
value: {
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
language: 'en-US',
languages: ['en-US', 'en'],
platform: 'Win32',
hardwareConcurrency: 4,
connection: {
effectiveType: '4g',
saveData: false,
},
},
configurable: true,
writable: true,
});
// Mock window for browser environment
Object.defineProperty(global, 'window', {
value: {
screen: {
width: 1920,
height: 1080,
},
innerWidth: 1920,
innerHeight: 1080,
devicePixelRatio: 1,
location: {
href: 'https://test.com',
hostname: 'test.com',
pathname: '/',
search: '',
hash: '',
},
setInterval: global.setInterval,
clearInterval: global.clearInterval,
setTimeout: global.setTimeout,
clearTimeout: global.clearTimeout,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
localStorage: {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
},
},
configurable: true,
writable: true,
});
});
describe('createMinimalSDK', () => {
it('should create a minimal SDK instance', () => {
const sdk = createMinimalSDK(mockConfig);
expect(sdk).toBeDefined();
expect(sdk.track).toBeDefined();
expect(sdk.trackPageView).toBeDefined();
expect(sdk.identify).toBeDefined();
});
it('should create SDK with provided config', () => {
const customConfig = {
apiKey: 'custom-key',
endpoint: 'https://custom.api.com',
debug: true,
};
const sdk = createMinimalSDK(customConfig);
expect(sdk).toBeDefined();
});
});
describe('createEnhancedSDK', () => {
it('should create enhanced SDK with additional features', async () => {
const sdk = await createEnhancedSDK(mockConfig);
expect(sdk).toBeDefined();
expect(sdk.track).toBeDefined();
expect((sdk as any)._environmentDetector).toBeDefined();
});
it('should include EnvironmentDetector', async () => {
const sdk = await createEnhancedSDK(mockConfig);
expect((sdk as any)._environmentDetector).toBeDefined();
});
});
describe('createFullSDK', () => {
it('should create full-featured SDK', async () => {
const sdk = await createFullSDK(mockConfig);
expect(sdk).toBeDefined();
expect(sdk.track).toBeDefined();
});
it('should attach all features to SDK', async () => {
const sdk = await createFullSDK(mockConfig);
// Check that features are attached (they may fail to initialize, but should be attempted)
expect(sdk).toBeDefined();
});
it('should handle feature initialization errors gracefully', async () => {
// Test with invalid config that might cause features to fail
const invalidConfig = {
apiKey: '',
endpoint: '',
};
// Should not throw, but log warnings
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
const sdk = await createFullSDK(invalidConfig);
expect(sdk).toBeDefined();
consoleSpy.mockRestore();
});
});
});
describe('Bundle Info', () => {
it('should return bundle size information', () => {
const info = getBundleInfo();
expect(info).toBeDefined();
expect(info.core).toBeDefined();
expect(info.environmentDetector).toBeDefined();
expect(info.eventQueue).toBeDefined();
expect(info.shadowDOMManager).toBeDefined();
expect(info.autoTracking).toBeDefined();
expect(info.advancedAnalytics).toBeDefined();
expect(info.abTesting).toBeDefined();
expect(info.heatmap).toBeDefined();
expect(info.performanceMonitoring).toBeDefined();
expect(info.total).toBeDefined();
});
it('should have correct bundle size format', () => {
const info = getBundleInfo();
// All values should contain "KB"
Object.values(info).forEach(value => {
expect(value).toContain('KB');
});
});
it('should list core features', () => {
const info = getBundleInfo();
expect(info.core).toContain('ErrorHandler');
expect(info.core).toContain('NetworkManager');
expect(info.core).toContain('PrivacyManager');
});
});
describe('Tree-shaking Support', () => {
it('should allow importing only needed features', async () => {
// Import only what's needed
const EnvironmentDetector = await loadEnvironmentDetector();
const EventQueue = await loadEventQueue();
expect(EnvironmentDetector).toBeDefined();
expect(EventQueue).toBeDefined();
});
it('should support selective feature loading', async () => {
// Load features individually
const features = await Promise.all([
loadEnvironmentDetector(),
loadAutoTracking(),
]);
expect(features).toHaveLength(2);
features.forEach(feature => {
expect(feature).toBeDefined();
});
});
});
});