diff --git a/app/controllers/alaveteli_pro/subscriptions_controller.rb b/app/controllers/alaveteli_pro/subscriptions_controller.rb index 2334b1beae..60ca0d743f 100644 --- a/app/controllers/alaveteli_pro/subscriptions_controller.rb +++ b/app/controllers/alaveteli_pro/subscriptions_controller.rb @@ -11,12 +11,6 @@ class AlaveteliPro::SubscriptionsController < AlaveteliPro::BaseController def index @customer = current_user.pro_account.try(:stripe_customer) @subscriptions = current_user.pro_account.subscriptions - - if @customer.default_source - @card = - @customer. - sources.select { |card| card.id == @customer.default_source }.first - end end # TODO: remove reminder of Stripe params once shipped diff --git a/app/models/alaveteli_pro/customer.rb b/app/models/alaveteli_pro/customer.rb new file mode 100644 index 0000000000..cd9ef2decc --- /dev/null +++ b/app/models/alaveteli_pro/customer.rb @@ -0,0 +1,12 @@ +## +# A wrapper for a Stripe::Customer +# +class AlaveteliPro::Customer < SimpleDelegator + def self.retrieve(id) + new(Stripe::Customer.retrieve(id)) + end + + def default_source + @default_source ||= sources.find { |c| c.id == __getobj__.default_source } + end +end diff --git a/app/models/pro_account.rb b/app/models/pro_account.rb index b12fae425c..81494ccd5b 100644 --- a/app/models/pro_account.rb +++ b/app/models/pro_account.rb @@ -72,9 +72,6 @@ def update_stripe_customer def stripe_customer! return unless stripe_customer_id - Stripe::Customer.retrieve( - id: stripe_customer_id, - expand: ['subscriptions.data.plan.product'] - ) + AlaveteliPro::Customer.retrieve(stripe_customer_id) end end diff --git a/app/views/alaveteli_pro/subscriptions/index.html.erb b/app/views/alaveteli_pro/subscriptions/index.html.erb index 21a382f72c..ae0614b813 100644 --- a/app/views/alaveteli_pro/subscriptions/index.html.erb +++ b/app/views/alaveteli_pro/subscriptions/index.html.erb @@ -36,7 +36,7 @@

<%= _('Your payment details') %>

<% if @customer.default_source %> - <%= render partial: 'card', locals: { card: @card } %> + <%= render partial: 'card', locals: { card: @customer.default_source } %> <% else %> <%= render partial: 'add_card' %> <% end %> diff --git a/spec/controllers/alaveteli_pro/subscriptions_controller_spec.rb b/spec/controllers/alaveteli_pro/subscriptions_controller_spec.rb index dad74b45bb..47cd0c38a7 100644 --- a/spec/controllers/alaveteli_pro/subscriptions_controller_spec.rb +++ b/spec/controllers/alaveteli_pro/subscriptions_controller_spec.rb @@ -772,11 +772,6 @@ expect(assigns[:subscriptions].first.id). to eq(customer.subscriptions.first.id) end - - it 'assigns the default source as card' do - get :index - expect(assigns[:card].id).to eq(customer.default_source) - end end end diff --git a/spec/models/alaveteli_pro/customer_spec.rb b/spec/models/alaveteli_pro/customer_spec.rb new file mode 100644 index 0000000000..669787c2a7 --- /dev/null +++ b/spec/models/alaveteli_pro/customer_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' +require 'stripe_mock' + +RSpec.describe AlaveteliPro::Customer do + describe '.retrieve' do + it 'returns a new customer instance when successful' do + stripe_customer = double('Stripe::Customer') + allow(Stripe::Customer).to receive(:retrieve).with('cus_123'). + and_return(stripe_customer) + + customer = described_class.retrieve('cus_123') + expect(customer).to be_an_instance_of(described_class) + expect(customer).to eq(stripe_customer) + end + + it 'raises Stripe::InvalidRequestError when customer does not exist' do + StripeMock.start + + error = Stripe::InvalidRequestError.new('', '') + StripeMock.prepare_error(error) + + expect { described_class.retrieve('cus_123') }.to raise_error( + Stripe::InvalidRequestError + ) + + StripeMock.stop + end + end + + describe '#default_source' do + let(:stripe_customer) do + double('Stripe::Customer', default_source: 'card_123') + end + + let(:customer) { described_class.new(stripe_customer) } + + it 'returns the default source from the customer sources' do + source1 = double('Stripe::Card', id: 'card_123') + source2 = double('Stripe::Card', id: 'card_456') + allow(customer).to receive(:sources).and_return([source1, source2]) + + expect(customer.default_source).to eq(source1) + end + + it 'memoizes the default source' do + source = double('Stripe::Card', id: 'card_123') + expect(customer).to receive(:sources).once.and_return([source]) + 2.times { expect(customer.default_source) } + end + end +end