1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as compute from "@distilled.cloud/gcp/compute_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7import * as Schedule from "effect/Schedule";
8
9const { test } = Test.make({ providers: GCP.providers() });
10
11const logLevel = Effect.provideService(
12 MinimumLogLevel,
13 process.env.DEBUG ? "Debug" : "Info",
14);
15
16const waitUntilGone = (project: string, region: string, urlMapName: string) =>
17 compute.getRegionUrlMaps({ project, region, urlMap: urlMapName }).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: 10,
24 }),
25 );
26
27test.provider(
28 "create, update, and delete a regional url map",
29 (stack) =>
30 Effect.gen(function* () {
31 yield* stack.destroy();
32
33 const created = yield* stack.deploy(
34 Effect.gen(function* () {
35 return yield* GCP.Compute.RegionUrlMap("Web", {
36 region: "us-central1",
37 description: "https redirect",
38 defaultUrlRedirect: {
39 httpsRedirect: true,
40 hostRedirect: "example.com",
41 stripQuery: false,
42 },
43 });
44 }),
45 );
46
47 expect(created.urlMapName).toEqual(expect.any(String));
48 expect(created.region).toEqual("us-central1");
49 expect(created.description).toEqual("https redirect");
50 expect(created.defaultUrlRedirect?.httpsRedirect).toEqual(true);
51 expect(created.defaultUrlRedirect?.hostRedirect).toEqual("example.com");
52
53 const fetched = yield* compute.getRegionUrlMaps({
54 project: created.project,
55 region: created.region,
56 urlMap: created.urlMapName,
57 });
58 expect(fetched.name).toEqual(created.urlMapName);
59 expect(fetched.defaultUrlRedirect?.hostRedirect).toEqual("example.com");
60 expect(fetched.description).toContain("[alchemy ");
61 expect(fetched.description).toContain("https redirect");
62
63 const updated = yield* stack.deploy(
64 Effect.gen(function* () {
65 return yield* GCP.Compute.RegionUrlMap("Web", {
66 urlMapName: created.urlMapName,
67 region: "us-central1",
68 description: "host rules",
69 defaultUrlRedirect: {
70 httpsRedirect: true,
71 hostRedirect: "example.org",
72 stripQuery: true,
73 },
74 hostRules: [{ hosts: ["example.org"], pathMatcher: "all" }],
75 pathMatchers: [
76 {
77 name: "all",
78 defaultUrlRedirect: {
79 httpsRedirect: true,
80 hostRedirect: "www.example.org",
81 stripQuery: false,
82 },
83 },
84 ],
85 });
86 }),
87 );
88
89 expect(updated.urlMapName).toEqual(created.urlMapName);
90 expect(updated.region).toEqual("us-central1");
91 expect(updated.description).toEqual("host rules");
92 expect(updated.defaultUrlRedirect?.hostRedirect).toEqual("example.org");
93 expect(updated.defaultUrlRedirect?.stripQuery).toEqual(true);
94 expect(updated.hostRules).toEqual(
95 expect.arrayContaining([
96 expect.objectContaining({
97 pathMatcher: "all",
98 hosts: expect.arrayContaining(["example.org"]),
99 }),
100 ]),
101 );
102 expect(updated.pathMatchers).toEqual(
103 expect.arrayContaining([
104 expect.objectContaining({
105 name: "all",
106 defaultUrlRedirect: expect.objectContaining({
107 hostRedirect: "www.example.org",
108 }),
109 }),
110 ]),
111 );
112
113 const refetched = yield* compute.getRegionUrlMaps({
114 project: updated.project,
115 region: updated.region,
116 urlMap: updated.urlMapName,
117 });
118 expect(refetched.defaultUrlRedirect?.hostRedirect).toEqual("example.org");
119 expect(refetched.hostRules?.[0]?.pathMatcher).toEqual("all");
120 expect(refetched.pathMatchers?.[0]?.name).toEqual("all");
121 expect(refetched.description).toContain("host rules");
122
123 yield* stack.destroy();
124
125 const gone = yield* waitUntilGone(
126 created.project,
127 created.region,
128 created.urlMapName,
129 );
130 expect(gone).toEqual("gone");
131 }).pipe(logLevel),
132 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
133);