Files
waggle-os/packages/core/tests/telemetry.test.ts
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

113 lines
3.8 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'vitest';
import { TelemetryCollector } from '../src/telemetry.js';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
describe('TelemetryCollector', () => {
let tmpDir: string;
beforeEach(() => {
tmpDir = path.join(os.tmpdir(), `waggle-telemetry-test-${Date.now()}`);
fs.mkdirSync(tmpDir, { recursive: true });
});
it('records events when enabled', () => {
const collector = new TelemetryCollector(tmpDir, true);
collector.recordToolUse('web_search');
collector.recordToolUse('web_search');
collector.recordToolUse('save_memory');
const report = collector.getReport();
expect(report.totalEvents).toBe(3);
const webSearch = report.events.find(e => e.name === 'web_search');
expect(webSearch?.count).toBe(2);
});
it('silently drops events when disabled', () => {
const collector = new TelemetryCollector(tmpDir, false);
collector.recordToolUse('web_search');
collector.recordCommand('/research');
collector.recordError('timeout');
const report = collector.getReport();
expect(report.totalEvents).toBe(0);
});
it('no PII in collected data — tool names only', () => {
const collector = new TelemetryCollector(tmpDir, true);
collector.recordToolUse('connector_github_create_issue');
collector.recordError('api_timeout');
collector.recordCapabilityGap('email sending');
const report = collector.getReport();
for (const event of report.events) {
// Only category, name, count, date — no message content or file paths
expect(Object.keys(event).sort()).toEqual(['category', 'count', 'date', 'name']);
}
});
it('daily aggregation: same-day events merge counts', () => {
const collector = new TelemetryCollector(tmpDir, true);
collector.recordToolUse('bash');
collector.recordToolUse('bash');
collector.recordToolUse('bash');
const report = collector.getReport();
const bashEvents = report.events.filter(e => e.name === 'bash');
expect(bashEvents).toHaveLength(1);
expect(bashEvents[0].count).toBe(3);
});
it('flush writes to telemetry.json', () => {
const collector = new TelemetryCollector(tmpDir, true);
collector.recordToolUse('search_memory');
collector.flush();
const filePath = path.join(tmpDir, 'telemetry.json');
expect(fs.existsSync(filePath)).toBe(true);
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
expect(data).toHaveLength(1);
expect(data[0].name).toBe('search_memory');
collector.close();
fs.rmSync(tmpDir, { recursive: true, force: true });
});
it('report covers last N days', () => {
const collector = new TelemetryCollector(tmpDir, true);
collector.recordToolUse('today_tool');
const report = collector.getReport(7);
expect(report.events.length).toBeGreaterThan(0);
expect(report.dateRange.from).toBeTruthy();
});
it('setEnabled toggles collection', () => {
const collector = new TelemetryCollector(tmpDir, false);
expect(collector.isEnabled()).toBe(false);
collector.setEnabled(true);
expect(collector.isEnabled()).toBe(true);
collector.recordToolUse('test_tool');
expect(collector.getReport().totalEvents).toBe(1);
});
it('recordSession aggregates duration and interaction count', () => {
const collector = new TelemetryCollector(tmpDir, true);
collector.recordSession(30000, 15);
collector.recordSession(20000, 10);
const report = collector.getReport();
const duration = report.events.find(e => e.name === 'duration_total_ms');
const interactions = report.events.find(e => e.name === 'interaction_count');
const sessions = report.events.find(e => e.name === 'session_count');
expect(duration?.count).toBe(50000);
expect(interactions?.count).toBe(25);
expect(sessions?.count).toBe(2);
});
});