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/solidstart-app",
22);
23const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
24const fixtureEntries = [
25 ".gitignore",
26 "package.json",
27 "vite.config.ts",
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 "SolidStart: deploy, GET /, destroy, gone",
45 (stack) =>
46 Effect.gen(function* () {
47 yield* stack.destroy();
48
49 const rootDir = yield* cloneFixture(fixtureDir, {
50 prefix: "alchemy-solidstart-fly-",
51 tempRoot,
52 entries: fixtureEntries,
53 });
54
55 const deployed = yield* stack.deploy(
56 Effect.gen(function* () {
57 const site = yield* Fly.Website.SolidStart("Web", {
58 rootDir,
59 memo: {
60 include: [
61 "src/**",
62 "public/**",
63 "package.json",
64 "vite.config.ts",
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!}/health`, "ok", {
79 timeout: "60 seconds",
80 label: "health",
81 });
82 yield* expectUrlContains(`${url!}/`, "SOLIDSTART_AWS_PAGE_MARKER", {
83 timeout: "180 seconds",
84 label: "home page",
85 });
86 yield* expectUrlContains(
87 `${url!}/api/hello?echo=roundtrip`,
88 "SOLIDSTART_AWS_API_MARKER",
89 {
90 timeout: "30 seconds",
91 label: "api route",
92 },
93 );
94
95 const appName = deployed.site.app!.appName;
96 yield* stack.destroy();
97 const gone = yield* waitUntilGone(appName);
98 expect(gone).toEqual("gone");
99 }).pipe(logLevel),
100 {
101 tags: [
102 "provider:fly",
103 "provider:fly:machine",
104 "provider:fly:website",
105 "live",
106 ],
107 timeout: 360000,
108 },
109);