Intermediate TDD in Rails : Save Subscription Details

Objective


To save subscription details in the database.

Steps


Step 1

We can now write a test for save_details method in subscription in specs/models/subscription_spec.rb.

  it 'should save the stripe subscription details' do
    h = JSON.parse(File.read("spec/fixtures/customer.json"))
    stripe_customer = Stripe::Customer.construct_from(h)    
    user = User.create(email: 'bugs@rubyplus.com', password: '12345678', password_confirmation: '12345678')
    plan_name = 'gold'

    expect do
      Subscription.save_details(stripe_customer, user, plan_name)
    end.to change(Subscription, :count).by (1)

  end

Step 2

Run the test.

$rspec spec/models/subscription_spec.rb 

It fails.

Step 3

Let's implement the method:

  def self.save_details(stripe_customer, user, plan_name)
    mapper = StripeCustomerMapper.new(stripe_customer)
    user.create_subscription(stripe_customer_token: stripe_customer.id,
                             plan_name:             plan_name,
                             last4digits:      mapper.credit_card_last4digits,
                             expiration_month: mapper.credit_card_expiration_month,
                             expiration_year:  mapper.credit_card_expiration_year)
  end

Step 4

It fails with:

undefined method `create_subscription' for #<User:0x007ffb8110a958>

We forgot to declare:

has_one :subscription 

in the user.rb. Add it now and run the test again. It passes.

Step 5

We need to make our subscription model immune to any changes due to Stripe API. Let's move the knowledge of extracting the stripe_customer_token to the mapper class. Add the following test to stripe_customer_mapper_spec.rb:

  it 'should map the stripe customer token' do
    h = JSON.parse(File.read("spec/fixtures/customer.json"))
    customer = Stripe::Customer.construct_from(h)    

    mapper = StripeCustomerMapper.new(customer)

    expect(mapper.customer_token).to eq('cus_5tDSlyr30eqCTa')    
  end
$rspec spec/models/stripe_customer_mapper_spec.rb

It fails. Let's implement the method.

Step 6

  def customer_token
    @customer.id
  end

The test now passes.

Step 7

Let's now cleanup the subscription model as follows:

class Subscription < ActiveRecord::Base
  belongs_to :user  

  def self.save_details(stripe_customer, user, plan_name)
    mapper = StripeCustomerMapper.new(stripe_customer)
    user.create_subscription(stripe_customer_token: mapper.customer_token,
                             plan_name:             plan_name,
                             last4digits:      mapper.credit_card_last4digits,
                             expiration_month: mapper.credit_card_expiration_month,
                             expiration_year:  mapper.credit_card_expiration_year)
  end
end

Run the test.

$rspec spec/models/subscription_spec.rb 

It passes.

Summary


In this lesson, we saved the subscription details in our database.


Related Articles


Create your own user feedback survey