import { describe, it, expect } from 'vitest'; import { MAP_CONFIG } from '@/constants'; import { LOW_IS_GOOD_COLOR_STOPS, HIGH_IS_GOOD_COLOR_STOPS, interpolateMetricColor, } from '@/constants/colorSchemes'; describe('MAP_CONFIG', () => { describe('B18 — default map center is London', () => { it('DEFAULT_CENTER points at London, not Czech Republic', () => { // London ≈ [-0.1276, 51.5074]. The old default ([13.38032, 49.994210]) // landed in Czech Republic which is jarring for a UK-only app. const [lng, lat] = MAP_CONFIG.DEFAULT_CENTER; expect(lng).toBeGreaterThan(-1); expect(lng).toBeLessThan(1); expect(lat).toBeGreaterThan(51); expect(lat).toBeLessThan(52); }); it('DEFAULT_ZOOM gives a city-level view (not continent-level)', () => { // Anything around 10 is a city / inner-borough view in Mapbox terms. expect(MAP_CONFIG.DEFAULT_ZOOM).toBeGreaterThanOrEqual(9); expect(MAP_CONFIG.DEFAULT_ZOOM).toBeLessThanOrEqual(13); }); }); describe('B19 / B29 — Mapbox token sourced from env only', () => { it('reads from VITE_MAPBOX_TOKEN (the test setup sets it to test-token)', () => { // The test harness (src/__tests__/setup.ts) sets VITE_MAPBOX_TOKEN // to "test-token". The constant module reads import.meta.env at import time. expect(MAP_CONFIG.MAPBOX_TOKEN).toBe('test-token'); }); it('does not contain a hard-coded Mapbox public key as a fallback', () => { // The previous code shipped a real public key (`pk.eyJ1...`). This regression // test ensures we never leak a token into the bundle again. expect(MAP_CONFIG.MAPBOX_TOKEN).not.toMatch(/^pk\.eyJ/); }); }); }); describe('interpolateMetricColor', () => { it('returns null for invalid inputs (NaN value, max <= min)', () => { expect(interpolateMetricColor(NaN, 0, 100, LOW_IS_GOOD_COLOR_STOPS)).toBeNull(); expect(interpolateMetricColor(50, 100, 100, LOW_IS_GOOD_COLOR_STOPS)).toBeNull(); expect(interpolateMetricColor(50, 50, 0, LOW_IS_GOOD_COLOR_STOPS)).toBeNull(); }); it('returns the LOW_IS_GOOD start (green) for value at min', () => { const c = interpolateMetricColor(0, 0, 100, LOW_IS_GOOD_COLOR_STOPS); expect(c).toBe('rgb(34, 197, 94)'); }); it('returns the LOW_IS_GOOD end (red) for value at max', () => { const c = interpolateMetricColor(100, 0, 100, LOW_IS_GOOD_COLOR_STOPS); expect(c).toBe('rgb(239, 68, 68)'); }); it('inverts for HIGH_IS_GOOD (small → red, large → green)', () => { expect(interpolateMetricColor(0, 0, 100, HIGH_IS_GOOD_COLOR_STOPS)).toBe('rgb(239, 68, 68)'); expect(interpolateMetricColor(100, 0, 100, HIGH_IS_GOOD_COLOR_STOPS)).toBe('rgb(34, 197, 94)'); }); it('clamps out-of-range values to the gradient endpoints', () => { const below = interpolateMetricColor(-9999, 0, 100, LOW_IS_GOOD_COLOR_STOPS); const above = interpolateMetricColor(9999, 0, 100, LOW_IS_GOOD_COLOR_STOPS); expect(below).toBe('rgb(34, 197, 94)'); expect(above).toBe('rgb(239, 68, 68)'); }); });