馃 distributed transcription service
thistle.dunkirk.sh
1import { afterEach, beforeEach, expect, test } from "bun:test";
2import db from "../db/schema";
3import {
4 createClass,
5 createMeetingTime,
6 deleteClass,
7 enrollUserInClass,
8 getClassesForUser,
9 getMeetingTimesForClass,
10 isUserEnrolledInClass,
11 removeUserFromClass,
12} from "./classes";
13
14// Track created resources for cleanup
15let createdUserIds: number[] = [];
16let createdClassIds: string[] = [];
17
18beforeEach(() => {
19 createdUserIds = [];
20 createdClassIds = [];
21});
22
23afterEach(() => {
24 // Clean up classes (cascades to members and meeting times)
25 for (const classId of createdClassIds) {
26 try {
27 deleteClass(classId);
28 } catch {
29 // May already be deleted
30 }
31 }
32
33 // Clean up users
34 for (const userId of createdUserIds) {
35 try {
36 db.run("DELETE FROM users WHERE id = ?", [userId]);
37 } catch {
38 // May already be deleted
39 }
40 }
41});
42
43function createTestUser(email: string): number {
44 db.run("INSERT INTO users (email, password_hash) VALUES (?, ?)", [
45 email,
46 "hash",
47 ]);
48 const userId = db
49 .query<{ id: number }, []>("SELECT last_insert_rowid() as id")
50 .get()?.id;
51 if (!userId) throw new Error("Failed to create user");
52 createdUserIds.push(userId);
53 return userId;
54}
55
56function createTestClass(data: {
57 course_code: string;
58 name: string;
59 professor: string;
60 semester: string;
61 year: number;
62}) {
63 const cls = createClass(data);
64 createdClassIds.push(cls.id);
65 return cls;
66}
67
68test("creates a class with all required fields", () => {
69 const cls = createTestClass({
70 course_code: "CS 101",
71 name: "Intro to CS",
72 professor: "Dr. Smith",
73 semester: "Fall",
74 year: 2024,
75 });
76
77 expect(cls.id).toBeTruthy();
78 expect(cls.course_code).toBe("CS 101");
79 expect(cls.name).toBe("Intro to CS");
80 expect(cls.professor).toBe("Dr. Smith");
81 expect(cls.semester).toBe("Fall");
82 expect(cls.year).toBe(2024);
83 expect(cls.archived).toBe(false);
84});
85
86test("enrolls user in class", () => {
87 const userId = createTestUser("test@example.com");
88
89 const cls = createTestClass({
90 course_code: "CS 101",
91 name: "Intro to CS",
92 professor: "Dr. Smith",
93 semester: "Fall",
94 year: 2024,
95 });
96
97 // Enroll user
98 enrollUserInClass(userId, cls.id);
99
100 // Verify enrollment
101 const isEnrolled = isUserEnrolledInClass(userId, cls.id);
102 expect(isEnrolled).toBe(true);
103
104 // Cleanup enrollment
105 removeUserFromClass(userId, cls.id);
106});
107
108test("gets classes for enrolled user", () => {
109 const userId = createTestUser("test@example.com");
110
111 // Create two classes
112 const cls1 = createTestClass({
113 course_code: "CS 101",
114 name: "Intro to CS",
115 professor: "Dr. Smith",
116 semester: "Fall",
117 year: 2024,
118 });
119
120 const cls2 = createTestClass({
121 course_code: "CS 102",
122 name: "Data Structures",
123 professor: "Dr. Jones",
124 semester: "Fall",
125 year: 2024,
126 });
127
128 // Enroll user in only one class
129 enrollUserInClass(userId, cls1.id);
130
131 // Get classes for user (non-admin)
132 const classesResult = getClassesForUser(userId, false);
133 expect(classesResult.data.length).toBe(1);
134 expect(classesResult.data[0]?.id).toBe(cls1.id);
135
136 // Admin should see all classes (not just the 2 test classes, but all in DB)
137 const allClassesResult = getClassesForUser(userId, true);
138 expect(allClassesResult.data.length).toBeGreaterThanOrEqual(2);
139 expect(allClassesResult.data.some((c) => c.id === cls1.id)).toBe(true);
140 expect(allClassesResult.data.some((c) => c.id === cls2.id)).toBe(true);
141
142 // Cleanup enrollment
143 removeUserFromClass(userId, cls1.id);
144});
145
146test("creates and retrieves meeting times", () => {
147 const cls = createTestClass({
148 course_code: "CS 101",
149 name: "Intro to CS",
150 professor: "Dr. Smith",
151 semester: "Fall",
152 year: 2024,
153 });
154
155 createMeetingTime(cls.id, "Monday Lecture");
156 createMeetingTime(cls.id, "Wednesday Lab");
157
158 const meetings = getMeetingTimesForClass(cls.id);
159 expect(meetings.length).toBe(2);
160 expect(meetings[0]?.label).toBe("Monday Lecture");
161 expect(meetings[1]?.label).toBe("Wednesday Lab");
162});