import type { ReactNode } from 'react'
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import UserMobileChangeModal from '@/app/(dashboard)/users/[id]/_components/UserMobileChangeModal'
const changeMobile = vi.fn()
const addToast = vi.fn()
vi.mock('@/services/adminUsers', () => ({
ADMIN_CHANGE_USER_MOBILE: (...args: unknown[]) => changeMobile(...args),
}))
vi.mock('@/lib/toast', () => ({ addToast: (...args: unknown[]) => addToast(...args) }))
vi.mock('@/components/formElements/Input', () => ({
default: ({ label, value, onValueChange }: { label: string; value?: unknown; onValueChange?: (value: string) => void }) => (
),
}))
vi.mock('@/components/formElements/Button', () => ({
default: ({ children, onClick }: { children: ReactNode; onClick?: () => void }) => (
),
}))
vi.mock('@/components/modals/Modal', () => ({
default: ({
isOpen,
title,
children,
acceptBtnText,
rejectBtnText,
acceptBtnDisabled,
onAccept,
onReject,
}: {
isOpen: boolean
title: string
children: ReactNode
acceptBtnText: string
rejectBtnText: string
acceptBtnDisabled?: boolean
onAccept?: () => void
onReject?: () => void
}) =>
isOpen ? (
{children}
) : null,
}))
describe('UserMobileChangeModal', () => {
afterEach(cleanup)
beforeEach(() => {
vi.clearAllMocks()
changeMobile.mockResolvedValue({ ok: true, data: { id: 'user-1', mobile: '989121231231' } })
})
it('requires all three confirmation stages before changing the mobile', async () => {
const onSuccess = vi.fn()
const onOpenChange = vi.fn()
render(
)
const firstAccept = screen.getByRole('button', { name: 'بررسی شماره' })
expect(firstAccept).toBeDisabled()
fireEvent.change(screen.getByLabelText('شماره موبایل جدید'), { target: { value: '09121231231' } })
expect(firstAccept).toBeEnabled()
fireEvent.click(firstAccept)
const secondAccept = screen.getByRole('button', { name: 'تأیید و ادامه' })
expect(secondAccept).toBeDisabled()
fireEvent.change(screen.getByLabelText('برای تأیید، شماره فعلی کاربر را وارد کنید'), {
target: { value: '09111111111' },
})
expect(secondAccept).toBeEnabled()
fireEvent.click(secondAccept)
const finalAccept = screen.getByRole('button', { name: 'تغییر قطعی شماره' })
expect(finalAccept).toBeDisabled()
fireEvent.change(screen.getByLabelText('عبارت «تغییر شماره» را وارد کنید'), {
target: { value: 'تغییر شماره' },
})
expect(finalAccept).toBeEnabled()
fireEvent.click(finalAccept)
await waitFor(() => {
expect(changeMobile).toHaveBeenCalledWith('user-1', '989121231231')
})
expect(addToast).toHaveBeenCalledWith(expect.objectContaining({ color: 'success' }))
expect(onSuccess).toHaveBeenCalledTimes(1)
expect(onOpenChange).toHaveBeenCalledWith(false)
})
})