← Files OpsTruthARCHIVED FILE

test/analytics.test.js

2.98 KB · Oct 2, 2026 · 00:31 UTC

↓ Download file

import assert from "node:assert/strict";
import test from "node:test";
import { analyticsPoint, classifyClient, feedbackPoint, recordFeedbackEvent, recordToolEvent, summarizeToolResult } from "../src/analytics.js";

test("analytics stores bounded aggregate dimensions only", () => {
  const request = new Request("https://example.test/mcp", { headers: { "user-agent": "ChatGPT/1.0" } });
  assert.equal(classifyClient(request), "chatgpt");
  const point = analyticsPoint({
    tool: "opstruth_audit_repository", outcome: "success", status: 200, latencyMs: 42, client: "chatgpt",
    verdict: "insufficient_evidence", counts: { evidence: 4, warnings: 2, failures: 0, notVerified: 3 }, ciObserved: true, signedEvidence: true,
  });
  assert.deepEqual(point.indexes, ["opstruth_audit_repository"]);
  assert.deepEqual(point.blobs, ["tool_call", "opstruth_audit_repository", "success", "chatgpt", "0.4.1", "insufficient_evidence", "ci_observed", "deployment_not_probed", "evidence_signed"]);
  assert.deepEqual(point.doubles, [42, 200, 4, 2, 0, 3]);
});

test("analytics v2 derives only bounded non-identifying result dimensions", () => {
  const summary = summarizeToolResult({ structuredContent: {
    subject: { repositoryName: "private/customer" },
    summary: { verdict: "CONTRADICTED", counts: { unproven: 2 } },
    nodes: [{ type: "ci_run" }, { type: "runtime_observation" }],
    proof: { signerFingerprint: `sha256:${"a".repeat(64)}` },
  } });
  assert.deepEqual(summary, {
    verdict: "CONTRADICTED",
    counts: { evidence: 2, warnings: 0, failures: 0, notVerified: 2 },
    ciObserved: true,
    deploymentProbed: true,
    signedEvidence: true,
  });
  assert.equal(JSON.stringify(summary).includes("private/customer"), false);
});

test("feedback is reason-coded with no free text or subject identifier", async () => {
  assert.deepEqual(feedbackPoint({ reason: "useful", surface: "mcp" }), {
    indexes: ["feedback"], blobs: ["feedback", "useful", "mcp", "0.4.1"], doubles: [1],
  });
  assert.throws(() => feedbackPoint({ reason: "my repository is broken", surface: "mcp" }), /reason_invalid/);
  const writes = [];
  const pending = [];
  const recorded = recordFeedbackEvent(
    { OPSTRUTH_ANALYTICS: { writeDataPoint: (point) => writes.push(point) } },
    { waitUntil: (promise) => pending.push(promise) },
    { reason: "incorrect_binding", surface: "chatgpt" },
  );
  await Promise.all(pending);
  assert.equal(recorded, true);
  assert.equal(writes.length, 1);
});

test("analytics writes are best effort and use waitUntil", async () => {
  const writes = [];
  const pending = [];
  const env = { OPSTRUTH_ANALYTICS: { writeDataPoint(point) { writes.push(point); } } };
  const ctx = { waitUntil(promise) { pending.push(promise); } };
  recordToolEvent(env, ctx, new Request("https://example.test/mcp"), { tool: "opstruth_probe_deployment", outcome: "success", status: 200, latencyMs: 4 });
  await Promise.all(pending);
  assert.equal(writes.length, 1);
  assert.equal(writes[0].blobs[1], "opstruth_probe_deployment");
});

SHA-256: 7bdb4e82909c68b9f8795e949981a1e1cb1163e97fd13f6d3b77e28f5e36b807