tarakan/test/support/stripe_stub.ex
Maxfield Luke af6077b9c3
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s
Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
2026-07-29 04:43:40 -04:00

83 lines
2.5 KiB
Elixir

defmodule Tarakan.Billing.StripeStub do
@moduledoc """
Test double for `Tarakan.Billing.Stripe`.
Serves deterministic default responses for the endpoints the market flow
uses. Tests can override behaviour per process:
Tarakan.Billing.StripeStub.respond_with({:error, :card_declined})
Tarakan.Billing.StripeStub.respond_with(fn :post, "/v1/refunds", _body -> ... end)
Tarakan.Billing.StripeStub.reset()
"""
@behaviour Tarakan.Billing.Stripe
@impl true
def request(method, path, body_or_params \\ nil) do
case Process.get(:stripe_stub_response) do
nil -> default_response(method, path, body_or_params)
fun when is_function(fun, 3) -> fun.(method, path, body_or_params)
response -> response
end
end
@doc "Overrides the stubbed response for the current test process."
def respond_with(response_or_fun), do: Process.put(:stripe_stub_response, response_or_fun)
@doc "Restores the default responses for the current test process."
def reset, do: Process.delete(:stripe_stub_response)
defp default_response(:post, "/v1/checkout/sessions", _body) do
id = "cs_test_#{System.unique_integer([:positive])}"
{:ok,
%{
"id" => id,
"url" => "https://checkout.stripe.com/c/pay/#{id}",
"payment_intent" => "pi_#{id}",
"status" => "open"
}}
end
defp default_response(:get, "/v1/checkout/sessions/" <> id, _params) do
{:ok, %{"id" => id, "payment_intent" => "pi_#{id}", "status" => "complete"}}
end
defp default_response(:post, "/v1/refunds", body) do
payment_intent = body[:payment_intent] || body["payment_intent"]
{:ok,
%{
"id" => "re_test_#{System.unique_integer([:positive])}",
"payment_intent" => payment_intent,
"status" => "succeeded"
}}
end
defp default_response(:post, "/v1/billing_portal/sessions", body) do
customer =
case body do
map when is_map(map) ->
map[:customer] || map["customer"]
list when is_list(list) ->
Enum.find_value(list, fn
{:customer, value} -> value
{"customer", value} -> value
_other -> nil
end)
_other ->
nil
end
{:ok,
%{
"id" => "bps_test_#{System.unique_integer([:positive])}",
"customer" => customer,
"url" => "https://billing.stripe.com/p/session/test_#{System.unique_integer([:positive])}"
}}
end
defp default_response(_method, _path, _body), do: {:error, :unexpected_request}
end