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 AdminEventCommissionModal from '@/features/events/detail/admin-event-detail/AdminEventCommissionModal'
const updateCommission = vi.fn()
const addToast = vi.fn()
const showAlert = vi.fn((_message: string, onConfirm?: () => unknown) => {
void onConfirm?.()
})
vi.mock('@/lib/toast', () => ({ addToast: (...args: unknown[]) => addToast(...args) }))
vi.mock('@/hooks/useAlertModal', () => ({ default: () => ({ showAlert }) }))
vi.mock('@/services/events', () => ({
updateEventCommissionAsAdmin: (...args: unknown[]) => updateCommission(...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,
disabled,
isLoading,
}: {
children: ReactNode
onClick?: () => void
disabled?: boolean
isLoading?: boolean
}) => (
),
}))
vi.mock('@/components/modals/Modal', () => ({
default: ({
isOpen,
title,
children,
footerChildren,
}: {
isOpen: boolean
title: string
children: ReactNode
footerChildren?: ReactNode
}) =>
isOpen ? (
{children}
{footerChildren}
) : null,
}))
describe('AdminEventCommissionModal', () => {
afterEach(cleanup)
beforeEach(() => {
vi.clearAllMocks()
showAlert.mockImplementation((_message: string, onConfirm?: () => unknown) => {
void onConfirm?.()
})
updateCommission.mockResolvedValue({
id: 'event-1',
commissionPercent: 12,
effectiveCommissionPercent: 12,
})
})
it('rejects out-of-range commission and does not call the API', () => {
const onUpdated = vi.fn()
const onOpenChange = vi.fn()
render(
)
fireEvent.change(screen.getByLabelText('درصد کمیسیون (۰ تا ۱۰۰)'), { target: { value: '150' } })
fireEvent.click(screen.getByRole('button', { name: 'ذخیره' }))
expect(screen.getByText('درصد کمیسیون باید عددی بین ۰ تا ۱۰۰ باشد')).toBeTruthy()
expect(updateCommission).not.toHaveBeenCalled()
expect(onUpdated).not.toHaveBeenCalled()
})
it('saves a valid override and closes on success', async () => {
const onUpdated = vi.fn()
const onOpenChange = vi.fn()
render(
)
fireEvent.change(screen.getByLabelText('درصد کمیسیون (۰ تا ۱۰۰)'), { target: { value: '12' } })
fireEvent.click(screen.getByRole('button', { name: 'ذخیره' }))
await waitFor(() => {
expect(updateCommission).toHaveBeenCalledWith('event-1', 12)
expect(onUpdated).toHaveBeenCalled()
expect(onOpenChange).toHaveBeenCalledWith(false)
})
})
it('resets to platform default when an override exists', async () => {
updateCommission.mockResolvedValue({
id: 'event-1',
commissionPercent: null,
effectiveCommissionPercent: 15,
})
const onUpdated = vi.fn()
const onOpenChange = vi.fn()
render(
)
fireEvent.click(screen.getByRole('button', { name: 'بازگشت به پیشفرض پلتفرم' }))
await waitFor(() => {
expect(updateCommission).toHaveBeenCalledWith('event-1', null)
expect(onUpdated).toHaveBeenCalled()
expect(onOpenChange).toHaveBeenCalledWith(false)
})
})
})