Skip to content

Commit 7b0473d

Browse files
test(frontend): add vitest unit tests for the /api/health route handler
Follow-up to PR #87 (docker: add multi-stage frontend Dockerfile with Next.js standalone output) to ensure the App Router liveness endpoint matches the Docker HEALTHCHECK expectations in docker/frontend.Dockerfile. - Assert GET returns status 200 and application/json content type - Assert the JSON body has status: ok plus an ISO 8601 UTC timestamp - Assert module-level dynamic = force-dynamic export so Next.js does not pre-render the route Refs #87
1 parent 7bbedc5 commit 7b0473d

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Tests for the GET /api/health liveness probe.
3+
*
4+
* Follow-up to PR #87 (`docker: add multi-stage frontend Dockerfile with
5+
* Next.js standalone output`) so the Next.js App Router endpoint matches
6+
* the Docker HEALTHCHECK expectations in `docker/frontend.Dockerfile`.
7+
*
8+
* The route is exercised by `wget --spider` against
9+
* `http://127.0.0.1:${PORT}/api/health`, so we assert only the
10+
* duck-typed Web Response shape — no `instanceof` checks against Next.js
11+
* internal classes, because vitest's module-resolution surface differs
12+
* from the production runtime and `instanceof NextResponse` is not
13+
* guaranteed to survive that.
14+
*/
15+
import { describe, it, expect } from 'vitest'
16+
import { GET, dynamic } from './route'
17+
18+
describe('GET /api/health', () => {
19+
it('returns status 200', () => {
20+
const response = GET()
21+
expect(response.status).toBe(200)
22+
})
23+
24+
it('returns application/json content type', () => {
25+
const response = GET()
26+
expect(response.headers.get('content-type')).toMatch(/application\/json/)
27+
})
28+
29+
it('returns body with status: "ok" and an ISO 8601 timestamp', async () => {
30+
const response = GET()
31+
const body = await response.json()
32+
33+
expect(body.status).toBe('ok')
34+
expect(typeof body.timestamp).toBe('string')
35+
expect(new Date(body.timestamp).toString()).not.toBe('Invalid Date')
36+
// Strict ISO 8601 UTC: 2024-05-04T12:34:56.789Z
37+
expect(body.timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/)
38+
})
39+
})
40+
41+
describe('route module config', () => {
42+
it('exports dynamic = "force-dynamic" so Next.js does not pre-render the route', () => {
43+
expect(dynamic).toBe('force-dynamic')
44+
})
45+
})

0 commit comments

Comments
 (0)