veza/apps/web/src/context/ToastContext.test.tsx
senke b103a09a25 chore: consolidate CI, E2E, backend and frontend updates
- CI: workflows updates (cd, ci), remove playwright.yml
- E2E: global-setup, auth/playlists/profile specs
- Remove playwright-report and test-results artifacts from tracking
- Backend: auth, handlers, services, workers, migrations
- Frontend: components, features, vite config
- Add e2e-results.json to gitignore
- Docs: REMEDIATION_PROGRESS, audit archive
- Rust: chat-server, stream-server updates
2026-02-17 16:43:21 +01:00

146 lines
3.5 KiB
TypeScript

import { renderHook, act, render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { ToastProvider, useToast } from '../components/feedback/ToastProvider';
import { ReactNode } from 'react';
// Mock toast to avoid react-hot-toast dynamic import issues in Vitest
vi.mock('@/utils/toast', () => {
const mockFn = (msg: string) => {
const el = document.createElement('div');
el.textContent = msg;
el.setAttribute('data-testid', 'toast-message');
document.body.appendChild(el);
};
return {
default: Object.assign(mockFn, {
success: mockFn,
error: mockFn,
warning: mockFn,
loading: mockFn,
custom: mockFn,
dismiss: vi.fn(),
remove: vi.fn(),
promise: vi.fn(() => Promise.resolve()),
}),
};
});
const wrapper = ({ children }: { children: ReactNode }) => (
<ToastProvider>{children}</ToastProvider>
);
describe('ToastContext', () => {
beforeEach(() => {
vi.clearAllMocks();
document.querySelectorAll('[data-testid="toast-message"]').forEach((el) => el.remove());
});
it('should provide toast context', () => {
const { result } = renderHook(() => useToast(), { wrapper });
expect(result.current).toBeDefined();
expect(result.current).toHaveProperty('addToast');
expect(typeof result.current.addToast).toBe('function');
});
it('should add toast', () => {
const TestComponent = () => {
const { addToast } = useToast();
return (
<div>
<button onClick={() => addToast('Test message', 'info')}>
Add Toast
</button>
</div>
);
};
render(
<ToastProvider>
<TestComponent />
</ToastProvider>,
);
const button = screen.getByText('Add Toast');
act(() => {
button.click();
});
// Toast should be added to the DOM
expect(screen.getByText('Test message')).toBeInTheDocument();
});
it('should add success toast', () => {
const TestComponent = () => {
const { addToast } = useToast();
return (
<div>
<button onClick={() => addToast('Success!', 'success')}>
Add Success
</button>
</div>
);
};
render(
<ToastProvider>
<TestComponent />
</ToastProvider>,
);
const button = screen.getByText('Add Success');
act(() => {
button.click();
});
expect(screen.getByText('Success!')).toBeInTheDocument();
});
it('should add error toast', () => {
const TestComponent = () => {
const { addToast } = useToast();
return (
<div>
<button onClick={() => addToast('Error!', 'error')}>Add Error</button>
</div>
);
};
render(
<ToastProvider>
<TestComponent />
</ToastProvider>,
);
const button = screen.getByText('Add Error');
act(() => {
button.click();
});
expect(screen.getByText('Error!')).toBeInTheDocument();
});
it('should use default type info when type not provided', () => {
const TestComponent = () => {
const { addToast } = useToast();
return (
<div>
<button onClick={() => addToast('Info message')}>Add Info</button>
</div>
);
};
render(
<ToastProvider>
<TestComponent />
</ToastProvider>,
);
const button = screen.getByText('Add Info');
act(() => {
button.click();
});
expect(screen.getByText('Info message')).toBeInTheDocument();
});
});