You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
taskbot/tests/web/app.preferences.page.test.ts

80 lines
2.5 KiB
TypeScript

import { describe, it, expect, beforeAll, afterAll } from 'bun:test';
import { Database } from 'bun:sqlite';
import { mkdtempSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { startWebServer } from './helpers/server';
import { initializeDatabase, ensureUserExists } from '../../src/db';
async function sha256Hex(input: string): Promise<string> {
const enc = new TextEncoder().encode(input);
const buf = await crypto.subtle.digest('SHA-256', enc);
const bytes = new Uint8Array(buf);
return Array.from(bytes)
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
}
function toIsoSql(d = new Date()): string {
return d.toISOString().replace('T', ' ').replace('Z', '');
}
describe('Web UI - /app/preferences', () => {
const userId = '34600123456';
let dbPath: string;
let server: Awaited<ReturnType<typeof startWebServer>> | null = null;
let tmpDir: string;
beforeAll(async () => {
tmpDir = mkdtempSync(join(tmpdir(), 'webtest-'));
dbPath = join(tmpDir, 'tasks.db');
// Inicializar DB en archivo (como en prod)
const db = new Database(dbPath);
initializeDatabase(db);
ensureUserExists(userId, db);
// Crear sesión válida
const sid = 'sid-test-pref-ui';
const hash = await sha256Hex(sid);
const now = new Date();
const nowIso = toIsoSql(now);
const expIso = toIsoSql(new Date(now.getTime() + 60 * 60 * 1000)); // +1h
db.prepare(`
INSERT INTO web_sessions (session_hash, user_id, created_at, last_seen_at, expires_at)
VALUES (?, ?, ?, ?, ?)
`).run(hash, userId, nowIso, nowIso, expIso);
db.close();
// Arrancar web apuntando a este DB
server = await startWebServer({
port: 19110,
env: { DB_PATH: dbPath, TZ: 'UTC' }
});
});
afterAll(async () => {
try { await server?.stop(); } catch {}
try { rmSync(tmpDir, { recursive: true, force: true }); } catch {}
});
it('renderiza el formulario con valores por defecto y muestra próximo recordatorio', async () => {
const sid = 'sid-test-pref-ui';
const res = await fetch(`${server!.baseUrl}/app/preferences`, {
headers: { Cookie: `sid=${sid}` }
});
expect(res.status).toBe(200);
const html = await res.text();
expect(html).toContain('Preferencias de recordatorios');
// select de frecuencia y opción 'off' presente
expect(html).toContain('<option value="off">Apagado</option>');
// input type="time" con valor por defecto
expect(html).toContain('type="time"');
expect(html).toContain('08:30');
// bloque de "Próximo recordatorio"
expect(html).toContain('Próximo recordatorio');
});
});