Vite + TypeScript PWA that mirrors the Android app's core features: - Pre-processed shelter data (build-time UTM33N→WGS84 conversion) - Leaflet map with shelter markers, user location, and offline tiles - Canvas compass arrow (ported from DirectionArrowView.kt) - IndexedDB shelter cache with 7-day staleness check - Service worker with CacheFirst tiles and precached app shell - i18n for en, nb, nn (ported from Android strings.xml) - iOS/Android compass handling with low-pass filter - Respects user map interaction (no auto-snap on pan/zoom) - Build revision cache-breaker for reliable SW updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { findNearest } from '../src/location/shelter-finder';
|
|
import type { Shelter } from '../src/types';
|
|
|
|
const shelters: Shelter[] = [
|
|
{
|
|
lokalId: 'a',
|
|
romnr: 1,
|
|
plasser: 100,
|
|
adresse: 'Near',
|
|
latitude: 59.91,
|
|
longitude: 10.75,
|
|
},
|
|
{
|
|
lokalId: 'b',
|
|
romnr: 2,
|
|
plasser: 200,
|
|
adresse: 'Mid',
|
|
latitude: 59.95,
|
|
longitude: 10.75,
|
|
},
|
|
{
|
|
lokalId: 'c',
|
|
romnr: 3,
|
|
plasser: 300,
|
|
adresse: 'Far',
|
|
latitude: 60.0,
|
|
longitude: 10.75,
|
|
},
|
|
{
|
|
lokalId: 'd',
|
|
romnr: 4,
|
|
plasser: 400,
|
|
adresse: 'Very Far',
|
|
latitude: 61.0,
|
|
longitude: 10.75,
|
|
},
|
|
];
|
|
|
|
describe('findNearest', () => {
|
|
it('returns shelters sorted by distance', () => {
|
|
const result = findNearest(shelters, 59.9, 10.75);
|
|
expect(result).toHaveLength(3);
|
|
expect(result[0].shelter.lokalId).toBe('a');
|
|
expect(result[1].shelter.lokalId).toBe('b');
|
|
expect(result[2].shelter.lokalId).toBe('c');
|
|
});
|
|
|
|
it('returns requested count', () => {
|
|
const result = findNearest(shelters, 59.9, 10.75, 2);
|
|
expect(result).toHaveLength(2);
|
|
});
|
|
|
|
it('returns all if fewer than count', () => {
|
|
const result = findNearest(shelters.slice(0, 1), 59.9, 10.75, 5);
|
|
expect(result).toHaveLength(1);
|
|
});
|
|
|
|
it('calculates distance and bearing', () => {
|
|
const result = findNearest(shelters, 59.9, 10.75, 1);
|
|
expect(result[0].distanceMeters).toBeGreaterThan(0);
|
|
expect(result[0].bearingDegrees).toBeGreaterThanOrEqual(0);
|
|
expect(result[0].bearingDegrees).toBeLessThan(360);
|
|
});
|
|
|
|
it('handles empty shelter list', () => {
|
|
const result = findNearest([], 59.9, 10.75);
|
|
expect(result).toHaveLength(0);
|
|
});
|
|
});
|