Files
pikasTech-unidesk/scripts/src/platform-infra-gitea-disclosure.test.ts
T

194 lines
9.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { buildMirrorWebhookStatusDisclosure, rawMirrorWebhookStatus } from "./platform-infra-gitea-disclosure";
import { renderMirrorWebhookStatus } from "./platform-infra-gitea-render";
describe("Gitea webhook status progressive disclosure", () => {
test("keeps --full as a bounded domain aggregate with repository drill-down commands", () => {
const view = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: null, deliveryId: null });
const serialized = JSON.stringify({ ok: true, command: "status --full", data: view }, null, 2);
expect(view.ok).toBe(true);
expect(view.view).toBe("domain-aggregate");
expect((view.repositories as unknown[]).length).toBe(2);
expect((view.deliveries as unknown[]).length).toBe(2);
expect((view.bridge as { durableInbox: { retainedDeliveryCount: number } }).durableInbox.retainedDeliveryCount).toBe(82);
expect(Object.prototype.hasOwnProperty.call(view, "raw")).toBe(false);
expect(serialized).not.toContain('"payloadSha"');
expect(serialized).not.toContain("outputTruncated");
expect(Buffer.byteLength(serialized, "utf8")).toBeLessThan(10_240);
expect((view.next as { repositories: Array<{ command: string }> }).repositories[0]?.command).toContain("--repo repo-a");
});
test("repository and deliveryId drill-down expose one inbox record, retry, logs and first error", () => {
const repository = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: "repo-a", deliveryId: null });
expect(repository.view).toBe("repository-drill-down");
expect((repository.deliveries as unknown[]).length).toBe(1);
expect((repository.selection as { effectiveDeliveryId: string }).effectiveDeliveryId).toBe("delivery-current-a");
expect((repository.retry as { totalAttempts: number }).totalAttempts).toBe(1);
const recovery = (repository.bridge as { durableInbox: { failedDeliveryRecovery: { entries: Array<Record<string, unknown>> } } }).durableInbox.failedDeliveryRecovery;
expect(recovery.entries).toHaveLength(1);
expect(recovery.entries[0]).toMatchObject({ deliveryId: "delivery-current-a", state: "attempted", attempts: 1, cooldownMs: 300_000, nextAt: "2026-07-11T00:05:00Z" });
expect(JSON.stringify(recovery)).not.toContain("https://");
const delivery = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: null, deliveryId: "delivery-5" });
expect(delivery.ok).toBe(true);
expect(delivery.view).toBe("delivery-drill-down");
expect((delivery.selection as { selectedRepoKey: string }).selectedRepoKey).toBe("repo-a");
expect((delivery.deliveries as Array<{ deliveryId: string }>)[0]?.deliveryId).toBe("delivery-5");
expect((delivery.retry as { totalAttempts: number; lastError: string }).totalAttempts).toBe(3);
expect((delivery.retry as { lastError: string }).lastError).toContain("authentication-failed");
expect((delivery.logs as { matched: number; events: unknown[] }).matched).toBe(1);
expect((delivery.diagnostics as { firstError: { domain: string } }).firstError.domain).toBe("durable-inbox-record");
});
test("reports missing retained delivery without hiding the operational payload", () => {
const view = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: "repo-a", deliveryId: "not-retained" });
expect(view.ok).toBe(false);
expect((view.selection as { error: string }).error).toBe("delivery-not-observed-in-retained-evidence");
const raw = rawMirrorWebhookStatus(fixture());
expect(raw.view).toBe("raw");
expect(raw.raw).toBeDefined();
expect((raw.safety as { explicitRawRequired: boolean; valuesPrinted: boolean }).explicitRawRequired).toBe(true);
expect((raw.safety as { valuesPrinted: boolean }).valuesPrinted).toBe(false);
});
test("keeps selected delivery GUID, status and accepted in one observation", () => {
const input = fixture();
const repo = (input.repositories as Array<Record<string, unknown>>)[0]!;
repo.latestPushDelivery = { deliveryId: "newer-unrelated", statusCode: 202, status: "OK" };
repo.selectedPushDelivery = { deliveryId: "selected-failed", hookId: 22, statusCode: 502, status: "misconfigured", deliveredAt: "2026-07-12T05:54:18Z" };
repo.deliveryId = "selected-failed";
repo.deliveryAccepted = false;
const disclosure = buildMirrorWebhookStatusDisclosure(input, { repoKey: null, deliveryId: null });
const summary = (disclosure.repositories as Array<{ selectedDelivery: Record<string, unknown> }>)[0]!.selectedDelivery;
expect(summary).toMatchObject({ deliveryId: "selected-failed", hookId: 22, statusCode: 502, status: "misconfigured", accepted: false });
const rendered = renderMirrorWebhookStatus(input, disclosure).renderedText;
expect(rendered).toContain("selected-failed:502:misconfigured");
expect(rendered).not.toContain("selected-failed:202:OK");
});
});
function fixture(): Record<string, unknown> {
const retained = Array.from({ length: 80 }, (_, index) => deliveryRecord(`delivery-${index}`, index === 5 || index % 2 === 0 ? "repo-a" : "repo-b", {
totalAttempts: index === 5 ? 3 : 1,
lastError: index === 5 ? { type: "authentication-failed", message: "authentication-failed" } : null,
}));
const currentA = deliveryRecord("delivery-current-a", "repo-a");
const currentB = deliveryRecord("delivery-current-b", "repo-b");
const bridge = {
deployment: "gitea-github-sync",
ready: true,
readyReplicas: "1/1",
serviceExists: true,
durableInbox: {
ready: true,
storageReady: true,
capacityAvailable: true,
counts: { committed: 81, retryWait: 1 },
deliveries: [...retained, currentA, currentB],
totalBytes: 2048,
maxBytes: 1_048_576,
errorType: null,
journal: { version: 1, kind: "GiteaGithubSyncDurableInbox", createdAt: "2026-07-11T00:00:00Z" },
failedDeliveryRecovery: {
enabled: true,
ready: true,
state: "ready",
counts: { pending: 0, attempted: 2, "delivery-succeeded-awaiting-source": 0, "source-committed": 0, "terminal-exhausted": 0 },
entries: [
{ repository: "pikasTech/repo-a", hookId: 1, deliveryId: "delivery-current-a", state: "attempted", attempts: 1, cooldownMs: 300_000, nextAt: "2026-07-11T00:05:00Z", updatedAt: "2026-07-11T00:00:00Z", lastStatusCode: 502 },
{ repository: "pikasTech/repo-b", hookId: 2, deliveryId: "delivery-current-b", state: "attempted", attempts: 2, cooldownMs: 300_000, nextAt: "2026-07-11T00:05:00Z", updatedAt: "2026-07-11T00:00:00Z", lastStatusCode: 504 },
],
},
},
};
return {
ok: true,
action: "platform-infra-gitea-mirror-webhook-status",
mutation: false,
target: { id: "NC01", route: "NC01:k3s", namespace: "devops-infra" },
webhook: {
enabled: true,
direction: "github-to-gitea",
publicUrl: "https://gitea.example/_unidesk/github-to-gitea/nc01",
events: ["push"],
responseBudgetMs: 8_000,
ingressAttemptBudgetMs: 2_000,
ingressResponseHeaderTimeoutMs: 3_000,
ingressRetry: { enabled: true, maxAttempts: 3, initialDelayMs: 1_000, maxDelayMs: 30_000 },
hookReconcile: { enabled: true, ownerTargetId: "NC01", runningOnTarget: true, intervalMs: 60_000, requestTimeoutMs: 15_000, desiredUrlSha256: "sha256:desired", topologySha256: "sha256:topology" },
bridge: { deploymentName: "gitea-github-sync", serviceName: "gitea-github-sync", retry: { maxAttempts: 3, initialDelayMs: 1_000, maxDelayMs: 30_000 } },
},
bridge,
repositories: [repository("repo-a", currentA), repository("repo-b", currentB)],
bridgeLogs: {
exitCode: 0,
events: [
{ event: "github-to-gitea-sync", repo: "repo-a", deliveryId: "delivery-current-a", ok: true, terminal: true, syncAttempt: 1, disposition: "committed", elapsedMs: 90 },
{ event: "github-to-gitea-sync", repo: "repo-a", deliveryId: "delivery-5", ok: false, terminal: true, syncAttempt: 3, errorType: "authentication-failed", error: "authentication-failed", elapsedMs: 120 },
],
errorTail: "",
},
mirrorStatus: { exitCode: 0, errorTail: "" },
remote: { ok: true, bridge, repositories: [repository("repo-a", currentA), repository("repo-b", currentB)] },
};
}
function repository(key: string, delivery: Record<string, unknown>): Record<string, unknown> {
return {
key,
repository: `pikasTech/${key}`,
branch: "master",
hookReady: true,
githubHead: "a".repeat(40),
branchCommit: "a".repeat(40),
snapshotCommit: "a".repeat(40),
authorityMatches: true,
bridgeEventStale: false,
staleReason: null,
deliveryId: delivery.deliveryId,
deliveryAccepted: true,
selectedPushDelivery: { deliveryId: delivery.deliveryId, hookId: 1, statusCode: 202, status: "OK", deliveredAt: "2026-07-11T00:00:00Z" },
latestPushDelivery: { deliveryId: delivery.deliveryId, hookId: 1, statusCode: 202, status: "OK", deliveredAt: "2026-07-11T00:00:00Z" },
hookTopology: {
ready: true,
desiredUrlSha256: "sha256:desired",
desiredTopologyUrlSha256: ["sha256:desired"],
observedManagedUrlSha256: ["sha256:desired"],
driftTypes: [],
},
durableInboxState: "committed",
durableInboxCommitted: true,
durableInboxRecord: delivery,
error: null,
};
}
function deliveryRecord(deliveryId: string, repo: string, overrides: Record<string, unknown> = {}): Record<string, unknown> {
return {
deliveryId,
repo,
repository: `pikasTech/${repo}`,
ref: "refs/heads/master",
requestedCommit: "a".repeat(40),
payloadSha: "b".repeat(64),
state: "committed",
acceptedSequence: 1,
totalAttempts: 1,
cycleAttempt: 1,
nextAttemptAt: null,
updatedAt: "2026-07-11T00:00:00Z",
result: {
sourceCommit: "a".repeat(40),
authorityCommit: "a".repeat(40),
snapshotRef: `refs/unidesk/snapshots/${repo}/${"a".repeat(40)}`,
disposition: "atomic-source-authority-committed",
},
lastError: null,
...overrides,
};
}