import { beforeEach, describe, expect, it, vi } from 'vitest' import { getJson, setUnauthorizedHandler } from '@/services/httpClient' const jsonHeaders = { headers: { get: (name: string) => (name.toLowerCase() === 'content-type' ? 'application/json' : null), }, } function mockJsonResponse(payload: unknown, status = 200): Response { return { ok: status >= 200 && status < 300, status, json: async () => payload, text: async () => JSON.stringify(payload), ...jsonHeaders, } as Response } describe('httpClient auth integration', () => { beforeEach(() => { vi.restoreAllMocks() sessionStorage.clear() localStorage.clear() setUnauthorizedHandler(null) }) it('adds Authorization when a session token exists', async () => { const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue(mockJsonResponse({ ok: true })) sessionStorage.setItem('th_hotel_access_token', 'session-token') await getJson('/api/reservation/orders') expect(fetchMock).toHaveBeenCalledWith( '/api/reservation/orders', expect.objectContaining({ headers: expect.objectContaining({ Authorization: 'Bearer session-token', }), }), ) }) it('runs the unauthorized handler for invalid auth sessions', async () => { const unauthorizedHandler = vi.fn() setUnauthorizedHandler(unauthorizedHandler) sessionStorage.setItem('th_hotel_access_token', 'expired-token') vi.spyOn(globalThis, 'fetch').mockResolvedValue( mockJsonResponse( { error_code: 'AUTH_SESSION_INVALID', message: '登录已失效。', }, 401, ), ) await expect(getJson('/api/auth/me')).rejects.toMatchObject({ status: 401, }) expect(unauthorizedHandler).toHaveBeenCalledOnce() }) })