1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as recaptchaenterprise from "@distilled.cloud/gcp/recaptchaenterprise_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 = (name: string) =>
17 recaptchaenterprise.getProjectsKeys({ 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: 10,
24 }),
25 );
26
27test.provider(
28 "create, update, and delete a reCAPTCHA key",
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.RecaptchaEnterprise.Key("Signup", {
36 displayName: "alchemy recaptcha signup",
37 labels: { env: "test" },
38 testingOptions: { testingScore: 0.9 },
39 webSettings: {
40 integrationType: "SCORE",
41 allowAllDomains: true,
42 },
43 });
44 }),
45 );
46
47 expect(created.name).toContain("/keys/");
48 expect(created.keyId).toEqual(expect.any(String));
49 expect(created.displayName).toEqual("alchemy recaptcha signup");
50 expect(created.labels).toMatchObject({ env: "test" });
51 expect(created.webSettings?.integrationType).toEqual("SCORE");
52 expect(created.testingOptions?.testingScore).toEqual(0.9);
53
54 const fetched = yield* recaptchaenterprise.getProjectsKeys({
55 name: created.name,
56 });
57 expect(fetched.name).toEqual(created.name);
58 expect(fetched.displayName).toEqual("alchemy recaptcha signup");
59 expect(fetched.labels?.env).toEqual("test");
60 expect(fetched.labels?.["alchemy-id"]).toEqual(expect.any(String));
61 expect(fetched.webSettings?.integrationType).toEqual("SCORE");
62
63 const updated = yield* stack.deploy(
64 Effect.gen(function* () {
65 return yield* GCP.RecaptchaEnterprise.Key("Signup", {
66 keyId: created.keyId,
67 displayName: "alchemy recaptcha signup v2",
68 labels: { env: "prod", role: "bot" },
69 testingOptions: { testingScore: 0.9 },
70 webSettings: {
71 integrationType: "SCORE",
72 allowAllDomains: true,
73 },
74 });
75 }),
76 );
77
78 expect(updated.name).toEqual(created.name);
79 expect(updated.keyId).toEqual(created.keyId);
80 expect(updated.displayName).toEqual("alchemy recaptcha signup v2");
81 expect(updated.labels).toMatchObject({ env: "prod", role: "bot" });
82 expect(updated.testingOptions?.testingScore).toEqual(0.9);
83
84 const fetchedUpdate = yield* recaptchaenterprise.getProjectsKeys({
85 name: created.name,
86 });
87 expect(fetchedUpdate.displayName).toEqual("alchemy recaptcha signup v2");
88 expect(fetchedUpdate.labels?.env).toEqual("prod");
89 expect(fetchedUpdate.labels?.role).toEqual("bot");
90 expect(fetchedUpdate.labels?.["alchemy-id"]).toEqual(expect.any(String));
91
92 yield* stack.destroy();
93
94 const gone = yield* waitUntilGone(created.name);
95 expect(gone).toEqual("gone");
96 }).pipe(logLevel),
97 {
98 tags: ["provider:gcp", "provider:gcp:recaptchaenterprise", "live"],
99 timeout: 90_000,
100 },
101);