Intermediate TDD in Rails : Subscribe to a Plan Feature Test

Objective


To implement subscribe to a plan feature.

Steps


Step 1

Add a feature spec:

  scenario "to a plan saves the subscription details" do
    expect do
      visit root_path

      click_link 'Register'
      fill_in 'Email', with: 'bugs2@rubyplus.com'
      fill_in 'Password', with: '12345678'    
      click_button 'Sign up'

      click_link 'Gold'
      fill_in "Card Number", with: '4242424242424242'
      page.select '10', from: "card_month"
      page.select '2029', from: 'card_year'
      click_button 'Subscribe Me'

    end.to change(Subscription, :count).by(1)
  end

Step 2

Run the test. The test fails with:

  SQLite3::BusyException: database is locked: commit transaction

SQLite does not allow concurrent access.

Step 3

Let's use MySQL database. Change the database.yml to:

  development:
    adapter: mysql2
    encoding: utf8
    reconnect: false
    database: blogger_development
    pool: 5
    username: root
    password: 
    host: localhost
    port: 3306

  # Warning: The database defined as "test" will be erased and
  # re-generated from your development database when you run "rake".
  # Do not set this db to the same as development or production.
  test:
    adapter: mysql2
    encoding: utf8
    reconnect: false
    database: blogger_test
    pool: 5
    username: root
    password: 
    host: localhost
    port: 3306

Step 4

Run rake db:migrate. It fails with :

Gem::LoadError: Specified 'mysql2' for database adapter, but the gem is not loaded. Add `gem 'mysql2'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).

Step 5

Add :

gem 'mysql2' 

to Gemfile and run bundle.

Step 6

Run

$rake db:migrate 

and

$rake db:create.

Step 7

Run the test again.

$rspec spec/features/subscription_spec.rb 

Step 8

It fails. Tailing the test log file did not give any clue. Ran the application locally and found out the issue was:

No API key provided. Set your API key using "Stripe.api_key = <API-KEY>". You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support@stripe.com if you have any questions.

Create a new file stripe.rb in config/initializers directory with the following contents:

Rails.configuration.stripe = {
    publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
    secret_key:      ENV['STRIPE_SECRET_KEY']
}

Stripe.api_key = Rails.configuration.stripe[:secret_key]
Stripe.api_version = "2015-02-18"

Step 9

In the terminal, set the values for the STRIPE_PUBLIC_KEY and STRIPE_SECRET_KEY environment variables as follows:

  export STRIPE_PUBLISHABLE_KEY='pk_test_GxDbP7Q6f4GkaUe0I0LrbQSz'
  export STRIPE_SECRET_KEY='sk_test_watHqWl2XD88WHqhknk7sqXN'

You can get these values for your account from your Stripe dashboard, API keys tab. You can verify it is set properly by running:

  $ echo $STRIPE_PUBLISHABLE_KEY
  $ echo $STRIPE_SECRET_KEY 

Step 10

Run the test again. It fails:

expected #count to have changed by 1, but was changed by 0. 

I tried to reproduce the problem in development. I was not able to reproduce it. The reason for the failure is that after you click 'Subscribe Me', you need to give some time for the network call to complete. So adding a sleep after clicking the 'Subscribe Me' button makes the test pass.

So our test now looks like this:

  scenario "to a plan saves the subscription details", js: true do
    expect do
      visit root_path

      click_link 'Register'
      fill_in 'Email', with: 'bugs2@rubyplus.com'
      fill_in 'Password', with: '12345678'    
      click_button 'Sign up'

      click_link 'Gold'
      fill_in "Card Number", with: '4242424242424242'
      page.select '10', from: "card_month"
      page.select '2029', from: 'card_year'
      click_button 'Subscribe Me'
      sleep 4
    end.to change(Subscription, :count).by(1)
  end

I have also turned on the javascript to true, since we are using javascript in the stripe.html.erb layout file. The test will fail because after the credit card form gets submitted to the Stripe servers, we get a stripe token, this is submitted to our server via javascript, since this call will fail, our test will also fail.

Summary


In this lesson we implemented the feature test for subscribing a user to a plan.


Related Articles


Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.