1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as datalabeling from "@distilled.cloud/gcp/datalabeling_v1beta1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import {
7 logLevel,
8 probe,
9 currentProject,
10 runLifecycle,
11 waitUntilGone,
12} from "./common.ts";
13
14const { test } = Test.make({ providers: GCP.providers() });
15
16test.provider(
17 "getProjectsInstructions on a missing instruction fails with a typed tag",
18 (stack) =>
19 Effect.gen(function* () {
20 const project = yield* currentProject;
21 yield* stack.destroy();
22
23 const error = yield* Effect.flip(
24 probe(
25 datalabeling.getProjectsInstructions({
26 name: `projects/${project}/instructions/alchemy-missing-instruction`,
27 }),
28 ),
29 );
30 expect(error._tag).toEqual("NotFound");
31
32 yield* stack.destroy();
33 }).pipe(logLevel),
34 {
35 tags: ["provider:gcp", "provider:gcp:datalabeling", "live"],
36 timeout: 90_000,
37 },
38);
39
40test.provider.skipIf(!runLifecycle)(
41 "create, replace, and delete an instruction",
42 (stack) =>
43 Effect.gen(function* () {
44 const project = yield* currentProject;
45 yield* stack.destroy();
46
47 const created = yield* stack.deploy(
48 Effect.gen(function* () {
49 return yield* GCP.DataLabeling.Instruction("HowTo", {
50 displayName: "image-classes",
51 dataType: "IMAGE",
52 description: "label each photo",
53 pdfInstruction: {
54 gcsFileUri: `gs://${project}-datalabeling/instructions.pdf`,
55 },
56 });
57 }),
58 );
59
60 expect(created.name).toContain("/instructions/");
61 expect(created.displayName).toEqual("image-classes");
62 expect(created.dataType).toEqual("IMAGE");
63 expect(created.description).toEqual("label each photo");
64
65 const fetched = yield* datalabeling.getProjectsInstructions({
66 name: created.name,
67 });
68 expect(fetched.name).toEqual(created.name);
69 expect(fetched.description).toContain("alchemy-id=");
70
71 const updated = yield* stack.deploy(
72 Effect.gen(function* () {
73 return yield* GCP.DataLabeling.Instruction("HowTo", {
74 instructionId: created.instructionId,
75 displayName: "image-classes",
76 dataType: "IMAGE",
77 description: "updated labeling notes",
78 pdfInstruction: {
79 gcsFileUri: `gs://${project}-datalabeling/instructions.pdf`,
80 },
81 });
82 }),
83 );
84
85 expect(updated.description).toEqual("updated labeling notes");
86
87 yield* stack.destroy();
88 const gone = yield* waitUntilGone(
89 datalabeling.getProjectsInstructions({ name: updated.name }),
90 );
91 expect(gone).toEqual("gone");
92 }).pipe(logLevel),
93 {
94 tags: ["provider:gcp", "provider:gcp:datalabeling", "live"],
95 timeout: 90_000,
96 },
97);