-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathanalytics-service.test.ts
More file actions
91 lines (78 loc) · 2.75 KB
/
Copy pathanalytics-service.test.ts
File metadata and controls
91 lines (78 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { describe, it, expect } from 'vitest';
import type { IAnalyticsService, AnalyticsResult, CubeMeta } from './analytics-service';
describe('Analytics Service Contract', () => {
it('should allow a minimal IAnalyticsService implementation with required methods', () => {
const service: IAnalyticsService = {
query: async (_query) => ({ rows: [], fields: [] }),
getMeta: async () => [],
};
expect(typeof service.query).toBe('function');
expect(typeof service.getMeta).toBe('function');
});
it('should allow a full implementation with optional methods', () => {
const service: IAnalyticsService = {
query: async () => ({ rows: [], fields: [] }),
getMeta: async () => [],
generateSql: async () => ({ sql: 'SELECT 1', params: [] }),
};
expect(service.generateSql).toBeDefined();
});
it('should execute an analytics query', async () => {
const service: IAnalyticsService = {
query: async (query): Promise<AnalyticsResult> => ({
rows: [
{ 'orders.status': 'active', 'orders.count': 42 },
{ 'orders.status': 'closed', 'orders.count': 18 },
],
fields: [
{ name: 'orders.status', type: 'string' },
{ name: 'orders.count', type: 'number' },
],
}),
getMeta: async () => [],
};
const result = await service.query({
cube: 'orders',
measures: ['orders.count'],
dimensions: ['orders.status'],
});
expect(result.rows).toHaveLength(2);
expect(result.fields).toHaveLength(2);
expect(result.rows[0]['orders.count']).toBe(42);
});
it('should return cube metadata', async () => {
const cubes: CubeMeta[] = [{
name: 'orders',
title: 'Orders',
measures: [{ name: 'orders.count', type: 'count' }],
dimensions: [{ name: 'orders.status', type: 'string' }],
}];
const service: IAnalyticsService = {
query: async () => ({ rows: [], fields: [] }),
getMeta: async (cubeName?) => {
if (cubeName) return cubes.filter(c => c.name === cubeName);
return cubes;
},
};
const meta = await service.getMeta();
expect(meta).toHaveLength(1);
expect(meta[0].name).toBe('orders');
expect(meta[0].measures).toHaveLength(1);
});
it('should generate SQL without executing', async () => {
const service: IAnalyticsService = {
query: async () => ({ rows: [], fields: [] }),
getMeta: async () => [],
generateSql: async (query) => ({
sql: `SELECT COUNT(*) FROM ${query.cube}`,
params: [],
}),
};
const result = await service.generateSql!({
cube: 'orders',
measures: ['orders.count'],
});
expect(result.sql).toContain('orders');
expect(result.params).toEqual([]);
});
});