Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrated card component to chakraUI #631

Merged
merged 12 commits into from
Jan 28, 2025
90 changes: 18 additions & 72 deletions frontend/__tests__/src/pages/Contribute.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react'

import { fireEvent, screen, waitFor } from '@testing-library/react'
import { fetchAlgoliaData } from 'api/fetchAlgoliaData'
import { MemoryRouter } from 'react-router-dom'

import { render } from 'wrappers/testUtil'
import ContributePage from 'pages/Contribute'

import { mockContributeData } from '@tests/data/mockContributeData'

jest.mock('api/fetchAlgoliaData', () => ({
Expand All @@ -31,11 +28,7 @@ describe('Contribute Component', () => {
})

test('renders loading spinner initially', async () => {
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)
const loadingSpinner = screen.getAllByAltText('Loading indicator')
await waitFor(() => {
expect(loadingSpinner.length).toBeGreaterThan(0)
Expand All @@ -48,11 +41,7 @@ describe('Contribute Component', () => {
hits: mockContributeData.issues,
totalPages: 1,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

await waitFor(() => {
expect(screen.getByText('Contribution 1')).toBeInTheDocument()
Expand All @@ -68,11 +57,7 @@ describe('Contribute Component', () => {
issues: [],
totalPages: 0,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)
await waitFor(() => {
expect(screen.getByText('No issues found')).toBeInTheDocument()
})
Expand All @@ -85,11 +70,7 @@ describe('Contribute Component', () => {
hits: mockContributeData.issues,
totalPages: 4,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)
await waitFor(() => {
const nextPageButton = screen.getByText('Next Page')
fireEvent.click(nextPageButton)
Expand All @@ -99,17 +80,14 @@ describe('Contribute Component', () => {
behavior: 'auto',
})
})

test('handles pagination for first page', async () => {
;(fetchAlgoliaData as jest.Mock).mockResolvedValue({
...mockContributeData,
totalPages: 2,
currentPage: 1,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)
await waitFor(() => {
expect(screen.getByText('Next Page')).toBeInTheDocument()
})
Expand All @@ -121,11 +99,7 @@ describe('Contribute Component', () => {
totalPages: 2,
currentPage: 2,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)
await waitFor(() => {
expect(screen.queryByText('Next Page')).not.toBeInTheDocument()
})
Expand All @@ -136,29 +110,21 @@ describe('Contribute Component', () => {
...mockContributeData,
total_pages: 1,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)
await waitFor(() => {
expect(screen.queryByText('Next Page')).not.toBeInTheDocument()
})
})

test('handles search functionality', async () => {
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

await waitFor(() => {
const searchInput = screen.getByPlaceholderText('Search for OWASP issues...')
fireEvent.change(searchInput, { target: { value: '' } })
})

expect(fetchAlgoliaData).toHaveBeenCalledWith('issues', '', 1)
expect(fetchAlgoliaData).toHaveBeenCalledWith('issues', '', 2)
})

test('handles error states in card rendering', async () => {
Expand All @@ -174,11 +140,7 @@ describe('Contribute Component', () => {
}
;(fetchAlgoliaData as jest.Mock).mockResolvedValue(mockErrorIssue)

render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

await waitFor(() => {
expect(screen.queryByText('Read More')).not.toBeInTheDocument()
Expand All @@ -191,11 +153,7 @@ describe('Contribute Component', () => {
hits: mockContributeData.issues,
totalPages: 1,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

await waitFor(() => {
const readMoreButton = screen.getByText('Read More')
Expand All @@ -209,11 +167,7 @@ describe('Contribute Component', () => {
hits: mockContributeData.issues,
totalPages: 1,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

await waitFor(() => {
const readMoreButton = screen.getByText('Read More')
Expand All @@ -232,11 +186,7 @@ describe('Contribute Component', () => {
hits: mockContributeData.issues,
totalPages: 1,
})
render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

await waitFor(() => {
const readMoreButton = screen.getByText('Read More')
Expand Down Expand Up @@ -264,11 +214,7 @@ describe('Contribute Component', () => {
}
;(fetchAlgoliaData as jest.Mock).mockResolvedValue(mockMultipleIssues)

render(
<MemoryRouter>
<ContributePage />
</MemoryRouter>
)
render(<ContributePage />)

// Wait for both cards to be rendered
await waitFor(() => {
Expand All @@ -285,7 +231,7 @@ describe('Contribute Component', () => {
expect(screen.getByText('Hint 1')).toBeInTheDocument()
})

//verify first issue button
// Verify first issue button
await waitFor(() => {
const viewIssueButton = screen.getByRole('button', { name: 'View Issue' })
expect(viewIssueButton).toBeInTheDocument()
Expand Down
41 changes: 26 additions & 15 deletions frontend/__tests__/src/pages/Modal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { ChakraProvider } from '@chakra-ui/react'
import { render, screen, fireEvent } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React from 'react'
import { system } from 'utils/theme'

import { Modal } from 'components/Modal'

Expand Down Expand Up @@ -31,23 +34,32 @@ describe('Modal Component', () => {
onclick: jest.fn(),
url: 'https://example.com/issue/123',
},
children: undefined as React.ReactNode | undefined,
}

const renderModal = (props = defaultProps) => {
return render(
<ChakraProvider value={system}>
<Modal {...props} />
</ChakraProvider>
)
}

it('renders nothing when isOpen is false', () => {
render(<Modal {...defaultProps} isOpen={false} />)
renderModal({ ...defaultProps, isOpen: false })
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
})

it('renders the action button and handles its events', async () => {
const onclick = jest.fn()
render(<Modal {...defaultProps} button={{ ...defaultProps.button, onclick }} />)
renderModal({ ...defaultProps, button: { ...defaultProps.button, onclick } })

const actionButton = screen.getByRole('link', { name: /Test Button/i })
expect(actionButton).toBeInTheDocument()
})

it('renders modal with all components when isOpen is true', () => {
render(<Modal {...defaultProps} />)
renderModal()

expect(screen.getByRole('dialog')).toBeInTheDocument()
expect(screen.getByText('Test Modal')).toBeInTheDocument()
Expand All @@ -57,18 +69,17 @@ describe('Modal Component', () => {
})

it('renders children content when provided', () => {
render(
<Modal {...defaultProps}>
<div data-testid="child-content">Child Content</div>
</Modal>
)
renderModal({
...defaultProps,
children: <div data-testid="child-content">Child Content</div>,
})

expect(screen.getByTestId('child-content')).toBeInTheDocument()
})

it('calls onClose when close button is clicked', async () => {
const onClose = jest.fn()
render(<Modal {...defaultProps} onClose={onClose} />)
renderModal({ ...defaultProps, onClose })

const closeButton = screen.getByRole('button', { name: /close modal/i })
await userEvent.click(closeButton)
Expand All @@ -78,7 +89,7 @@ describe('Modal Component', () => {

it('calls onClose when clicking outside the modal', () => {
const onClose = jest.fn()
render(<Modal {...defaultProps} onClose={onClose} />)
renderModal({ ...defaultProps, onClose })

const overlay = screen.getByRole('presentation')
fireEvent.mouseDown(overlay)
Expand All @@ -88,15 +99,15 @@ describe('Modal Component', () => {

it('handles escape key press', () => {
const onClose = jest.fn()
render(<Modal {...defaultProps} onClose={onClose} />)
renderModal({ ...defaultProps, onClose })

fireEvent.keyDown(screen.getByRole('dialog'), { key: 'Escape' })

expect(onClose).toHaveBeenCalledTimes(2)
})

it('manages body overflow style correctly', () => {
const { unmount } = render(<Modal {...defaultProps} />)
const { unmount } = renderModal()

expect(document.body.style.overflow).toBe('hidden')

Expand All @@ -106,7 +117,7 @@ describe('Modal Component', () => {
})

it('renders with correct accessibility attributes', () => {
render(<Modal {...defaultProps} />)
renderModal()

const dialog = screen.getByRole('dialog')
expect(dialog).toHaveAttribute('aria-modal', 'true')
Expand All @@ -120,7 +131,7 @@ describe('Modal Component', () => {
hint: undefined,
}

render(<Modal {...propsWithoutHint} />)
renderModal(propsWithoutHint)

expect(screen.queryByText('How to tackle it')).not.toBeInTheDocument()
})
Expand All @@ -130,7 +141,7 @@ describe('Modal Component', () => {
const addEventListenerSpy = jest.spyOn(document, 'addEventListener')
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')

const { unmount } = render(<Modal {...defaultProps} />)
const { unmount } = renderModal()

expect(addEventListenerSpy).toHaveBeenCalledWith('keydown', expect.any(Function))

Expand Down
7 changes: 6 additions & 1 deletion frontend/jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import '@testing-library/jest-dom'
import { TextEncoder } from 'util'
import dotenv from 'dotenv'
import React from 'react'
import 'core-js/actual/structured-clone'

dotenv.config()

global.React = React
global.TextEncoder = TextEncoder
global.structuredClone = (val) => JSON.parse(JSON.stringify(val))

if (!global.structuredClone) {
global.structuredClone = (val) => JSON.parse(JSON.stringify(val))
}

beforeEach(() => {
jest.spyOn(console, 'error').mockImplementation((...args) => {
throw new Error(`Console error: ${args.join(' ')}`)
Expand Down
Loading
Loading