mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-21 08:22:20 +02:00
Apply the reviewed change for Keep proven external connection failures out of Sentry. Validation: local typecheck/build and focused regression tests, passing exact-head CI, Greptile 5/5, and independent source review. The PR records full-suite evidence and any local environment limitations. Co-Authored-By: Paperclip <noreply@paperclip.ing>
106 lines
5.0 KiB
TypeScript
106 lines
5.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { readConnectionFailure } from "./connection-failure.js";
|
|
|
|
describe("readConnectionFailure", () => {
|
|
const git = { schemaVersion: 1, provider: "git", operation: "clone", reason: "authentication_failed" };
|
|
const gateway = { schemaVersion: 1, provider: "hermes_gateway", operation: "create_run", reason: "connection_refused" };
|
|
const mcp = { schemaVersion: 1, provider: "mcp_http", operation: "discover_tools", reason: "connection_refused" };
|
|
|
|
it.each([
|
|
"authentication_failed", "repository_unavailable", "invalid_remote", "dns_failure", "connection_refused",
|
|
"network_unreachable", "connection_reset", "connection_timeout", "tls_failure", "rate_limited", "remote_unavailable",
|
|
])("accepts the Git clone reason %s", (reason) => {
|
|
const input = { ...git, reason };
|
|
expect(readConnectionFailure(input)).toEqual(input);
|
|
});
|
|
|
|
it.each(["endpoint_missing", "endpoint_invalid", "insecure_transport", "credentials_missing"])(
|
|
"accepts the gateway configuration reason %s", (reason) => {
|
|
const input = { ...gateway, operation: "configuration", reason };
|
|
expect(readConnectionFailure(input)).toEqual(input);
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
"authentication_failed", "endpoint_not_found", "rate_limited", "remote_unavailable", "connection_refused",
|
|
"dns_failure", "network_unreachable", "connection_reset", "connection_timeout", "tls_failure",
|
|
])("accepts the gateway request reason %s", (reason) => {
|
|
const input = { ...gateway, reason };
|
|
expect(readConnectionFailure(input)).toEqual(input);
|
|
});
|
|
|
|
it.each([
|
|
"authentication_failed", "endpoint_not_found", "rate_limited", "remote_unavailable", "connection_refused",
|
|
"dns_failure", "network_unreachable", "connection_reset", "connection_timeout", "tls_failure",
|
|
])("accepts the MCP tool discovery request reason %s", (reason) => {
|
|
const input = { ...mcp, reason };
|
|
expect(readConnectionFailure(input)).toEqual(input);
|
|
});
|
|
|
|
it.each([
|
|
{ ...git, operation: "fetch" },
|
|
{ ...git, operation: "create_run" },
|
|
{ ...git, reason: "endpoint_not_found" },
|
|
{ ...gateway, operation: "clone" },
|
|
{ ...gateway, operation: "poll_status" },
|
|
{ ...gateway, operation: "stop_run" },
|
|
{ ...gateway, operation: "configuration" },
|
|
{ ...gateway, reason: "credentials_missing" },
|
|
{ ...gateway, reason: "repository_unavailable" },
|
|
{ ...gateway, reason: "timeout" },
|
|
{ ...gateway, reason: "unknown" },
|
|
{ ...gateway, provider: "other_gateway" },
|
|
{ ...gateway, provider: "hermes_local" },
|
|
{ ...mcp, operation: "create_run" },
|
|
{ ...mcp, operation: "clone" },
|
|
{ ...mcp, operation: "configuration" },
|
|
{ ...mcp, operation: "call_tool" },
|
|
{ ...mcp, reason: "credentials_missing" },
|
|
{ ...mcp, reason: "repository_unavailable" },
|
|
{ ...gateway, operation: "discover_tools" },
|
|
{ ...git, operation: "discover_tools" },
|
|
])("rejects an unsupported provider/operation/reason combination: %j", (input) => {
|
|
expect(readConnectionFailure(input)).toBeNull();
|
|
});
|
|
|
|
it.each([
|
|
undefined, null, false, 1, "connection_refused", [], [gateway], {},
|
|
{ ...gateway, schemaVersion: 0 }, { ...gateway, schemaVersion: 2 }, { ...gateway, schemaVersion: "1" },
|
|
{ ...gateway, schemaVersion: null }, { ...gateway, schemaVersion: undefined },
|
|
{ ...gateway, provider: null }, { ...gateway, provider: ["hermes_gateway"] },
|
|
{ ...gateway, operation: null }, { ...gateway, operation: 1 },
|
|
{ ...gateway, reason: null }, { ...gateway, reason: 1 }, { ...gateway, reason: ["connection_refused"] },
|
|
{ ...gateway, reason: { code: "ECONNREFUSED" } },
|
|
{ provider: "hermes_gateway", operation: "create_run", reason: "connection_refused" },
|
|
{ ...gateway, reason: "connection_refused " }, { ...gateway, reason: "CONNECTION_REFUSED" },
|
|
])("rejects unknown versions or malformed values: %j", (input) => {
|
|
expect(readConnectionFailure(input)).toBeNull();
|
|
});
|
|
|
|
it.each([
|
|
{ url: "https://private.example.test" },
|
|
{ account: "private-account" },
|
|
{ token: "synthetic-secret" },
|
|
{ remoteRunAccepted: false },
|
|
{ providerWorkStarted: false },
|
|
{ details: { message: "private diagnostics" } },
|
|
{ extra: undefined },
|
|
])("rejects extra metadata instead of broadening the bounded marker: %j", (extra) => {
|
|
expect(readConnectionFailure({ ...gateway, ...extra })).toBeNull();
|
|
});
|
|
|
|
it("rejects unknown own fields even when a prototype supplies a valid descriptor", () => {
|
|
const input = Object.assign(Object.create(gateway), { a: 1, b: 2, c: 3, d: 4 });
|
|
expect(readConnectionFailure(input)).toBeNull();
|
|
});
|
|
|
|
it("returns an independent bounded value without mutating its producer's input", () => {
|
|
const input = Object.freeze({ ...gateway });
|
|
const output = readConnectionFailure(input);
|
|
expect(output).toEqual(gateway);
|
|
expect(output).not.toBe(input);
|
|
expect(input).toEqual(gateway);
|
|
expect(Object.keys(output ?? {}).sort()).toEqual(["operation", "provider", "reason", "schemaVersion"]);
|
|
});
|
|
});
|