1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as saasservicemgmt from "@distilled.cloud/gcp/saasservicemgmt_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import {
7 location,
8 logLevel,
9 currentProject,
10 runLifecycle,
11 waitUntilGone,
12} from "./common.ts";
13
14const { test } = Test.make({ providers: GCP.providers() });
15
16test.provider(
17 "getProjectsLocationsUnits on a missing unit fails with a typed tag",
18 (stack) =>
19 Effect.gen(function* () {
20 const project = yield* currentProject;
21 yield* stack.destroy();
22
23 const error = yield* Effect.flip(
24 saasservicemgmt.getProjectsLocationsUnits({
25 name: `projects/${project}/locations/${location}/units/alchemy-missing-unit`,
26 }),
27 );
28 expect(error._tag).toEqual("NotFound");
29
30 yield* stack.destroy();
31 }).pipe(logLevel),
32 {
33 tags: ["provider:gcp", "provider:gcp:saasservicemgmt", "live"],
34 timeout: 90_000,
35 },
36);
37
38test.provider.skipIf(!runLifecycle)(
39 "create, update, and delete a unit",
40 (stack) =>
41 Effect.gen(function* () {
42 yield* stack.destroy();
43
44 const created = yield* stack.deploy(
45 Effect.gen(function* () {
46 const product = yield* GCP.SaasServiceManagement.Saa("Inventory", {
47 location,
48 locations: [{ name: location }],
49 });
50 const tenant = yield* GCP.SaasServiceManagement.Tenant("Acme", {
51 location,
52 saas: product.name,
53 });
54 const kind = yield* GCP.SaasServiceManagement.UnitKind("Store", {
55 location,
56 saas: product.name,
57 });
58 const unit = yield* GCP.SaasServiceManagement.Unit("Store1", {
59 location,
60 unitKind: kind.name,
61 tenant: tenant.name,
62 managementMode: "MANAGEMENT_MODE_USER",
63 labels: { env: "test" },
64 });
65 return { product, tenant, kind, unit };
66 }),
67 );
68
69 expect(created.unit.name).toContain("/units/");
70 expect(created.unit.unitKindId).toEqual(created.kind.unitKindId);
71 expect(created.unit.tenantId).toEqual(created.tenant.tenantId);
72 expect(created.unit.labels).toMatchObject({ env: "test" });
73
74 const fetched = yield* saasservicemgmt.getProjectsLocationsUnits({
75 name: created.unit.name,
76 });
77 expect(fetched.name).toEqual(created.unit.name);
78 expect(fetched.labels?.env).toEqual("test");
79 expect(
80 Object.keys(fetched.labels ?? {}).some((key) =>
81 key.startsWith("alchemy-"),
82 ),
83 ).toEqual(true);
84
85 const updated = yield* stack.deploy(
86 Effect.gen(function* () {
87 const product = yield* GCP.SaasServiceManagement.Saa("Inventory", {
88 saasId: created.product.saasId,
89 location,
90 locations: [{ name: location }],
91 });
92 const tenant = yield* GCP.SaasServiceManagement.Tenant("Acme", {
93 tenantId: created.tenant.tenantId,
94 location,
95 saas: product.name,
96 });
97 const kind = yield* GCP.SaasServiceManagement.UnitKind("Store", {
98 unitKindId: created.kind.unitKindId,
99 location,
100 saas: product.name,
101 });
102 const unit = yield* GCP.SaasServiceManagement.Unit("Store1", {
103 unitId: created.unit.unitId,
104 location,
105 unitKind: kind.name,
106 tenant: tenant.name,
107 managementMode: "MANAGEMENT_MODE_USER",
108 labels: { env: "prod" },
109 });
110 return { product, tenant, kind, unit };
111 }),
112 );
113
114 expect(updated.unit.name).toEqual(created.unit.name);
115 expect(updated.unit.labels).toMatchObject({ env: "prod" });
116
117 yield* stack.destroy();
118 const gone = yield* waitUntilGone(
119 saasservicemgmt.getProjectsLocationsUnits({ name: created.unit.name }),
120 );
121 expect(gone).toEqual("gone");
122 }).pipe(logLevel),
123 {
124 tags: ["provider:gcp", "provider:gcp:saasservicemgmt", "live"],
125 timeout: 90_000,
126 },
127);