8a6758b591
- Add ofsted_framework field to School type - Add OfstedListBadge interface and buildOfstedListBadge pure function to utils.ts - Add fetchNationalAverages API function that calls GET /api/national-averages - Add test suite for buildOfstedListBadge (all 6 new tests pass) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
144 lines
4.3 KiB
TypeScript
144 lines
4.3 KiB
TypeScript
/**
|
|
* Utility Functions Tests
|
|
*/
|
|
|
|
import {
|
|
formatPercentage,
|
|
formatProgress,
|
|
calculateTrend,
|
|
isValidPostcode,
|
|
debounce,
|
|
buildOfstedListBadge,
|
|
} from '@/lib/utils';
|
|
|
|
describe('formatPercentage', () => {
|
|
it('formats percentages correctly', () => {
|
|
expect(formatPercentage(75.5)).toBe('75.5%');
|
|
expect(formatPercentage(100)).toBe('100.0%');
|
|
expect(formatPercentage(0)).toBe('0.0%');
|
|
});
|
|
|
|
it('handles null values', () => {
|
|
expect(formatPercentage(null)).toBe('-');
|
|
});
|
|
});
|
|
|
|
describe('formatProgress', () => {
|
|
it('formats progress scores correctly', () => {
|
|
expect(formatProgress(2.5)).toBe('+2.5');
|
|
expect(formatProgress(-1.3)).toBe('-1.3');
|
|
expect(formatProgress(0)).toBe('0.0');
|
|
});
|
|
|
|
it('handles null values', () => {
|
|
expect(formatProgress(null)).toBe('-');
|
|
});
|
|
});
|
|
|
|
describe('calculateTrend', () => {
|
|
it('calculates upward trend', () => {
|
|
expect(calculateTrend(75, 70)).toBe('up');
|
|
});
|
|
|
|
it('calculates downward trend', () => {
|
|
expect(calculateTrend(70, 75)).toBe('down');
|
|
});
|
|
|
|
it('calculates same trend', () => {
|
|
expect(calculateTrend(75, 75)).toBe('same');
|
|
});
|
|
|
|
it('handles null previous value', () => {
|
|
expect(calculateTrend(75, null)).toBe('same');
|
|
});
|
|
|
|
it('handles null current value', () => {
|
|
expect(calculateTrend(null, 75)).toBe('same');
|
|
});
|
|
});
|
|
|
|
describe('isValidPostcode', () => {
|
|
it('validates correct UK postcodes', () => {
|
|
expect(isValidPostcode('SW1A 1AA')).toBe(true);
|
|
expect(isValidPostcode('M1 1AE')).toBe(true);
|
|
expect(isValidPostcode('B33 8TH')).toBe(true);
|
|
});
|
|
|
|
it('rejects invalid postcodes', () => {
|
|
expect(isValidPostcode('INVALID')).toBe(false);
|
|
expect(isValidPostcode('12345')).toBe(false);
|
|
expect(isValidPostcode('')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('debounce', () => {
|
|
jest.useFakeTimers();
|
|
|
|
it('delays function execution', () => {
|
|
const mockFn = jest.fn();
|
|
const debouncedFn = debounce(mockFn, 300);
|
|
|
|
debouncedFn('test');
|
|
expect(mockFn).not.toHaveBeenCalled();
|
|
|
|
jest.advanceTimersByTime(300);
|
|
expect(mockFn).toHaveBeenCalledWith('test');
|
|
expect(mockFn).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('cancels previous calls', () => {
|
|
const mockFn = jest.fn();
|
|
const debouncedFn = debounce(mockFn, 300);
|
|
|
|
debouncedFn('first');
|
|
jest.advanceTimersByTime(150);
|
|
debouncedFn('second');
|
|
jest.advanceTimersByTime(150);
|
|
debouncedFn('third');
|
|
jest.advanceTimersByTime(300);
|
|
|
|
expect(mockFn).toHaveBeenCalledWith('third');
|
|
expect(mockFn).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
jest.useRealTimers();
|
|
});
|
|
|
|
describe('buildOfstedListBadge', () => {
|
|
it('returns grade word + year for OEIF Outstanding', () => {
|
|
const badge = buildOfstedListBadge({ ofsted_grade: 1, ofsted_date: '2023-11-15', ofsted_framework: 'OEIF' });
|
|
expect(badge.label).toBe('Outstanding · 2023');
|
|
expect(badge.cssClass).toBe('ofsted1');
|
|
});
|
|
|
|
it('returns grade word for each OEIF grade', () => {
|
|
expect(buildOfstedListBadge({ ofsted_grade: 2, ofsted_date: '2022-05-01' }).label).toBe('Good · 2022');
|
|
expect(buildOfstedListBadge({ ofsted_grade: 3, ofsted_date: '2021-01-01' }).label).toBe('Req. Improvement · 2021');
|
|
expect(buildOfstedListBadge({ ofsted_grade: 4, ofsted_date: '2020-03-01' }).label).toBe('Inadequate · 2020');
|
|
});
|
|
|
|
it('returns grade word without year when date is missing', () => {
|
|
const badge = buildOfstedListBadge({ ofsted_grade: 2, ofsted_date: null });
|
|
expect(badge.label).toBe('Good');
|
|
expect(badge.cssClass).toBe('ofsted2');
|
|
});
|
|
|
|
it('returns Report Card badge when framework is ReportCard', () => {
|
|
const badge = buildOfstedListBadge({ ofsted_grade: null, ofsted_date: '2025-11-01', ofsted_framework: 'ReportCard' });
|
|
expect(badge.label).toBe('Report Card · 2025');
|
|
expect(badge.cssClass).toBe('ofstedRc');
|
|
});
|
|
|
|
it('returns pending badge when no grade and no ReportCard framework', () => {
|
|
const badge = buildOfstedListBadge({ ofsted_grade: null, ofsted_date: null, ofsted_framework: null });
|
|
expect(badge.label).toBe('Not yet inspected');
|
|
expect(badge.cssClass).toBe('ofstedPending');
|
|
});
|
|
|
|
it('returns pending badge when all fields are undefined', () => {
|
|
const badge = buildOfstedListBadge({});
|
|
expect(badge.label).toBe('Not yet inspected');
|
|
expect(badge.cssClass).toBe('ofstedPending');
|
|
});
|
|
});
|