1import { GcpEnvironment } from "@/GCP/Environment";
2import * as GCP from "@/GCP";
3import * as Test from "@/Test/Alchemy";
4import * as ccaip from "@distilled.cloud/gcp/contactcenteraiplatform_v1alpha1";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import { MinimumLogLevel } from "effect/References";
8import * as Schedule from "effect/Schedule";
9
10const { test } = Test.make({ providers: GCP.providers() });
11
12const logLevel = Effect.provideService(
13 MinimumLogLevel,
14 process.env.DEBUG ? "Debug" : "Info",
15);
16
17// The Contact Center AI Platform API is not enabled in the testing project.
18// Set GCP_TEST_CONTACT_CENTER_AI_PLATFORM=1 on a project where it is; the
19// lifecycle also needs GCP_TEST_SLOW (instances take 30–45 minutes).
20const entitled = !!process.env.GCP_TEST_CONTACT_CENTER_AI_PLATFORM;
21const runLifecycle =
22 entitled && !!process.env.GCP_TEST_SLOW && !process.env.FAST;
23
24const waitUntilGone = (name: string) =>
25 ccaip.getProjectsLocationsContactCenters({ name }).pipe(
26 Effect.as("found" as const),
27 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
28 Effect.repeat({
29 schedule: Schedule.spaced("2 seconds"),
30 until: (status) => status === "gone",
31 times: 10,
32 }),
33 );
34
35test.provider.skipIf(!entitled)(
36 "getProjectsLocationsContactCenters on a missing contact center fails with a typed tag",
37 (stack) =>
38 Effect.gen(function* () {
39 const { project } = yield* GcpEnvironment.current;
40 const parent = `projects/${project}/locations/us-central1`;
41 const missingName = `${parent}/contactCenters/alchemy-missing-cc`;
42
43 yield* stack.destroy();
44 const error = yield* Effect.flip(
45 ccaip.getProjectsLocationsContactCenters({ name: missingName }),
46 );
47 expect(error._tag).toEqual("NotFound");
48
49 const page = yield* ccaip.listProjectsLocationsContactCenters({
50 parent,
51 pageSize: 10,
52 });
53 expect(
54 (page.contactCenters ?? []).map((item) => item.name),
55 ).not.toContain(missingName);
56
57 yield* stack.destroy();
58 }).pipe(logLevel),
59 {
60 tags: ["provider:gcp", "provider:gcp:contactcenteraiplatform", "live"],
61 timeout: 90_000,
62 },
63);
64
65test.provider.skipIf(entitled)(
66 "getProjectsLocationsContactCenters fails with ServiceDisabled while the API is disabled",
67 (stack) =>
68 Effect.gen(function* () {
69 const { project } = yield* GcpEnvironment.current;
70 yield* stack.destroy();
71
72 const error = yield* Effect.flip(
73 ccaip.getProjectsLocationsContactCenters({
74 name: `projects/${project}/locations/us-central1/contactCenters/alchemy-missing-cc`,
75 }),
76 );
77 expect(error._tag).toEqual("ServiceDisabled");
78
79 yield* stack.destroy();
80 }).pipe(logLevel),
81 {
82 tags: ["provider:gcp", "provider:gcp:contactcenteraiplatform", "live"],
83 timeout: 90_000,
84 },
85);
86
87test.provider.skipIf(!runLifecycle)(
88 "create, update, and delete a contact center",
89 (stack) =>
90 Effect.gen(function* () {
91 yield* stack.destroy();
92
93 const created = yield* stack.deploy(
94 Effect.gen(function* () {
95 return yield* GCP.ContactCenterAIPlatform.ContactCenter("Support", {
96 displayName: "support",
97 instanceSize: "DEV_SMALL",
98 labels: { env: "test" },
99 });
100 }),
101 );
102
103 expect(created.name).toContain("/contactCenters/");
104 expect(created.location).toEqual("us-central1");
105 expect(created.displayName).toEqual("support");
106 expect(created.customerDomainPrefix).toEqual(expect.any(String));
107 expect(created.labels).toMatchObject({ env: "test" });
108
109 const fetched = yield* ccaip.getProjectsLocationsContactCenters({
110 name: created.name,
111 });
112 expect(fetched.name).toEqual(created.name);
113 expect(fetched.labels?.env).toEqual("test");
114 expect(fetched.labels?.["alchemy-id"]).toEqual(expect.any(String));
115
116 const updated = yield* stack.deploy(
117 Effect.gen(function* () {
118 return yield* GCP.ContactCenterAIPlatform.ContactCenter("Support", {
119 contactCenterId: created.contactCenterId,
120 location: created.location,
121 customerDomainPrefix: created.customerDomainPrefix,
122 displayName: "support-desk",
123 instanceSize: "DEV_SMALL",
124 labels: { env: "prod", role: "ccaip" },
125 });
126 }),
127 );
128
129 expect(updated.name).toEqual(created.name);
130 expect(updated.displayName).toEqual("support-desk");
131 expect(updated.labels).toMatchObject({ env: "prod", role: "ccaip" });
132
133 yield* stack.destroy();
134 const gone = yield* waitUntilGone(created.name);
135 expect(gone).toEqual("gone");
136 }).pipe(logLevel),
137 {
138 tags: ["provider:gcp", "provider:gcp:contactcenteraiplatform", "live"],
139 timeout: 3_600_000,
140 },
141);