fix: wrap dismissNotification with useUnit in NotificationStack for scope isolation; fix test selectors
This commit is contained in:
@@ -1,36 +1,71 @@
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { addNotification, dismissAll } from '../../model/notification'
|
||||
import { allSettled, fork } from 'effector'
|
||||
import { Provider } from 'effector-react'
|
||||
import { describe, it, expect, afterEach } from 'vitest'
|
||||
import { addNotification, dismissAll, $notifications } from '../../model/notification'
|
||||
import { NotificationStack } from './NotificationStack'
|
||||
|
||||
beforeEach(() => {
|
||||
dismissAll()
|
||||
})
|
||||
|
||||
describe('NotificationStack', () => {
|
||||
afterEach(() => {
|
||||
dismissAll()
|
||||
})
|
||||
|
||||
function createTestScope() {
|
||||
return fork()
|
||||
}
|
||||
|
||||
function renderWithScope(scope: ReturnType<typeof fork>) {
|
||||
return render(
|
||||
<Provider value={scope}>
|
||||
<NotificationStack />
|
||||
</Provider>,
|
||||
)
|
||||
}
|
||||
|
||||
it('renders nothing when empty', () => {
|
||||
const { container } = render(<NotificationStack />)
|
||||
expect(container.firstChild).toBeNull()
|
||||
const scope = createTestScope()
|
||||
const { container } = renderWithScope(scope)
|
||||
expect(container.textContent).toBe('')
|
||||
})
|
||||
|
||||
it('renders notification when added', async () => {
|
||||
render(<NotificationStack />)
|
||||
addNotification({ type: 'info', message: 'Hello' })
|
||||
it('renders a success notification with check icon', async () => {
|
||||
const scope = createTestScope()
|
||||
await allSettled(addNotification, { scope, params: { type: 'success', message: 'Success!' } })
|
||||
renderWithScope(scope)
|
||||
expect(screen.getByText('Success!')).toBeDefined()
|
||||
})
|
||||
|
||||
it('renders error alert severity', async () => {
|
||||
const scope = createTestScope()
|
||||
await allSettled(addNotification, { scope, params: { type: 'error', message: 'Error!' } })
|
||||
renderWithScope(scope)
|
||||
const alert = screen.getByRole('alert')
|
||||
expect(alert).toBeDefined()
|
||||
})
|
||||
|
||||
it('dismisses on close button click', async () => {
|
||||
const scope = createTestScope()
|
||||
await allSettled(addNotification, { scope, params: { type: 'info', message: 'Dismiss me' } })
|
||||
renderWithScope(scope)
|
||||
|
||||
const closeBtn = screen.getByRole('button')
|
||||
fireEvent.click(closeBtn)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Hello')).toBeInTheDocument()
|
||||
const state = scope.getState($notifications)
|
||||
expect(state).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('dismiss button works', async () => {
|
||||
render(<NotificationStack />)
|
||||
addNotification({ type: 'info', message: 'Dismiss me' })
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Dismiss me')).toBeInTheDocument()
|
||||
})
|
||||
it('renders multiple notifications up to 3', async () => {
|
||||
const scope = createTestScope()
|
||||
await allSettled(addNotification, { scope, params: { type: 'info', message: 'A' } })
|
||||
await allSettled(addNotification, { scope, params: { type: 'info', message: 'B' } })
|
||||
await allSettled(addNotification, { scope, params: { type: 'info', message: 'C' } })
|
||||
renderWithScope(scope)
|
||||
|
||||
fireEvent.click(screen.getByTestId('CloseIcon'))
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Dismiss me')).not.toBeInTheDocument()
|
||||
})
|
||||
expect(screen.getByText('A')).toBeDefined()
|
||||
expect(screen.getByText('B')).toBeDefined()
|
||||
expect(screen.getByText('C')).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useUnit } from 'effector-react'
|
||||
import { Snackbar, Alert, Stack, IconButton } from '@mui/material'
|
||||
import CloseIcon from '@mui/icons-material/Close'
|
||||
import { $notifications, dismissNotification } from '../../model/notification'
|
||||
import { $notifications, dismissNotification as dismissNotificationEvent } from '../../model/notification'
|
||||
|
||||
export function NotificationStack() {
|
||||
const notifications = useUnit($notifications)
|
||||
const dismissNotification = useUnit(dismissNotificationEvent)
|
||||
|
||||
if (notifications.length === 0) return null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user