stratoflights-web/tests/unit/history.test.ts
2026-08-14 00:01:49 +09:00

69 lines
2.3 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { toHistoryRow } from '$domain';
import type { RawPrediction } from '$domain';
const result: RawPrediction = {
metadata: { start_datetime: '2026-01-01T00:00:00Z', complete_datetime: '2026-01-01T01:30:00Z' },
prediction: [
{
stage: 'ascent',
trajectory: [
{ altitude: 0, datetime: '2026-01-01T00:00:00Z', latitude: 62.0, longitude: 129.0 },
{ altitude: 30000, datetime: '2026-01-01T01:00:00Z', latitude: 62.1, longitude: 129.2 }
]
},
{
stage: 'descent',
trajectory: [
{ altitude: 30000, datetime: '2026-01-01T01:00:00Z', latitude: 62.1, longitude: 129.2 },
{ altitude: 0, datetime: '2026-01-01T01:30:00Z', latitude: 62.05, longitude: 129.4 }
]
}
]
};
describe('toHistoryRow', () => {
it('summarises a stored prediction into landing and flight time', () => {
const row = toHistoryRow({ id: 'a', created_at: '2026-01-01T00:00:00Z', result });
expect(row.broken).toBe(false);
expect(row.landing).toEqual({ lat: 62.05, lng: 129.4 });
expect(row.flightTime).toBe(90 * 60);
expect(row.createdAt.toISOString()).toBe('2026-01-01T00:00:00.000Z');
});
it('marks a run with no result as broken rather than throwing', () => {
const row = toHistoryRow({ id: 'b', created_at: '2026-01-01T00:00:00Z', result: null });
expect(row.broken).toBe(true);
expect(row.landing).toBeNull();
expect(row.flightTime).toBe(0);
});
it('summarises an ensemble run by its footprint instead of a trajectory', () => {
const row = toHistoryRow({
id: 'e',
created_at: '2026-01-01T00:00:00Z',
result: {
ensemble: {
members: [{ member: 0, landing: { lat: 62, lng: 129, alt: 0 } }],
failed: [],
footprint: {
count: 21,
mean: { lat: 62.5, lng: 129.5 },
radius_km: 4.2,
ellipse: { semi_major_km: 7, semi_minor_km: 3, bearing_deg: 10 }
}
}
}
});
expect(row.kind).toBe('ensemble');
expect(row.members).toBe(21);
expect(row.landing).toEqual({ lat: 62.5, lng: 129.5 });
expect(row.broken).toBe(false);
});
it('marks a truncated result (single stage) as broken', () => {
const partial = { ...result, prediction: [result.prediction[0]] };
const row = toHistoryRow({ id: 'c', created_at: '2026-01-01T00:00:00Z', result: partial });
expect(row.broken).toBe(true);
});
});