1import * as Alchemy from "alchemy";
2import * as Neon from "alchemy/Neon";
3import * as Test from "alchemy/Test/Bun";
4import { expect } from "bun:test";
5import * as Console from "effect/Console";
6import * as Effect from "effect/Effect";
7import Stack from "../alchemy.run.ts";
8
9const { test, beforeAll, afterAll, deploy, destroy } = Test.make({
10 providers: Neon.providers(),
11 state: Alchemy.localState(),
12 profile: process.env.ALCHEMY_PROFILE,
13});
14
15const stack = beforeAll(
16 destroy(Stack).pipe(Effect.andThen(deploy(Stack)), Effect.tap(Console.log)),
17 {
18 timeout: 120_000,
19 },
20);
21afterAll.skipIf(!!process.env.NO_DESTROY)(destroy(Stack), { timeout: 120_000 });
22
23const base = Effect.map(stack, ({ url }) => {
24 if (!url) throw new Error("Expected a deployed website URL");
25 return String(url).replace(/\/+$/, "");
26});
27
28test(
29 "serves the rendered home page",
30 Effect.gen(function* () {
31 const url = yield* base;
32 const response = yield* Test.getWhenReady(url);
33 expect(response.status).toBe(200);
34 expect(yield* response.text).toContain("Hello from Astro on Neon!");
35 }),
36 { timeout: 120_000 },
37);
38
39test(
40 "serves a static asset without falling back to HTML",
41 Effect.gen(function* () {
42 const url = yield* base;
43 const response = yield* Test.getWhenReady(`${url}/example.json`);
44 expect(response.status).toBe(200);
45 expect(yield* response.json).toEqual({
46 framework: "Astro",
47 greeting: "Hello from Astro on Neon!",
48 });
49 }),
50 { timeout: 120_000 },
51);
52
53test(
54 "serves a request-dependent endpoint with runtime environment",
55 Effect.gen(function* () {
56 const url = yield* base;
57 for (const name of ["Neon", "Alchemy"]) {
58 const response = yield* Test.getWhenReady(
59 `${url}/api/hello?name=${name}`,
60 );
61 expect(response.status).toBe(200);
62 expect(yield* response.json).toEqual({
63 name,
64 greeting: "Hello from Astro on Neon!",
65 });
66 }
67 }),
68 { timeout: 120_000 },
69);
70
71test(
72 "serves the fully static Astro build and its assets",
73 Effect.gen(function* () {
74 const { staticUrl } = yield* stack;
75 if (!staticUrl) throw new Error("Expected the static Astro URL");
76 const url = String(staticUrl).replace(/\/+$/, "");
77 const response = yield* Test.getWhenReady(url);
78 expect(response.status).toBe(200);
79 expect(yield* response.text).toContain("Static Astro on Neon");
80 const asset = yield* Test.getWhenReady(`${url}/example.json`);
81 expect(asset.status).toBe(200);
82 expect(yield* asset.json).toHaveProperty("framework", "Astro");
83 }),
84 { timeout: 120_000 },
85);