Route: 503 als INTERNAL_PUSH_SECRET uitstaat, 401 bij verkeerd secret (timingSafeEqual), 400 bij invalid JSON, 422 bij Zod-fout, 204 bij succes. push-server.ts: env-import vervangen door process.env om SESSION_SECRET validatie tijdens build te omzeilen. Tests aangepast. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
|
|
vi.mock('server-only', () => ({}))
|
|
|
|
const { mockSendPushToUser } = vi.hoisted(() => ({
|
|
mockSendPushToUser: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/lib/push-server', () => ({
|
|
sendPushToUser: mockSendPushToUser,
|
|
enabled: true,
|
|
}))
|
|
|
|
vi.hoisted(() => {
|
|
process.env.INTERNAL_PUSH_SECRET = 'a-valid-secret-that-is-at-least-32-chars'
|
|
})
|
|
|
|
import { POST } from '@/app/api/internal/push/send/route'
|
|
|
|
const VALID_BODY = {
|
|
userId: 'user-1',
|
|
payload: { title: 'Hello', body: 'World', url: '/dashboard' },
|
|
}
|
|
const SECRET = 'a-valid-secret-that-is-at-least-32-chars'
|
|
|
|
function makeRequest(body: unknown, bearer?: string) {
|
|
return new Request('http://localhost/api/internal/push/send', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...(bearer !== undefined ? { Authorization: bearer } : {}),
|
|
},
|
|
body: JSON.stringify(body),
|
|
})
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mockSendPushToUser.mockResolvedValue(undefined)
|
|
})
|
|
|
|
describe('POST /api/internal/push/send', () => {
|
|
it('returns 401 without authorization header', async () => {
|
|
const res = await POST(makeRequest(VALID_BODY))
|
|
expect(res.status).toBe(401)
|
|
expect(mockSendPushToUser).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('returns 401 with wrong bearer secret', async () => {
|
|
const res = await POST(makeRequest(VALID_BODY, 'Bearer wrong-secret'))
|
|
expect(res.status).toBe(401)
|
|
})
|
|
|
|
it('returns 422 with invalid body', async () => {
|
|
const res = await POST(makeRequest({ userId: '', payload: {} }, `Bearer ${SECRET}`))
|
|
expect(res.status).toBe(422)
|
|
expect(mockSendPushToUser).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('returns 204 and calls sendPushToUser on success', async () => {
|
|
const res = await POST(makeRequest(VALID_BODY, `Bearer ${SECRET}`))
|
|
expect(res.status).toBe(204)
|
|
expect(mockSendPushToUser).toHaveBeenCalledWith('user-1', VALID_BODY.payload)
|
|
})
|
|
|
|
it('returns 400 for invalid JSON', async () => {
|
|
const req = new Request('http://localhost/api/internal/push/send', {
|
|
method: 'POST',
|
|
headers: { Authorization: `Bearer ${SECRET}`, 'Content-Type': 'application/json' },
|
|
body: 'not-json',
|
|
})
|
|
const res = await POST(req)
|
|
expect(res.status).toBe(400)
|
|
})
|
|
})
|