Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

ai-incident.test.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

ai-incident.test.tsBlame82 lines · 1 contributor
1e162a8Claude1/**
2 * Block D4 — AI Incident Responder tests.
3 *
4 * These tests exercise the pure helper (no I/O) and confirm that
5 * `onDeployFailure` degrades gracefully when the repository does not exist
6 * (or the DB is unavailable) without ever throwing.
7 */
8
9import { describe, it, expect } from "bun:test";
10import {
11 onDeployFailure,
12 summariseCommitsForIncident,
13} from "../lib/ai-incident";
14
15describe("lib/ai-incident — module shape", () => {
16 it("imports cleanly and exports the expected functions", () => {
17 expect(typeof summariseCommitsForIncident).toBe("function");
18 expect(typeof onDeployFailure).toBe("function");
19 });
20});
21
22describe("lib/ai-incident — summariseCommitsForIncident", () => {
23 it("formats each commit as `- <sha7> <subject> — <author>`", () => {
24 const out = summariseCommitsForIncident([
25 { sha: "abcdef1234567890", message: "fix: handle null", author: "alice" },
26 { sha: "fedcba0987654321", message: "feat: new thing", author: "bob" },
27 ]);
28 expect(out).toBe(
29 "- abcdef1 fix: handle null — alice\n" +
30 "- fedcba0 feat: new thing — bob"
31 );
32 });
33
34 it("keeps only the first line of multi-line commit messages", () => {
35 const out = summariseCommitsForIncident([
36 {
37 sha: "1111111aaaaaaa",
38 message: "first line\n\nbody goes here",
39 author: "carol",
40 },
41 ]);
42 expect(out).toBe("- 1111111 first line — carol");
43 });
44
45 it("handles an empty list as an empty string", () => {
46 expect(summariseCommitsForIncident([])).toBe("");
47 });
48
49 it("tolerates missing fields without throwing", () => {
50 const out = summariseCommitsForIncident([
51 { sha: "", message: "", author: "" },
52 ]);
53 // Expect a renderable line even when fields are blank.
54 expect(out).toContain(" — ");
55 });
56});
57
58describe("lib/ai-incident — onDeployFailure", () => {
59 it("returns { issueNumber: null, reason: <non-empty> } for an unknown repositoryId without throwing", async () => {
60 const result = await onDeployFailure({
61 repositoryId: "00000000-0000-0000-0000-000000000000",
62 deploymentId: "00000000-0000-0000-0000-000000000000",
63 ref: "refs/heads/main",
64 commitSha: "0".repeat(40),
9ecf5a4Claude65 target: "vapron",
1e162a8Claude66 errorMessage: "HTTP 500",
67 });
68 expect(result).toBeDefined();
69 expect(result.issueNumber).toBeNull();
70 expect(typeof result.reason).toBe("string");
71 expect(result.reason.length).toBeGreaterThan(0);
72 });
73
74 it("never throws even when all optional fields are missing", async () => {
75 await expect(
76 onDeployFailure({
77 repositoryId: "00000000-0000-0000-0000-000000000000",
78 deploymentId: "00000000-0000-0000-0000-000000000000",
79 })
80 ).resolves.toBeDefined();
81 });
82});