diff --git a/frontend/__tests__/unit/components/Modal.test.tsx b/frontend/__tests__/unit/components/Modal.test.tsx
index 9b57dae1f7..fded18b0c4 100644
--- a/frontend/__tests__/unit/components/Modal.test.tsx
+++ b/frontend/__tests__/unit/components/Modal.test.tsx
@@ -1,8 +1,7 @@
import { faCheck } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
-import { fireEvent, screen, waitFor } from '@testing-library/react'
-import { render } from 'wrappers/testUtil'
-import '@testing-library/jest-dom'
+import { render, screen, fireEvent } from '@testing-library/react'
+import React from 'react'
import DialogComp from 'components/Modal'
jest.mock('@/components/MarkdownWrapper', () => {
@@ -21,6 +20,56 @@ jest.mock('components/ActionButton', () => ({ children, onClick }) => (
))
+// Mock @heroui/modal components to avoid framer-motion issues
+jest.mock('@heroui/modal', () => {
+ return {
+ Modal: ({ isOpen, children }: { isOpen: boolean; children: React.ReactNode }) =>
+ isOpen ? : null,
+ ModalContent: ({
+ children,
+ className,
+ ...props
+ }: React.PropsWithChildren<{ className?: string } & Record>) => (
+
+ {children}
+
+ ),
+ ModalHeader: ({
+ children,
+ className,
+ ...props
+ }: React.PropsWithChildren<{ className?: string } & Record>) => (
+
+ ),
+ ModalBody: ({ children, ...props }: React.PropsWithChildren>) => (
+ {children}
+ ),
+ ModalFooter: ({
+ children,
+ className,
+ ...props
+ }: React.PropsWithChildren<{ className?: string } & Record>) => (
+
+ ),
+ }
+})
+
+jest.mock('@heroui/button', () => ({
+ Button: ({
+ children,
+ onPress,
+ ...props
+ }: React.PropsWithChildren<{ onPress?: () => void } & Record>) => (
+
+ ),
+}))
+
describe('DialogComp', () => {
const mockOnClose = jest.fn()
const mockOnClick = jest.fn()
@@ -43,54 +92,126 @@ describe('DialogComp', () => {
beforeEach(() => {
jest.clearAllMocks()
})
+
afterEach(() => {
jest.clearAllMocks()
jest.restoreAllMocks()
})
- test('does not render when isOpen is false', async () => {
+ it('does not render modal content when isOpen is false', () => {
render()
-
- await waitFor(() => expect(screen.queryByText('Test Title')).not.toBeInTheDocument())
+ expect(screen.queryByText('Test Title')).not.toBeInTheDocument()
})
- test('renders summary section correctly', async () => {
+ it('renders modal with title and description correctly', () => {
render()
-
- await waitFor(() => expect(screen.getByText('Summary')).toBeInTheDocument())
+ expect(screen.getByText('Test Title')).toBeInTheDocument()
+ expect(screen.getByText('Test Description')).toBeInTheDocument()
})
- test('renders hint section when hint prop is provided', async () => {
+ it('renders summary section correctly', () => {
render()
+ expect(screen.getByText('Summary')).toBeInTheDocument()
+ const markdownElements = screen.getAllByTestId('markdown')
+ expect(markdownElements.length).toBeGreaterThan(0)
+ })
- await waitFor(() => expect(screen.getByText('How to tackle it')).toBeInTheDocument())
+ it('renders hint section when hint prop is provided', () => {
+ render()
+ expect(screen.getByText('How to tackle it')).toBeInTheDocument()
+ const markdownElements = screen.getAllByTestId('markdown')
+ expect(markdownElements).toHaveLength(2)
})
- test('does not render hint section when hint prop is not provided', async () => {
+ it('does not render hint section when hint prop is not provided', () => {
render()
-
- await waitFor(() => expect(screen.queryByText('How to tackle it')).not.toBeInTheDocument())
+ expect(screen.queryByText('How to tackle it')).not.toBeInTheDocument()
+ const markdownElements = screen.getAllByTestId('markdown')
+ expect(markdownElements).toHaveLength(1)
})
- test('renders children content when provided', async () => {
+ it('renders children content when provided', () => {
render(
Child Content
)
+ expect(screen.getByTestId('child-content')).toBeInTheDocument()
+ expect(screen.getByText('Child Content')).toBeInTheDocument()
+ })
- await waitFor(() => {
- expect(screen.getByTestId('child-content')).toBeInTheDocument()
- expect(screen.getByText('Child Content')).toBeInTheDocument()
- })
+ it('calls onClose when close button is clicked', () => {
+ render()
+ const closeButton = screen.getByRole('button', { name: /close/i })
+ fireEvent.click(closeButton)
+ expect(mockOnClose).toHaveBeenCalledTimes(1)
+ })
+
+ it('renders action button when button prop is provided', () => {
+ render()
+ expect(screen.getByTestId('action-button')).toBeInTheDocument()
+ expect(screen.getByText('Action')).toBeInTheDocument()
+ })
+
+ it('renders with minimal required props', () => {
+ const minimalProps = {
+ title: 'Minimal Title',
+ summary: 'Minimal Summary',
+ isOpen: true,
+ onClose: mockOnClose,
+ description: '',
+ button: {
+ label: 'Minimal Action',
+ icon: null,
+ url: '',
+ onPress: mockOnClick,
+ },
+ }
+
+ render()
+ expect(screen.getByText('Minimal Title')).toBeInTheDocument()
+ expect(screen.getByText('Summary')).toBeInTheDocument()
+ expect(screen.getByText('Minimal Action')).toBeInTheDocument()
+ })
+
+ it('handles empty title, summary, description', () => {
+ render()
+ expect(screen.getByRole('dialog')).toBeInTheDocument()
+ expect(screen.getByText('Summary')).toBeInTheDocument()
})
- test('calls onClose when close button is clicked', async () => {
+ it('has correct accessibility attributes', () => {
render()
+ const modal = screen.getByRole('dialog')
+ expect(modal).toBeInTheDocument()
const closeButton = screen.getByText('Close')
- fireEvent.click(closeButton)
+ expect(closeButton).toHaveAttribute('aria-label', 'close-modal')
+ })
+
+ it('renders important classNames and DOM structure', () => {
+ render()
+ expect(document.querySelector('.animate-scaleIn')).toBeInTheDocument()
+ expect(document.querySelector('.font-bold')).toBeInTheDocument()
+ expect(document.querySelector('.flex.justify-end')).toBeInTheDocument()
+ })
+
+ it('handles null hint prop', () => {
+ render()
+ expect(screen.getByText('Summary')).toBeInTheDocument()
+ expect(screen.queryByText('How to tackle it')).not.toBeInTheDocument()
+ })
- await waitFor(() => expect(mockOnClose).toHaveBeenCalledTimes(1))
+ it('renders markdown content correctly', () => {
+ const markdownContent = '**Bold text** and *italic text*'
+
+ render()
+
+ const markdownElements = screen.getAllByTestId('markdown')
+ expect(markdownElements).toHaveLength(2)
+
+ markdownElements.forEach((element) => {
+ expect(element).toHaveClass('md-wrapper')
+ })
})
})