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/astro-app",
22);
23const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
24const fixtureEntries = [
25 ".gitignore",
26 "package.json",
27 "astro.config.mjs",
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 "Astro SSR: GET / and a dynamic API route",
45 (stack) =>
46 Effect.gen(function* () {
47 yield* stack.destroy();
48
49 const rootDir = yield* cloneFixture(fixtureDir, {
50 prefix: "alchemy-astro-fly-",
51 tempRoot,
52 entries: fixtureEntries,
53 });
54
55 const deployed = yield* stack.deploy(
56 Effect.gen(function* () {
57 const site = yield* Fly.Website.Astro("Web", {
58 rootDir,
59 memo: {
60 include: [
61 "src/**",
62 "public/**",
63 "package.json",
64 "astro.config.mjs",
65 ],
66 },
67 });
68 return { site };
69 }),
70 );
71
72 const url = deployed.site.url;
73 expect(url).toBeDefined();
74 expect(url).toMatch(/^https:\/\//);
75 expect(deployed.site.service).toBeDefined();
76 expect(deployed.site.app).toBeDefined();
77
78 yield* expectUrlContains(`${url!}/`, "ASTRO_AWS_PAGE_MARKER", {
79 timeout: "90 seconds",
80 label: "astro ssr home",
81 });
82 yield* expectUrlContains(
83 `${url!}/api/hello?echo=roundtrip`,
84 "ASTRO_AWS_API_MARKER",
85 {
86 timeout: "30 seconds",
87 label: "astro api route",
88 },
89 );
90
91 const appName = deployed.site.app!.appName;
92 yield* stack.destroy();
93 const gone = yield* waitUntilGone(appName);
94 expect(gone).toEqual("gone");
95 }).pipe(logLevel),
96 {
97 tags: [
98 "provider:fly",
99 "provider:fly:machine",
100 "provider:fly:website",
101 "live",
102 ],
103 timeout: 240_000,
104 },
105);