UNPKG

@pinelab/vendure-plugin-metrics

Version:

Vendure plugin measuring and visualizing e-commerce metrics

287 lines (286 loc) 14.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const metric_request_entity_1 = require("../entities/metric-request.entity"); const metric_util_1 = require("./metric-util"); (0, vitest_1.describe)('getMonthName()', () => { (0, vitest_1.it)('returns correct month names for valid indices', () => { (0, vitest_1.expect)((0, metric_util_1.getMonthName)(0)).toBe('Jan'); (0, vitest_1.expect)((0, metric_util_1.getMonthName)(6)).toBe('Jul'); (0, vitest_1.expect)((0, metric_util_1.getMonthName)(11)).toBe('Dec'); }); (0, vitest_1.it)('returns undefined for invalid indices', () => { (0, vitest_1.expect)((0, metric_util_1.getMonthName)(12)).toBeUndefined(); (0, vitest_1.expect)((0, metric_util_1.getMonthName)(-1)).toBeUndefined(); }); }); (0, vitest_1.describe)('splitEntitiesInMonths()', () => { // Test entities with different date fields const testEntities = [ { id: 1, createdAt: new Date('2023-01-15T00:00:00Z'), updatedAt: new Date('2023-01-20T00:00:00Z'), orderPlacedAt: new Date('2023-01-25T00:00:00Z'), }, { id: 2, createdAt: new Date('2023-02-10T00:00:00Z'), updatedAt: new Date('2023-02-15T00:00:00Z'), orderPlacedAt: new Date('2023-02-20T00:00:00Z'), }, { id: 3, createdAt: new Date('2023-02-25T00:00:00Z'), updatedAt: new Date('2023-03-05T00:00:00Z'), orderPlacedAt: new Date('2023-03-10T00:00:00Z'), }, { id: 4, createdAt: new Date('2023-04-03T00:00:00Z'), updatedAt: new Date('2023-04-02T00:00:00Z'), orderPlacedAt: new Date('2023-04-03T00:00:00Z'), }, ]; (0, vitest_1.it)('splits entities by createdAt correctly', () => { const from = new Date('2023-01-04T00:00:00Z'); const to = new Date('2023-03-04T00:00:00Z'); const result = (0, metric_util_1.groupEntitiesPerMonth)(testEntities, 'createdAt', from, to); // Should have 3 months (Jan, Feb, Mar) (0, vitest_1.expect)(result.length).toBe(3); // January should have 1 entity (0, vitest_1.expect)(result.find((m) => m.monthNr === 0)?.entities.length).toBe(1); // February should have 2 entities (0, vitest_1.expect)(result.find((m) => m.monthNr === 1)?.entities.length).toBe(2); }); (0, vitest_1.it)('splits entities by orderPlacedAt correctly', () => { const from = new Date('2023-01-02T00:00:00Z'); const to = new Date('2023-05-03T00:00:00Z'); const result = (0, metric_util_1.groupEntitiesPerMonth)(testEntities, 'orderPlacedAt', from, to); // Should have 4 months (Jan, Feb, Mar, Apr, May) (0, vitest_1.expect)(result.length).toBe(5); // Check entity count per month (0, vitest_1.expect)(result.find((m) => m.monthNr === 0 && m.year === 2023)?.entities.length).toBe(1); (0, vitest_1.expect)(result.find((m) => m.monthNr === 1 && m.year === 2023)?.entities.length).toBe(1); (0, vitest_1.expect)(result.find((m) => m.monthNr === 2 && m.year === 2023)?.entities.length).toBe(1); (0, vitest_1.expect)(result.find((m) => m.monthNr === 3 && m.year === 2023)?.entities.length).toBe(1); (0, vitest_1.expect)(result.find((m) => m.monthNr === 4 && m.year === 2023)?.entities.length).toBe(0); }); (0, vitest_1.it)('includes empty months in the range', () => { const from = new Date('2022-11-03T00:00:00Z'); const to = new Date('2023-02-03T00:00:00Z'); const result = (0, metric_util_1.groupEntitiesPerMonth)(testEntities, 'createdAt', from, to); // Should have months (Nov, Dec, Jan, Feb) (0, vitest_1.expect)(result.length).toBe(4); // November and December should be empty (0, vitest_1.expect)(result.find((m) => m.monthNr === 10 && m.year === 2022)?.entities.length).toBe(0); (0, vitest_1.expect)(result.find((m) => m.monthNr === 11 && m.year === 2022)?.entities.length).toBe(0); // January should have 1 entity (0, vitest_1.expect)(result.find((m) => m.monthNr === 0 && m.year === 2023)?.entities.length).toBe(1); // February should have 1 entity (0, vitest_1.expect)(result.find((m) => m.monthNr === 1 && m.year === 2023)?.entities.length).toBe(2); }); (0, vitest_1.it)('throws error for entities with invalid dates', () => { const invalidEntities = [{ id: 1, createdAt: new Date('invalid date') }]; const from = new Date('2023-01-03T00:00:00Z'); const to = new Date('2023-02-03T00:00:00Z'); (0, vitest_1.expect)(() => { (0, metric_util_1.groupEntitiesPerMonth)(invalidEntities, 'createdAt', from, to); }).toThrow(); }); (0, vitest_1.it)('handles empty entity array', () => { const from = new Date('2023-01-03T00:00:00Z'); const to = new Date('2023-03-03T00:00:00Z'); const result = (0, metric_util_1.groupEntitiesPerMonth)([], 'createdAt', from, to); // Should still have 2 months, just with empty entity arrays (0, vitest_1.expect)(result.length).toBe(3); (0, vitest_1.expect)(result[0].entities.length).toBe(0); (0, vitest_1.expect)(result[1].entities.length).toBe(0); (0, vitest_1.expect)(result[2].entities.length).toBe(0); }); }); (0, vitest_1.describe)('mapToSeries()', () => { (0, vitest_1.it)('transforms empty map to empty array', () => { const dataPointsMap = new Map(); const result = (0, metric_util_1.mapToSeries)(dataPointsMap); (0, vitest_1.expect)(result).toEqual([]); }); (0, vitest_1.it)('transforms single series correctly', () => { const dataPointsMap = new Map(); dataPointsMap.set('Series A', [10, 20, 30]); const result = (0, metric_util_1.mapToSeries)(dataPointsMap); (0, vitest_1.expect)(result).toEqual([{ name: 'Series A', values: [10, 20, 30] }]); }); (0, vitest_1.it)('transforms multiple series correctly', () => { const dataPointsMap = new Map(); dataPointsMap.set('Series A', [10, 20, 30]); dataPointsMap.set('Series B', [5, 15, 25]); dataPointsMap.set('Series C', [1, 2, 3]); const result = (0, metric_util_1.mapToSeries)(dataPointsMap); // Check length (0, vitest_1.expect)(result.length).toBe(3); // Check contents (order might vary) (0, vitest_1.expect)(result).toContainEqual({ name: 'Series A', values: [10, 20, 30] }); (0, vitest_1.expect)(result).toContainEqual({ name: 'Series B', values: [5, 15, 25] }); (0, vitest_1.expect)(result).toContainEqual({ name: 'Series C', values: [1, 2, 3] }); }); (0, vitest_1.it)('preserves empty values arrays', () => { const dataPointsMap = new Map(); dataPointsMap.set('Empty Series', []); const result = (0, metric_util_1.mapToSeries)(dataPointsMap); (0, vitest_1.expect)(result).toEqual([{ name: 'Empty Series', values: [] }]); }); }); (0, vitest_1.describe)('getSessions()', () => { // Helper function to create a MetricRequest with the given properties function createRequest(identifier, timestamp, deviceType = 'Desktop') { const request = new metric_request_entity_1.MetricRequest(); request.identifier = identifier; request.createdAt = timestamp; request.deviceType = deviceType; return request; } (0, vitest_1.it)('returns empty array for empty input', () => { const sessions = (0, metric_util_1.getSessions)([], 30); (0, vitest_1.expect)(sessions).toEqual([]); }); (0, vitest_1.it)('creates a single session for a single request', () => { const timestamp = new Date('2023-01-03T12:00:00Z'); const request = createRequest('user1', timestamp); const sessions = (0, metric_util_1.getSessions)([request], 30); (0, vitest_1.expect)(sessions).toHaveLength(1); (0, vitest_1.expect)(sessions[0]).toEqual({ identifier: 'user1', start: timestamp, end: timestamp, deviceType: 'Desktop', }); }); (0, vitest_1.it)('combines requests within session window into one session', () => { const startTime = new Date('2023-01-03T12:00:00Z'); const fiveMinLater = new Date(startTime.getTime() + 5 * 60 * 1000); const tenMinLater = new Date(startTime.getTime() + 10 * 60 * 1000); const requests = [ createRequest('user1', startTime), createRequest('user1', fiveMinLater), createRequest('user1', tenMinLater), ]; const sessions = (0, metric_util_1.getSessions)(requests, 30); (0, vitest_1.expect)(sessions).toHaveLength(1); (0, vitest_1.expect)(sessions[0]).toEqual({ identifier: 'user1', start: startTime, end: tenMinLater, deviceType: 'Desktop', }); }); (0, vitest_1.it)('creates separate sessions for requests outside session window', () => { const startTime = new Date('2023-01-03T12:00:00Z'); const fiveMinLater = new Date(startTime.getTime() + 5 * 60 * 1000); const tenMinLater = new Date(startTime.getTime() + 10 * 60 * 1000); const requests = [ createRequest('user1', startTime), createRequest('user1', fiveMinLater), createRequest('user1', tenMinLater), ]; const sessions = (0, metric_util_1.getSessions)(requests, 6); (0, vitest_1.expect)(sessions).toHaveLength(2); (0, vitest_1.expect)(sessions[0]).toEqual({ identifier: 'user1', start: startTime, end: fiveMinLater, deviceType: 'Desktop', }); (0, vitest_1.expect)(sessions[1]).toEqual({ identifier: 'user1', start: tenMinLater, end: tenMinLater, deviceType: 'Desktop', }); }); (0, vitest_1.it)('handles requests from different identifiers as separate sessions', () => { const baseTime = new Date('2023-01-03T12:00:00Z'); const requests = [ createRequest('user1', baseTime), createRequest('user2', baseTime), createRequest('user1', new Date(baseTime.getTime() + 5 * 60 * 1000)), createRequest('user2', new Date(baseTime.getTime() + 5 * 60 * 1000)), ]; const sessions = (0, metric_util_1.getSessions)(requests, 30); (0, vitest_1.expect)(sessions).toHaveLength(2); const user1Session = sessions.find((s) => s.identifier === 'user1'); const user2Session = sessions.find((s) => s.identifier === 'user2'); (0, vitest_1.expect)(user1Session?.start).toEqual(baseTime); (0, vitest_1.expect)(user1Session?.end).toEqual(new Date(baseTime.getTime() + 5 * 60 * 1000)); (0, vitest_1.expect)(user2Session?.start).toEqual(baseTime); (0, vitest_1.expect)(user2Session?.end).toEqual(new Date(baseTime.getTime() + 5 * 60 * 1000)); }); (0, vitest_1.it)('counts each request as separate session if session length is 0', () => { const now = new Date('2023-01-03T12:00:00Z'); const requests = [ createRequest('user1', now), createRequest('user1', now), createRequest('user1', now), ]; const sessions = (0, metric_util_1.getSessions)(requests, 0); (0, vitest_1.expect)(sessions).toHaveLength(3); (0, vitest_1.expect)(sessions[0]).toEqual({ identifier: 'user1', start: now, end: now, deviceType: 'Desktop', }); (0, vitest_1.expect)(sessions[1]).toEqual({ identifier: 'user1', start: now, end: now, deviceType: 'Desktop', }); }); (0, vitest_1.it)('preserves device type information', () => { const baseTime = new Date('2023-01-03T12:00:00Z'); const requests = [ createRequest('user1', baseTime, 'Desktop'), createRequest('user2', baseTime, 'Mobile'), createRequest('user3', baseTime, 'Tablet'), ]; const sessions = (0, metric_util_1.getSessions)(requests, 30); (0, vitest_1.expect)(sessions).toHaveLength(3); (0, vitest_1.expect)(sessions.find((s) => s.identifier === 'user1')?.deviceType).toBe('Desktop'); (0, vitest_1.expect)(sessions.find((s) => s.identifier === 'user2')?.deviceType).toBe('Mobile'); (0, vitest_1.expect)(sessions.find((s) => s.identifier === 'user3')?.deviceType).toBe('Tablet'); }); }); (0, vitest_1.describe)('getEntitiesForMonth()', () => { // Test entities with different date fields const testEntities = [ { id: 1, createdAt: new Date('2023-01-15T00:00:00Z'), }, { id: 2, createdAt: new Date('2023-02-10T00:00:00Z'), }, { id: 3, createdAt: new Date('2024-01-25T00:00:00Z'), // Correct month, wrong year }, ]; (0, vitest_1.it)('returns entities for the specified month and year', () => { const date = new Date('2023-01-15T00:00:00Z'); const result = (0, metric_util_1.getEntitiesForMonth)(testEntities, date, 'createdAt'); (0, vitest_1.expect)(result).toHaveLength(1); (0, vitest_1.expect)(result[0].id).toBe(1); }); (0, vitest_1.it)('returns empty array when no entities match the month and year', () => { const date = new Date('2023-03-15T00:00:00Z'); const result = (0, metric_util_1.getEntitiesForMonth)(testEntities, date, 'createdAt'); (0, vitest_1.expect)(result).toHaveLength(0); }); (0, vitest_1.it)('handles empty entity array', () => { const date = new Date('2023-01-15T00:00:00Z'); const result = (0, metric_util_1.getEntitiesForMonth)([], date, 'createdAt'); (0, vitest_1.expect)(result).toHaveLength(0); }); });