SPB Git

spb/earth-now Public License

earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.

TypeScript 93% Shell 2.3% SQL 1.4% JavaScript 1.3% Dockerfile 1.2% CSS 0.8%
3.4 KB · 100 lines typescript
Raw Blame History
1/**2 * earth-now.co3 * Author:  Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File:    apps/ingest/test/usgs.test.ts6 * Purpose: USGS FDSN parsers/fetcher tests — fixture-backed, no network7 */89import { readFileSync } from "node:fs";10import { describe, expect, it } from "vitest";11import type { FetchLike } from "../src/fetch-like";12import {13  fetchUsgsQuakeCount,14  parseUsgsCount,15  parseUsgsLastMajor,16  usgsCountUrl,17} from "../src/sources/usgs";1819const fixture = (name: string): string =>20  readFileSync(new URL(`./fixtures/${name}`, import.meta.url), "utf8");2122const fakeFetch =23  (body: string, ok = true, status = 200): FetchLike =>24  async () => ({ ok, status, text: async () => body });2526describe("usgsCountUrl", () => {27  it("builds a deterministic count URL from a parameterized now", () => {28    const nowMs = Date.parse("2026-08-09T12:00:00Z");29    expect(usgsCountUrl(24, 4.5, nowMs)).toBe(30      "https://earthquake.usgs.gov/fdsnws/event/1/count?format=geojson" +31        "&starttime=2026-08-08T12%3A00%3A00.000Z&minmagnitude=4.5",32    );33  });34});3536describe("parseUsgsCount", () => {37  it("returns the count from a realistic payload", () => {38    expect(parseUsgsCount(JSON.parse(fixture("usgs_count_sample.json")))).toBe(132);39  });4041  it("throws descriptive errors on malformed payloads", () => {42    expect(() => parseUsgsCount(JSON.parse(fixture("usgs_count_malformed.json")))).toThrow(43      /'count' must be a non-negative integer/,44    );45    expect(() => parseUsgsCount(null)).toThrow(/not an object/);46    expect(() => parseUsgsCount({ count: -3 })).toThrow(/non-negative/);47    expect(() => parseUsgsCount({ count: "132" })).toThrow(/non-negative integer/);48  });49});5051describe("parseUsgsLastMajor", () => {52  it("extracts mag/place/timeIso from features[0]", () => {53    const result = parseUsgsLastMajor(JSON.parse(fixture("usgs_query_sample.json")));54    expect(result).toEqual({55      mag: 6.3,56      place: "142 km E of Petropavlovsk-Kamchatsky, Russia",57      timeIso: new Date(1754650000000).toISOString(),58    });59  });6061  it("throws on the degraded fixture (missing mag, non-numeric time)", () => {62    expect(() => parseUsgsLastMajor(JSON.parse(fixture("usgs_query_malformed.json")))).toThrow(63      /mag is not a finite number/,64    );65  });6667  it("throws on empty or missing features", () => {68    expect(() => parseUsgsLastMajor({ type: "FeatureCollection", features: [] })).toThrow(69      /'features' is missing or empty/,70    );71    expect(() => parseUsgsLastMajor({})).toThrow(/'features' is missing or empty/);72  });73});7475describe("fetchUsgsQuakeCount", () => {76  it("fetches and parses via an injected fetchImpl (no network)", async () => {77    const seen: string[] = [];78    const fetchImpl: FetchLike = async (url) => {79      seen.push(url);80      return { ok: true, status: 200, text: async () => fixture("usgs_count_sample.json") };81    };82    await expect(fetchUsgsQuakeCount(24, 4.5, fetchImpl)).resolves.toBe(132);83    expect(seen).toHaveLength(1);84    expect(seen[0]).toContain("/fdsnws/event/1/count?format=geojson");85    expect(seen[0]).toContain("minmagnitude=4.5");86  });8788  it("throws on HTTP errors", async () => {89    await expect(fetchUsgsQuakeCount(24, 4.5, fakeFetch("", false, 503))).rejects.toThrow(90      /HTTP 503/,91    );92  });9394  it("throws on non-JSON bodies", async () => {95    await expect(fetchUsgsQuakeCount(24, 4.5, fakeFetch("<html>oops</html>"))).rejects.toThrow(96      /not valid JSON/,97    );98  });99});100