1import * as Cloudflare from "@/Cloudflare";
2import { CloudflareEnvironment } from "@/Cloudflare/CloudflareEnvironment";
3import * as Provider from "@/Provider";
4import * as Test from "@/Test/Alchemy";
5import * as emailSecurity from "@distilled.cloud/cloudflare/email-security";
6import { expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8import { MinimumLogLevel } from "effect/References";
9import * as Schedule from "effect/Schedule";
10import * as Stream from "effect/Stream";
11
12const { test } = Test.make({ providers: Cloudflare.providers() });
13
14const logLevel = Effect.provideService(
15 MinimumLogLevel,
16 process.env.DEBUG ? "Debug" : "Info",
17);
18
19// Email Security (Area 1) is an enterprise add-on — the standard testing
20// account is not entitled (typed `EmailSecurityNotEntitled`), so the
21// lifecycle test is gated behind an entitled account flagged via env.
22const entitled = !!process.env.CLOUDFLARE_EMAIL_SECURITY;
23
24const forbiddenRetrySchedule = Schedule.exponential("500 millis");
25
26const pattern = "alchemy-trusted.alchemy-test-2.us";
27
28const findByPattern = (accountId: string) =>
29 emailSecurity.listSettingTrustedDomains.items({ accountId, pattern }).pipe(
30 Stream.runCollect,
31 Effect.map((chunk) => Array.from(chunk).find((p) => p.pattern === pattern)),
32 Effect.retry({
33 while: (e) => e._tag === "Forbidden",
34 schedule: forbiddenRetrySchedule,
35 times: 8,
36 }),
37 );
38
39test.provider.skipIf(!entitled)(
40 "create, update in place, destroy",
41 (stack) =>
42 Effect.gen(function* () {
43 const { accountId } = yield* yield* CloudflareEnvironment;
44
45 yield* stack.destroy();
46
47 // Trust a lookalike partner domain.
48 const created = yield* stack.deploy(
49 Effect.gen(function* () {
50 return yield* Cloudflare.Email.TrustedDomain("Trusted", {
51 pattern,
52 isSimilarity: true,
53 comments: "v1",
54 });
55 }),
56 );
57 expect(created.trustedDomainId).toBeDefined();
58 expect(created.accountId).toEqual(accountId);
59 expect(created.pattern).toEqual(pattern);
60 expect(created.isSimilarity).toEqual(true);
61 expect(created.isRecent).toEqual(false);
62 expect(created.isRegex).toEqual(false);
63 expect(created.comments).toEqual("v1");
64
65 // Out-of-band verification via the distilled API.
66 const live = yield* findByPattern(accountId);
67 expect(live?.id).toEqual(created.trustedDomainId);
68
69 // Update mutable fields in place — same physical entry.
70 const updated = yield* stack.deploy(
71 Effect.gen(function* () {
72 return yield* Cloudflare.Email.TrustedDomain("Trusted", {
73 pattern,
74 isSimilarity: true,
75 isRecent: true,
76 comments: "v2",
77 });
78 }),
79 );
80 expect(updated.trustedDomainId).toEqual(created.trustedDomainId);
81 expect(updated.isRecent).toEqual(true);
82 expect(updated.comments).toEqual("v2");
83
84 yield* stack.destroy();
85
86 // The entry is gone after destroy.
87 const gone = yield* findByPattern(accountId).pipe(
88 Effect.repeat({
89 schedule: Schedule.spaced("2 seconds"),
90 until: (p) => p === undefined,
91 times: 10,
92 }),
93 );
94 expect(gone).toBeUndefined();
95 }).pipe(logLevel),
96 {
97 tags: ["provider:cloudflare", "provider:cloudflare:email", "live"],
98 timeout: 120_000,
99 },
100);
101
102// `list()` enumerates the account's trusted domains. On the standard testing
103// account (not entitled) the typed `EmailSecurityNotEntitled` error is caught
104// and the result is an empty array — so this assertion is meaningful without
105// the add-on. On an entitled account it also asserts the deployed entry is
106// present.
107test.provider(
108 "list enumerates trusted domains",
109 (stack) =>
110 Effect.gen(function* () {
111 yield* stack.destroy();
112
113 const provider = yield* Provider.findProvider(
114 Cloudflare.Email.TrustedDomain,
115 );
116
117 if (!entitled) {
118 // Unentitled account: typed entitlement error -> [].
119 const all = yield* provider.list();
120 expect(all).toEqual([]);
121 return;
122 }
123
124 const deployed = yield* stack.deploy(
125 Effect.gen(function* () {
126 return yield* Cloudflare.Email.TrustedDomain("ListTrusted", {
127 pattern,
128 isSimilarity: true,
129 });
130 }),
131 );
132
133 const all = yield* provider.list();
134 expect(
135 all.some((x) => x.trustedDomainId === deployed.trustedDomainId),
136 ).toBe(true);
137
138 yield* stack.destroy();
139 }).pipe(logLevel),
140 {
141 tags: ["provider:cloudflare", "provider:cloudflare:email", "live"],
142 timeout: 120_000,
143 },
144);