paperclip/server/src/__tests__/heartbeat-run-summary.test.ts

58 lines
1.9 KiB
TypeScript
Raw Normal View History

import { describe, expect, it } from "vitest";
import {
summarizeHeartbeatRunResultJson,
buildHeartbeatRunIssueComment,
} from "../services/heartbeat-run-summary.js";
describe("summarizeHeartbeatRunResultJson", () => {
it("truncates text fields and preserves cost aliases", () => {
const summary = summarizeHeartbeatRunResultJson({
summary: "a".repeat(600),
result: "ok",
message: "done",
error: "failed",
total_cost_usd: 1.23,
cost_usd: 0.45,
costUsd: 0.67,
nested: { ignored: true },
});
expect(summary).toEqual({
summary: "a".repeat(500),
result: "ok",
message: "done",
error: "failed",
total_cost_usd: 1.23,
cost_usd: 0.45,
costUsd: 0.67,
});
});
it("returns null for non-object and irrelevant payloads", () => {
expect(summarizeHeartbeatRunResultJson(null)).toBeNull();
expect(summarizeHeartbeatRunResultJson(["nope"] as unknown as Record<string, unknown>)).toBeNull();
expect(summarizeHeartbeatRunResultJson({ nested: { only: "ignored" } })).toBeNull();
});
});
describe("buildHeartbeatRunIssueComment", () => {
it("uses the final summary text for issue comments on successful runs", () => {
const comment = buildHeartbeatRunIssueComment({
summary: "## Summary\n\n- fixed deploy config\n- posted issue update",
});
expect(comment).toContain("## Summary");
expect(comment).toContain("- fixed deploy config");
expect(comment).not.toContain("Run summary");
});
it("falls back to result or message when summary is missing", () => {
expect(buildHeartbeatRunIssueComment({ result: "done" })).toBe("done");
expect(buildHeartbeatRunIssueComment({ message: "completed" })).toBe("completed");
});
it("returns null when there is no usable final text", () => {
expect(buildHeartbeatRunIssueComment({ costUsd: 1.2 })).toBeNull();
});
});