馃 distributed transcription service
thistle.dunkirk.sh
1import { expect, test } from "bun:test";
2import {
3 deleteTranscript,
4 getTranscript,
5 getTranscriptVTT,
6 hasTranscript,
7 saveTranscript,
8 saveTranscriptVTT,
9} from "./transcript-storage";
10
11test("transcript storage", async () => {
12 const testId = "test-transcript-123";
13 const testContent = "This is a test transcript with some content.";
14
15 // Should not exist initially
16 expect(await hasTranscript(testId)).toBe(false);
17 expect(await getTranscript(testId)).toBe(null);
18
19 // Save transcript
20 await saveTranscript(testId, testContent);
21
22 // Should exist now
23 expect(await hasTranscript(testId)).toBe(true);
24 expect(await getTranscript(testId)).toBe(testContent);
25
26 // Delete transcript
27 await deleteTranscript(testId);
28
29 // Should not exist anymore
30 expect(await hasTranscript(testId)).toBe(false);
31 expect(await getTranscript(testId)).toBe(null);
32});
33
34test("transcript storage handles large content", async () => {
35 const testId = "test-large-transcript";
36 // Create a 1MB transcript
37 const largeContent = "A".repeat(1024 * 1024);
38
39 await saveTranscript(testId, largeContent);
40 const retrieved = await getTranscript(testId);
41
42 expect(retrieved).toBe(largeContent);
43 expect(retrieved?.length).toBe(1024 * 1024);
44
45 await deleteTranscript(testId);
46});
47
48test("transcript storage prevents directory traversal", async () => {
49 const maliciousIds = [
50 "../../../etc/passwd",
51 "../../secret.txt",
52 "../config",
53 "test/../../../etc/passwd",
54 "test/../../passwd",
55 ];
56
57 for (const id of maliciousIds) {
58 await expect(saveTranscript(id, "malicious")).rejects.toThrow();
59 await expect(getTranscript(id)).rejects.toThrow();
60 await expect(deleteTranscript(id)).rejects.toThrow();
61 await expect(hasTranscript(id)).rejects.toThrow();
62 }
63});
64
65test("transcript storage validates ID format", async () => {
66 const invalidIds = [
67 "test; rm -rf /",
68 "test`whoami`",
69 "test\x00null",
70 "test\nls",
71 "test&&ls",
72 ];
73
74 for (const id of invalidIds) {
75 await expect(saveTranscript(id, "test")).rejects.toThrow(
76 "Invalid transcription ID",
77 );
78 }
79});
80
81test("transcript storage accepts valid UUIDs", async () => {
82 const validIds = [
83 "550e8400-e29b-41d4-a716-446655440000",
84 "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
85 "test-abc-123",
86 "abc123",
87 ];
88
89 for (const id of validIds) {
90 await saveTranscript(id, "test");
91 expect(await getTranscript(id)).toBe("test");
92 await deleteTranscript(id);
93 }
94});
95
96test("VTT transcript storage", async () => {
97 const testId = "test-vtt-123";
98 const vttContent = "WEBVTT\n\n00:00:00.000 --> 00:00:02.500\nHello world\n\n";
99
100 // Save VTT
101 await saveTranscriptVTT(testId, vttContent);
102
103 // Read VTT
104 const retrieved = await getTranscriptVTT(testId);
105 expect(retrieved).toBe(vttContent);
106
107 // Clean up
108 await deleteTranscript(testId);
109});
110