feat: exponer feeds ICS en la UI y añadir /app/integrations
Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>webui
parent
b738d8008d
commit
2412b7fa66
@ -0,0 +1,14 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch }) => {
|
||||
const res = await fetch('/api/integrations/feeds', { method: 'GET', headers: { 'cache-control': 'no-store' } });
|
||||
if (!res.ok) {
|
||||
return {
|
||||
personal: { url: null },
|
||||
aggregate: { url: null },
|
||||
groups: []
|
||||
};
|
||||
}
|
||||
const data = await res.json();
|
||||
return data;
|
||||
};
|
||||
@ -0,0 +1,76 @@
|
||||
import { describe, it, expect, afterAll } from 'bun:test';
|
||||
import Database from 'bun:sqlite';
|
||||
import { startWebServer } from './helpers/server';
|
||||
import { createTempDb } from './helpers/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 page - /app/integrations', () => {
|
||||
const PORT = 19124;
|
||||
const BASE = `http://127.0.0.1:${PORT}`;
|
||||
const USER = '34600123456';
|
||||
const GROUP = '123@g.us';
|
||||
const SID = 'sid-test-456';
|
||||
|
||||
const tmp = createTempDb();
|
||||
const db: any = tmp.db as Database;
|
||||
|
||||
// Sembrar datos mínimos
|
||||
db.exec(`INSERT OR IGNORE INTO users (id) VALUES ('${USER}')`);
|
||||
db.exec(`INSERT OR IGNORE INTO groups (id, community_id, name, active) VALUES ('${GROUP}', 'comm1', 'Group Test', 1)`);
|
||||
db.exec(`INSERT OR IGNORE INTO allowed_groups (group_id, status, discovered_at, updated_at) VALUES ('${GROUP}', 'allowed', '${toIsoSql()}', '${toIsoSql()}')`);
|
||||
db.exec(`INSERT OR IGNORE INTO group_members (group_id, user_id, is_admin, is_active, first_seen_at, last_seen_at) VALUES ('${GROUP}', '${USER}', 0, 1, '${toIsoSql()}', '${toIsoSql()}')`);
|
||||
|
||||
const sidHashPromise = sha256Hex(SID);
|
||||
const serverPromise = startWebServer({
|
||||
port: PORT,
|
||||
env: {
|
||||
DB_PATH: tmp.path,
|
||||
WEB_BASE_URL: BASE
|
||||
}
|
||||
});
|
||||
|
||||
let server: Awaited<typeof serverPromise> | null = null;
|
||||
|
||||
afterAll(async () => {
|
||||
try { await server?.stop(); } catch {}
|
||||
try { tmp.cleanup(); } catch {}
|
||||
});
|
||||
|
||||
it('GET /app/integrations: muestra URLs ICS (personal, grupo y multigrupo) cuando se autogeneran', async () => {
|
||||
server = await serverPromise;
|
||||
|
||||
const sidHash = await sidHashPromise;
|
||||
// Insertar sesión
|
||||
db.exec(`
|
||||
INSERT OR REPLACE INTO web_sessions (id, user_id, session_hash, created_at, last_seen_at, expires_at)
|
||||
VALUES ('sess-2', '${USER}', '${sidHash}', '${toIsoSql()}', '${toIsoSql()}', '${toIsoSql(new Date(Date.now() + 2 * 60 * 60 * 1000))}')
|
||||
`);
|
||||
|
||||
const res = await fetch(`${BASE}/app/integrations`, {
|
||||
headers: { cookie: `sid=${SID}` }
|
||||
});
|
||||
expect(res.status).toBe(200);
|
||||
const html = await res.text();
|
||||
|
||||
// Debe incluir títulos y al menos una URL .ics
|
||||
expect(html.includes('Integraciones')).toBe(true);
|
||||
expect(html.includes('Mis tareas (con fecha)')).toBe(true);
|
||||
expect(html.includes('Mis grupos (sin responsable)')).toBe(true);
|
||||
expect(html.includes('/ics/personal/')).toBe(true);
|
||||
expect(html.includes('/ics/group/')).toBe(true);
|
||||
expect(html.includes('/ics/aggregate/')).toBe(true);
|
||||
expect(html.includes('.ics')).toBe(true);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue