diff --git a/apps/backend/controllers/djs.controller.ts b/apps/backend/controllers/djs.controller.ts index 1e160cf..d179fc7 100644 --- a/apps/backend/controllers/djs.controller.ts +++ b/apps/backend/controllers/djs.controller.ts @@ -21,7 +21,7 @@ export const addToBin: RequestHandler = async (req, re }; try { const added_bin_item = await DJService.addToBin(bin_entry); - res.status(200).json(added_bin_item); + res.status(201).json(added_bin_item); } catch (e) { console.error('Server error: Failed to insert into bin'); console.error(e); diff --git a/apps/backend/controllers/flowsheet.controller.ts b/apps/backend/controllers/flowsheet.controller.ts index c8074c5..3fd0b84 100644 --- a/apps/backend/controllers/flowsheet.controller.ts +++ b/apps/backend/controllers/flowsheet.controller.ts @@ -182,7 +182,7 @@ export const addEntry: RequestHandler = async (req: Request console.error('[Flowsheet] Metadata fetch failed:', err)); } - res.status(200).json(completedEntry); + res.status(201).json(completedEntry); } else if ( body.album_title === undefined || body.artist_name === undefined || @@ -210,7 +210,7 @@ export const addEntry: RequestHandler = async (req: Request console.error('[Flowsheet] Metadata fetch failed:', err)); } - res.status(200).json(completedEntry); + res.status(201).json(completedEntry); } } catch (e) { console.error('Error: Failed to add track to flowsheet'); @@ -229,7 +229,7 @@ export const addEntry: RequestHandler = async (req: Request = } else { try { const rotationRelease: RotationRelease = await libraryService.addToRotation(req.body); - res.status(200).json(rotationRelease); + res.status(201).json(rotationRelease); } catch (e) { console.error(e); next(e); @@ -228,7 +228,7 @@ export const addFormat: RequestHandler = async (req, res, next) => { }; const insertion = await libraryService.insertFormat(newFormat); - res.status(200).json(insertion); + res.status(201).json(insertion); } catch (e) { console.error('Failed to add new format'); console.error(e); @@ -258,7 +258,7 @@ export const addGenre: RequestHandler = async (req, res, next) => { const insertion = await libraryService.insertGenre(newGenre); - res.status(200).json(insertion); + res.status(201).json(insertion); } catch (e) { console.error('Failed to add new genre'); console.error(e); diff --git a/apps/backend/controllers/schedule.controller.ts b/apps/backend/controllers/schedule.controller.ts index 48b4153..db6aa43 100644 --- a/apps/backend/controllers/schedule.controller.ts +++ b/apps/backend/controllers/schedule.controller.ts @@ -17,7 +17,7 @@ export const addToSchedule: RequestHandler = async (req: Request { track_title: 'Carry the Zero', // record_label: 'Warner Bros', }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.album_title).toEqual('Keep it Like a Secret'); @@ -182,7 +182,7 @@ describe('Add to Flowsheet', () => { track_title: 'Carry the Zero', rotation_id: 1, }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.album_title).toEqual('Keep it Like a Secret'); @@ -197,7 +197,7 @@ describe('Add to Flowsheet', () => { track_title: 'Carry the Zero', record_label: 'Warner Bros', }) - .expect(200); + .expect(201); expect(res.body.album_title).toEqual('Keep it Like a Secret'); expect(res.body.track_title).toEqual('Carry the Zero'); @@ -213,7 +213,7 @@ describe('Add to Flowsheet', () => { track_title: 'Carry the Zero', request_flag: true, }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.album_title).toEqual('Keep it Like a Secret'); @@ -229,7 +229,7 @@ describe('Add to Flowsheet', () => { album_title: 'Keep it Like a Secret', track_title: 'Carry the Zero', }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.album_title).toEqual('Keep it Like a Secret'); @@ -246,7 +246,7 @@ describe('Add to Flowsheet', () => { track_title: 'Carry the Zero', record_label: 'Warner Bros', }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.album_title).toEqual('Keep it Like a Secret'); @@ -264,7 +264,7 @@ describe('Add to Flowsheet', () => { track_title: 'Carry the Zero', request_flag: true, }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.album_title).toEqual('Keep it Like a Secret'); @@ -278,7 +278,7 @@ describe('Add to Flowsheet', () => { .send({ message: 'Test Message', }) - .expect(200); + .expect(201); expect(res.body).toBeDefined(); expect(res.body.message).toEqual('Test Message'); @@ -477,7 +477,7 @@ describe('Retrieve Now Playing', () => { album_id: 1, //Built to Spill - Keep it Like a Secret track_title: 'Carry the Zero', }) - .expect(200); + .expect(201); }); afterEach(async () => { @@ -500,7 +500,7 @@ describe('Retrieve Now Playing', () => { album_id: 2, //Ravyn Lenae - Crush track_title: 'Venom', }) - .expect(200); + .expect(201); res = await request.get('/flowsheet/latest').expect(200); expect(res.body).toBeDefined(); @@ -522,7 +522,7 @@ describe('Shift Flowsheet Entries', () => { album_id: 1, //Built to Spill - Keep it Like a Secret track_title: 'Carry the Zero', }) - .expect(200); + .expect(201); await request .post('/flowsheet') @@ -531,7 +531,7 @@ describe('Shift Flowsheet Entries', () => { album_id: 2, //Ravyn Lenae - Crush track_title: 'Venom', }) - .expect(200); + .expect(201); await request .post('/flowsheet') @@ -540,7 +540,7 @@ describe('Shift Flowsheet Entries', () => { album_id: 3, //Jockstrap - I Love You Jennifer B track_title: 'Debra', }) - .expect(200); + .expect(201); }); afterEach(async () => { @@ -685,7 +685,7 @@ describe('Retrieve Playlist Object', () => { album_id: 3, //Jockstrap - I Love You Jennifer B track_title: 'Debra', }) - .expect(200); + .expect(201); await fls_util.leave_show(global.primary_dj_id, global.access_token); }); @@ -735,7 +735,7 @@ describe('V2 Playlist - Discriminated Union Format', () => { album_id: 3, //Jockstrap - I Love You Jennifer B track_title: 'Debra', }) - .expect(200); + .expect(201); await fls_util.leave_show(global.primary_dj_id, global.access_token); }); @@ -793,7 +793,7 @@ describe('V1 API - entry_type field', () => { album_id: 1, track_title: 'Carry the Zero', }) - .expect(200); + .expect(201); // V1 response should now include entry_type (additive change) expect(addRes.body.entry_type).toBe('track'); diff --git a/tests/unit/controllers/create-status-codes.test.ts b/tests/unit/controllers/create-status-codes.test.ts new file mode 100644 index 0000000..12ded7f --- /dev/null +++ b/tests/unit/controllers/create-status-codes.test.ts @@ -0,0 +1,60 @@ +import { Request, Response, NextFunction } from 'express'; + +jest.mock('../../../apps/backend/services/djs.service'); +jest.mock('../../../apps/backend/services/schedule.service'); + +import * as DJService from '../../../apps/backend/services/djs.service'; +import * as ScheduleService from '../../../apps/backend/services/schedule.service'; +import { addToBin } from '../../../apps/backend/controllers/djs.controller'; +import { addToSchedule } from '../../../apps/backend/controllers/schedule.controller'; + +function mockReqResNext(body: Record = {}) { + const req = { body } as unknown as Request; + const statusMock = jest.fn().mockReturnThis(); + const jsonMock = jest.fn().mockReturnThis(); + const sendMock = jest.fn().mockReturnThis(); + const res = { + status: statusMock, + json: jsonMock, + send: sendMock, + } as unknown as Response; + const next = jest.fn() as unknown as NextFunction; + return { req, res, next, statusMock, jsonMock, sendMock }; +} + +describe('create endpoints return 201', () => { + describe('addToBin', () => { + it('should return 201 when a bin entry is created', async () => { + const created = { id: 1, dj_id: 'dj-1', album_id: 10, track_title: null }; + (DJService.addToBin as jest.Mock).mockResolvedValue(created); + + const { req, res, next, statusMock, jsonMock } = mockReqResNext({ + dj_id: 'dj-1', + album_id: 10, + }); + + await addToBin(req, res, next); + + expect(statusMock).toHaveBeenCalledWith(201); + expect(jsonMock).toHaveBeenCalledWith(created); + }); + }); + + describe('addToSchedule', () => { + it('should return 201 when a schedule entry is created', async () => { + const created = { id: 1, day: 'Monday', start_time: '10:00', end_time: '12:00' }; + (ScheduleService.addToSchedule as jest.Mock).mockResolvedValue(created); + + const { req, res, next, statusMock, jsonMock } = mockReqResNext({ + day: 'Monday', + start_time: '10:00', + end_time: '12:00', + }); + + await addToSchedule(req, res, next); + + expect(statusMock).toHaveBeenCalledWith(201); + expect(jsonMock).toHaveBeenCalledWith(created); + }); + }); +});