mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-05 13:15:24 +02:00
78840c64a8
Dashboard: Supabase edge function serving self-contained HTML with PKCE OAuth, 6 parallel client-side REST queries, SVG charts, dark theme, auto-refresh, who's-online from heartbeats. Public URL. Regression alert: webhook on eval_runs INSERT, 5-min cooldown dedup via alert_cooldowns, Slack notification on >5% pass rate drop. Weekly digest: pg_cron Monday 9am UTC, aggregates 7-day team data, Slack message with evals/ships/sessions/costs. 15 tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
/**
|
|
* Tests for dashboard UI HTML generation.
|
|
*/
|
|
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { getDashboardHTML } from '../supabase/functions/dashboard/ui';
|
|
|
|
const SUPABASE_URL = 'https://test-project.supabase.co';
|
|
const ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.test-anon-key';
|
|
|
|
describe('getDashboardHTML', () => {
|
|
const html = getDashboardHTML(SUPABASE_URL, ANON_KEY);
|
|
|
|
test('returns valid HTML document', () => {
|
|
expect(html).toContain('<!DOCTYPE html>');
|
|
expect(html).toContain('<html');
|
|
expect(html).toContain('</html>');
|
|
});
|
|
|
|
test('contains page title', () => {
|
|
expect(html).toContain('<title>gstack Dashboard</title>');
|
|
});
|
|
|
|
test('embeds supabase URL', () => {
|
|
expect(html).toContain(SUPABASE_URL);
|
|
});
|
|
|
|
test('embeds anon key', () => {
|
|
expect(html).toContain(ANON_KEY);
|
|
});
|
|
|
|
test('contains login UI elements', () => {
|
|
expect(html).toContain('Sign in with GitHub');
|
|
});
|
|
|
|
test('contains tab navigation', () => {
|
|
expect(html).toContain('Overview');
|
|
expect(html).toContain('Evals');
|
|
expect(html).toContain('Ships');
|
|
expect(html).toContain('Costs');
|
|
expect(html).toContain('Leaderboard');
|
|
expect(html).toContain('QA');
|
|
});
|
|
|
|
test('contains auto-refresh logic', () => {
|
|
expect(html).toContain('visibilitychange');
|
|
expect(html).toContain('setInterval');
|
|
});
|
|
|
|
test('contains PKCE auth code', () => {
|
|
expect(html).toContain('code_challenge');
|
|
expect(html).toContain('code_verifier');
|
|
});
|
|
|
|
test('uses textContent for XSS prevention', () => {
|
|
expect(html).toContain('textContent');
|
|
});
|
|
|
|
test('contains dark theme styling', () => {
|
|
expect(html).toContain('#0a0a0a');
|
|
});
|
|
|
|
test('contains SVG chart elements', () => {
|
|
expect(html).toContain('svg');
|
|
});
|
|
|
|
test('fetches from eval_runs endpoint', () => {
|
|
expect(html).toContain('eval_runs');
|
|
});
|
|
|
|
test('fetches from ship_logs endpoint', () => {
|
|
expect(html).toContain('ship_logs');
|
|
});
|
|
|
|
test('fetches from sync_heartbeats for who\'s online', () => {
|
|
expect(html).toContain('sync_heartbeats');
|
|
});
|
|
|
|
test('contains sign out functionality', () => {
|
|
expect(html).toContain('Sign out');
|
|
});
|
|
});
|