test(frontend): ProfileSecurityPage ContactBindingsSection contract coverage

- Add test verifying ContactBindingsSection receives correct capability props
- Test userId, emailBindingEnabled, phoneBindingEnabled, refreshSessionUser
- Lock regression: prevent future removal of prop-passing while keeping render

Refs: review-fix-closure-2026-05-28 ProfileSecurityPage component contract
This commit is contained in:
Your Name
2026-05-29 12:32:16 +08:00
parent 320aa9476f
commit 5da7ecfcfd

View File

@@ -192,8 +192,10 @@ vi.mock('@/services/operation-logs', () => ({
listMyOperationLogs: () => listMyOperationLogsMock(),
}))
const contactBindingsSectionMock = vi.fn(() => <div data-testid="contact-bindings-section" />)
vi.mock('./ContactBindingsSection', () => ({
ContactBindingsSection: () => <div data-testid="contact-bindings-section" />,
ContactBindingsSection: (props: unknown) => contactBindingsSectionMock(props),
}))
function buildDevice(id: number, name: string, status: 0 | 1, isTrusted = false): Device {
@@ -318,6 +320,7 @@ describe('ProfileSecurityPage behavior', () => {
created_at: '2026-03-27 09:10:00',
}],
})
contactBindingsSectionMock.mockClear()
vi.spyOn(window, 'getComputedStyle').mockImplementation((element) => {
return originalGetComputedStyle.call(window, element)
@@ -467,6 +470,24 @@ describe('ProfileSecurityPage behavior', () => {
expect(message.success).toHaveBeenCalledWith('密码修改成功')
})
it('passes contact binding capabilities to ContactBindingsSection', async () => {
render(<ProfileSecurityPage />)
await waitFor(() => expect(contactBindingsSectionMock).toHaveBeenCalled())
const latestProps = contactBindingsSectionMock.mock.calls.at(-1)?.[0] as {
userId: number
emailBindingEnabled: boolean
phoneBindingEnabled: boolean
refreshSessionUser: () => Promise<void>
}
expect(latestProps.userId).toBe(1)
expect(latestProps.emailBindingEnabled).toBe(true)
expect(latestProps.phoneBindingEnabled).toBe(true)
await latestProps.refreshSessionUser()
expect(refreshUserMock).toHaveBeenCalledTimes(1)
})
it('toggles device status, refetches the list, and deletes devices', async () => {
const user = userEvent.setup()