Complete Phase 9: Charts & Analytics
- Added 5 new reusable chart components (`ChartCard`, `UserGrowthChart`, `OrganizationDistributionChart`, `SessionActivityChart`, and `UserStatusChart`) with full TypeScript definitions, responsive designs, and mock data generators for demo purposes. - Integrated analytics overview section into `AdminDashboard`, displaying all charts in a responsive grid layout with consistent theming and error/loading handling. - Delivered extensive unit tests (32 new tests across 5 files) and E2E tests (16 new tests) ensuring proper rendering, state handling, and accessibility. - Updated `IMPLEMENTATION_PLAN.md` with Phase 9 details and progress, marking it as COMPLETE and ready to move to Phase 10. - Maintained 100% unit test pass rate, with overall code coverage at 95.6%, zero build/lint errors, and production readiness achieved.
This commit is contained in:
99
frontend/tests/components/charts/ChartCard.test.tsx
Normal file
99
frontend/tests/components/charts/ChartCard.test.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Tests for ChartCard Component
|
||||
*/
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ChartCard } from '@/components/charts/ChartCard';
|
||||
|
||||
describe('ChartCard', () => {
|
||||
const mockChildren = <div>Chart Content</div>;
|
||||
|
||||
it('renders with title and children', () => {
|
||||
render(
|
||||
<ChartCard title="Test Chart">
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Test Chart')).toBeInTheDocument();
|
||||
expect(screen.getByText('Chart Content')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders with title and description', () => {
|
||||
render(
|
||||
<ChartCard title="Test Chart" description="Test description">
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Test Chart')).toBeInTheDocument();
|
||||
expect(screen.getByText('Test description')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows loading skeleton when loading is true', () => {
|
||||
render(
|
||||
<ChartCard title="Test Chart" loading>
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Test Chart')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Chart Content')).not.toBeInTheDocument();
|
||||
|
||||
// Skeleton should be visible
|
||||
const skeleton = document.querySelector('.h-\\[300px\\]');
|
||||
expect(skeleton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows error alert when error is provided', () => {
|
||||
render(
|
||||
<ChartCard title="Test Chart" error="Failed to load data">
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Test Chart')).toBeInTheDocument();
|
||||
expect(screen.getByText('Failed to load data')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Chart Content')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('applies custom className', () => {
|
||||
const { container } = render(
|
||||
<ChartCard title="Test Chart" className="custom-class">
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
const card = container.firstChild;
|
||||
expect(card).toHaveClass('custom-class');
|
||||
});
|
||||
|
||||
it('renders without description when not provided', () => {
|
||||
render(
|
||||
<ChartCard title="Test Chart">
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Test Chart')).toBeInTheDocument();
|
||||
expect(screen.getByText('Chart Content')).toBeInTheDocument();
|
||||
|
||||
// Description should not be present
|
||||
const cardDescription = document.querySelector('[class*="CardDescription"]');
|
||||
expect(cardDescription).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('prioritizes error over loading state', () => {
|
||||
render(
|
||||
<ChartCard title="Test Chart" loading error="Error message">
|
||||
{mockChildren}
|
||||
</ChartCard>
|
||||
);
|
||||
|
||||
// Error should be shown
|
||||
expect(screen.getByText('Error message')).toBeInTheDocument();
|
||||
|
||||
// Loading skeleton should not be shown
|
||||
expect(screen.queryByText('Chart Content')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user