make-mp-data 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dungeons/adspend.js +96 -0
- package/dungeons/anon.js +104 -0
- package/dungeons/big.js +225 -0
- package/dungeons/business.js +345 -0
- package/dungeons/complex.js +396 -0
- package/dungeons/experiments.js +125 -0
- package/dungeons/foobar.js +241 -0
- package/dungeons/funnels.js +272 -0
- package/dungeons/gaming.js +315 -0
- package/dungeons/media.js +7 -7
- package/dungeons/mirror.js +129 -0
- package/dungeons/sanity.js +113 -0
- package/dungeons/scd.js +205 -0
- package/dungeons/simple.js +195 -0
- package/dungeons/userAgent.js +190 -0
- package/entry.js +57 -0
- package/index.js +96 -68
- package/lib/cli/cli.js +5 -4
- package/lib/core/config-validator.js +28 -12
- package/lib/core/context.js +147 -130
- package/lib/core/storage.js +45 -31
- package/lib/data/defaults.js +2 -2
- package/lib/generators/adspend.js +1 -2
- package/lib/generators/events.js +35 -24
- package/lib/generators/funnels.js +1 -2
- package/lib/generators/mirror.js +1 -2
- package/lib/orchestrators/mixpanel-sender.js +15 -7
- package/lib/orchestrators/user-loop.js +21 -10
- package/lib/orchestrators/worker-manager.js +5 -2
- package/lib/utils/ai.js +36 -63
- package/lib/utils/chart.js +5 -0
- package/lib/utils/instructions.txt +593 -0
- package/lib/utils/utils.js +162 -38
- package/package.json +23 -9
- package/types.d.ts +376 -376
- package/.claude/settings.local.json +0 -21
- package/.gcloudignore +0 -18
- package/.gitattributes +0 -2
- package/.prettierrc +0 -0
- package/.vscode/launch.json +0 -80
- package/.vscode/settings.json +0 -69
- package/.vscode/tasks.json +0 -12
- package/dungeons/customers/.gitkeep +0 -0
- package/env.yaml +0 -1
- package/lib/cloud-function.js +0 -20
- package/scratch.mjs +0 -62
- package/scripts/dana.mjs +0 -137
- package/scripts/deploy.sh +0 -15
- package/scripts/jsdoctest.js +0 -5
- package/scripts/new-dungeon.sh +0 -98
- package/scripts/new-project.mjs +0 -14
- package/scripts/run-index.sh +0 -2
- package/scripts/update-deps.sh +0 -5
- package/tests/benchmark/concurrency.mjs +0 -52
- package/tests/cli.test.js +0 -124
- package/tests/coverage/.gitkeep +0 -0
- package/tests/e2e.test.js +0 -379
- package/tests/int.test.js +0 -715
- package/tests/testCases.mjs +0 -229
- package/tests/testSoup.mjs +0 -28
- package/tests/unit.test.js +0 -910
- package/tmp/.gitkeep +0 -0
- package/tsconfig.json +0 -18
- package/vitest.config.js +0 -47
package/tests/cli.test.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
//@ts-nocheck
|
|
2
|
-
import generate from '../index.js';
|
|
3
|
-
import 'dotenv/config';
|
|
4
|
-
import { execSync } from "child_process";
|
|
5
|
-
import * as u from 'ak-tools';
|
|
6
|
-
import Papa from 'papaparse';
|
|
7
|
-
|
|
8
|
-
import simple from '../dungeons/simple.js';
|
|
9
|
-
import complex from '../dungeons/complex.js';
|
|
10
|
-
import anon from '../dungeons/anon.js';
|
|
11
|
-
import funnels from '../dungeons/funnels.js';
|
|
12
|
-
import foobar from '../dungeons/foobar.js';
|
|
13
|
-
import mirror from '../dungeons/mirror.js';
|
|
14
|
-
import adspend from '../dungeons/adspend.js';
|
|
15
|
-
import scd from '../dungeons/scd.js';
|
|
16
|
-
|
|
17
|
-
const timeout = 600000;
|
|
18
|
-
const testToken = process.env.TEST_TOKEN || "hello token!";
|
|
19
|
-
|
|
20
|
-
// Use sequential execution to prevent CLI tests from interfering with each other
|
|
21
|
-
// since they use execSync and create/modify files in the same directories
|
|
22
|
-
describe.sequential('cli', () => {
|
|
23
|
-
|
|
24
|
-
test('sanity check', async () => {
|
|
25
|
-
console.log('SANITY TEST');
|
|
26
|
-
const run = execSync(`node ./index.js --numEvents 100 --numUsers 10`);
|
|
27
|
-
const ending = `completed successfully!`;
|
|
28
|
-
expect(run.toString().trim().endsWith(ending)).toBe(true);
|
|
29
|
-
const files = (await u.ls('./data')).filter(a => a.includes('.csv'));
|
|
30
|
-
expect(files.length).toBe(2);
|
|
31
|
-
const users = files.filter(a => a.includes('USERS'));
|
|
32
|
-
const events = files.filter(a => a.includes('EVENTS'));
|
|
33
|
-
expect(users.length).toBe(1);
|
|
34
|
-
expect(events.length).toBe(1);
|
|
35
|
-
const eventData = (await u.load(events[0])).trim();
|
|
36
|
-
const userProfilesData = (await u.load(users[0])).trim();
|
|
37
|
-
const parsedEvents = Papa.parse(eventData, { header: true }).data;
|
|
38
|
-
const parsedUsers = Papa.parse(userProfilesData, { header: true }).data;
|
|
39
|
-
expect(parsedEvents.length).toBeGreaterThan(10);
|
|
40
|
-
expect(parsedUsers.length).toBeGreaterThan(5);
|
|
41
|
-
expect(parsedUsers.every(u => u.distinct_id)).toBe(true);
|
|
42
|
-
expect(parsedEvents.every(e => e.event)).toBe(true);
|
|
43
|
-
expect(parsedEvents.every(e => e.time)).toBe(true);
|
|
44
|
-
expect(parsedEvents.every(e => e.insert_id)).toBe(true);
|
|
45
|
-
expect(parsedEvents.every(e => e.device_id || e.user_id)).toBe(true);
|
|
46
|
-
expect(parsedUsers.every(u => u.name)).toBe(true);
|
|
47
|
-
expect(parsedUsers.every(u => u.email)).toBe(true);
|
|
48
|
-
// expect(parsedUsers.every(u => u.created)).toBe(true);
|
|
49
|
-
expect(parsedUsers.every(u => u.avatar)).toBe(false);
|
|
50
|
-
expect(parsedEvents.every(e => validateEvent(e))).toBe(true);
|
|
51
|
-
expect(parsedUsers.every(u => validateUser(u))).toBe(true);
|
|
52
|
-
}, timeout);
|
|
53
|
-
|
|
54
|
-
test('no args', async () => {
|
|
55
|
-
console.log('BARE CLI TEST');
|
|
56
|
-
const run = execSync(`node ./index.js --numEvents 100 --numUsers 10`);
|
|
57
|
-
expect(run.toString().trim().includes('completed successfully!')).toBe(true);
|
|
58
|
-
const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
|
|
59
|
-
expect(csvs.length).toBe(2);
|
|
60
|
-
|
|
61
|
-
}, timeout);
|
|
62
|
-
|
|
63
|
-
test('--complex', async () => {
|
|
64
|
-
console.log('COMPLEX CLI TEST');
|
|
65
|
-
const run = execSync(`node ./index.js --numEvents 100 --numUsers 10 --seed "deal with it" --complex`, { stdio: "ignore" });
|
|
66
|
-
const csvs = (await u.ls('./data')).filter(a => a.includes('.json'));
|
|
67
|
-
expect(csvs.length).toBeGreaterThan(7);
|
|
68
|
-
|
|
69
|
-
}, timeout);
|
|
70
|
-
|
|
71
|
-
test('--simple', async () => {
|
|
72
|
-
console.log('SIMPLE CLI TEST');
|
|
73
|
-
const run = execSync(`node ./index.js --numEvents 100 --numUsers 10 --seed "deal with it" --simple`);
|
|
74
|
-
expect(run.toString().trim().includes('completed successfully!')).toBe(true);
|
|
75
|
-
const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
|
|
76
|
-
expect(csvs.length).toBe(2);
|
|
77
|
-
|
|
78
|
-
}, timeout);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
beforeEach(() => {
|
|
84
|
-
clearData();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
afterEach(() => {
|
|
88
|
-
clearData();
|
|
89
|
-
});
|
|
90
|
-
function clearData() {
|
|
91
|
-
try {
|
|
92
|
-
console.log('clearing...');
|
|
93
|
-
execSync(`npm run prune`);
|
|
94
|
-
console.log('...files cleared 👍');
|
|
95
|
-
}
|
|
96
|
-
catch (err) {
|
|
97
|
-
console.log('error clearing files');
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function validateEvent(event) {
|
|
102
|
-
if (!event.event) return false;
|
|
103
|
-
if (!event.device_id && !event.user_id) return false;
|
|
104
|
-
if (!event.time) return false;
|
|
105
|
-
if (!event.insert_id) return false;
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
function validateUser(user) {
|
|
111
|
-
if (!user.distinct_id) return false;
|
|
112
|
-
if (!user.name) return false;
|
|
113
|
-
if (!user.email) return false;
|
|
114
|
-
// if (!user.created) return false;
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function validTime(str) {
|
|
120
|
-
if (!str) return false;
|
|
121
|
-
if (str.startsWith('-')) return false;
|
|
122
|
-
if (!str.startsWith('20')) return false;
|
|
123
|
-
return true;
|
|
124
|
-
}
|
package/tests/coverage/.gitkeep
DELETED
|
File without changes
|
package/tests/e2e.test.js
DELETED
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
/* cSpell:disable */
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
/* eslint-disable no-undef */
|
|
4
|
-
/* eslint-disable no-debugger */
|
|
5
|
-
/* eslint-disable no-unused-vars */
|
|
6
|
-
import generate from '../index.js';
|
|
7
|
-
import 'dotenv/config';
|
|
8
|
-
import { execSync } from "child_process";
|
|
9
|
-
import * as u from 'ak-tools';
|
|
10
|
-
import Papa from 'papaparse';
|
|
11
|
-
|
|
12
|
-
import simple from '../dungeons/simple.js';
|
|
13
|
-
import complex from '../dungeons/complex.js';
|
|
14
|
-
import anon from '../dungeons/anon.js';
|
|
15
|
-
import funnels from '../dungeons/funnels.js';
|
|
16
|
-
import foobar from '../dungeons/foobar.js';
|
|
17
|
-
import mirror from '../dungeons/mirror.js';
|
|
18
|
-
import adspend from '../dungeons/adspend.js';
|
|
19
|
-
import scd from '../dungeons/scd.js';
|
|
20
|
-
|
|
21
|
-
// 1 minute timeout
|
|
22
|
-
const timeout = 60000;
|
|
23
|
-
const testToken = process.env.TEST_TOKEN || "hello token!";
|
|
24
|
-
|
|
25
|
-
describe('module', () => {
|
|
26
|
-
|
|
27
|
-
test('works as module (no config)', async () => {
|
|
28
|
-
console.log('MODULE TEST');
|
|
29
|
-
const results = await generate({ verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
30
|
-
const { eventData, groupProfilesData, lookupTableData, scdTableData, userProfilesData } = results;
|
|
31
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
32
|
-
expect(groupProfilesData.length).toBe(0);
|
|
33
|
-
expect(lookupTableData.length).toBe(0);
|
|
34
|
-
expect(scdTableData.length).toBe(0);
|
|
35
|
-
expect(userProfilesData.length).toBe(100);
|
|
36
|
-
|
|
37
|
-
}, timeout);
|
|
38
|
-
|
|
39
|
-
test('works as module (simple)', async () => {
|
|
40
|
-
console.log('MODULE TEST: SIMPLE');
|
|
41
|
-
const results = await generate({ ...simple, verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
42
|
-
const { eventData, groupProfilesData, lookupTableData, scdTableData, userProfilesData } = results;
|
|
43
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
44
|
-
expect(groupProfilesData.length).toBe(0);
|
|
45
|
-
expect(lookupTableData.length).toBe(0);
|
|
46
|
-
expect(scdTableData.length).toBe(0);
|
|
47
|
-
expect(userProfilesData.length).toBe(100);
|
|
48
|
-
|
|
49
|
-
}, timeout);
|
|
50
|
-
|
|
51
|
-
test('works as module (complex)', async () => {
|
|
52
|
-
console.log('MODULE TEST: COMPLEX');
|
|
53
|
-
const results = await generate({ ...complex, verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
54
|
-
const { eventData, groupProfilesData, lookupTableData, scdTableData, userProfilesData } = results;
|
|
55
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
56
|
-
expect(groupProfilesData[0]?.length).toBe(500);
|
|
57
|
-
expect(lookupTableData.length).toBe(2);
|
|
58
|
-
expect(lookupTableData[0].length).toBe(1000);
|
|
59
|
-
expect(scdTableData.length).toBe(5);
|
|
60
|
-
expect(userProfilesData.length).toBe(100);
|
|
61
|
-
|
|
62
|
-
}, timeout);
|
|
63
|
-
|
|
64
|
-
test('works as module (funnels)', async () => {
|
|
65
|
-
console.log('MODULE TEST: FUNNELS');
|
|
66
|
-
const results = await generate({ ...funnels, verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
67
|
-
const { eventData, groupProfilesData, scdTableData, userProfilesData } = results;
|
|
68
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
69
|
-
expect(groupProfilesData.length).toBe(3);
|
|
70
|
-
expect(groupProfilesData[0]?.length).toBe(5000);
|
|
71
|
-
expect(groupProfilesData[1]?.length).toBe(500);
|
|
72
|
-
expect(groupProfilesData[2]?.length).toBe(50);
|
|
73
|
-
expect(userProfilesData.length).toBe(100);
|
|
74
|
-
|
|
75
|
-
}, timeout);
|
|
76
|
-
|
|
77
|
-
test('works as module (mirror)', async () => {
|
|
78
|
-
console.log('MODULE TEST: MIRROR');
|
|
79
|
-
const results = await generate({ ...mirror, verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
80
|
-
const { eventData, userProfilesData, mirrorEventData } = results;
|
|
81
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
82
|
-
expect(mirrorEventData.length).toBeGreaterThan(980);
|
|
83
|
-
expect(mirrorEventData.every(e => e.newlyCreated)).toBe(true);
|
|
84
|
-
expect(eventData.every(e => e.newlyCreated)).toBe(false);
|
|
85
|
-
expect(userProfilesData.length).toBe(100);
|
|
86
|
-
|
|
87
|
-
}, timeout);
|
|
88
|
-
|
|
89
|
-
test('works as module (foobar)', async () => {
|
|
90
|
-
console.log('MODULE TEST: FOOBAR');
|
|
91
|
-
const results = await generate({ ...foobar, verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
92
|
-
const { eventData, userProfilesData } = results;
|
|
93
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
94
|
-
expect(userProfilesData.length).toBe(100);
|
|
95
|
-
|
|
96
|
-
}, timeout);
|
|
97
|
-
|
|
98
|
-
test('works as module (adspend)', async () => {
|
|
99
|
-
console.log('MODULE TEST: ADSPEND');
|
|
100
|
-
const results = await generate({ ...adspend, verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it" });
|
|
101
|
-
const { eventData, adSpendData, userProfilesData } = results;
|
|
102
|
-
expect(eventData.length).toBeGreaterThan(980);
|
|
103
|
-
expect(userProfilesData.length).toBe(100);
|
|
104
|
-
expect(adSpendData.length).toBe(14600);
|
|
105
|
-
|
|
106
|
-
}, timeout);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
test('works as module (scd)', async () => {
|
|
110
|
-
console.log('MODULE TEST: scd');
|
|
111
|
-
// const scdSchema = (await import('../dungeons/scd.js')).default;
|
|
112
|
-
const config = {
|
|
113
|
-
...scd,
|
|
114
|
-
token: testToken,
|
|
115
|
-
serviceAccount: process.env.SERVICE_ACCOUNT,
|
|
116
|
-
projectId: process.env.PROJECT_ID,
|
|
117
|
-
serviceSecret: process.env.SERVICE_SECRET,
|
|
118
|
-
verbose: false, writeToDisk: false, numEvents: 100, numUsers: 10, seed: "deal with it"
|
|
119
|
-
};
|
|
120
|
-
const results = await generate(config);
|
|
121
|
-
const { importResults } = results;
|
|
122
|
-
const { MRR_scd, NPS_scd, plan_scd, role_scd } = importResults;
|
|
123
|
-
expect(MRR_scd.success).toBeGreaterThan(10);
|
|
124
|
-
expect(NPS_scd.success).toBeGreaterThan(10);
|
|
125
|
-
expect(plan_scd.success).toBeGreaterThan(10);
|
|
126
|
-
expect(role_scd.success).toBeGreaterThan(10);
|
|
127
|
-
expect(MRR_scd.failed).toBe(0);
|
|
128
|
-
expect(NPS_scd.failed).toBe(0);
|
|
129
|
-
expect(plan_scd.failed).toBe(0);
|
|
130
|
-
expect(role_scd.failed).toBe(0);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}, timeout);
|
|
134
|
-
|
|
135
|
-
test('fails with invalid configuration', async () => {
|
|
136
|
-
try {
|
|
137
|
-
await generate({ numUsers: -10 });
|
|
138
|
-
} catch (e) {
|
|
139
|
-
expect(e).toBeDefined();
|
|
140
|
-
}
|
|
141
|
-
}, timeout);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
test('works with no params', async () => {
|
|
145
|
-
const { eventData, userProfilesData, groupProfilesData, files, importResults, lookupTableData, mirrorEventData, scdTableData } = await generate({ writeToDisk: false });
|
|
146
|
-
expect(eventData.length).toBeGreaterThan(100000);
|
|
147
|
-
expect(userProfilesData.length).toBe(1000);
|
|
148
|
-
expect(groupProfilesData.length).toBe(0);
|
|
149
|
-
expect(importResults).toBe(undefined);
|
|
150
|
-
expect(scdTableData.length).toBe(0);
|
|
151
|
-
expect(lookupTableData.length).toBe(0);
|
|
152
|
-
expect(mirrorEventData.length).toBe(0);
|
|
153
|
-
}, timeout);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// describe('batching', () => {
|
|
161
|
-
// test('batch writes', async () => {
|
|
162
|
-
// const results = await generate({ ...foobar, batchSize: 1000, writeToDisk: true, numEvents: 10_000, numUsers: 5000, seed: "deal" });
|
|
163
|
-
// const { eventData, userProfilesData } = results;
|
|
164
|
-
// const files = (await u.ls('./data')).filter(a => a.endsWith('.json'));
|
|
165
|
-
// const eventFiles = files.filter(a => a.includes('EVENTS'));
|
|
166
|
-
// const userFiles = files.filter(a => a.includes('USERS'));
|
|
167
|
-
// const evWriteDir = eventData.getWriteDir();
|
|
168
|
-
// const usWriteDir = userProfilesData.getWriteDir();
|
|
169
|
-
// const evWritePath = eventData.getWritePath();
|
|
170
|
-
// const usWritePath = userProfilesData.getWritePath();
|
|
171
|
-
|
|
172
|
-
// const expectedEvWriteDir = `-EVENTS.json`;
|
|
173
|
-
// const expectedUsWriteDir = `-USERS.json`;
|
|
174
|
-
// const expectedWritePath = `-part-`;
|
|
175
|
-
|
|
176
|
-
// expect(eventFiles.length).toBe(22);
|
|
177
|
-
// expect(userFiles.length).toBe(5);
|
|
178
|
-
|
|
179
|
-
// expect(eventFiles.filter(a => a.includes('part')).length).toBe(23);
|
|
180
|
-
// expect(userFiles.filter(a => a.includes('part')).length).toBe(5);
|
|
181
|
-
// expect(evWriteDir.endsWith(expectedEvWriteDir)).toBe(true);
|
|
182
|
-
// expect(usWriteDir.endsWith(expectedUsWriteDir)).toBe(true);
|
|
183
|
-
// expect(evWritePath.includes(expectedWritePath)).toBe(true);
|
|
184
|
-
// expect(usWritePath.includes(expectedWritePath)).toBe(true);
|
|
185
|
-
|
|
186
|
-
// }, timeout);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
// test('dont batch', async () => {
|
|
190
|
-
// const results = await generate({ ...foobar, writeToDisk: true, numEvents: 5000, numUsers: 1000, seed: "deal" });
|
|
191
|
-
// const { eventData, userProfilesData } = results;
|
|
192
|
-
// const files = await u.ls('./data');
|
|
193
|
-
// const eventFiles = files.filter(a => a.includes('EVENTS'));
|
|
194
|
-
// const userFiles = files.filter(a => a.includes('USERS'));
|
|
195
|
-
// expect(eventFiles.length).toBe(1);
|
|
196
|
-
// expect(userFiles.length).toBe(1);
|
|
197
|
-
// expect(eventFiles.filter(a => a.includes('part')).length).toBe(0);
|
|
198
|
-
// const evWriteDir = eventData.getWriteDir();
|
|
199
|
-
// const usWriteDir = userProfilesData.getWriteDir();
|
|
200
|
-
// const expectedEvWriteDir = `-EVENTS.json`;
|
|
201
|
-
// const expectedUsWriteDir = `-USERS.json`;
|
|
202
|
-
// expect(evWriteDir.endsWith(expectedEvWriteDir)).toBe(true);
|
|
203
|
-
// expect(usWriteDir.endsWith(expectedUsWriteDir)).toBe(true);
|
|
204
|
-
|
|
205
|
-
// const evWritePath = eventData.getWritePath();
|
|
206
|
-
// const usWritePath = userProfilesData.getWritePath();
|
|
207
|
-
// expect(evWritePath.endsWith(expectedEvWriteDir)).toBe(true);
|
|
208
|
-
// expect(usWritePath.endsWith(expectedUsWriteDir)).toBe(true);
|
|
209
|
-
|
|
210
|
-
// }, timeout);
|
|
211
|
-
|
|
212
|
-
// test('send to mp: batches', async () => {
|
|
213
|
-
// const results = await generate({ ...foobar, numDays: 90, hasAdSpend: true, token: testToken, batchSize: 4500, writeToDisk: true, numEvents: 10_000, numUsers: 5000, seed: "deal" });
|
|
214
|
-
// const { importResults } = results;
|
|
215
|
-
// const { adSpend, events, groups, users } = importResults;
|
|
216
|
-
// expect(adSpend.success).toBeGreaterThan(0);
|
|
217
|
-
// expect(events.success).toBeGreaterThan(0);
|
|
218
|
-
// expect(users.success).toBeGreaterThan(0);
|
|
219
|
-
// expect(groups[0].success).toBeGreaterThan(0);
|
|
220
|
-
// expect(groups[1].success).toBeGreaterThan(0);
|
|
221
|
-
// expect(adSpend.success).toBe(adSpend.total);
|
|
222
|
-
// expect(events.success).toBe(events.total);
|
|
223
|
-
// // expect(users.success).toBe(users.total);
|
|
224
|
-
// expect(groups.length).toBe(2);
|
|
225
|
-
// expect(groups[0].success).toBe(groups[0].total);
|
|
226
|
-
// expect(groups[1].success).toBe(groups[1].total);
|
|
227
|
-
// expect(adSpend.failed).toBe(0);
|
|
228
|
-
// expect(events.failed).toBe(0);
|
|
229
|
-
// expect(users.failed).toBe(0);
|
|
230
|
-
// expect(groups[0].failed).toBe(0);
|
|
231
|
-
// expect(groups[1].failed).toBe(0);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
// }, timeout);
|
|
235
|
-
|
|
236
|
-
// test('send to mp: no batch', async () => {
|
|
237
|
-
// const results = await generate({ ...foobar, numDays: 90, hasAdSpend: true, token: testToken, writeToDisk: true, numEvents: 5000, numUsers: 1000, seed: "deal" });
|
|
238
|
-
// const { importResults } = results;
|
|
239
|
-
// const { adSpend, events, groups, users } = importResults;
|
|
240
|
-
// expect(adSpend.success).toBeGreaterThan(0);
|
|
241
|
-
// expect(events.success).toBeGreaterThan(0);
|
|
242
|
-
// expect(users.success).toBeGreaterThan(0);
|
|
243
|
-
// expect(groups[0].success).toBeGreaterThan(0);
|
|
244
|
-
// expect(groups[1].success).toBeGreaterThan(0);
|
|
245
|
-
// expect(adSpend.success).toBe(adSpend.total);
|
|
246
|
-
// expect(events.success).toBe(events.total);
|
|
247
|
-
// expect(users.success).toBe(users.total);
|
|
248
|
-
// expect(groups.length).toBe(2);
|
|
249
|
-
// expect(groups[0].success).toBe(groups[0].total);
|
|
250
|
-
// expect(groups[1].success).toBe(groups[1].total);
|
|
251
|
-
// expect(adSpend.failed).toBe(0);
|
|
252
|
-
// expect(events.failed).toBe(0);
|
|
253
|
-
// expect(users.failed).toBe(0);
|
|
254
|
-
// expect(groups[0].failed).toBe(0);
|
|
255
|
-
// expect(groups[1].failed).toBe(0);
|
|
256
|
-
|
|
257
|
-
// }, timeout);
|
|
258
|
-
// });
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
describe('options + tweaks', () => {
|
|
262
|
-
test('creates sessionIds', async () => {
|
|
263
|
-
const results = await generate({ writeToDisk: false, numEvents: 1000, numUsers: 100, hasSessionIds: true });
|
|
264
|
-
const { eventData } = results;
|
|
265
|
-
const sessionIds = eventData.map(a => a.session_id).filter(a => a);
|
|
266
|
-
expect(sessionIds.length).toBe(eventData.length);
|
|
267
|
-
}, timeout);
|
|
268
|
-
|
|
269
|
-
test('no hasSessionIds', async () => {
|
|
270
|
-
const results = await generate({ writeToDisk: false, numEvents: 1000, numUsers: 100, hasSessionIds: false });
|
|
271
|
-
const { eventData } = results;
|
|
272
|
-
const noSessionIds = eventData.map(a => a.session_id).filter(a => a);
|
|
273
|
-
expect(noSessionIds.length).toBe(0);
|
|
274
|
-
}, timeout);
|
|
275
|
-
|
|
276
|
-
test('creates anonymousIds', async () => {
|
|
277
|
-
const results = await generate({ writeToDisk: false, numEvents: 1000, numUsers: 100, hasAnonIds: true });
|
|
278
|
-
const { eventData } = results;
|
|
279
|
-
const anonymousEvents = eventData.map(a => a.device_id).filter(a => a);
|
|
280
|
-
const userIds = eventData.map(a => a.user_id).filter(a => a);
|
|
281
|
-
expect(anonymousEvents.length).toBe(eventData.length);
|
|
282
|
-
expect(userIds.length).toBeLessThan(anonymousEvents.length);
|
|
283
|
-
}, timeout);
|
|
284
|
-
|
|
285
|
-
test('no anonymousIds', async () => {
|
|
286
|
-
const results = await generate({ writeToDisk: false, numEvents: 1000, numUsers: 100, hasAnonIds: false });
|
|
287
|
-
const { eventData } = results;
|
|
288
|
-
const unanonymousEvents = eventData.map(a => a.device_id).filter(a => a);
|
|
289
|
-
expect(unanonymousEvents.length).toBe(0);
|
|
290
|
-
}, timeout);
|
|
291
|
-
|
|
292
|
-
test('sends data to mixpanel', async () => {
|
|
293
|
-
console.log('NETWORK TEST');
|
|
294
|
-
const results = await generate({ verbose: false, writeToDisk: false, numEvents: 1100, numUsers: 100, seed: "deal with it", token: testToken });
|
|
295
|
-
const { events, users, groups } = results.importResults;
|
|
296
|
-
expect(events.success).toBeGreaterThan(980);
|
|
297
|
-
expect(users.success).toBe(100);
|
|
298
|
-
expect(groups.length).toBe(0);
|
|
299
|
-
}, timeout);
|
|
300
|
-
|
|
301
|
-
test('every record is valid', async () => {
|
|
302
|
-
console.log('VALIDATION TEST');
|
|
303
|
-
const results = await generate({ verbose: false, writeToDisk: false, numEvents: 1000, numUsers: 100 });
|
|
304
|
-
const { eventData, userProfilesData } = results;
|
|
305
|
-
const areEventsValid = eventData.every(validateEvent);
|
|
306
|
-
const areUsersValid = userProfilesData.every(validateUser);
|
|
307
|
-
|
|
308
|
-
const invalidEvents = eventData.filter(e => !validateEvent(e));
|
|
309
|
-
const invalidUsers = userProfilesData.filter(u => !validateUser(u));
|
|
310
|
-
|
|
311
|
-
expect(areEventsValid).toBe(true);
|
|
312
|
-
expect(areUsersValid).toBe(true);
|
|
313
|
-
}, timeout);
|
|
314
|
-
|
|
315
|
-
test('every date is valid', async () => {
|
|
316
|
-
console.log('DATE TEST');
|
|
317
|
-
const results = await generate({ ...simple, writeToDisk: false, verbose: false, numEvents: 1000, numUsers: 100 });
|
|
318
|
-
const { eventData } = results;
|
|
319
|
-
const invalidDates = eventData.filter(e => !validTime(e.time));
|
|
320
|
-
expect(eventData.every(e => validTime(e.time))).toBe(true);
|
|
321
|
-
|
|
322
|
-
}, timeout);
|
|
323
|
-
|
|
324
|
-
test('anonymous users', async () => {
|
|
325
|
-
console.log('ANON TEST');
|
|
326
|
-
const results = await generate({ ...anon, writeToDisk: false, verbose: false, numEvents: 1000, numUsers: 100 });
|
|
327
|
-
const { userProfilesData } = results;
|
|
328
|
-
expect(userProfilesData.every(u => u.name === 'Anonymous User')).toBe(true);
|
|
329
|
-
|
|
330
|
-
}, timeout);
|
|
331
|
-
|
|
332
|
-
test('no avatars (default)', async () => {
|
|
333
|
-
console.log('AVATAR TEST');
|
|
334
|
-
const results = await generate({ ...simple, writeToDisk: false, verbose: false, numEvents: 1000, numUsers: 100 });
|
|
335
|
-
const { userProfilesData } = results;
|
|
336
|
-
expect(userProfilesData.every(u => !u.avatar)).toBe(true);
|
|
337
|
-
|
|
338
|
-
}, timeout);
|
|
339
|
-
|
|
340
|
-
test('yes avatars', async () => {
|
|
341
|
-
console.log('AVATAR TEST');
|
|
342
|
-
const results = await generate({ ...simple, writeToDisk: false, verbose: false, numEvents: 1000, numUsers: 100, hasAvatar: true });
|
|
343
|
-
const { userProfilesData } = results;
|
|
344
|
-
expect(userProfilesData.every(u => u.avatar)).toBe(true);
|
|
345
|
-
|
|
346
|
-
}, timeout);
|
|
347
|
-
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
//helpers
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
function validateEvent(event) {
|
|
357
|
-
if (!event.event) return false;
|
|
358
|
-
if (!event.device_id && !event.user_id) return false;
|
|
359
|
-
if (!event.time) return false;
|
|
360
|
-
if (!event.insert_id) return false;
|
|
361
|
-
return true;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
function validateUser(user) {
|
|
366
|
-
if (!user.distinct_id) return false;
|
|
367
|
-
if (!user.name) return false;
|
|
368
|
-
if (!user.email) return false;
|
|
369
|
-
// if (!user.created) return false;
|
|
370
|
-
return true;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
function validTime(str) {
|
|
375
|
-
if (!str) return false;
|
|
376
|
-
if (str.startsWith('-')) return false;
|
|
377
|
-
if (!str.startsWith('20')) return false;
|
|
378
|
-
return true;
|
|
379
|
-
}
|