1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as firebasedataconnect from "@distilled.cloud/gcp/firebasedataconnect_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as Schedule from "effect/Schedule";
7import { location, logLevel, missingService } from "./common.ts";
8
9const { test } = Test.make({ providers: GCP.providers() });
10
11const waitUntilGone = (name: string) =>
12 firebasedataconnect.getProjectsLocationsServices({ name }).pipe(
13 Effect.as("found" as const),
14 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
15 Effect.repeat({
16 schedule: Schedule.spaced("3 seconds"),
17 until: (status) => status === "gone",
18 times: 10,
19 }),
20 );
21
22test.provider(
23 "getProjectsLocationsServices on a missing service fails with a typed tag",
24 (stack) =>
25 Effect.gen(function* () {
26 yield* stack.destroy();
27
28 const error = yield* Effect.flip(
29 firebasedataconnect.getProjectsLocationsServices({
30 name: yield* missingService(),
31 }),
32 );
33 expect(error._tag).toEqual("NotFound");
34
35 yield* stack.destroy();
36 }).pipe(logLevel),
37 {
38 tags: ["provider:gcp", "provider:gcp:firebasedataconnect", "live"],
39 timeout: 90_000,
40 },
41);
42
43test.provider(
44 "create, update, and delete a firebase data connect service",
45 (stack) =>
46 Effect.gen(function* () {
47 yield* stack.destroy();
48
49 const created = yield* stack.deploy(
50 Effect.gen(function* () {
51 return yield* GCP.FirebaseDataConnect.Service("Notes", {
52 location,
53 displayName: "notes",
54 labels: { env: "test" },
55 });
56 }),
57 );
58
59 expect(created.name).toContain("/services/");
60 expect(created.displayName).toEqual("notes");
61 expect(created.labels).toMatchObject({ env: "test" });
62
63 const fetched = yield* firebasedataconnect.getProjectsLocationsServices({
64 name: created.name,
65 });
66 expect(fetched.name).toEqual(created.name);
67
68 const updated = yield* stack.deploy(
69 Effect.gen(function* () {
70 return yield* GCP.FirebaseDataConnect.Service("Notes", {
71 serviceId: created.serviceId,
72 location,
73 displayName: "notes-v2",
74 labels: { env: "prod", role: "fdc" },
75 });
76 }),
77 );
78
79 expect(updated.name).toEqual(created.name);
80 expect(updated.displayName).toEqual("notes-v2");
81
82 yield* stack.destroy();
83 const gone = yield* waitUntilGone(created.name);
84 expect(gone).toEqual("gone");
85 }).pipe(logLevel),
86 {
87 tags: ["provider:gcp", "provider:gcp:firebasedataconnect", "live"],
88 timeout: 180_000,
89 },
90);