Files
ridebus-pwa/test/stops.test.mjs
Zakhar Timoshenko 6fe039cefa feat: add StopsMap and WalkingDirections components for enhanced map functionality
- Implemented StopsMap component to display bus stops on a map using MapLibre GL.
- Integrated walking directions feature in WalkingDirections component to calculate routes from user location to selected bus stop.
- Added geo utility functions for coordinate validation and distance calculation.
- Created route grouping and stop filtering logic in routeGroups module.
- Developed custom hooks for managing stop routes with React Query.
- Added tests for routing and stop functionalities to ensure reliability.
2026-10-08 00:18:10 +03:00

56 lines
3.6 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { coordinates } from '../server/coordinates.mjs';
import { createRideBusClient, normalizeCities, normalizeStop, normalizeStops, parseRequest } from '../server/ridebus.mjs';
import { distanceMeters, hasCoordinates, walkingLink } from '../src/lib/geo.ts';
test('map coordinates accept numeric strings and preserve missing/invalid pairs as missing', () => {
assert.deepEqual(coordinates('55.517553', 28.776448), { latitude: 55.517553, longitude: 28.776448 });
assert.deepEqual(coordinates(0, 0), { latitude: 0, longitude: 0 });
for (const [lat, lon] of [[null, 28], ['', 28], [55, undefined], [91, 28], [55, -181], [true, 28], ['bad', 28], [NaN, 28]]) {
assert.deepEqual(coordinates(lat, lon), {});
assert.equal(hasCoordinates({ latitude: lat, longitude: lon }), false);
}
assert.equal(hasCoordinates({ latitude: 0, longitude: 0 }), true);
assert.deepEqual(normalizeCities([{ id: 1, name: 'Полоцк', center_lat: '55.4869', center_lon: '28.7856' }])[0].latitude, 55.4869);
});
test('stop catalog retains platform coordinates and detail exposes only active distinct routes', () => {
const raw = { id: 95, name: '11 Июля', latitude: 55.517553, longitude: 28.776448, address: ' улица Ленина ', description: ' на Лозовку ', routes_count: '4' };
assert.equal(normalizeStops([raw])[0].address, 'улица Ленина');
assert.equal(normalizeStops([raw])[0].longitude, 28.776448);
const detail = normalizeStop({ ...raw, secret: 'hidden', routes: [
{ id: 2, route_number: '12', name: 'Центр', is_active: true },
{ id: 1, route_number: '4', name: 'Вокзал' },
{ id: 1, route_number: '4', name: 'Вокзал' },
{ id: 3, route_number: '2', name: 'Больница', is_active: false },
] });
assert.deepEqual(detail.routes.map(route => route.number), ['4', '12']);
assert.equal(detail.routesCount, 2);
assert.equal('secret' in detail, false);
assert.throws(() => normalizeStop({ ...raw, routes: null }), error => error.status === 502);
});
test('stop details validate identifiers, coalesce loads and isolate city caches', async () => {
assert.deepEqual(parseRequest(new URLSearchParams('resource=stop&cityId=1&stopId=95')), { resource: 'stop', cityId: 1, stopId: 95 });
for (const input of ['resource=stop&cityId=1', 'resource=stop&cityId=1&stopId=-1', 'resource=stop&cityId=1&stopId=../1']) assert.throws(() => parseRequest(new URLSearchParams(input)), error => error.status === 400);
const calls = [];
const client = createRideBusClient({ apiKey: 'private-key', fetchData: async (url, options) => {
calls.push([url.pathname, options.headers['X-City-Id']]);
return { ok: true, json: async () => ({ id: 95, name: '11 Июля', routes: [] }) };
} });
const input = { resource: 'stop', cityId: 1, stopId: 95 };
await Promise.all([client.get(input), client.get(input)]); await client.get(input); await client.get({ ...input, cityId: 2 });
assert.deepEqual(calls, [['/api/v1/stops/95', '1'], ['/api/v1/stops/95', '2']]);
});
test('nearby distances use geographic coordinates and walking links use the selected platform', () => {
const a = { latitude: 55.4849, longitude: 28.7685 }, b = { latitude: 55.4852, longitude: 28.7691 };
assert.equal(distanceMeters(a, a), 0);
assert.ok(distanceMeters(a, b) > 40 && distanceMeters(a, b) < 60);
assert.equal(distanceMeters(a, b), distanceMeters(b, a));
const link = new URL(walkingLink(b));
assert.equal(link.searchParams.get('destination'), '55.4852,28.7691');
assert.equal(link.searchParams.get('travelmode'), 'walking');
});