// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // One business procedure end to end: the CRM module's page over the platform's CRM service, through the // business gateway's binding and admission, on the fake platform of @conusai-kit/testing (no live service). // An organization nobody has bound sees the typed refusal in its own words; once an administrator binds it with // the scopes the app declares, a member adds a party through the page's form and finds it in the list. import { buildRegistry } from "@conusai-kit/core" import { expect, test } from "@playwright/test" import { declaredBusinessScopes } from "../apps/worker/src/fake-business-bindings" import { appModules } from "../modules/index" import { bindBusinessServices, makeOrganization, ready, signIn, unique, violations } from "./support/app" test("a party is added through the CRM page once the organization is bound, and refused in words before", async ({ page, }) => { // The e2e app selects CRM (scripts/vendor/test-template.sh); its declared scopes are what the binding grants. const grants = declaredBusinessScopes(buildRegistry([...appModules])) expect(Object.keys(grants)).toContain("crm") await signIn(page, `${unique("buyer")}@example.test`) const { orgId, org, workspace, project } = await makeOrganization(page, "buyer") const crm = `/${org}/${workspace}/${project}/crm` // Not bound: the page says so in place of the list, as a refusal, never a crash. await page.goto(crm) await ready(page) await expect(page.getByText("This app tenant and environment have no verified service binding.")).toBeVisible() expect(await violations(page)).toEqual([]) // The administrator's act, then the member's: a party added through the form appears in the list. await bindBusinessServices(orgId, grants) await page.goto(crm) await ready(page) await expect(page.getByRole("heading", { level: 1, name: "Customers" })).toBeVisible() const name = unique("Supplier") await page.getByLabel("Name", { exact: true }).fill(name) await page.getByLabel(/^Country/).fill("LT") await page.getByRole("button", { name: "Add party" }).click() // The service minted the party: its own page opens, and the list has it. await expect(page.getByRole("heading", { level: 1, name })).toBeVisible() expect(await violations(page)).toEqual([]) await page.getByRole("link", { name: "All parties" }).click() await expect(page.getByRole("row").filter({ hasText: name })).toBeVisible() expect(await violations(page)).toEqual([]) })