1import * as Cloudflare from "@/Cloudflare";
2import { CloudflareEnvironment } from "@/Cloudflare/CloudflareEnvironment";
3import * as Provider from "@/Provider";
4import * as Test from "@/Test/Alchemy";
5import * as magicTransit from "@distilled.cloud/cloudflare/magic-transit";
6import { expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8import { MinimumLogLevel } from "effect/References";
9
10const { test } = Test.make({ providers: Cloudflare.providers() });
11
12const logLevel = Effect.provideService(
13 MinimumLogLevel,
14 process.env.DEBUG ? "Debug" : "Info",
15);
16
17// Magic WAN sites (and their LANs) are entitlement-gated. On the standard
18// testing account every Magic Transit call fails with the typed
19// `MagicWanUnauthorized` error (Cloudflare code 1025) or `Forbidden` (403)
20// depending on token scope. `list()` catches `MagicWanUnauthorized` and
21// returns `[]`, so the read-only list assertion below always runs; the live
22// deploy+enumerate case is gated behind an explicit opt-in env flag for
23// entitled accounts.
24const entitled = !!process.env.CLOUDFLARE_TEST_MAGIC_WAN;
25
26test.provider(
27 "list returns a well-typed array (empty on unentitled accounts)",
28 (stack) =>
29 Effect.gen(function* () {
30 yield* stack.destroy();
31
32 const provider = yield* Provider.findProvider(
33 Cloudflare.MagicTransit.MagicSiteLan,
34 );
35 const all = yield* provider.list();
36
37 // Either the exhaustively-paginated LANs (entitled) or [] (unentitled).
38 expect(Array.isArray(all)).toBe(true);
39
40 yield* stack.destroy();
41 }).pipe(logLevel),
42 {
43 tags: ["provider:cloudflare", "provider:cloudflare:magictransit", "live"],
44 timeout: 120_000,
45 },
46);
47
48test.provider.skipIf(!entitled)(
49 "list enumerates the deployed Magic WAN site LANs",
50 (stack) =>
51 Effect.gen(function* () {
52 const { accountId } = yield* yield* CloudflareEnvironment;
53
54 yield* stack.destroy();
55
56 const deployed = yield* stack.deploy(
57 Effect.gen(function* () {
58 const site = yield* Cloudflare.MagicTransit.MagicSite("Site", {
59 name: "alchemy-magic-site-lanlist",
60 description: "alchemy magic site list test",
61 });
62 const lan = yield* Cloudflare.MagicTransit.MagicSiteLan("ListLan", {
63 siteId: site.siteId,
64 physport: 2,
65 name: "alchemy-site-lan-list",
66 vlanTag: 30,
67 staticAddressing: { address: "192.168.30.1/24" },
68 });
69 return { site, lan };
70 }),
71 );
72
73 expect(deployed.lan.lanId).toBeTruthy();
74
75 const provider = yield* Provider.findProvider(
76 Cloudflare.MagicTransit.MagicSiteLan,
77 );
78 const all = yield* provider.list();
79
80 // The deployed LAN is present in the exhaustively-paginated result,
81 // hydrated into the same Attributes shape `read` produces.
82 const found = all.find((l) => l.lanId === deployed.lan.lanId);
83 expect(found).toBeDefined();
84 expect(found?.siteId).toEqual(deployed.site.siteId);
85 expect(found?.accountId).toEqual(accountId);
86 expect(found?.name).toEqual("alchemy-site-lan-list");
87
88 yield* stack.destroy();
89 }).pipe(logLevel),
90 {
91 tags: ["provider:cloudflare", "provider:cloudflare:magictransit", "live"],
92 timeout: 180_000,
93 },
94);