Files
alrahma_sunday_school_api/apps/marketplace/src/middleware.test.ts
T
2026-06-11 03:22:12 -04:00

105 lines
3.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
const nextServer = vi.hoisted(() => {
const next = vi.fn((init?: { request?: { headers?: Headers } }) => ({
kind: 'next',
init,
cookies: {
set: vi.fn(),
},
}))
const MockNextResponse = vi.fn((body?: string, init?: { status?: number }) => ({
kind: 'response',
body,
status: init?.status,
})) as any
MockNextResponse.next = next
return { next, MockNextResponse }
})
vi.mock('next/server', () => ({
NextResponse: nextServer.MockNextResponse,
}))
function request(options: { cookies?: Record<string, string>; headers?: Record<string, string> } = {}) {
const cookies = new Map(Object.entries(options.cookies ?? {}))
const headers = new Headers(options.headers ?? {})
return {
cookies: {
get: vi.fn((name: string) => {
const value = cookies.get(name)
return value ? { value } : undefined
}),
},
headers,
}
}
beforeEach(() => {
nextServer.next.mockClear()
})
describe('marketplace middleware language bootstrap', () => {
it('rejects middleware subrequest headers before language handling', async () => {
const { middleware } = await import('./middleware')
const response = middleware(request({
headers: { 'x-middleware-subrequest': 'middleware:middleware' },
}) as never) as any
expect(response).toEqual({ kind: 'response', body: 'Unsupported internal request header', status: 400 })
expect(nextServer.next).not.toHaveBeenCalled()
})
it('does nothing when the canonical shared language cookie is valid', async () => {
const { middleware } = await import('./middleware')
const response = middleware(request({ cookies: { 'rentaldrivego-language': 'fr' } }) as never) as any
expect(response.kind).toBe('next')
expect(nextServer.next).toHaveBeenCalledWith()
expect(response.cookies.set).not.toHaveBeenCalled()
})
it('migrates the legacy marketplace language cookie into the shared cookie and request headers', async () => {
const { middleware } = await import('./middleware')
const response = middleware(request({
cookies: { 'marketplace-language': 'ar' },
headers: { cookie: 'session=abc' },
}) as never) as any
expect(response.cookies.set).toHaveBeenCalledWith('rentaldrivego-language', 'ar', expect.objectContaining({
path: '/',
sameSite: 'lax',
}))
expect(response.init?.request?.headers?.get('cookie')).toBe('session=abc; rentaldrivego-language=ar')
})
it('detects Arabic and French from Accept-Language before falling back to English', async () => {
const { middleware } = await import('./middleware')
const arabic = middleware(request({ headers: { 'accept-language': 'ar-MA,fr;q=0.8,en;q=0.6' } }) as never) as any
expect(arabic.cookies.set).toHaveBeenCalledWith('rentaldrivego-language', 'ar', expect.any(Object))
expect(arabic.init?.request?.headers?.get('cookie')).toBe('rentaldrivego-language=ar')
const french = middleware(request({ headers: { 'accept-language': 'de-DE,fr-FR;q=0.7,en;q=0.3' } }) as never) as any
expect(french.cookies.set).toHaveBeenCalledWith('rentaldrivego-language', 'fr', expect.any(Object))
const fallback = middleware(request({ headers: { 'accept-language': 'de-DE,es;q=0.9' } }) as never) as any
expect(fallback.cookies.set).toHaveBeenCalledWith('rentaldrivego-language', 'en', expect.any(Object))
})
it('rejects invalid shared and legacy language values before resolving from headers', async () => {
const { middleware } = await import('./middleware')
const response = middleware(request({
cookies: { 'rentaldrivego-language': 'es', 'marketplace-language': 'it' },
headers: { 'accept-language': 'fr-CA,ar;q=0.5' },
}) as never) as any
expect(response.cookies.set).toHaveBeenCalledWith('rentaldrivego-language', 'fr', expect.any(Object))
expect(response.init?.request?.headers?.get('cookie')).toBe('rentaldrivego-language=fr')
})
})