discourse-subscriptions/spec/requests/user/subscriptions_controller_spec.rb
Blake Erickson 100b276c9d
DEV: Add pagination to plans request (#272)
When pulling up a users subscriptions a 500 might occur if we don't find
their plan. If your account happens to have over 100 plans this can be
the cause of the 500 error. This change adds pagination when fetching
plans form stripe, so that we fetch them all.

https://meta.discourse.org/t/problem-with-500-error-with-subscriptions/360808?u=blake
2025-04-10 07:35:31 -06:00

138 lines
4.3 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
RSpec.describe DiscourseSubscriptions::User::SubscriptionsController do
before { SiteSetting.discourse_subscriptions_enabled = true }
def create_price(id, product)
price = { id: id, product: product }
def price.id
self[:id]
end
price
end
it "is a subclass of ApplicationController" do
expect(DiscourseSubscriptions::User::SubscriptionsController < ::ApplicationController).to eq(
true,
)
end
context "when not authenticated" do
it "does not get the subscriptions" do
::Stripe::Customer.expects(:list).never
get "/s/user/subscriptions.json"
end
it "does not destroy a subscription" do
::Stripe::Subscription.expects(:delete).never
patch "/s/user/subscriptions/sub_12345.json"
end
it "doesn't update payment method for subscription" do
::Stripe::Subscription.expects(:update).never
::Stripe::PaymentMethod.expects(:attach).never
put "/s/user/subscriptions/sub_12345.json", params: { payment_method: "pm_abc123abc" }
end
end
context "when authenticated" do
let(:user) { Fabricate(:user, email: "beanie@example.com") }
let(:customer) do
Fabricate(:customer, user_id: user.id, customer_id: "cus_23456", product_id: "prod_123")
end
before do
sign_in(user)
Fabricate(:subscription, customer_id: customer.id, external_id: "sub_10z")
end
describe "index" do
plans_json =
File.read(
Rails.root.join(
"plugins",
"discourse-subscriptions",
"spec",
"fixtures",
"json",
"stripe-price-list.json",
),
)
it "gets subscriptions" do
::Stripe::Price.stubs(:list).returns(JSON.parse(plans_json, symbolize_names: true))
subscriptions_json =
File.read(
Rails.root.join(
"plugins",
"discourse-subscriptions",
"spec",
"fixtures",
"json",
"stripe-subscription-list.json",
),
)
::Stripe::Subscription.stubs(:list).returns(
JSON.parse(subscriptions_json, symbolize_names: true),
)
get "/s/user/subscriptions.json"
subscription = JSON.parse(response.body, symbolize_names: true).first
expect(subscription[:id]).to eq("sub_10z")
expect(subscription[:items][:data][0][:plan][:id]).to eq("price_1OrmlvEYXaQnncShNahrpKvA")
expect(subscription[:product][:name]).to eq("Exclusive Access")
end
it "aggregates prices from multiple pages using pagination logic" do
subscription_data = { id: "sub_10z", items: { data: [{ price: { id: "price_200" } }] } }
::Stripe::Subscription
.stubs(:list)
.with(customer: "cus_23456", status: "all")
.returns({ data: [subscription_data] })
# Build the first page of 100 prices that do NOT include the desired price.
prices_page_1 =
(1..100).map do |i|
create_price("price_#{i}", { id: "prod_dummy", name: "Dummy Product #{i}" })
end
# Second page containing the desired price.
prices_page_2 = [create_price("price_200", { id: "prod_200", name: "Matching Product" })]
::Stripe::Price
.expects(:list)
.with(has_entries(limit: 100, expand: ["data.product"]))
.returns({ data: prices_page_1, has_more: true })
::Stripe::Price
.expects(:list)
.with(has_entries(limit: 100, expand: ["data.product"], starting_after: "price_100"))
.returns({ data: prices_page_2, has_more: false })
get "/s/user/subscriptions.json"
result = JSON.parse(response.body, symbolize_names: true)
subscription = result.first
expect(subscription[:id]).to eq("sub_10z")
expect(subscription[:plan][:id]).to eq("price_200")
expect(subscription[:product][:id]).to eq("prod_200")
expect(subscription[:product][:name]).to eq("Matching Product")
end
end
describe "update" do
it "updates the payment method for subscription" do
::Stripe::Subscription.expects(:update).once
::Stripe::PaymentMethod.expects(:attach).once
put "/s/user/subscriptions/sub_10z.json", params: { payment_method: "pm_abc123abc" }
end
end
end
end