import { createElement } from 'react' import { renderToStaticMarkup } from 'react-dom/server' import { afterEach, describe, expect, it, vi } from 'vitest' import { api } from '../src/api' import { auth } from '../src/auth' import { GeneratedCredentialPanel, oneTimePasswordCredential } from '../src/components/oneTimePasswordUi' describe('管理员一次性密码发放', () => { afterEach(() => { auth.clear() vi.unstubAllGlobals() }) it('调用精确 one-time-password 端点并使用 POST', async () => { const response = { owner: 'alice', id: 'otp_123', oneTimePassword: 'otp-0001', mustChangePassword: true } const fetchSpy = vi.fn().mockResolvedValue(new Response(JSON.stringify(response), { status: 200, headers: { 'Content-Type': 'application/json' }, })) vi.stubGlobal('fetch', fetchSpy) const out = await api.adminIssueOneTimePassword('alice') expect(fetchSpy).toHaveBeenCalledTimes(1) // 服务端严格解码 JSON 对象体:无体无 Content-Type 会被拒为 400 EOF。 expect(fetchSpy).toHaveBeenCalledWith('/api/admin/users/alice/one-time-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}', }) expect(out).toEqual(response) }) it('展示后端返回的 oneTimePassword', () => { const credential = oneTimePasswordCredential({ owner: 'alice', id: 'otp_123', oneTimePassword: 'otp-0001', mustChangePassword: true }) const html = renderToStaticMarkup(createElement(GeneratedCredentialPanel, { credential, onClose: () => undefined, })) expect(html).toContain('otp-0001') expect(html).toContain('一次性登录密码仅显示一次') }) })