Complete Next.js migration with SSR and Docker deployment
- Migrate from vanilla JavaScript SPA to Next.js 16 with App Router - Add server-side rendering for all pages (Home, Compare, Rankings) - Create individual school pages with dynamic routing (/school/[urn]) - Implement Chart.js and Leaflet map integrations - Add comprehensive SEO with sitemap, robots.txt, and JSON-LD - Set up Docker multi-service architecture (PostgreSQL, FastAPI, Next.js) - Update CI/CD pipeline to build both backend and frontend images - Fix Dockerfile to include devDependencies for TypeScript compilation - Add Jest testing configuration - Implement performance optimizations (code splitting, caching) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
63
nextjs-app/__tests__/components/SchoolCard.test.tsx
Normal file
63
nextjs-app/__tests__/components/SchoolCard.test.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* SchoolCard Component Tests
|
||||
*/
|
||||
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { SchoolCard } from '@/components/SchoolCard';
|
||||
import type { School } from '@/lib/types';
|
||||
|
||||
const mockSchool: School = {
|
||||
urn: 100001,
|
||||
school_name: 'Test Primary School',
|
||||
local_authority: 'Westminster',
|
||||
school_type: 'Academy',
|
||||
address: '123 Test Street',
|
||||
postcode: 'SW1A 1AA',
|
||||
latitude: 51.5074,
|
||||
longitude: -0.1278,
|
||||
rwm_expected_pct: 75.5,
|
||||
rwm_higher_pct: 25.3,
|
||||
prev_rwm_expected_pct: 70.0,
|
||||
};
|
||||
|
||||
describe('SchoolCard', () => {
|
||||
it('renders school information correctly', () => {
|
||||
render(<SchoolCard school={mockSchool} />);
|
||||
|
||||
expect(screen.getByText('Test Primary School')).toBeInTheDocument();
|
||||
expect(screen.getByText('Westminster')).toBeInTheDocument();
|
||||
expect(screen.getByText('Academy')).toBeInTheDocument();
|
||||
expect(screen.getByText('75.5%')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('links to school detail page', () => {
|
||||
render(<SchoolCard school={mockSchool} />);
|
||||
|
||||
const link = screen.getByRole('link', { name: /test primary school/i });
|
||||
expect(link).toHaveAttribute('href', '/school/100001');
|
||||
});
|
||||
|
||||
it('calls onAddToCompare when Add to Compare button is clicked', () => {
|
||||
const mockAddToCompare = jest.fn();
|
||||
render(<SchoolCard school={mockSchool} onAddToCompare={mockAddToCompare} />);
|
||||
|
||||
const addButton = screen.getByText('Add to Compare');
|
||||
fireEvent.click(addButton);
|
||||
|
||||
expect(mockAddToCompare).toHaveBeenCalledWith(mockSchool);
|
||||
expect(mockAddToCompare).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not render Add to Compare button when handler not provided', () => {
|
||||
render(<SchoolCard school={mockSchool} />);
|
||||
|
||||
expect(screen.queryByText('Add to Compare')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('displays trend indicator for positive change', () => {
|
||||
render(<SchoolCard school={mockSchool} />);
|
||||
|
||||
// Should show upward trend (75.5 > 70.0)
|
||||
expect(screen.getByText('↗')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user