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%
1/**2 * earth-now.co3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: apps/ingest/test/archive.test.ts6 * Purpose: Raw archive tests — payload + sha256 checksum written under ${dir}/${sourceId}/, deterministic timestamps7 */89import { createHash } from "node:crypto";10import { mkdtempSync, readFileSync } from "node:fs";11import { tmpdir } from "node:os";12import { join, sep } from "node:path";13import { describe, expect, it } from "vitest";14import { archiveRaw } from "../src/archive";1516describe("archiveRaw", () => {17 it("writes the raw payload and a sha256 sidecar under dir/sourceId/", async () => {18 const dir = mkdtempSync(join(tmpdir(), "earth-now-archive-"));19 const payload = "year month value\n2024 1 422.80\n";20 const now = new Date("2026-08-09T12:00:00.000Z");2122 const result = await archiveRaw("noaa_gml_mlo", payload, { dir, now });2324 expect(result.rawPath).toBe(join(dir, "noaa_gml_mlo", "2026-08-09T12-00-00-000Z.raw"));25 expect(result.checksumPath).toBe(`${result.rawPath}.sha256`);26 expect(readFileSync(result.rawPath, "utf8")).toBe(payload);2728 const expectedSha = createHash("sha256").update(payload, "utf8").digest("hex");29 expect(result.sha256).toBe(expectedSha);30 expect(readFileSync(result.checksumPath, "utf8")).toBe(31 `${expectedSha} 2026-08-09T12-00-00-000Z.raw\n`,32 );33 });3435 it("accepts binary payloads (Uint8Array)", async () => {36 const dir = mkdtempSync(join(tmpdir(), "earth-now-archive-"));37 const payload = new Uint8Array([0, 1, 2, 254, 255]);38 const result = await archiveRaw("usgs_fdsn", payload, { dir });39 expect(readFileSync(result.rawPath)).toEqual(Buffer.from(payload));40 expect(result.rawPath.split(sep)).toContain("usgs_fdsn");41 });4243 it("rejects path-unsafe source ids", async () => {44 await expect(archiveRaw("../evil", "x", { dir: tmpdir() })).rejects.toThrow(/invalid sourceId/);45 });46});47