384 lines
15 KiB
TypeScript
384 lines
15 KiB
TypeScript
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
|
// Simulated native transport and actual template admission boundaries; no live readiness is asserted.
|
|
|
|
import * as nativeCore from "@conusai-kit/core" // kit:guides // kit:support
|
|
import { Container, type ServiceAdmissionContext } from "@conusai-kit/core"
|
|
import * as kitData from "@conusai-kit/data" // kit:guides // kit:support
|
|
import * as kitGuides from "@conusai-kit/guides" // kit:guides // kit:support
|
|
import * as kitSupport from "@conusai-kit/support" // kit:guides // kit:support
|
|
import * as kitTenancy from "@conusai-kit/tenancy" // kit:guides // kit:support
|
|
import { describe, expect, it, vi } from "vitest"
|
|
import { nativeHelpSelectors as webSelectors } from "../apps/web/src/server/ports.js" // kit:guides // kit:support
|
|
import { nativeHelpSelectors as workerSelectors } from "../apps/worker/src/ports.js" // kit:guides // kit:support
|
|
import { businessServiceComposition } from "../config/src/business-services.js"
|
|
import { crmModule } from "../modules/crm/module.js"
|
|
|
|
const env = {
|
|
deployment: {
|
|
CONUSAI_API_URL: "https://platform.example.test/api",
|
|
CONUSAI_API_TOKEN: "synthetic-token",
|
|
CONUSAI_PROJECT_ID: "9",
|
|
},
|
|
}
|
|
const context = {
|
|
container: new Container(),
|
|
module: "crm",
|
|
procedure: "crm.party.list",
|
|
kind: "read",
|
|
scope: {
|
|
level: "org",
|
|
orgId: "01900000-0000-7000-8000-000000000001",
|
|
actor: { userId: "01900000-0000-7000-8000-000000000002" },
|
|
},
|
|
} satisfies ServiceAdmissionContext
|
|
describe("optional business request composition", () => {
|
|
it("requires no additional deployment metadata when business modules are absent", () => {
|
|
expect(businessServiceComposition(env, [], "postgres")).toEqual({})
|
|
})
|
|
it("does not send native platform requirements to the business gateway", async () => {
|
|
const native = {
|
|
...crmModule,
|
|
serviceRequirements: crmModule.serviceRequirements.map((requirement) => ({
|
|
...requirement,
|
|
transport: "platform" as const,
|
|
})),
|
|
}
|
|
expect(businessServiceComposition(env, [native], "postgres").serviceReadiness).toBeDefined()
|
|
const hooks = businessServiceComposition(env, [crmModule], "postgres")
|
|
expect(native.serviceRequirements).toHaveLength(1)
|
|
for (const requirement of native.serviceRequirements)
|
|
await expect(hooks.serviceReadiness?.observe(requirement, context)).rejects.toMatchObject({
|
|
code: "service_observation_missing",
|
|
})
|
|
})
|
|
it("routes native observations through the exact environment and independently expected Cloud identity", async () => {
|
|
const descriptor = `sha256:${"a".repeat(64)}`
|
|
const source = "b".repeat(40)
|
|
const complete = {
|
|
deployment: {
|
|
...env.deployment,
|
|
CONUSAI_ORG_ID: "1",
|
|
CONUSAI_ENVIRONMENT_ID: "3",
|
|
CONUSAI_ORG_SLUG: "org",
|
|
CONUSAI_WORKSPACE_SLUG: "workspace",
|
|
CONUSAI_PROJECT_SLUG: "project",
|
|
CONUSAI_PLATFORM_RELEASE_DESCRIPTOR: descriptor,
|
|
CONUSAI_PLATFORM_SOURCE_COMMIT: source,
|
|
},
|
|
}
|
|
const baseRequirement = crmModule.serviceRequirements[0]
|
|
if (!baseRequirement) throw new Error("the CRM fixture must declare a service requirement")
|
|
const requirement = {
|
|
...baseRequirement,
|
|
transport: "platform" as const,
|
|
service: "ocr",
|
|
apiRange: "=1.0.0-preview.20261103",
|
|
partitionRequired: false,
|
|
operations: { "crm.party.list": ["ocr:use"] },
|
|
}
|
|
const module = { ...crmModule, serviceRequirements: [requirement] }
|
|
const fetch = vi.spyOn(globalThis, "fetch").mockResolvedValue(
|
|
Response.json({
|
|
component: {
|
|
id: "ocr",
|
|
observed_at: new Date().toISOString(),
|
|
facts: {
|
|
installed: "true",
|
|
enabled: "true",
|
|
entitled: "true",
|
|
configured: "true",
|
|
ready: "true",
|
|
},
|
|
},
|
|
authorized: "true",
|
|
environment_bound: "true",
|
|
compatible: "true",
|
|
dependencies_ready: "true",
|
|
policy_epoch: 2,
|
|
descriptor_digest: descriptor,
|
|
source_commit: source,
|
|
organization_id: 1,
|
|
project_id: 9,
|
|
environment_id: 3,
|
|
authorization_checked_at: new Date().toISOString(),
|
|
}),
|
|
)
|
|
try {
|
|
const hooks = businessServiceComposition(complete, [module], "postgres")
|
|
const projectContext = {
|
|
...context,
|
|
scope: {
|
|
level: "project" as const,
|
|
orgId: "01900000-0000-7000-8000-000000000001",
|
|
workspaceId: "local-workspace",
|
|
projectId: "local-project",
|
|
actor: { userId: "01900000-0000-7000-8000-000000000002" },
|
|
},
|
|
}
|
|
await hooks.prepareServices?.(new Container(), projectContext, [requirement])
|
|
expect(fetch).not.toHaveBeenCalled()
|
|
const observation = await hooks.serviceReadiness?.observe(requirement, projectContext)
|
|
expect(observation?.nativeAuthority?.expectedDescriptorDigest).toBe(descriptor)
|
|
expect(new URL(String(fetch.mock.calls[0]?.[0])).pathname).toBe(
|
|
"/api/v1/orgs/org/workspaces/workspace/projects/project/environments/3/platform-services/ocr/readiness",
|
|
)
|
|
expect(fetch).toHaveBeenCalledTimes(1)
|
|
} finally {
|
|
fetch.mockRestore()
|
|
}
|
|
})
|
|
it("constructs no provider or network work and leaves unrelated procedures usable", async () => {
|
|
const fetch = vi.spyOn(globalThis, "fetch")
|
|
try {
|
|
const hooks = businessServiceComposition(env, [crmModule], "postgres")
|
|
await hooks.prepareServices?.(
|
|
new Container(),
|
|
{ ...context, module: "tenancy", procedure: "tenancy.org.list" },
|
|
[],
|
|
)
|
|
expect(fetch).not.toHaveBeenCalled()
|
|
await expect(
|
|
hooks.prepareServices?.(new Container(), context, crmModule.serviceRequirements ?? []),
|
|
).rejects.toMatchObject({ code: "service_configuration_missing" })
|
|
expect(fetch).not.toHaveBeenCalled()
|
|
} finally {
|
|
fetch.mockRestore()
|
|
}
|
|
})
|
|
it("refuses Convex business dispatch with the supported-profile reason", async () => {
|
|
const hooks = businessServiceComposition(env, [crmModule], "convex")
|
|
await expect(
|
|
hooks.prepareServices?.(new Container(), context, crmModule.serviceRequirements ?? []),
|
|
).rejects.toMatchObject({ code: "service_profile_unsupported" })
|
|
})
|
|
})
|
|
|
|
// kit:support:begin
|
|
// kit:guides:begin
|
|
// Trusted selectors read the same bound ports that perform actual effects.
|
|
describe("native help composition", () => {
|
|
for (const [host, selectors] of [
|
|
["web", webSelectors],
|
|
["worker", workerSelectors],
|
|
] as const) {
|
|
for (const service of ["support", "guides"] as const) {
|
|
it(`${host} routes the actual ${service} selector at dispatch and refreshes port changes`, async () => {
|
|
let container = new Container()
|
|
const descriptor = `sha256:${"a".repeat(64)}`
|
|
const source = "b".repeat(40)
|
|
const deployment = {
|
|
...env.deployment,
|
|
CONUSAI_ORG_ID: "1",
|
|
CONUSAI_ENVIRONMENT_ID: "3",
|
|
CONUSAI_ORG_SLUG: "org",
|
|
CONUSAI_WORKSPACE_SLUG: "workspace",
|
|
CONUSAI_PROJECT_SLUG: "project",
|
|
CONUSAI_PLATFORM_RELEASE_DESCRIPTOR: descriptor,
|
|
CONUSAI_PLATFORM_SOURCE_COMMIT: source,
|
|
}
|
|
const base = crmModule.serviceRequirements[0]
|
|
if (!base) throw new Error("CRM fixture requires a service requirement")
|
|
const requirement = {
|
|
...base,
|
|
service,
|
|
transport: "platform" as const,
|
|
partitionRequired: false,
|
|
apiRange: "=1.0.0-preview.20261103",
|
|
operations: { "crm.party.list": [service === "support" ? "support:widget-sessions" : "guides:runtime"] },
|
|
}
|
|
const hooks = businessServiceComposition(
|
|
{ deployment },
|
|
[{ ...crmModule, serviceRequirements: [requirement] }],
|
|
"postgres",
|
|
selectors,
|
|
)
|
|
const readiness = hooks.serviceReadiness
|
|
if (!readiness) throw new Error("Native readiness must be composed")
|
|
const dispatch = () => readiness.observe(requirement, { ...context, container })
|
|
const fetch = vi.spyOn(globalThis, "fetch").mockImplementation(async () =>
|
|
Response.json({
|
|
component: {
|
|
id: service,
|
|
observed_at: new Date().toISOString(),
|
|
facts: { installed: "true", enabled: "true", entitled: "true", configured: "true", ready: "true" },
|
|
},
|
|
authorized: "true",
|
|
environment_bound: "true",
|
|
compatible: "true",
|
|
dependencies_ready: "true",
|
|
policy_epoch: 2,
|
|
descriptor_digest: descriptor,
|
|
source_commit: source,
|
|
organization_id: 1,
|
|
project_id: 9,
|
|
environment_id: 3,
|
|
app_scope: "org",
|
|
authorization_checked_at: new Date().toISOString(),
|
|
}),
|
|
)
|
|
const bind = (selector: string) => {
|
|
container = container.child()
|
|
if (service === "support")
|
|
container.value(kitSupport.SUPPORT_PLATFORM, {
|
|
mode: "platform",
|
|
channel: selector,
|
|
client: {},
|
|
} as kitSupport.SupportPlatform)
|
|
else
|
|
container.value(kitGuides.GUIDES_PLATFORM, {
|
|
mode: "platform",
|
|
identityNamespace: selector,
|
|
client: {},
|
|
} as kitGuides.GuidesPlatform)
|
|
}
|
|
await expect(dispatch()).rejects.toMatchObject({ code: "service_configuration_missing" })
|
|
expect(fetch).not.toHaveBeenCalled()
|
|
for (const value of ["selected_first", "selected_second"]) {
|
|
bind(value)
|
|
await dispatch()
|
|
const request = JSON.parse(String(fetch.mock.calls.at(-1)?.[1]?.body))
|
|
expect(String(fetch.mock.calls.at(-1)?.[0])).toContain(`/platform-services/${service}/readiness`)
|
|
expect(request).toMatchObject({
|
|
app_scope: "org",
|
|
[service === "support" ? "channel" : "identity_namespace"]: value,
|
|
})
|
|
}
|
|
bind("invalid/selector")
|
|
await expect(dispatch()).rejects.toMatchObject({ code: "service_configuration_missing" })
|
|
expect(fetch).toHaveBeenCalledTimes(2)
|
|
container = container.child()
|
|
if (service === "support") container.value(kitSupport.SUPPORT_PLATFORM, { mode: "offline" })
|
|
else container.value(kitGuides.GUIDES_PLATFORM, { mode: "offline" })
|
|
await expect(dispatch()).rejects.toMatchObject({ code: "service_configuration_missing" })
|
|
expect(fetch).toHaveBeenCalledTimes(2)
|
|
})
|
|
}
|
|
}
|
|
})
|
|
|
|
it("admits an actual Guides request through trusted composition and fences removed members and revoked native permission", async () => {
|
|
const registry = nativeCore.buildRegistry([kitTenancy.tenancyModule, kitGuides.guidesModule])
|
|
const data = kitData.createMemoryDataSource({ entities: kitData.entitiesOf(registry, "postgres") })
|
|
const root = new Container()
|
|
root.value(kitData.DATA_SOURCE, data)
|
|
root.value(kitData.SYSTEM_DATA, data)
|
|
root.value(kitGuides.GUIDES_REGISTRY, registry)
|
|
const descriptor = `sha256:${"a".repeat(64)}`
|
|
const source = "b".repeat(40)
|
|
const deployment = {
|
|
...env.deployment,
|
|
CONUSAI_ORG_ID: "1",
|
|
CONUSAI_ENVIRONMENT_ID: "3",
|
|
CONUSAI_ORG_SLUG: "org",
|
|
CONUSAI_WORKSPACE_SLUG: "workspace",
|
|
CONUSAI_PROJECT_SLUG: "project",
|
|
CONUSAI_PLATFORM_RELEASE_DESCRIPTOR: descriptor,
|
|
CONUSAI_PLATFORM_SOURCE_COMMIT: source,
|
|
}
|
|
let authorized = "true"
|
|
const runtimeInputs: unknown[] = []
|
|
const fetch = vi.spyOn(globalThis, "fetch").mockImplementation(async (url, init) => {
|
|
if (String(url).includes("/platform-services/guides/readiness"))
|
|
return Response.json({
|
|
component: {
|
|
id: "guides",
|
|
observed_at: new Date().toISOString(),
|
|
facts: { installed: "true", enabled: "true", entitled: "true", configured: "true", ready: "true" },
|
|
},
|
|
authorized,
|
|
environment_bound: "true",
|
|
compatible: "true",
|
|
dependencies_ready: "true",
|
|
policy_epoch: 2,
|
|
descriptor_digest: descriptor,
|
|
source_commit: source,
|
|
organization_id: 1,
|
|
project_id: 9,
|
|
environment_id: 3,
|
|
app_scope: "org",
|
|
authorization_checked_at: new Date().toISOString(),
|
|
})
|
|
runtimeInputs.push(url instanceof Request ? await url.clone().json() : JSON.parse(String(init?.body)))
|
|
return Response.json({ outcomes: [] })
|
|
})
|
|
root.value(
|
|
kitGuides.GUIDES_PLATFORM,
|
|
kitGuides.guidesPlatform({
|
|
apiUrl: deployment.CONUSAI_API_URL,
|
|
token: deployment.CONUSAI_API_TOKEN,
|
|
fake: false,
|
|
identityNamespace: "selected_namespace",
|
|
}),
|
|
)
|
|
const hooks = businessServiceComposition(
|
|
{ deployment },
|
|
[kitTenancy.tenancyModule, kitGuides.guidesModule],
|
|
"postgres",
|
|
webSelectors,
|
|
)
|
|
const caller = (actor: nativeCore.Actor) => {
|
|
const container = root.child()
|
|
const tenancy = kitTenancy.createTenancyHooks({ data, registry })
|
|
container.value(kitTenancy.TENANCY, tenancy)
|
|
return nativeCore.createCaller({ registry, container, tenancy, ...hooks }, { actor })
|
|
}
|
|
const owner = await data.global(kitTenancy.users).insert({
|
|
issuer: "https://identity.example.test",
|
|
subject: "owner",
|
|
email: "owner@example.test",
|
|
displayName: "Owner",
|
|
locale: "en",
|
|
})
|
|
const member = await data.global(kitTenancy.users).insert({
|
|
issuer: "https://identity.example.test",
|
|
subject: "member",
|
|
email: "member@example.test",
|
|
displayName: "Member",
|
|
locale: "en",
|
|
})
|
|
const actor = { userId: owner.id }
|
|
const alpha = (await caller(actor).callByName("tenancy.org.create", { slug: "alpha", name: "Alpha" })) as {
|
|
orgId: string
|
|
}
|
|
await caller(actor).callByName("tenancy.org.create", { slug: "bravo", name: "Bravo" })
|
|
await data.unitOfWork.run({ level: "org", orgId: alpha.orgId, actor }, (tx) =>
|
|
tx.of(kitTenancy.orgMemberships).insert({ userId: member.id, role: "viewer" }),
|
|
)
|
|
const input = {
|
|
org: "alpha",
|
|
idempotencyKey: "guides:test",
|
|
events: [
|
|
{
|
|
schema_version: 1,
|
|
event_id: "018f0000-0000-7000-8000-000000000001",
|
|
occurred_at: new Date().toISOString(),
|
|
type: "track",
|
|
name: "test",
|
|
},
|
|
],
|
|
}
|
|
const dispatch = (org = "alpha") =>
|
|
caller({ userId: member.id }).callByName("guides.runtime.record", { ...input, org })
|
|
await expect(dispatch("bravo")).rejects.toMatchObject({ status: 404 })
|
|
expect(fetch).not.toHaveBeenCalled()
|
|
await dispatch()
|
|
expect(JSON.parse(String(fetch.mock.calls[0]?.[1]?.body))).toMatchObject({
|
|
app_scope: "org",
|
|
identity_namespace: "selected_namespace",
|
|
})
|
|
expect(fetch).toHaveBeenCalledTimes(2)
|
|
expect(runtimeInputs[0]).toMatchObject({
|
|
identity: { identity_namespace: "selected_namespace", subject: member.id, app_tenant: alpha.orgId },
|
|
})
|
|
authorized = "false"
|
|
await expect(dispatch()).rejects.toMatchObject({ code: "service_permission_missing" })
|
|
expect(fetch).toHaveBeenCalledTimes(3)
|
|
await caller(actor).callByName("tenancy.member.remove", { org: "alpha", userId: member.id })
|
|
authorized = "true"
|
|
await expect(dispatch()).rejects.toMatchObject({ status: 404 })
|
|
expect(fetch).toHaveBeenCalledTimes(3)
|
|
})
|
|
|
|
// kit:guides:end
|
|
// kit:support:end
|