import { afterEach, describe, expect, it, vi } from 'vitest' import { ApiError, getOrgs, logout, provisionChannels, updateContact } from './client' afterEach(() => { vi.unstubAllGlobals() document.cookie = 'XSRF-TOKEN=; expires=Thu, 01 Jan 1970 00:00:00 GMT' }) describe('api client', () => { it('기관 목록을 가져온다', async () => { const fetchMock = vi.fn().mockResolvedValue({ ok: true, json: async () => [{ id: 1, orgNo: '001', orgName: '국제방송교류재단', status: 'READY' }], }) vi.stubGlobal('fetch', fetchMock) const orgs = await getOrgs() expect(orgs).toHaveLength(1) expect(orgs[0].orgNo).toBe('001') expect(fetchMock).toHaveBeenCalledWith('/api/orgs', expect.objectContaining({ credentials: 'same-origin', })) }) it('쓰기 요청에 CSRF 헤더를 붙인다', async () => { document.cookie = 'XSRF-TOKEN=token-value' const fetchMock = vi.fn().mockResolvedValue({ ok: true, json: async () => ({}) }) vi.stubGlobal('fetch', fetchMock) await provisionChannels(7) const [, init] = fetchMock.mock.calls[0] expect(init.method).toBe('POST') expect(init.headers['X-XSRF-TOKEN']).toBe('token-value') }) it('로그아웃은 CSRF 헤더를 붙여 POST한다', async () => { document.cookie = 'XSRF-TOKEN=token-value' const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 204 }) vi.stubGlobal('fetch', fetchMock) await logout() const [url, init] = fetchMock.mock.calls[0] expect(url).toBe('/api/auth/logout') expect(init.method).toBe('POST') expect(init.headers['X-XSRF-TOKEN']).toBe('token-value') expect(init.credentials).toBe('same-origin') }) it('응답이 실패면 status를 담은 ApiError를 던진다', async () => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: false, status: 400, text: async () => 'bad request', })) const promise = updateContact(1, { deptName: '', managerName: '', managerTitle: '', managerPhone: '', managerEmail: '', }) await expect(promise).rejects.toThrow() await expect(promise).rejects.toBeInstanceOf(ApiError) await expect(promise).rejects.toMatchObject({ status: 400 }) }) })