129 lines
3.3 KiB
TypeScript
129 lines
3.3 KiB
TypeScript
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import Dashboard from './page';
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
|
|
// Mock next/navigation
|
|
vi.mock('next/navigation', () => ({
|
|
useRouter: () => ({
|
|
push: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
// Mock ResizeObserver
|
|
global.ResizeObserver = class ResizeObserver {
|
|
observe(): void {
|
|
/* noop */
|
|
}
|
|
unobserve(): void {
|
|
/* noop */
|
|
}
|
|
disconnect(): void {
|
|
/* noop */
|
|
}
|
|
};
|
|
|
|
// Mock fetch
|
|
global.fetch = vi.fn();
|
|
|
|
const createTestQueryClient = () =>
|
|
new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
retry: false,
|
|
},
|
|
},
|
|
});
|
|
|
|
describe('Dashboard', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
|
|
// Mock Auth Response
|
|
vi.mocked(global.fetch).mockImplementation((url: string | URL | Request) => {
|
|
if (url === '/api/auth') {
|
|
return Promise.resolve({
|
|
json: () => Promise.resolve({ authenticated: true, token: 'test-token' }),
|
|
} as Response);
|
|
}
|
|
if (url === '/api/habits') {
|
|
return Promise.resolve({
|
|
ok: true,
|
|
json: () =>
|
|
Promise.resolve({
|
|
habits: [
|
|
{
|
|
id: 1,
|
|
name: 'Test Habit',
|
|
type: 'neutral',
|
|
totalLogs: 5,
|
|
logsLastWeek: 2,
|
|
logsLastMonth: 5,
|
|
createdAt: new Date().toISOString(),
|
|
lastLoggedAt: new Date().toISOString(),
|
|
},
|
|
],
|
|
}),
|
|
} as Response);
|
|
}
|
|
return Promise.resolve({ ok: true, json: () => Promise.resolve({}) } as Response);
|
|
});
|
|
});
|
|
|
|
it('renders habits correctly', async () => {
|
|
render(
|
|
<QueryClientProvider client={createTestQueryClient()}>
|
|
<Dashboard />
|
|
</QueryClientProvider>,
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Test Habit')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('opens edit dialog when edit button is clicked', async () => {
|
|
render(
|
|
<QueryClientProvider client={createTestQueryClient()}>
|
|
<Dashboard />
|
|
</QueryClientProvider>,
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Test Habit')).toBeInTheDocument();
|
|
});
|
|
|
|
const editBtn = screen.getByTestId('edit-habit-1');
|
|
fireEvent.click(editBtn);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
expect(screen.getByText('Edit Habit')).toBeInTheDocument();
|
|
expect(screen.getByDisplayValue('Test Habit')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('opens archive confirmation when archive button is clicked', async () => {
|
|
render(
|
|
<QueryClientProvider client={createTestQueryClient()}>
|
|
<Dashboard />
|
|
</QueryClientProvider>,
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Test Habit')).toBeInTheDocument();
|
|
});
|
|
|
|
// Open Edit Dialog
|
|
fireEvent.click(screen.getByTestId('edit-habit-1'));
|
|
await waitFor(() => screen.getByRole('dialog'));
|
|
|
|
// Click Archive
|
|
fireEvent.click(screen.getByText('Archive Habit'));
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Confirm Delete')).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|