1import * as Provider from "@/Provider";
2import * as Stripe from "@/Stripe";
3import * as Test from "@/Test/Alchemy";
4import {
5 GetRadarValueListItem,
6 GetRadarValueLists,
7} from "@distilled.cloud/stripe/stripe";
8import { expect } from "alchemy-test";
9import * as Effect from "effect/Effect";
10import { MinimumLogLevel } from "effect/References";
11import * as Result from "effect/Result";
12import * as Schedule from "effect/Schedule";
13import { isMissingStripeResource } from "@/Stripe/missing.ts";
14
15const { test } = Test.make({ providers: Stripe.providers() });
16
17const logLevel = Effect.provideService(
18 MinimumLogLevel,
19 process.env.DEBUG ? "Debug" : "Info",
20);
21
22const isMissing = isMissingStripeResource;
23
24const waitUntilGone = (id: string) =>
25 GetRadarValueListItem({ item: id }).pipe(
26 Effect.as("found" as const),
27 Effect.catchIf(isMissing, () => Effect.succeed("gone" as const)),
28 Effect.repeat({
29 schedule: Schedule.spaced("1 second"),
30 until: (status) => status === "gone",
31 times: 10,
32 }),
33 );
34
35test.provider(
36 "radar value lists entitlement probe",
37 (stack) =>
38 Effect.gen(function* () {
39 yield* stack.destroy();
40
41 const result = yield* GetRadarValueLists({ limit: 1 }).pipe(
42 Effect.result,
43 );
44
45 if (Result.isSuccess(result)) {
46 expect(Array.isArray(result.success.data)).toBe(true);
47 } else {
48 expect(["InvalidRequestError", "Forbidden", "Unauthorized"]).toContain(
49 result.failure._tag,
50 );
51 }
52
53 yield* stack.destroy();
54 }).pipe(logLevel),
55 {
56 tags: [
57 "provider:stripe",
58 "provider:stripe:radarvaluelist",
59 "provider:stripe:radarvaluelistitem",
60 "live",
61 ],
62 timeout: 60_000,
63 },
64);
65
66test.provider(
67 "create, update, and delete a radar value list item",
68 (stack) =>
69 Effect.gen(function* () {
70 yield* stack.destroy();
71
72 const created = yield* stack.deploy(
73 Effect.gen(function* () {
74 const list = yield* Stripe.RadarValueList("ItemLifecycleList", {
75 name: "Alchemy Radar Value List Item Lifecycle",
76 itemType: "email",
77 });
78 const item = yield* Stripe.RadarValueListItem("BlockedEmail", {
79 valueList: list.id,
80 value: "blocked@example.com",
81 });
82 return { list, item };
83 }),
84 );
85
86 expect(created.item.id).toMatch(/^rsli_/);
87 expect(created.item.valueList).toEqual(created.list.id);
88 expect(created.item.value).toEqual("blocked@example.com");
89 expect(created.item.livemode).toEqual(false);
90 expect(created.item.created).toEqual(expect.any(Number));
91 expect(created.item.createdBy).toEqual(expect.any(String));
92
93 const fetched = yield* GetRadarValueListItem({
94 item: created.item.id,
95 });
96 expect(fetched.id).toEqual(created.item.id);
97 expect(fetched.value_list).toEqual(created.list.id);
98 expect(fetched.value).toEqual("blocked@example.com");
99 expect(fetched.livemode).toEqual(false);
100
101 const updated = yield* stack.deploy(
102 Effect.gen(function* () {
103 const list = yield* Stripe.RadarValueList("ItemLifecycleList", {
104 name: "Alchemy Radar Value List Item Lifecycle",
105 itemType: "email",
106 });
107 const item = yield* Stripe.RadarValueListItem("BlockedEmail", {
108 valueList: list.id,
109 value: "blocked@example.com",
110 });
111 return { list, item };
112 }),
113 );
114
115 expect(updated.item.id).toEqual(created.item.id);
116 expect(updated.item.valueList).toEqual(created.list.id);
117 expect(updated.item.value).toEqual("blocked@example.com");
118
119 yield* stack.destroy();
120
121 const gone = yield* waitUntilGone(created.item.id);
122 expect(gone).toEqual("gone");
123 }).pipe(logLevel),
124 {
125 tags: [
126 "provider:stripe",
127 "provider:stripe:radarvaluelist",
128 "provider:stripe:radarvaluelistitem",
129 "live",
130 ],
131 timeout: 120_000,
132 },
133);
134
135test.provider(
136 "list enumerates the deployed radar value list item",
137 (stack) =>
138 Effect.gen(function* () {
139 yield* stack.destroy();
140
141 const deployed = yield* stack.deploy(
142 Effect.gen(function* () {
143 const list = yield* Stripe.RadarValueList("ItemListList", {
144 name: "Alchemy Radar Value List Item List",
145 itemType: "email",
146 });
147 const item = yield* Stripe.RadarValueListItem("ListEmail", {
148 valueList: list.id,
149 value: "list@example.com",
150 });
151 return { list, item };
152 }),
153 );
154
155 const provider = yield* Provider.findProvider(Stripe.RadarValueListItem);
156 const all = yield* provider.list();
157 const found = all.find((item) => item.id === deployed.item.id);
158 expect(found).toBeDefined();
159 expect(found?.valueList).toEqual(deployed.list.id);
160 expect(found?.value).toEqual("list@example.com");
161
162 yield* stack.destroy();
163
164 const gone = yield* waitUntilGone(deployed.item.id);
165 expect(gone).toEqual("gone");
166
167 const after = yield* provider.list();
168 expect(
169 after.find((item) => item.id === deployed.item.id),
170 ).toBeUndefined();
171 }).pipe(logLevel),
172 {
173 tags: [
174 "provider:stripe",
175 "provider:stripe:radarvaluelist",
176 "provider:stripe:radarvaluelistitem",
177 "live",
178 ],
179 timeout: 120_000,
180 },
181);
182
183test.provider(
184 "replace when the item value changes",
185 (stack) =>
186 Effect.gen(function* () {
187 yield* stack.destroy();
188
189 const created = yield* stack.deploy(
190 Effect.gen(function* () {
191 const list = yield* Stripe.RadarValueList("ItemReplaceList", {
192 name: "Alchemy Radar Value List Item Replace",
193 itemType: "email",
194 });
195 const item = yield* Stripe.RadarValueListItem("ReplaceEmail", {
196 valueList: list.id,
197 value: "first@example.com",
198 });
199 return { list, item };
200 }),
201 );
202
203 expect(created.item.value).toEqual("first@example.com");
204
205 const replaced = yield* stack.deploy(
206 Effect.gen(function* () {
207 const list = yield* Stripe.RadarValueList("ItemReplaceList", {
208 name: "Alchemy Radar Value List Item Replace",
209 itemType: "email",
210 });
211 const item = yield* Stripe.RadarValueListItem("ReplaceEmail", {
212 valueList: list.id,
213 value: "second@example.com",
214 });
215 return { list, item };
216 }),
217 );
218
219 expect(replaced.item.id).not.toEqual(created.item.id);
220 expect(replaced.item.valueList).toEqual(created.list.id);
221 expect(replaced.item.value).toEqual("second@example.com");
222
223 const newFetched = yield* GetRadarValueListItem({
224 item: replaced.item.id,
225 });
226 expect(newFetched.value).toEqual("second@example.com");
227
228 const oldGone = yield* waitUntilGone(created.item.id);
229 expect(oldGone).toEqual("gone");
230
231 yield* stack.destroy();
232
233 const gone = yield* waitUntilGone(replaced.item.id);
234 expect(gone).toEqual("gone");
235 }).pipe(logLevel),
236 {
237 tags: [
238 "provider:stripe",
239 "provider:stripe:radarvaluelist",
240 "provider:stripe:radarvaluelistitem",
241 "live",
242 ],
243 timeout: 120_000,
244 },
245);