1import * as Cloudflare from "alchemy/Cloudflare";
2import * as Test from "alchemy/Test/Bun";
3import { expect } from "bun:test";
4import * as Console from "effect/Console";
5import * as Effect from "effect/Effect";
6import * as HttpClientRequest from "effect/http/HttpClientRequest";
7import Stack from "../alchemy.run.ts";
8
9const { getWhenReady } = Test;
10
11const { test, beforeAll, afterAll, deploy, destroy } = Test.make({
12 providers: Cloudflare.providers(),
13 state: Cloudflare.state(),
14});
15
16const stack = beforeAll(deploy(Stack).pipe(Effect.tap(Console.log)), {
17 timeout: 600_000,
18});
19afterAll.skipIf(!!process.env.NO_DESTROY)(destroy(Stack));
20
21const base = Effect.map(stack, ({ url }) => {
22 if (!url) throw new Error("expected the site to expose a workers.dev url");
23 return url.replace(/\/+$/, "");
24});
25
26test(
27 "deploys and exposes a url",
28 Effect.gen(function* () {
29 const { url } = yield* stack;
30 expect(url).toBeString();
31 }),
32 { timeout: 180_000 },
33);
34
35test(
36 "serves documentation pages",
37 Effect.gen(function* () {
38 const url = yield* base;
39 for (const [pathname, content] of [
40 ["/", "Alchemy with Vocs"],
41 ["/guide", "Deployment guide"],
42 ["/counter", "Interactive component"],
43 ] as const) {
44 const response = yield* Test.executeWhenReady(
45 HttpClientRequest.get(`${url}${pathname}`, {
46 headers: { accept: "text/html", "user-agent": "Mozilla/5.0" },
47 }),
48 );
49 expect(response.status).toBe(200);
50 expect(response.headers["content-type"]).toContain("text/html");
51 expect(yield* response.text).toContain(content);
52 }
53 }),
54 { timeout: 180_000 },
55);
56
57test(
58 "serves public and generated assets",
59 Effect.gen(function* () {
60 const url = yield* base;
61 const asset = yield* getWhenReady(`${url}/hello.txt`);
62 expect(asset.status).toBe(200);
63 expect(yield* asset.text).toContain("Vocs public directory");
64
65 const llms = yield* getWhenReady(`${url}/llms.txt`);
66 expect(llms.status).toBe(200);
67 expect(yield* llms.text).toContain("Alchemy with Vocs");
68 }),
69 { timeout: 180_000 },
70);