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.getSettingsDatasources({ 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 "getSettingsDatasources on a missing datasource fails with a typed tag",
24 (stack) =>
25 Effect.gen(function* () {
26 yield* stack.destroy();
27
28 const error = yield* Effect.flip(
29 cloudsearch.getSettingsDatasources({
30 name: "datasources/alchemy-missing-datasource",
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 "createSettingsDatasources 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.createSettingsDatasources({
51 body: {
52 displayName: "Alchemy Cloud Search Probe",
53 shortName: "alchprobe",
54 },
55 }),
56 );
57 expect(error._tag).toEqual("InsufficientScopes");
58
59 yield* stack.destroy();
60 }).pipe(logLevel),
61 {
62 tags: ["provider:gcp", "provider:gcp:cloudsearch", "live"],
63 timeout: 90_000,
64 },
65);
66
67test.provider.skipIf(!runLifecycle)(
68 "create, update, and delete a datasource",
69 (stack) =>
70 Effect.gen(function* () {
71 yield* stack.destroy();
72
73 const created = yield* stack.deploy(
74 Effect.gen(function* () {
75 return yield* GCP.CloudSearch.SettingsDatasource("Wiki", {
76 displayName: "Wiki",
77 shortName: "wiki",
78 returnThumbnailUrls: true,
79 });
80 }),
81 );
82
83 expect(created.name.startsWith("datasources/")).toEqual(true);
84 expect(created.datasourceId.length).toBeGreaterThan(0);
85 expect(created.displayName).toEqual("Wiki");
86 expect(created.shortName).toEqual("wiki");
87 expect(created.returnThumbnailUrls).toEqual(true);
88
89 const fetched = yield* cloudsearch.getSettingsDatasources({
90 name: created.name,
91 });
92 expect(fetched.name).toEqual(created.name);
93 expect(fetched.displayName).toEqual(created.displayName);
94
95 const updated = yield* stack.deploy(
96 Effect.gen(function* () {
97 return yield* GCP.CloudSearch.SettingsDatasource("Wiki", {
98 datasourceId: created.datasourceId,
99 displayName: "Knowledge base",
100 shortName: "wiki",
101 disableServing: true,
102 returnThumbnailUrls: true,
103 });
104 }),
105 );
106
107 expect(updated.datasourceId).toEqual(created.datasourceId);
108 expect(updated.displayName).toEqual("Knowledge base");
109 expect(updated.disableServing).toEqual(true);
110
111 yield* stack.destroy();
112
113 const gone = yield* waitUntilGone(created.name);
114 expect(gone).toEqual("gone");
115 }).pipe(logLevel),
116 {
117 tags: ["provider:gcp", "provider:gcp:cloudsearch", "live"],
118 timeout: 90_000,
119 },
120);