CI / build-and-test (push) Successful in 13m34s
- Strategy Pattern front: ChannelProviderInterface + 6 providers (yt/dm/tw/pt/od/ru) + factory (ids longs/courts) - ChannelContentService: cache par onglet/tri/recherche (TTL 5min), pagination nextPage - ChannelPage: header (banniere/avatar/subs/description ...plus), tabs dynamiques par capabilities, grilles videos/shorts 9:16/playlists/live, recherche debounced, tri recent/populaire, infinite scroll IntersectionObserver, skeletons/empty/error - Backend: GET /api/channels/:provider/:id/content (videos/shorts/playlists/live) natif par provider
53 lines
2.1 KiB
JavaScript
53 lines
2.1 KiB
JavaScript
// Integration test for minimal telemetry (Step 13)
|
|
// Run with: npm run test:telemetry
|
|
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import os from 'node:os';
|
|
|
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'newtube-telemetry-test-'));
|
|
process.env.NEWTUBE_DB_FILE = path.join(tmpDir, 'test.db');
|
|
|
|
const dbMod = await import('../db.mjs');
|
|
const { insertUser, cryptoRandomUUID, insertTelemetryEvent, listTelemetryEvents, countTelemetryEvents } = dbMod;
|
|
|
|
function expect(cond, msg) {
|
|
if (!cond) throw new Error(`Assertion failed: ${msg}`);
|
|
}
|
|
function logOk(msg) { console.log(`✓ ${msg}`); }
|
|
|
|
const user = cryptoRandomUUID();
|
|
insertUser({ id: user, username: 'tel-a', email: null, passwordHash: 'x' });
|
|
|
|
// 1) Insert + read back
|
|
const row = insertTelemetryEvent({ userId: user, event: 'search_submit', meta: { providers: ['yt', 'dm'], queryLength: 5 } });
|
|
expect(row && row.id, 'insert returns a row with id');
|
|
logOk('insertTelemetryEvent returns id');
|
|
|
|
// 2) List filters by event
|
|
const all = listTelemetryEvents({ userId: undefined });
|
|
expect(all.length === 1, `one event stored (got ${all.length})`);
|
|
const mine = listTelemetryEvents({ event: 'search_submit' });
|
|
expect(mine.length === 1, 'list filters by event name');
|
|
const none = listTelemetryEvents({ event: 'provider_apply' });
|
|
expect(none.length === 0, 'unknown event name yields empty list');
|
|
logOk('listTelemetryEvents filters by event');
|
|
|
|
// 3) Count
|
|
expect(countTelemetryEvents({ event: 'search_submit' }) === 1, 'count by event');
|
|
expect(countTelemetryEvents({}) === 1, 'count all');
|
|
logOk('countTelemetryEvents');
|
|
|
|
// 4) Meta round-trips as JSON
|
|
const meta = JSON.parse(mine[0].metaJson);
|
|
expect(Array.isArray(meta.providers) && meta.providers.join(',') === 'yt,dm', 'meta.providers round-trips');
|
|
expect(meta.queryLength === 5, 'meta.queryLength round-trips');
|
|
logOk('meta JSON round-trip');
|
|
|
|
// 5) Long event names are truncated, never thrown
|
|
const longOk = insertTelemetryEvent({ userId: user, event: 'x'.repeat(500), meta: null });
|
|
expect(longOk !== null, 'oversized event name does not throw');
|
|
logOk('oversized event name handled');
|
|
|
|
console.log('\nAll telemetry tests passed.');
|