馃 distributed transcription service thistle.dunkirk.sh
1import { afterEach, beforeEach, describe, expect, test } from "bun:test"; 2import db from "../db/schema"; 3import { createSession, createUser } from "./auth"; 4 5describe("subscription-protected routes", () => { 6 let testUserId: number; 7 let sessionCookie: string; 8 9 beforeEach(async () => { 10 // Create test user 11 const user = await createUser( 12 `test-${Date.now()}@example.com`, 13 "0".repeat(64), 14 "Test User", 15 ); 16 testUserId = user.id; 17 const sessionId = createSession(testUserId, "127.0.0.1", "test"); 18 sessionCookie = `session=${sessionId}`; 19 }); 20 21 afterEach(() => { 22 // Cleanup 23 db.run("DELETE FROM users WHERE id = ?", [testUserId]); 24 db.run("DELETE FROM subscriptions WHERE user_id = ?", [testUserId]); 25 }); 26 27 test("GET /api/transcriptions requires subscription", async () => { 28 const response = await fetch("http://localhost:3000/api/transcriptions", { 29 headers: { Cookie: sessionCookie }, 30 }); 31 32 expect(response.status).toBe(403); 33 const data = await response.json(); 34 expect(data.error).toContain("subscription"); 35 }); 36 37 test("GET /api/transcriptions succeeds with active subscription", async () => { 38 // Add subscription 39 db.run( 40 "INSERT INTO subscriptions (id, user_id, customer_id, status) VALUES (?, ?, ?, ?)", 41 ["test-sub", testUserId, "test-customer", "active"], 42 ); 43 44 const response = await fetch("http://localhost:3000/api/transcriptions", { 45 headers: { Cookie: sessionCookie }, 46 }); 47 48 expect(response.status).toBe(200); 49 const data = await response.json(); 50 expect(data.jobs).toBeDefined(); 51 }); 52 53 test("GET /api/transcriptions succeeds for admin without subscription", async () => { 54 // Make user admin 55 db.run("UPDATE users SET role = ? WHERE id = ?", ["admin", testUserId]); 56 57 const response = await fetch("http://localhost:3000/api/transcriptions", { 58 headers: { Cookie: sessionCookie }, 59 }); 60 61 expect(response.status).toBe(200); 62 const data = await response.json(); 63 expect(data.jobs).toBeDefined(); 64 }); 65 66 test("POST /api/transcriptions requires subscription", async () => { 67 const formData = new FormData(); 68 const file = new File(["test"], "test.mp3", { type: "audio/mpeg" }); 69 formData.append("audio", file); 70 71 const response = await fetch("http://localhost:3000/api/transcriptions", { 72 method: "POST", 73 headers: { Cookie: sessionCookie }, 74 body: formData, 75 }); 76 77 expect(response.status).toBe(403); 78 const data = await response.json(); 79 expect(data.error).toContain("subscription"); 80 }); 81 82 test("/api/auth/me includes subscription status", async () => { 83 const response = await fetch("http://localhost:3000/api/auth/me", { 84 headers: { Cookie: sessionCookie }, 85 }); 86 87 expect(response.status).toBe(200); 88 const data = await response.json(); 89 expect(data.has_subscription).toBe(false); 90 91 // Add subscription 92 db.run( 93 "INSERT INTO subscriptions (id, user_id, customer_id, status) VALUES (?, ?, ?, ?)", 94 ["test-sub", testUserId, "test-customer", "active"], 95 ); 96 97 const response2 = await fetch("http://localhost:3000/api/auth/me", { 98 headers: { Cookie: sessionCookie }, 99 }); 100 101 expect(response2.status).toBe(200); 102 const data2 = await response2.json(); 103 expect(data2.has_subscription).toBe(true); 104 }); 105});