From 9214ace9eacbc3d2dd77f6cdc36ffb4704622b1c Mon Sep 17 00:00:00 2001 From: Rafiat Date: Mon, 27 Jul 2026 22:54:11 +0300 Subject: [PATCH] test(creators): assert no leaked internals and 404 shape parity for creator detail Extends the creator detail 404 integration test to cover the remaining acceptance criteria from #665: the response must match the standard { success, error: { code, message } } envelope used by other 404s (e.g. GET /:id/holders), and must not leak Prisma/DB error details, table or model names, or stack traces. --- ...eator-detail-not-found.integration.test.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/modules/creators/creator-detail-not-found.integration.test.ts b/src/modules/creators/creator-detail-not-found.integration.test.ts index 6770750..cd8de14 100644 --- a/src/modules/creators/creator-detail-not-found.integration.test.ts +++ b/src/modules/creators/creator-detail-not-found.integration.test.ts @@ -31,4 +31,56 @@ describe('GET /api/v1/creators/:id — not found', () => { expect(res.body.error.code).toBe('NOT_FOUND'); expect(res.body.error.message).toMatch(/creator.*not found/i); }); + + it('matches the standard 404 response shape used by other creator routes', async () => { + const { default: app } = await import('../../app'); + + const res = await supertest(app).get( + '/api/v1/creators/non-existent-creator-for-404-test' + ); + + // Same envelope as GET /:id/holders and other 404s in the API: + // exactly { success, error: { code, message } }, no extra fields. + expect(res.body).toEqual({ + success: false, + error: { + code: 'NOT_FOUND', + message: 'Creator not found', + }, + }); + }); + + it('does not leak database errors, table/model names, or stack traces', async () => { + const { default: app } = await import('../../app'); + + const res = await supertest(app).get( + '/api/v1/creators/non-existent-creator-for-404-test' + ); + + const serializedBody = JSON.stringify(res.body).toLowerCase(); + + const forbiddenPatterns = [ + 'stack', + 'trace', + 'prisma', + 'creatorprofile', + 'creator_profile', + 'select ', + 'sql', + '.ts:', + '.js:', + 'node_modules', + 'at object', + 'errno', + 'econnrefused', + ]; + + for (const pattern of forbiddenPatterns) { + expect(serializedBody).not.toContain(pattern); + } + + // Only the documented error keys should be present—nothing + // implementation-specific like a Prisma error `code`/`meta`/`clientVersion`. + expect(Object.keys(res.body.error).sort()).toEqual(['code', 'message']); + }); });