1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as Core from "@/Test/Core";
4import * as cloudtasks from "@distilled.cloud/gcp/cloudtasks_v2";
5import { describe, expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import { dockerAvailable, expectProbe } from "../bindingHost.ts";
8import CloudTasksBindingsHost, {
9 Jobs,
10 TASK_URL,
11} from "./fixtures/bindings-host.ts";
12
13const testOptions = { providers: GCP.providers() };
14const { test, beforeAll, afterAll } = Test.make(testOptions);
15const sharedStack = Core.scratchStack(testOptions, "CloudTasksBindings");
16
17let baseUrl: string;
18let queueName: string;
19let hostAccount: string;
20
21describe.skipIf(!dockerAvailable)(
22 "CloudTasks Bindings",
23 {
24 tags: [
25 "provider:gcp",
26 "provider:gcp:cloudtasks",
27 "provider:gcp:run",
28 "live",
29 ],
30 },
31 () => {
32 beforeAll(
33 Effect.gen(function* () {
34 yield* sharedStack.destroy();
35 const out = yield* sharedStack.deploy(
36 Effect.gen(function* () {
37 const host = yield* CloudTasksBindingsHost;
38 const queue = yield* Jobs;
39 return {
40 uri: host.uri,
41 serviceAccount: host.serviceAccount,
42 queue: queue.name,
43 };
44 }),
45 );
46 baseUrl = out.uri!;
47 queueName = out.queue;
48 hostAccount = out.serviceAccount!;
49 }),
50 { timeout: 900_000 },
51 );
52
53 afterAll(sharedStack.destroy(), { timeout: 600_000 });
54
55 describe("CreateTask", () => {
56 test.provider(
57 "enqueues a task as the host's service account, granted on the queue only",
58 (_stack) =>
59 Effect.gen(function* () {
60 const task = yield* expectProbe<cloudtasks.Task>(
61 baseUrl,
62 "createTask",
63 );
64 expect(task.name?.startsWith(`${queueName}/tasks/`)).toBe(true);
65 expect(task.httpRequest?.url).toEqual(TASK_URL);
66
67 const live = yield* cloudtasks.getProjectsLocationsQueuesTasks({
68 name: task.name!,
69 });
70 expect(live.name).toEqual(task.name);
71 expect(live.httpRequest?.url).toEqual(TASK_URL);
72 expect(live.httpRequest?.httpMethod).toEqual("POST");
73
74 const policy =
75 yield* cloudtasks.getIamPolicyProjectsLocationsQueues({
76 resource: queueName,
77 });
78 const roles = (policy.bindings ?? [])
79 .filter((binding) =>
80 (binding.members ?? []).includes(
81 `serviceAccount:${hostAccount}`,
82 ),
83 )
84 .map((binding) => binding.role)
85 .sort();
86 expect(roles).toEqual(["roles/cloudtasks.enqueuer"]);
87 }),
88 {
89 tags: ["provider:gcp", "provider:gcp:cloudtasks", "live"],
90 timeout: 600_000,
91 },
92 );
93 });
94 },
95);