Some checks failed
CI / Frontend Lint (pull_request) Failing after 7s
CI / Frontend Type Check (pull_request) Failing after 6s
CI / Frontend Build (pull_request) Failing after 8s
CI / Frontend E2E Tests (pull_request) Failing after 9s
CI / Orchestrator Build (pull_request) Failing after 7s
CI / Orchestrator Unit Tests (pull_request) Failing after 6s
CI / Orchestrator E2E (Testcontainers) (pull_request) Has been skipped
CI / Contracts Compile (pull_request) Failing after 7s
CI / Contracts Test (pull_request) Failing after 6s
Code Quality / SonarQube Analysis (pull_request) Failing after 20s
Code Quality / Code Quality Checks (pull_request) Failing after 6s
Security Scan / Dependency Vulnerability Scan (pull_request) Failing after 4s
Security Scan / OWASP ZAP Scan (pull_request) Failing after 4s
Mirrors the external-dependency blocker gate added to the proxmox
repo (scripts/verify/check-external-dependencies.sh + docs/03-
deployment/EXTERNAL_DEPENDENCY_BLOCKERS.md) so orchestrator startup
logs and provider-switch mock-mode logs surface the same EXT-* IDs
the deployment pipeline already tracks.
Central registry:
- src/config/externalBlockers.ts — typed EXT_BLOCKER_IDS union
(EXT-DBIS-CORE, EXT-CC-PAYMENT-ADAPTERS, EXT-CC-AUDIT-LEDGER,
EXT-CC-SHARED-EVENTS, EXT-CC-SHARED-SCHEMAS, EXT-FIN-GATEWAY,
EXT-CHAIN138-CI-RPC), BLOCKER_DETAILS map with per-id resolving
env var, evaluateBlockers(env) / activeBlockers() / and
logBlockerStatusAtBoot(logger) for a single-line structured
startup summary.
Wired sites:
- src/index.ts — logs the full blocker summary after validateEnv().
- services/dbisCore/client.ts — mock-mode log now carries
blockerId: EXT-DBIS-CORE.
- services/finLink/client.ts — getFinLinkClient() now logs live vs.
in-process sandbox decisions; sandbox path carries
blockerId: EXT-FIN-GATEWAY.
- services/bank.ts — migrated from console.log to pino; mock-mode
(no DBIS_CORE_URL) carries blockerId: EXT-DBIS-CORE because
dbis_core is the bank's real back-end.
- services/completeCredential/identityClient.ts — mock log tagged
'upstream cc-identity-core ships code but not yet deployed' to
distinguish 'env not set' from the cc-* scaffold blockers.
Unit tests: tests/config/externalBlockers.test.ts — 11 tests
covering registry shape, evaluation across env permutations (empty
env, each resolving env set, scaffold blockers remain active,
empty-string treated as unset), and log emission.
Full unit suite: 13 suites / 167 tests passing. tsc --noEmit clean.
No UI changes.
120 lines
4.0 KiB
TypeScript
120 lines
4.0 KiB
TypeScript
/**
|
|
* Unit tests for the EXT-* external-dependency blocker registry.
|
|
* Headless — no network, no UI.
|
|
*/
|
|
|
|
import {
|
|
EXT_BLOCKER_IDS,
|
|
BLOCKER_DETAILS,
|
|
evaluateBlockers,
|
|
activeBlockers,
|
|
logBlockerStatusAtBoot,
|
|
} from "../../src/config/externalBlockers";
|
|
|
|
describe("externalBlockers registry", () => {
|
|
it("exposes exactly the 7 blocker IDs the proxmox checker tracks", () => {
|
|
expect(EXT_BLOCKER_IDS).toEqual([
|
|
"EXT-DBIS-CORE",
|
|
"EXT-CC-PAYMENT-ADAPTERS",
|
|
"EXT-CC-AUDIT-LEDGER",
|
|
"EXT-CC-SHARED-EVENTS",
|
|
"EXT-CC-SHARED-SCHEMAS",
|
|
"EXT-FIN-GATEWAY",
|
|
"EXT-CHAIN138-CI-RPC",
|
|
]);
|
|
});
|
|
|
|
it("has a detail record for every id", () => {
|
|
for (const id of EXT_BLOCKER_IDS) {
|
|
expect(BLOCKER_DETAILS[id]).toBeDefined();
|
|
expect(BLOCKER_DETAILS[id].id).toBe(id);
|
|
expect(BLOCKER_DETAILS[id].title.length).toBeGreaterThan(0);
|
|
expect(BLOCKER_DETAILS[id].description.length).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("evaluateBlockers()", () => {
|
|
it("marks everything active on an empty env", () => {
|
|
const records = evaluateBlockers({});
|
|
expect(records).toHaveLength(EXT_BLOCKER_IDS.length);
|
|
expect(records.every((r) => r.status === "active")).toBe(true);
|
|
});
|
|
|
|
it("resolves EXT-DBIS-CORE when DBIS_CORE_URL is set", () => {
|
|
const records = evaluateBlockers({ DBIS_CORE_URL: "http://x.test" });
|
|
const rec = records.find((r) => r.id === "EXT-DBIS-CORE");
|
|
expect(rec?.status).toBe("resolved");
|
|
expect(rec?.resolvedVia).toBe("DBIS_CORE_URL");
|
|
});
|
|
|
|
it("resolves EXT-FIN-GATEWAY when FIN_SANDBOX_URL is set", () => {
|
|
const records = evaluateBlockers({ FIN_SANDBOX_URL: "http://fin.test" });
|
|
expect(records.find((r) => r.id === "EXT-FIN-GATEWAY")?.status).toBe("resolved");
|
|
});
|
|
|
|
it("resolves EXT-CHAIN138-CI-RPC when CHAIN_138_RPC_URL is set", () => {
|
|
const records = evaluateBlockers({
|
|
CHAIN_138_RPC_URL: "https://rpc.public-0138.defi-oracle.io",
|
|
});
|
|
expect(records.find((r) => r.id === "EXT-CHAIN138-CI-RPC")?.status).toBe("resolved");
|
|
});
|
|
|
|
it("leaves cc-* scaffold blockers active regardless of env", () => {
|
|
const records = evaluateBlockers({
|
|
DBIS_CORE_URL: "http://x",
|
|
FIN_SANDBOX_URL: "http://y",
|
|
CHAIN_138_RPC_URL: "http://z",
|
|
});
|
|
const scaffoldIds = [
|
|
"EXT-CC-PAYMENT-ADAPTERS",
|
|
"EXT-CC-AUDIT-LEDGER",
|
|
"EXT-CC-SHARED-EVENTS",
|
|
"EXT-CC-SHARED-SCHEMAS",
|
|
];
|
|
for (const id of scaffoldIds) {
|
|
expect(records.find((r) => r.id === id)?.status).toBe("active");
|
|
}
|
|
});
|
|
|
|
it("treats empty-string env var as unset (not resolved)", () => {
|
|
const records = evaluateBlockers({ DBIS_CORE_URL: "" });
|
|
expect(records.find((r) => r.id === "EXT-DBIS-CORE")?.status).toBe("active");
|
|
});
|
|
});
|
|
|
|
describe("activeBlockers()", () => {
|
|
it("returns 7 when env is empty", () => {
|
|
expect(activeBlockers({})).toHaveLength(7);
|
|
});
|
|
|
|
it("returns 6 when Chain-138 RPC is resolved", () => {
|
|
const ids = activeBlockers({
|
|
CHAIN_138_RPC_URL: "https://rpc.public-0138.defi-oracle.io",
|
|
});
|
|
expect(ids).not.toContain("EXT-CHAIN138-CI-RPC");
|
|
expect(ids).toHaveLength(6);
|
|
});
|
|
});
|
|
|
|
describe("logBlockerStatusAtBoot()", () => {
|
|
it("emits a single summary with active + resolved counts", () => {
|
|
const calls: Array<{ obj: Record<string, unknown>; msg: string }> = [];
|
|
const fakeLogger = {
|
|
info: (obj: Record<string, unknown>, msg: string) => calls.push({ obj, msg }),
|
|
};
|
|
const prev = process.env.CHAIN_138_RPC_URL;
|
|
process.env.CHAIN_138_RPC_URL = "https://rpc.public-0138.defi-oracle.io";
|
|
try {
|
|
logBlockerStatusAtBoot(fakeLogger);
|
|
} finally {
|
|
if (prev === undefined) delete process.env.CHAIN_138_RPC_URL;
|
|
else process.env.CHAIN_138_RPC_URL = prev;
|
|
}
|
|
expect(calls).toHaveLength(1);
|
|
expect(calls[0].msg).toMatch(/active,.*resolved/);
|
|
expect((calls[0].obj.activeCount as number) + (calls[0].obj.resolvedCount as number)).toBe(7);
|
|
expect(calls[0].obj.resolvedCount).toBeGreaterThanOrEqual(1);
|
|
});
|
|
});
|