ruby-on-railsrspecdeviseintegration-testing

rspec, request spec, devise, multi-controller


I'm trying to build a request spec which tests the full gamut of creating a new user via devise API.

I currently have this sitting in RegistrationsController spec, but this won't work if I want to follow the mail link to the confirmations controller.

I haven't been able to find a good example of how people have tested the 'hand-off' from one controller to another and the intermittent 'steps' (we have custom devise methods scattered throughout the process which this test will encompass too).

it "creates a user, sends a welcome email, confirms the user, and registers the user in email campaigns" do
  post :create, {user: new_user_params}
  last_email = ActionMailer::Base.deliveries.last.body

  ConfirmationsController.any_instance.should_receive(:after_filter_method_to_subscribe_user)

  redirect_to confirmation_link(last_email) # helper method

  last_email.should include("Thanks for joining!")
  user = User.find_by_first_name(new_first_name)
  user.confirmed?.should be_true
  user.email_lists.should_not be_empty
end

Edit:

I should also add that I need http_basic_auth to run the spec which I'm including in a spec/support file and sets the request.env['HTTP_AUTHORIZATION'] to variables stored in the API::Base controller. I currently have nil as a request obect when running specs in the spec/request folder, which I'll need to run the specs.

Edit:

Thanks to people who've taken a look. I figured it out after piecing together two SO searches and the code I had. I'll post an answer for future SO'ers when I can.


Solution

  • I figured this out shortly after posting my question with good luck finds on more google searches. Kudos to a couple SO references ~> request spec relish && setting request headers for http basic auth in request specs

    My spec turned out to look something like the below Hope this helps someone not waste 4 hours like me :).

    spec/requests/api/user_registration_spec.rb.

    it "sends a welcome email, confirms the user, and signs the user up to email campaigns" do
      email_list = FactoryGirl.create(:email_list, name: "funky-email-campaign")
      user_name  = Api::RegistrationsController::USER
      password   = Api::RegistrationsController::PASSWORD
    
      # post to /users/registration
      post api_registrations_path({user: new_user_params}), nil , {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user_name, password)}
    
      last_email = ActionMailer::Base.deliveries.last.body
    
      UserService.should_receive(:subscribe_to_email).and_call_original # check that after_filter is called
    
      get confirmation_link(last_email) # follow link in email (/users/confirmation)
    
      response.should redirect_to(custom_path) # tests after_confirmation_path_for override
      last_email.should include(new_first_name)
      last_email.should include("Thanks for joining!")
      user = User.find_by_first_name(new_first_name)
      user.confirmed?.should be_true
      user.email_lists.first.name.should eq(email_list.name)
    end