1import * as Provider from "@/Provider";
2import * as Stripe from "@/Stripe";
3import * as Test from "@/Test/Alchemy";
4import { GetPaymentMethodConfiguration } from "@distilled.cloud/stripe/stripe";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import { MinimumLogLevel } from "effect/References";
8import * as Schedule from "effect/Schedule";
9import { isMissingStripeResource } from "@/Stripe/missing.ts";
10
11const { test } = Test.make({ providers: Stripe.providers() });
12
13const logLevel = Effect.provideService(
14 MinimumLogLevel,
15 process.env.DEBUG ? "Debug" : "Info",
16);
17
18const isMissing = isMissingStripeResource;
19
20const waitUntilInactive = (id: string) =>
21 GetPaymentMethodConfiguration({ configuration: id }).pipe(
22 Effect.map((configuration) =>
23 configuration.active ? ("active" as const) : ("inactive" as const),
24 ),
25 Effect.catchIf(isMissing, () => Effect.succeed("inactive" as const)),
26 Effect.repeat({
27 schedule: Schedule.spaced("1 second"),
28 until: (status) => status === "inactive",
29 times: 10,
30 }),
31 );
32
33test.provider(
34 "create, update, and deactivate a payment method configuration",
35 (stack) =>
36 Effect.gen(function* () {
37 yield* stack.destroy();
38
39 const created = yield* stack.deploy(
40 Effect.gen(function* () {
41 return yield* Stripe.PaymentMethodConfiguration("Checkout", {
42 name: "Alchemy Checkout PMC",
43 card: { displayPreference: { preference: "on" } },
44 link: { displayPreference: { preference: "off" } },
45 });
46 }),
47 );
48
49 expect(created.id).toMatch(/^pmc_/);
50 expect(created.name).toEqual("Alchemy Checkout PMC");
51 expect(created.active).toEqual(true);
52 expect(created.isDefault).toEqual(false);
53 expect(created.card?.displayPreference.preference).toEqual("on");
54 expect(created.link?.displayPreference.preference).toEqual("off");
55 expect(created.livemode).toEqual(false);
56
57 const fetched = yield* GetPaymentMethodConfiguration({
58 configuration: created.id,
59 });
60 expect(fetched.id).toEqual(created.id);
61 expect(fetched.name).toEqual("Alchemy Checkout PMC");
62 expect(fetched.active).toEqual(true);
63 expect(fetched.is_default).toEqual(false);
64 expect(fetched.card?.display_preference.preference).toEqual("on");
65 expect(fetched.link?.display_preference.preference).toEqual("off");
66
67 const updated = yield* stack.deploy(
68 Effect.gen(function* () {
69 return yield* Stripe.PaymentMethodConfiguration("Checkout", {
70 name: "Alchemy Checkout PMC Updated",
71 card: { displayPreference: { preference: "on" } },
72 link: { displayPreference: { preference: "on" } },
73 });
74 }),
75 );
76
77 expect(updated.id).toEqual(created.id);
78 expect(updated.name).toEqual("Alchemy Checkout PMC Updated");
79 expect(updated.active).toEqual(true);
80 expect(updated.isDefault).toEqual(false);
81 expect(updated.card?.displayPreference.preference).toEqual("on");
82 expect(updated.link?.displayPreference.preference).toEqual("on");
83
84 const refetched = yield* GetPaymentMethodConfiguration({
85 configuration: updated.id,
86 });
87 expect(refetched.id).toEqual(updated.id);
88 expect(refetched.name).toEqual("Alchemy Checkout PMC Updated");
89 expect(refetched.card?.display_preference.preference).toEqual("on");
90 expect(refetched.link?.display_preference.preference).toEqual("on");
91 expect(refetched.active).toEqual(true);
92
93 yield* stack.destroy();
94
95 const inactive = yield* waitUntilInactive(created.id);
96 expect(inactive).toEqual("inactive");
97 const deactivated = yield* GetPaymentMethodConfiguration({
98 configuration: created.id,
99 });
100 expect(deactivated.active).toEqual(false);
101 }).pipe(logLevel),
102 {
103 tags: [
104 "provider:stripe",
105 "provider:stripe:paymentmethodconfiguration",
106 "live",
107 ],
108 timeout: 120_000,
109 },
110);
111
112test.provider(
113 "list enumerates the deployed payment method configuration",
114 (stack) =>
115 Effect.gen(function* () {
116 yield* stack.destroy();
117
118 const deployed = yield* stack.deploy(
119 Effect.gen(function* () {
120 return yield* Stripe.PaymentMethodConfiguration("ListCheckout", {
121 name: "Alchemy List PMC",
122 card: { displayPreference: { preference: "on" } },
123 });
124 }),
125 );
126
127 const provider = yield* Provider.findProvider(
128 Stripe.PaymentMethodConfiguration,
129 );
130 const all = yield* provider.list();
131 const found = all.find(
132 (configuration) => configuration.id === deployed.id,
133 );
134 expect(found).toBeDefined();
135 expect(found?.name).toEqual(deployed.name);
136 expect(found?.isDefault).toEqual(false);
137 expect(found?.card?.displayPreference.preference).toEqual("on");
138
139 yield* stack.destroy();
140
141 const inactive = yield* waitUntilInactive(deployed.id);
142 expect(inactive).toEqual("inactive");
143
144 const after = yield* provider.list();
145 expect(
146 after.find((configuration) => configuration.id === deployed.id),
147 ).toBeUndefined();
148 }).pipe(logLevel),
149 {
150 tags: [
151 "provider:stripe",
152 "provider:stripe:paymentmethodconfiguration",
153 "live",
154 ],
155 timeout: 120_000,
156 },
157);