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.

103 lines
3.8 KiB
TypeScript

/**
* E2E test database seeder.
*
* Creates known test users and sessions in the test Postgres database.
* Designed to be idempotent: uses INSERT ... ON CONFLICT DO NOTHING.
*
* Usage: npx tsx seed.ts
*/
import pg from 'pg';
import { createHash } from 'node:crypto';
const { Client } = pg;
// ---------------------------------------------------------------------------
// Known test tokens (raw values that go into cookies / URLs).
// Their SHA-256 hashes are stored in the DB.
// ---------------------------------------------------------------------------
export const ADMIN_SESSION_TOKEN = 'e2e-admin-session-token-for-testing-only';
export const USER_SESSION_TOKEN = 'e2e-user-session-token-for-testing-only';
function sha256(input: string): string {
return createHash('sha256').update(input).digest('hex');
}
async function seed() {
const databaseUrl =
process.env.DATABASE_URL ??
'postgres://ai_synth_test:testpassword@localhost:5433/ai_synth_test';
const client = new Client({ connectionString: databaseUrl });
await client.connect();
try {
// -----------------------------------------------------------------------
// 1. Create admin user
// -----------------------------------------------------------------------
const adminId = '00000000-0000-4000-a000-000000000001';
await client.query(
`INSERT INTO users (id, email, display_name, role, created_at, updated_at)
VALUES ($1, 'admin@test.local', 'Test Admin', 'admin', now(), now())
ON CONFLICT (id) DO NOTHING`,
[adminId],
);
// -----------------------------------------------------------------------
// 2. Create regular user
// -----------------------------------------------------------------------
const userId = '00000000-0000-4000-a000-000000000002';
await client.query(
`INSERT INTO users (id, email, display_name, role, created_at, updated_at)
VALUES ($1, 'user@test.local', 'Test User', 'user', now(), now())
ON CONFLICT (id) DO NOTHING`,
[userId],
);
// -----------------------------------------------------------------------
// 3. Create sessions (hash tokens with SHA-256 before inserting)
// -----------------------------------------------------------------------
const adminSessionHash = sha256(ADMIN_SESSION_TOKEN);
const userSessionHash = sha256(USER_SESSION_TOKEN);
const expiresAt = new Date(
Date.now() + 30 * 24 * 60 * 60 * 1000,
).toISOString(); // 30 days
await client.query(
`INSERT INTO sessions (session_hash, user_id, created_at, expires_at, last_active_at)
VALUES ($1, $2, now(), $3, now())
ON CONFLICT (session_hash) DO NOTHING`,
[adminSessionHash, adminId, expiresAt],
);
await client.query(
`INSERT INTO sessions (session_hash, user_id, created_at, expires_at, last_active_at)
VALUES ($1, $2, now(), $3, now())
ON CONFLICT (session_hash) DO NOTHING`,
[userSessionHash, userId, expiresAt],
);
// -----------------------------------------------------------------------
// 4. Ensure Gemini provider exists and is enabled
// (The migration seeds it, but make sure is_enabled = true)
// -----------------------------------------------------------------------
await client.query(
`UPDATE admin_providers SET is_enabled = true WHERE provider_name = 'gemini'`,
);
console.log('Seed completed successfully.');
console.log(` Admin: admin@test.local (id=${adminId})`);
console.log(` User: user@test.local (id=${userId})`);
console.log(` Admin session hash: ${adminSessionHash.slice(0, 16)}...`);
console.log(` User session hash: ${userSessionHash.slice(0, 16)}...`);
} finally {
await client.end();
}
}
seed().catch((err) => {
console.error('Seed failed:', err);
process.exit(1);
});