41 lines
1.7 KiB
TypeScript
41 lines
1.7 KiB
TypeScript
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('一次性登录密码仅显示一次')
|
|
})
|
|
})
|