From f2639558fd4a586d931e2f1cad634504e649a93b Mon Sep 17 00:00:00 2001 From: DavisVT Date: Sun, 31 May 2026 18:54:47 +0100 Subject: [PATCH] Implement 405 Method Not Allowed handling and add integration tests - Add 405 handlers to creator routes - Add integration tests using supertest --- src/modules/creator/creator.routes.ts | 8 +++ ...ute-method-not-allowed.integration.test.ts | 60 +++++++++++++++++++ src/modules/creators/creators.routes.ts | 8 +++ 3 files changed, 76 insertions(+) create mode 100644 src/modules/creators/creator-route-method-not-allowed.integration.test.ts diff --git a/src/modules/creator/creator.routes.ts b/src/modules/creator/creator.routes.ts index f87b4ce..9f7f690 100644 --- a/src/modules/creator/creator.routes.ts +++ b/src/modules/creator/creator.routes.ts @@ -36,6 +36,10 @@ router.get( ), listCreators ); +// 405 handler for CREATORS_ROOT +router.all(CREATORS_ROOT, (_req, res) => { + res.set('Allow', 'GET').sendStatus(405); +}); /** * @route GET /api/v1/creators/:creatorId/profile @@ -61,5 +65,9 @@ router.put( requireCreatorProfileOwnership('creatorId'), upsertCreatorProfileHandler ); +// 405 handler for /:creatorId/profile +router.all('/:creatorId/profile', (_req, res) => { + res.set('Allow', 'GET, PUT').sendStatus(405); +}); export default router; diff --git a/src/modules/creators/creator-route-method-not-allowed.integration.test.ts b/src/modules/creators/creator-route-method-not-allowed.integration.test.ts new file mode 100644 index 0000000..7020d37 --- /dev/null +++ b/src/modules/creators/creator-route-method-not-allowed.integration.test.ts @@ -0,0 +1,60 @@ +// Integration test: creator route Method Not Allowed (405) validation +// +// Creator routes should return a 405 Method Not Allowed response when called with an +// unsupported HTTP method, and include an Allow header listing supported methods. + +// Mock chalk first to avoid ESM issues +jest.mock('chalk', () => ({ + red: (text: string) => text, + green: (text: string) => text, + magenta: (text: string) => text, + cyan: (text: string) => text, +})); + +// Mock tspec to prevent hanging +jest.mock('tspec', () => ({ + TspecDocsMiddleware: jest.fn().mockResolvedValue([]), +})); + +import supertest from 'supertest'; +import app from '../../app'; + +// Mock all the things so we don't need a real database +jest.mock('../../utils/prisma.utils'); +jest.mock('../../utils/logger.utils', () => ({ + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + } +})); +jest.mock('../../config', () => ({ + envConfig: { MODE: 'test', PORT: 3000, ENABLE_REQUEST_LOGGING: false }, + appConfig: { allowedOrigins: [] } +})); + +describe('Creator routes — Method Not Allowed (405) validation', () => { + describe('POST /api/v1/creators (unsupported method)', () => { + it('returns 405 status code', async () => { + const res = await supertest(app).post('/api/v1/creators'); + expect(res.status).toBe(405); + }); + + it('includes Allow header with GET', async () => { + const res = await supertest(app).post('/api/v1/creators'); + expect(res.headers.allow).toBe('GET'); + }); + }); + + describe('POST /api/v1/creators/test-id/stats (unsupported method)', () => { + it('returns 405 status code', async () => { + const res = await supertest(app).post('/api/v1/creators/test-id/stats'); + expect(res.status).toBe(405); + }); + + it('includes Allow header with GET', async () => { + const res = await supertest(app).post('/api/v1/creators/test-id/stats'); + expect(res.headers.allow).toBe('GET'); + }); + }); +}); diff --git a/src/modules/creators/creators.routes.ts b/src/modules/creators/creators.routes.ts index 0666bcd..d1f752c 100644 --- a/src/modules/creators/creators.routes.ts +++ b/src/modules/creators/creators.routes.ts @@ -25,6 +25,10 @@ creatorsRouter.get( cacheControl(CREATOR_PUBLIC_ROUTE_CACHE_PRESETS[CREATOR_PUBLIC_ROUTE_NAMES.LIST]), httpListCreators ); +// 405 handler for / +creatorsRouter.all('/', (_req, res) => { + res.set('Allow', 'GET').sendStatus(405); +}); /** * GET /api/v1/creators/:id/stats @@ -38,5 +42,9 @@ creatorsRouter.get( cacheControl(CREATOR_PUBLIC_ROUTE_CACHE_PRESETS[CREATOR_PUBLIC_ROUTE_NAMES.GET_STATS]), httpGetCreatorStats ); +// 405 handler for /:id/stats +creatorsRouter.all('/:id/stats', (_req, res) => { + res.set('Allow', 'GET').sendStatus(405); +}); export default creatorsRouter; \ No newline at end of file