···
9
-
import { hashPasswordClient } from "./lib/client-auth";
import type { Subprocess } from "bun";
10
+
import { hashPasswordClient } from "./lib/client-auth";
// Test server configuration
···
const stdoutReader = serverProcess.stdout.getReader();
const stderrReader = serverProcess.stderr.getReader();
const decoder = new TextDecoder();
···
···
// Clear database between each test
const db = require("bun:sqlite").Database.open(TEST_DB_PATH);
// Delete all data from tables (preserve schema)
db.run("DELETE FROM rate_limit_attempts");
db.run("DELETE FROM email_change_tokens");
···
db.run("DELETE FROM classes");
db.run("DELETE FROM class_waitlist");
db.run("DELETE FROM users WHERE id != 0"); // Keep ghost user
···
// Helper to register a user, verify email, and get session via login
197
-
async function registerAndLogin(user: { email: string; password: string; name?: string }): Promise<string> {
197
+
async function registerAndLogin(user: {
201
+
}): Promise<string> {
const hashedPassword = await clientHashPassword(user.email, user.password);
···
// Helper to add active subscription to a user
function addSubscription(userEmail: string): void {
const db = require("bun:sqlite").Database.open(TEST_DB_PATH);
245
-
const user = db.query("SELECT id FROM users WHERE email = ?").get(userEmail) as { id: number };
250
+
.query("SELECT id FROM users WHERE email = ?")
251
+
.get(userEmail) as { id: number };
throw new Error(`User ${userEmail} not found`);
"INSERT INTO subscriptions (id, user_id, customer_id, status) VALUES (?, ?, ?, ?)",
253
-
[`test-sub-${user.id}`, user.id, `test-customer-${user.id}`, "active"]
259
+
[`test-sub-${user.id}`, user.id, `test-customer-${user.id}`, "active"],
···
expect(response.status).toBe(201);
const data = await response.json();
expect(data.user).toBeDefined();
expect(data.user.email).toBe(TEST_USER.email);
···
expect(data.error).toBe("Email and password required");
306
-
"should reject registration with invalid password format",
308
-
const response = await fetch(`${BASE_URL}/api/auth/register`, {
310
-
headers: { "Content-Type": "application/json" },
311
-
body: JSON.stringify({
312
-
email: TEST_USER.email,
311
+
test("should reject registration with invalid password format", async () => {
312
+
const response = await fetch(`${BASE_URL}/api/auth/register`, {
314
+
headers: { "Content-Type": "application/json" },
315
+
body: JSON.stringify({
316
+
email: TEST_USER.email,
317
-
expect(response.status).toBe(400);
318
-
const data = await response.json();
319
-
expect(data.error).toBe("Invalid password format");
321
+
expect(response.status).toBe(400);
322
+
const data = await response.json();
323
+
expect(data.error).toBe("Invalid password format");
test("should reject duplicate email registration", async () => {
const hashedPassword = await clientHashPassword(
···
// Manually complete the email change in the database (simulating verification)
const db = require("bun:sqlite").Database.open(TEST_DB_PATH);
476
-
const tokenData = db.query("SELECT user_id, new_email FROM email_change_tokens ORDER BY created_at DESC LIMIT 1").get() as { user_id: number, new_email: string };
477
-
db.run("UPDATE users SET email = ?, email_verified = 1 WHERE id = ?", [tokenData.new_email, tokenData.user_id]);
478
-
db.run("DELETE FROM email_change_tokens WHERE user_id = ?", [tokenData.user_id]);
479
+
const tokenData = db
481
+
"SELECT user_id, new_email FROM email_change_tokens ORDER BY created_at DESC LIMIT 1",
483
+
.get() as { user_id: number; new_email: string };
484
+
db.run("UPDATE users SET email = ?, email_verified = 1 WHERE id = ?", [
485
+
tokenData.new_email,
488
+
db.run("DELETE FROM email_change_tokens WHERE user_id = ?", [
···
describe("API Endpoints - Health", () => {
describe("GET /api/health", () => {
650
-
"should return service health status with details",
652
-
const response = await fetch(`${BASE_URL}/api/health`);
661
+
test("should return service health status with details", async () => {
662
+
const response = await fetch(`${BASE_URL}/api/health`);
654
-
expect(response.status).toBe(200);
655
-
const data = await response.json();
656
-
expect(data).toHaveProperty("status");
657
-
expect(data).toHaveProperty("timestamp");
658
-
expect(data).toHaveProperty("services");
659
-
expect(data.services).toHaveProperty("database");
660
-
expect(data.services).toHaveProperty("whisper");
661
-
expect(data.services).toHaveProperty("storage");
664
+
expect(response.status).toBe(200);
665
+
const data = await response.json();
666
+
expect(data).toHaveProperty("status");
667
+
expect(data).toHaveProperty("timestamp");
668
+
expect(data).toHaveProperty("services");
669
+
expect(data.services).toHaveProperty("database");
670
+
expect(data.services).toHaveProperty("whisper");
671
+
expect(data.services).toHaveProperty("storage");
···
test("should return user transcriptions", async () => {
const sessionCookie = await registerAndLogin(TEST_USER);
addSubscription(TEST_USER.email);
···
test("should upload audio file and start transcription", async () => {
const sessionCookie = await registerAndLogin(TEST_USER);
addSubscription(TEST_USER.email);
···
test("should reject non-audio files", async () => {
const sessionCookie = await registerAndLogin(TEST_USER);
addSubscription(TEST_USER.email);
···
test("should reject files exceeding size limit", async () => {
const sessionCookie = await registerAndLogin(TEST_USER);
addSubscription(TEST_USER.email);
···
adminCookie = await registerAndLogin(TEST_ADMIN);
// Manually set admin role in database
const db = require("bun:sqlite").Database.open(TEST_DB_PATH);
db.run("UPDATE users SET role = 'admin' WHERE email = ?", [
···
.query<{ id: number }, [string]>("SELECT id FROM users WHERE email = ?")
userId = userIdResult?.id;
···
describe("POST /api/passkeys/register/options", () => {
1099
-
"should return registration options for authenticated user",
1101
-
const response = await authRequest(
1102
-
`${BASE_URL}/api/passkeys/register/options`,
1107
+
test("should return registration options for authenticated user", async () => {
1108
+
const response = await authRequest(
1109
+
`${BASE_URL}/api/passkeys/register/options`,
1109
-
expect(response.status).toBe(200);
1110
-
const data = await response.json();
1111
-
expect(data).toHaveProperty("challenge");
1112
-
expect(data).toHaveProperty("rp");
1113
-
expect(data).toHaveProperty("user");
1116
+
expect(response.status).toBe(200);
1117
+
const data = await response.json();
1118
+
expect(data).toHaveProperty("challenge");
1119
+
expect(data).toHaveProperty("rp");
1120
+
expect(data).toHaveProperty("user");
test("should require authentication", async () => {
const response = await fetch(