// Run with: node --experimental-strip-types --test test/*.test.ts
// (Node's built-in runner — no localhost/dev-server dependency.)
import { test } from "node:test";
import assert from "node:assert/strict";
import { parseHeartbeat } from "../src/heartbeat.ts";

const valid = {
  installId: "11111111-2222-3333-4444-555555555555",
  platform: "macos",
  osVersion: "26.0",
  channel: "beta",
  appVersion: "0.1.0",
  build: "42",
  arch: "arm64",
  locale: "en",
};

test("accepts a well-formed macOS payload", () => {
  const r = parseHeartbeat(valid);
  assert.equal(r.ok, true);
  if (r.ok) assert.equal(r.value.platform, "macos");
});

test("accepts an iOS App Store payload", () => {
  const r = parseHeartbeat({ ...valid, platform: "ios", channel: "appstore", osVersion: "17.4" });
  assert.equal(r.ok, true);
});

test("rejects a missing installId", () => {
  assert.deepEqual(parseHeartbeat({ ...valid, installId: "" }), { ok: false, error: "installId" });
});

test("rejects an over-long installId", () => {
  assert.deepEqual(parseHeartbeat({ ...valid, installId: "x".repeat(200) }), { ok: false, error: "installId" });
});

test("rejects an unknown platform", () => {
  assert.deepEqual(parseHeartbeat({ ...valid, platform: "windows" }), { ok: false, error: "platform" });
});

test("rejects an unknown channel", () => {
  assert.deepEqual(parseHeartbeat({ ...valid, channel: "nightly" }), { ok: false, error: "channel" });
});

test("defaults missing minor fields to unknown", () => {
  const { osVersion, arch, ...rest } = valid;
  const r = parseHeartbeat(rest);
  assert.equal(r.ok, true);
  if (r.ok) {
    assert.equal(r.value.osVersion, "unknown");
    assert.equal(r.value.arch, "unknown");
  }
});

test("rejects non-objects", () => {
  assert.equal(parseHeartbeat(null).ok, false);
  assert.equal(parseHeartbeat("x").ok, false);
  assert.equal(parseHeartbeat(42).ok, false);
});
