1import * as machines from "@distilled.cloud/fly-io/machines";
2import * as Fly from "@/Fly";
3import * as Test from "@/Test/Alchemy";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7import * as Schedule from "effect/Schedule";
8import * as pathe from "pathe";
9import { cloneFixture } from "../../Cloudflare/Utils/Fixture.ts";
10import { expectUrlContains } from "../../Cloudflare/Utils/Http.ts";
11
12const { test } = Test.make({ providers: Fly.providers() });
13
14const logLevel = Effect.provideService(
15 MinimumLogLevel,
16 process.env.DEBUG ? "Debug" : "Info",
17);
18
19const fixtureDir = pathe.resolve(
20 import.meta.dirname,
21 "../../AWS/Website/fixtures/waku-app",
22);
23const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
24const fixtureEntries = [
25 ".gitignore",
26 "package.json",
27 "tsconfig.json",
28 "src",
29 "public",
30];
31
32const waitUntilGone = (appName: string) =>
33 machines.getApp({ app_name: appName }).pipe(
34 Effect.as("found" as const),
35 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
36 Effect.repeat({
37 schedule: Schedule.spaced("1 second"),
38 until: (status) => status === "gone",
39 times: 10,
40 }),
41 );
42
43test.provider(
44 "Waku: deploy, GET /, destroy, gone",
45 (stack) =>
46 Effect.gen(function* () {
47 yield* stack.destroy();
48
49 const rootDir = yield* cloneFixture(fixtureDir, {
50 prefix: "alchemy-waku-fly-",
51 tempRoot,
52 entries: fixtureEntries,
53 });
54
55 const deployed = yield* stack.deploy(
56 Effect.gen(function* () {
57 const site = yield* Fly.Website.Waku("Web", {
58 rootDir,
59 memo: {
60 include: ["src/**", "public/**", "package.json", "tsconfig.json"],
61 },
62 });
63 return { site };
64 }),
65 );
66
67 const url = deployed.site.url;
68 expect(url).toBeDefined();
69 expect(url).toMatch(/^https:\/\//);
70 expect(deployed.site.service).toBeDefined();
71 expect(deployed.site.app).toBeDefined();
72
73 yield* expectUrlContains(`${url!}/`, "WAKU_AWS_PAGE_MARKER", {
74 timeout: "90 seconds",
75 label: "home page",
76 });
77 yield* expectUrlContains(
78 `${url!}/echo?echo=roundtrip`,
79 "WAKU_AWS_API_MARKER",
80 {
81 timeout: "30 seconds",
82 label: "api route",
83 },
84 );
85 yield* expectUrlContains(`${url!}/about`, "WAKU_AWS_STATIC_MARKER", {
86 timeout: "30 seconds",
87 label: "extra route",
88 });
89
90 const appName = deployed.site.app!.appName;
91 yield* stack.destroy();
92 const gone = yield* waitUntilGone(appName);
93 expect(gone).toEqual("gone");
94 }).pipe(logLevel),
95 {
96 tags: [
97 "provider:fly",
98 "provider:fly:machine",
99 "provider:fly:website",
100 "live",
101 ],
102 timeout: 180000,
103 },
104);