157 lines
4.3 KiB
TypeScript
157 lines
4.3 KiB
TypeScript
import { renderHook, act, waitFor } from '@testing-library/react-native'
|
|
import { useChangePassword } from '@/hooks/use-change-password'
|
|
import { authClient } from '@/lib/auth'
|
|
|
|
// Mock authClient
|
|
jest.mock('@/lib/auth', () => ({
|
|
authClient: {
|
|
changePassword: jest.fn(),
|
|
},
|
|
}))
|
|
|
|
describe('useChangePassword', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks()
|
|
})
|
|
|
|
it('should change password successfully', async () => {
|
|
const mockChangePassword = authClient.changePassword as jest.MockedFunction<typeof authClient.changePassword>
|
|
mockChangePassword.mockResolvedValue({ error: null })
|
|
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
await act(async () => {
|
|
await result.current.changePassword({
|
|
oldPassword: 'oldPass123',
|
|
newPassword: 'newPass123',
|
|
})
|
|
})
|
|
|
|
expect(mockChangePassword).toHaveBeenCalledWith({
|
|
oldPassword: 'oldPass123',
|
|
newPassword: 'newPass123',
|
|
revokeOtherSessions: true,
|
|
})
|
|
expect(result.current.error).toBeNull()
|
|
})
|
|
|
|
it('should validate old password is not empty', async () => {
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
await act(async () => {
|
|
await result.current.changePassword({
|
|
oldPassword: '',
|
|
newPassword: 'newPass123',
|
|
})
|
|
})
|
|
|
|
expect(result.current.error).toEqual({
|
|
message: '旧密码不能为空',
|
|
})
|
|
expect(authClient.changePassword).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should validate new password and confirm password match', async () => {
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
await act(async () => {
|
|
await result.current.changePassword({
|
|
oldPassword: 'oldPass123',
|
|
newPassword: 'newPass123',
|
|
confirmPassword: 'differentPass123',
|
|
})
|
|
})
|
|
|
|
expect(result.current.error).toEqual({
|
|
message: '新密码和确认密码不一致',
|
|
})
|
|
expect(authClient.changePassword).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should validate new password length (minimum 6 characters)', async () => {
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
await act(async () => {
|
|
await result.current.changePassword({
|
|
oldPassword: 'oldPass123',
|
|
newPassword: '12345',
|
|
})
|
|
})
|
|
|
|
expect(result.current.error).toEqual({
|
|
message: '新密码长度至少为6位',
|
|
})
|
|
expect(authClient.changePassword).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should validate new password is different from old password', async () => {
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
await act(async () => {
|
|
await result.current.changePassword({
|
|
oldPassword: 'samePass123',
|
|
newPassword: 'samePass123',
|
|
})
|
|
})
|
|
|
|
expect(result.current.error).toEqual({
|
|
message: '新密码不能与当前密码相同',
|
|
})
|
|
expect(authClient.changePassword).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle API errors', async () => {
|
|
const mockError = {
|
|
status: 400,
|
|
statusText: 'Bad Request',
|
|
message: '旧密码错误',
|
|
}
|
|
|
|
const mockChangePassword = authClient.changePassword as jest.MockedFunction<typeof authClient.changePassword>
|
|
mockChangePassword.mockRejectedValue(mockError)
|
|
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
await act(async () => {
|
|
await result.current.changePassword({
|
|
oldPassword: 'wrongPass',
|
|
newPassword: 'newPass123',
|
|
})
|
|
})
|
|
|
|
expect(result.current.error).toEqual(mockError)
|
|
})
|
|
|
|
it('should set loading state during password change', async () => {
|
|
let resolveChangePassword: (value: any) => void
|
|
const changePasswordPromise = new Promise((resolve) => {
|
|
resolveChangePassword = resolve
|
|
})
|
|
|
|
const mockChangePassword = authClient.changePassword as jest.MockedFunction<typeof authClient.changePassword>
|
|
mockChangePassword.mockReturnValue(changePasswordPromise)
|
|
|
|
const { result } = renderHook(() => useChangePassword())
|
|
|
|
act(() => {
|
|
result.current.changePassword({
|
|
oldPassword: 'oldPass123',
|
|
newPassword: 'newPass123',
|
|
})
|
|
})
|
|
|
|
expect(result.current.loading).toBe(true)
|
|
|
|
await act(async () => {
|
|
resolveChangePassword!({ error: null })
|
|
await changePasswordPromise
|
|
})
|
|
|
|
expect(result.current.loading).toBe(false)
|
|
})
|
|
})
|