import { spawn } from 'child_process'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const AUTHENTIK_URL = process.env.AUTHENTIK_URL || 'http://localhost:9000'; const CLIENT_ID = process.env.CLIENT_ID || 'kaboot-spa'; const CLIENT_SECRET = process.env.CLIENT_SECRET || ''; const USERNAME = process.env.TEST_USERNAME || ''; const PASSWORD = process.env.TEST_PASSWORD || ''; const TEST_TOKEN = process.env.TEST_TOKEN || ''; async function getToken(): Promise { const tokenUrl = `${AUTHENTIK_URL}/application/o/token/`; if (CLIENT_SECRET) { const params = new URLSearchParams({ grant_type: 'client_credentials', client_id: CLIENT_ID, client_secret: CLIENT_SECRET, scope: 'openid profile email', }); const response = await fetch(tokenUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString(), }); if (response.ok) { const data = await response.json(); return data.access_token; } } if (!USERNAME || !PASSWORD) { throw new Error( 'TEST_USERNAME and TEST_PASSWORD must be set in .env.test\n' + 'See tests/README.md for setup instructions.' ); } const params = new URLSearchParams({ grant_type: 'password', client_id: CLIENT_ID, username: USERNAME, password: PASSWORD, scope: 'openid profile email', }); const response = await fetch(tokenUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString(), }); if (!response.ok) { const error = await response.text(); throw new Error(`Failed to get token: ${response.status} - ${error}`); } const data = await response.json(); return data.access_token; } async function runTests(token: string): Promise { return new Promise((resolve) => { const __dirname = dirname(fileURLToPath(import.meta.url)); const testFile = join(__dirname, 'api.test.ts'); const child = spawn(process.execPath, [ '--import', 'tsx', testFile ], { env: { ...process.env, TEST_TOKEN: token, }, stdio: 'inherit', }); child.on('close', (code) => { resolve(code ?? 1); }); }); } async function main() { console.log('Kaboot API Test Runner'); console.log('======================\n'); let token: string; if (TEST_TOKEN) { console.log('Using TEST_TOKEN from environment.\n'); token = TEST_TOKEN; } else { console.log('Obtaining access token from Authentik...'); try { token = await getToken(); console.log(' Token obtained successfully.\n'); } catch (error) { console.error(` Failed: ${error instanceof Error ? error.message : error}`); process.exit(1); } } console.log('Running API tests...\n'); const exitCode = await runTests(token); process.exit(exitCode); } main();