- All 8 home page sections: Hero, Locations slider, WhyParents accordion, Birthday pricing cards, Video, Gallery, Reviews slider, News - UI components: NavLink, BtnPrimary, BtnGradient, BtnDetails, AccordionItem - Layout: sticky Header (NavLink + BtnPrimary), Footer with logo - Figma Code Connect: 5 components published (.figma.tsx + figma.config.json) - Public assets: all Figma images and SVGs exported - Pages: /kvytky, /lokatsii, /blog, /dni-narodzhennia, /grupovi-vidviduvannia - Tests: Vitest unit/api suites, Playwright e2e screenshots - Payload CMS: blocks, collections, seed data updates - Hero negative-margin to extend behind sticky header - Custom Tailwind breakpoints: lg=1440px, xl=1920px - Fix ESLint config: drop FlatCompat, use eslint-config-next flat export - Add tsconfig.tsbuildinfo, test-results/, agentdb.rvf* to .gitignore Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
106 lines
3.5 KiB
TypeScript
106 lines
3.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
|
|
const mockQuery = vi.fn()
|
|
const mockGetPayload = vi.fn()
|
|
|
|
vi.mock('payload', () => ({ getPayload: mockGetPayload }))
|
|
vi.mock('@payload-config', () => ({ default: {} }))
|
|
|
|
let GET: () => Promise<Response>
|
|
|
|
beforeEach(async () => {
|
|
vi.resetModules()
|
|
mockQuery.mockReset()
|
|
mockGetPayload.mockReset()
|
|
mockGetPayload.mockResolvedValue({ db: { pool: { query: mockQuery } } })
|
|
mockQuery.mockResolvedValue([])
|
|
vi.spyOn(globalThis, 'fetch').mockResolvedValue({ ok: true } as Response)
|
|
const mod = await import('@/app/api/health/route')
|
|
GET = mod.GET
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
describe('GET /api/health', () => {
|
|
it('returns 200 with status:healthy when db and ezy are up', async () => {
|
|
const res = await GET()
|
|
expect(res.status).toBe(200)
|
|
const json = await res.json()
|
|
expect(json.status).toBe('healthy')
|
|
expect(json.db).toBe('ok')
|
|
expect(json.ezy).toBe('ok')
|
|
})
|
|
|
|
it('includes a numeric timestamp', async () => {
|
|
const before = Date.now()
|
|
const res = await GET()
|
|
const after = Date.now()
|
|
const { ts } = await res.json()
|
|
expect(typeof ts).toBe('number')
|
|
expect(ts).toBeGreaterThanOrEqual(before)
|
|
expect(ts).toBeLessThanOrEqual(after)
|
|
})
|
|
|
|
it('returns 503 with status:degraded when db is down', async () => {
|
|
mockGetPayload.mockRejectedValueOnce(new Error('db connection failed'))
|
|
const res = await GET()
|
|
expect(res.status).toBe(503)
|
|
const json = await res.json()
|
|
expect(json.status).toBe('degraded')
|
|
expect(json.db).toBe('error')
|
|
})
|
|
|
|
it('returns 503 with status:degraded when ezy returns non-ok', async () => {
|
|
vi.mocked(globalThis.fetch).mockResolvedValueOnce({ ok: false } as Response)
|
|
const res = await GET()
|
|
expect(res.status).toBe(503)
|
|
const json = await res.json()
|
|
expect(json.status).toBe('degraded')
|
|
expect(json.ezy).toBe('error')
|
|
})
|
|
|
|
it('returns 503 with status:degraded when ezy fetch throws', async () => {
|
|
vi.mocked(globalThis.fetch).mockRejectedValueOnce(new Error('network error'))
|
|
const res = await GET()
|
|
expect(res.status).toBe(503)
|
|
const json = await res.json()
|
|
expect(json.status).toBe('degraded')
|
|
expect(json.ezy).toBe('error')
|
|
})
|
|
|
|
it('returns 503 with ezy:error when EZY_ACTIVITY env var is not set', async () => {
|
|
vi.stubEnv('EZY_ACTIVITY', '')
|
|
vi.resetModules()
|
|
mockGetPayload.mockResolvedValue({ db: { pool: { query: mockQuery } } })
|
|
mockQuery.mockResolvedValue([])
|
|
vi.spyOn(globalThis, 'fetch').mockResolvedValue({ ok: true } as Response)
|
|
const mod = await import('@/app/api/health/route')
|
|
const res = await mod.GET()
|
|
expect(res.status).toBe(503)
|
|
const json = await res.json()
|
|
expect(json.ezy).toBe('error')
|
|
expect(json.status).toBe('degraded')
|
|
})
|
|
|
|
it('returns 503 with db:error when pool.query itself throws', async () => {
|
|
mockQuery.mockRejectedValueOnce(new Error('query failed'))
|
|
const res = await GET()
|
|
expect(res.status).toBe(503)
|
|
const json = await res.json()
|
|
expect(json.db).toBe('error')
|
|
expect(json.status).toBe('degraded')
|
|
})
|
|
|
|
it('returns 503 with degraded when both db and ezy fail', async () => {
|
|
mockGetPayload.mockRejectedValueOnce(new Error('db down'))
|
|
vi.mocked(globalThis.fetch).mockRejectedValueOnce(new Error('ezy down'))
|
|
const res = await GET()
|
|
expect(res.status).toBe(503)
|
|
const json = await res.json()
|
|
expect(json.db).toBe('error')
|
|
expect(json.ezy).toBe('error')
|
|
expect(json.status).toBe('degraded')
|
|
})
|
|
})
|