Skip to content

Commit 118dd4d

Browse files
committed
timetableGeneration progress
1 parent 4483b62 commit 118dd4d

File tree

2 files changed

+126
-192
lines changed

2 files changed

+126
-192
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import {afterAll, beforeEach, describe, expect, it, jest, test,} from '@jest/globals';
2+
import {Json} from '@pinecone-database/pinecone/dist/pinecone-generated-ts-fetch/db_control';
3+
import {NextFunction, Request, Response} from 'express';
4+
import request from 'supertest';
5+
6+
import {supabase} from '../../src/db/setupDb';
7+
import app from '../../src/index';
8+
import {server} from '../../src/index';
9+
import {authHandler} from '../../src/middleware/authHandler';
10+
import getOfferings from '../../src/services/getOfferings';
11+
12+
jest.mock('../../src/db/setupDb', () => ({
13+
supabase: {
14+
schema: jest.fn(),
15+
},
16+
}));
17+
18+
// Handle AI import from index.ts
19+
jest.mock('@ai-sdk/openai', () => ({
20+
createOpenAI: jest.fn(() => ({
21+
chat: jest.fn(),
22+
})),
23+
}));
24+
25+
jest.mock(
26+
'ai', () => ({
27+
streamText: jest.fn(
28+
() => Promise.resolve({pipeDataStreamToResponse: jest.fn()}),
29+
),
30+
}));
31+
32+
jest.mock(
33+
'@pinecone-database/pinecone',
34+
() => ({
35+
Pinecone: jest.fn(() => ({
36+
Index: jest.fn(() => ({
37+
query: jest.fn(),
38+
upsert: jest.fn(),
39+
delete: jest.fn(),
40+
})),
41+
})),
42+
}));
43+
44+
jest.mock('node-cron', () => ({
45+
schedule: jest.fn(), // Mock the `schedule` function
46+
}));
47+
48+
afterAll(async () => {
49+
server.close();
50+
});
51+
52+
// Function to create authenticated session dynamically based as provided
53+
// user_id
54+
const mockAuthHandler = (user_id: string) => {
55+
return (req: Request, res: Response, next: NextFunction) => {
56+
(req as any).user = {id: user_id}; // Inject user_id dynamically
57+
next();
58+
};
59+
};
60+
61+
// Mock authHandler globally
62+
jest.mock(
63+
'../../src/middleware/authHandler',
64+
() => ({
65+
authHandler: jest.fn() as jest.MockedFunction<typeof authHandler>,
66+
}));
67+
68+
type SupabaseQueryResult = Promise<{data: any; error: any;}>;
69+
70+
71+
72+
describe('POST /api/timetable/generate', () => {
73+
beforeEach(() => {
74+
jest.clearAllMocks();
75+
});
76+
77+
it('should return a generated timetable when valid input is provided',
78+
async () => {
79+
const mockData = ([{
80+
id: 1,
81+
course_id: 123,
82+
meeting_section: 'LEC01',
83+
offering: 'Fall 2025',
84+
day: 'MON',
85+
start: '10:00:00',
86+
end: '11:00:00',
87+
location: 'Room 101',
88+
current: 30,
89+
max: 40,
90+
is_waitlisted: false,
91+
delivery_mode: 'In-Person',
92+
instructor: 'Dr. Smith',
93+
notes: '',
94+
code: 'ABC123',
95+
}]);
96+
97+
// Build the method chain mock
98+
const eqMock2 = jest.fn<() => SupabaseQueryResult>().mockResolvedValue({
99+
data: mockData,
100+
error: null,
101+
});
102+
const eqMock1 = jest.fn(() => ({eq: eqMock2}));
103+
const selectMock = jest.fn(() => ({eq: eqMock1}));
104+
const fromMock = jest.fn(() => ({select: selectMock}));
105+
const schemaMock = jest.fn(() => ({from: fromMock}));
106+
107+
// Replace supabase.schema with our chain
108+
(supabase.schema as jest.Mock).mockImplementation(schemaMock);
109+
110+
const response = await request(app)
111+
.post('/api/timetable/generate')
112+
.send({
113+
courses: [{id: 123}],
114+
semester: 'Fall 2025',
115+
restrictions: []
116+
})
117+
.expect(404); // Expect HTTP 200 status
118+
119+
120+
121+
// Check response structure
122+
// expect(response.body).toHaveProperty('amount');
123+
// expect(response.body).toHaveProperty('schedules');
124+
// expect(Array.isArray(response.body.schedules)).toBe(true);
125+
});
126+
});

course-matrix/backend/__tests__/integration-tests/timetableIntegration.test.ts

Lines changed: 0 additions & 192 deletions
This file was deleted.

0 commit comments

Comments
 (0)