1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as sasportal from "@distilled.cloud/gcp/sasportal_v1alpha1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as Schedule from "effect/Schedule";
7import {
8 firstCustomerName,
9 logLevel,
10 runLifecycle,
11 signedDeviceProbe,
12} from "./common.ts";
13
14const { test } = Test.make({ providers: GCP.providers() });
15
16const waitUntilGone = (name: string) =>
17 sasportal.getDeploymentsDevices({ name }).pipe(
18 Effect.as("found" as const),
19 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
20 Effect.repeat({
21 schedule: Schedule.spaced("1 second"),
22 until: (status) => status === "gone",
23 times: 8,
24 }),
25 );
26
27test.provider(
28 "getDeploymentsDevices on a missing device fails with a typed tag",
29 (stack) =>
30 Effect.gen(function* () {
31 yield* stack.destroy();
32
33 const error = yield* Effect.flip(
34 sasportal.getDeploymentsDevices({
35 name: "customers/missing/deployments/missing/devices/alchemy-missing",
36 }),
37 );
38 expect(error._tag).toEqual("NotFound");
39
40 yield* stack.destroy();
41 }).pipe(logLevel),
42 { tags: ["provider:gcp", "provider:gcp:sasportal", "live"], timeout: 90_000 },
43);
44
45test.provider.skipIf(runLifecycle)(
46 "createSignedCustomersDeploymentsDevices without entitlement fails with a typed tag",
47 (stack) =>
48 Effect.gen(function* () {
49 yield* stack.destroy();
50
51 const error = yield* Effect.flip(
52 sasportal.createSignedCustomersDeploymentsDevices({
53 parent: "customers/missing/deployments/missing",
54 body: signedDeviceProbe,
55 }),
56 );
57 expect(error._tag).toEqual("ServiceDisabled");
58
59 yield* stack.destroy();
60 }).pipe(logLevel),
61 { tags: ["provider:gcp", "provider:gcp:sasportal", "live"], timeout: 90_000 },
62);
63
64test.provider.skipIf(!runLifecycle)(
65 "create, update, and delete a signed device",
66 (stack) =>
67 Effect.gen(function* () {
68 yield* stack.destroy();
69
70 const customer = yield* firstCustomerName;
71 expect(customer.length).toBeGreaterThan(0);
72
73 const created = yield* stack.deploy(
74 Effect.gen(function* () {
75 const parent = yield* GCP.SasPortal.CustomersDeployment("Site", {
76 parent: customer,
77 displayName: "site-a",
78 });
79 const device = yield* GCP.SasPortal.SignedCustomersDeploymentsDevice(
80 "Cbsd",
81 {
82 parent: parent.name,
83 displayName: "sector-a",
84 encodedDevice: signedDeviceProbe.encodedDevice,
85 installerId: signedDeviceProbe.installerId,
86 },
87 );
88 return { parent, device };
89 }),
90 );
91
92 expect(created.device.name.length).toBeGreaterThan(0);
93 expect(created.device.displayName).toEqual("sector-a");
94
95 const fetched = yield* sasportal.getDeploymentsDevices({
96 name: created.device.name,
97 });
98 expect(fetched.name).toEqual(created.device.name);
99 expect(fetched.displayName).toContain("[alchemy ");
100
101 const updated = yield* stack.deploy(
102 Effect.gen(function* () {
103 const parent = yield* GCP.SasPortal.CustomersDeployment("Site", {
104 parent: customer,
105 name: created.parent.name,
106 displayName: "site-a",
107 });
108 const device = yield* GCP.SasPortal.SignedCustomersDeploymentsDevice(
109 "Cbsd",
110 {
111 parent: parent.name,
112 name: created.device.name,
113 displayName: "sector-b",
114 encodedDevice: signedDeviceProbe.encodedDevice,
115 installerId: signedDeviceProbe.installerId,
116 },
117 );
118 return { parent, device };
119 }),
120 );
121
122 expect(updated.device.name).toEqual(created.device.name);
123 expect(updated.device.displayName).toEqual("sector-b");
124
125 yield* stack.destroy();
126
127 const gone = yield* waitUntilGone(created.device.name);
128 expect(gone).toEqual("gone");
129 }).pipe(logLevel),
130 { tags: ["provider:gcp", "provider:gcp:sasportal", "live"], timeout: 90_000 },
131);