1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as cloudsearch from "@distilled.cloud/gcp/cloudsearch_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as Schedule from "effect/Schedule";
7import { logLevel, runLifecycle } from "./common.ts";
8
9const { test } = Test.make({ providers: GCP.providers() });
10
11const waitUntilGone = (name: string) =>
12 cloudsearch.getSettingsSearchapplications({ name }).pipe(
13 Effect.as("found" as const),
14 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
15 Effect.repeat({
16 schedule: Schedule.spaced("1 second"),
17 until: (status) => status === "gone",
18 times: 10,
19 }),
20 );
21
22test.provider(
23 "getSettingsSearchapplications on a missing application fails with a typed tag",
24 (stack) =>
25 Effect.gen(function* () {
26 yield* stack.destroy();
27
28 const error = yield* Effect.flip(
29 cloudsearch.getSettingsSearchapplications({
30 name: "searchapplications/alchemy-missing-search-app",
31 }),
32 );
33 expect(error._tag).toEqual("InsufficientScopes");
34
35 yield* stack.destroy();
36 }).pipe(logLevel),
37 {
38 tags: ["provider:gcp", "provider:gcp:cloudsearch", "live"],
39 timeout: 90_000,
40 },
41);
42
43test.provider.skipIf(runLifecycle)(
44 "createSettingsSearchapplications without Cloud Search admin fails with a typed tag",
45 (stack) =>
46 Effect.gen(function* () {
47 yield* stack.destroy();
48
49 const error = yield* Effect.flip(
50 cloudsearch.createSettingsSearchapplications({
51 body: {
52 displayName: "Alchemy Cloud Search App Probe",
53 },
54 }),
55 );
56 expect(error._tag).toEqual("InsufficientScopes");
57
58 yield* stack.destroy();
59 }).pipe(logLevel),
60 {
61 tags: ["provider:gcp", "provider:gcp:cloudsearch", "live"],
62 timeout: 90_000,
63 },
64);
65
66test.provider.skipIf(!runLifecycle)(
67 "create, update, and delete a search application",
68 (stack) =>
69 Effect.gen(function* () {
70 yield* stack.destroy();
71
72 const created = yield* stack.deploy(
73 Effect.gen(function* () {
74 return yield* GCP.CloudSearch.SettingsSearchapplication("Intranet", {
75 displayName: "Intranet",
76 enableAuditLog: true,
77 });
78 }),
79 );
80
81 expect(created.name.startsWith("searchapplications/")).toEqual(true);
82 expect(created.searchApplicationId.length).toBeGreaterThan(0);
83 expect(created.displayName).toEqual("Intranet");
84 expect(created.enableAuditLog).toEqual(true);
85
86 const fetched = yield* cloudsearch.getSettingsSearchapplications({
87 name: created.name,
88 });
89 expect(fetched.name).toEqual(created.name);
90 expect(fetched.displayName).toEqual(created.displayName);
91
92 const updated = yield* stack.deploy(
93 Effect.gen(function* () {
94 return yield* GCP.CloudSearch.SettingsSearchapplication("Intranet", {
95 searchApplicationId: created.searchApplicationId,
96 displayName: "Company search",
97 enableAuditLog: true,
98 returnResultThumbnailUrls: true,
99 });
100 }),
101 );
102
103 expect(updated.searchApplicationId).toEqual(created.searchApplicationId);
104 expect(updated.displayName).toEqual("Company search");
105 expect(updated.returnResultThumbnailUrls).toEqual(true);
106
107 yield* stack.destroy();
108
109 const gone = yield* waitUntilGone(created.name);
110 expect(gone).toEqual("gone");
111 }).pipe(logLevel),
112 {
113 tags: ["provider:gcp", "provider:gcp:cloudsearch", "live"],
114 timeout: 90_000,
115 },
116);