Files
waggle-os/app/tests/cockpit-agent-intelligence.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

93 lines
2.9 KiB
TypeScript

/**
* AgentIntelligenceCard — tests that feedback stats are rendered correctly.
*
* Uses a lightweight approach: tests the data-transformation logic and
* verifies the component accepts the FeedbackStats shape without errors.
* Since this is a Tauri desktop app (not Next.js), we test the card's
* data contract and rendering expectations.
*/
import { describe, it, expect } from 'vitest';
import type { FeedbackStats } from '../src/components/cockpit/types';
describe('AgentIntelligenceCard data contract', () => {
it('FeedbackStats shape matches the /api/feedback/stats response', () => {
const stats: FeedbackStats = {
totalFeedback: 42,
positiveRate: 0.85,
topIssues: ['wrong_answer', 'too_verbose'],
correctionsThisWeek: 3,
improvementTrend: '+12%',
};
expect(stats.totalFeedback).toBe(42);
expect(stats.positiveRate).toBe(0.85);
expect(stats.topIssues).toHaveLength(2);
expect(stats.correctionsThisWeek).toBe(3);
expect(stats.improvementTrend).toBe('+12%');
});
it('handles empty stats (zero feedback)', () => {
const stats: FeedbackStats = {
totalFeedback: 0,
positiveRate: 0,
topIssues: [],
correctionsThisWeek: 0,
improvementTrend: '0%',
};
expect(stats.totalFeedback).toBe(0);
expect(stats.positiveRate).toBe(0);
expect(stats.topIssues).toEqual([]);
});
it('handles negative improvement trend', () => {
const stats: FeedbackStats = {
totalFeedback: 10,
positiveRate: 0.5,
topIssues: ['wrong_tool'],
correctionsThisWeek: 7,
improvementTrend: '-5%',
};
expect(stats.improvementTrend).toBe('-5%');
// Negative trend starts with '-'
expect(stats.improvementTrend.startsWith('-')).toBe(true);
});
it('trend parsing for positive values', () => {
const trend = '+12%';
const match = trend.match(/^([+-]?\d+)%$/);
expect(match).not.toBeNull();
expect(parseInt(match![1], 10)).toBe(12);
});
it('trend parsing for negative values', () => {
const trend = '-5%';
const match = trend.match(/^([+-]?\d+)%$/);
expect(match).not.toBeNull();
expect(parseInt(match![1], 10)).toBe(-5);
});
it('trend parsing for zero', () => {
const trend = '0%';
const match = trend.match(/^([+-]?\d+)%$/);
expect(match).not.toBeNull();
expect(parseInt(match![1], 10)).toBe(0);
});
it('reason formatting converts snake_case to Title Case', () => {
const formatReason = (reason: string): string =>
reason
.split('_')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
expect(formatReason('wrong_answer')).toBe('Wrong Answer');
expect(formatReason('too_verbose')).toBe('Too Verbose');
expect(formatReason('wrong_tool')).toBe('Wrong Tool');
expect(formatReason('too_slow')).toBe('Too Slow');
expect(formatReason('other')).toBe('Other');
});
});