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; headers?: Record } = {}) { 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') }) })