import { describe, expect, it, vi } from "vitest"; import { createApplication, type ApplicationOutputPorts, } from "../../src/application/create-application.ts"; import { createTestApplication } from "../helpers/create-test-application.ts"; import { createProductFeaturesStub, createRuntimeCapabilitiesStub } from "../helpers/runtime-capabilities-stub.ts"; declare module "../../src/application/ports/in/application-api.ts" { interface ApplicationFeatureInputs { "test-feature": Readonly<{ run(): "ok"; }>; } } describe("application input/output boundary", () => { it("exposes intent-oriented input APIs without leaking output ports", async () => { const application = createTestApplication(); expect(Object.keys(application)).toEqual([ "session", "preferences", "diagnostics", "runtime", "recovery", "features", ]); expect(application).not.toHaveProperty("storage"); expect(application).not.toHaveProperty("telemetry"); expect(application).not.toHaveProperty("releaseInfo"); expect(application.features.has("not-installed")).toBe(false); expect(() => Reflect.apply(application.features.get, application.features, [ "not-installed", ]), ).toThrow("Application feature is not installed"); await expect(application.runtime.getReleaseSummary()).resolves.toEqual({ buildId: "test-build", releaseId: "test-release", configSchemaVersion: "1", apiContractVersion: "1", }); }); it("returns a typed input for an installed generic feature", () => { const featureInput = Object.freeze({ run: () => "ok" as const, }); const application = createTestApplication({ featureInputs: { "test-feature": featureInput }, }); expect(application.features.has("test-feature")).toBe(true); expect(application.features.get("test-feature")).toBe(featureInput); expect(application.features.get("test-feature").run()).toBe("ok"); }); it("uses fake output ports for preference, session, and safe diagnostics flows", async () => { const write = vi.fn(() => ({ ok: true as const })); const emit = vi.fn(); const record = vi.fn(); const subscribe = vi.fn(() => () => {}); const beginSignIn = vi.fn(async () => {}); const signOut = vi.fn(async () => {}); const recover = vi.fn(async () => "restored" as const); const ports = { session: { getState: () => "authenticated" as const, subscribe, beginSignIn, signOut, recover, }, preferences: { read: () => ({ ok: true as const, value: "dark" }), write, remove: () => ({ ok: true as const }), }, diagnostics: { record }, telemetry: { emit }, releaseInfo: { getCurrent: async () => ({ buildId: "build-a", releaseId: "release-a", configSchemaVersion: "1", apiContractVersion: "1", assetManifestHash: "hash-a", routeChunks: { "route-home": "assets/home.js" }, }), refresh: async () => ({ buildId: "build-a", releaseId: "release-a", configSchemaVersion: "1", apiContractVersion: "1", assetManifestHash: "hash-a", routeChunks: { "route-home": "assets/home.js" }, }), }, runtimeCapabilities: createRuntimeCapabilitiesStub(), productFeatures: createProductFeaturesStub(), navigation: { reload: () => {} }, } satisfies ApplicationOutputPorts; const application = createApplication(ports); expect(application.session.getSnapshot()).toBe("authenticated"); const listener = vi.fn(); expect(application.session.subscribe(listener)).toBeTypeOf("function"); expect(subscribe).toHaveBeenCalledWith(listener); await application.session.beginSignIn("/return"); expect(beginSignIn).toHaveBeenCalledWith("/return"); await application.session.signOut(); expect(signOut).toHaveBeenCalledOnce(); await expect(application.session.recover()).resolves.toBe("restored"); expect(application.preferences.getColorScheme()).toBe("dark"); expect(application.preferences.setColorScheme("light")).toEqual({ ok: true }); expect(write).toHaveBeenCalledWith("COLOR_SCHEME", "light"); application.diagnostics.reportRenderFailure({ routeId: "APP_HOME", buildId: "build-a", boundaryName: "route", }); expect(record).toHaveBeenCalledWith({ level: "error", eventId: "ui.render.failed", context: { route_id: "APP_HOME", build_id: "build-a", component_boundary: "route", }, }); expect(emit).toHaveBeenCalledWith("ui.render.failed", { route_id: "APP_HOME", build_id: "build-a", component_boundary: "route", }); application.diagnostics.reportRouteChanged({ routeId: "APP_HOME", buildId: "build-a", }); expect(record).toHaveBeenCalledWith({ level: "info", eventId: "route.changed", context: { route_id: "APP_HOME", build_id: "build-a" }, }); }); it("does not let a failing diagnostics output escape into presentation", () => { const application = createTestApplication({ diagnostics: { record() { throw new Error("sink details"); }, }, telemetry: { emit() { throw new Error("telemetry details"); }, }, }); expect(() => application.diagnostics.reportRenderFailure({ routeId: "APP_HOME", buildId: "build-a", boundaryName: "feature", }), ).not.toThrow(); }); });