Search code examples
ruby-on-rails-5rspec-rails

Rails request specs - ArgumentError: at least 2 arguments required


I'm working on my first request spec. I have the following setup.

provider_dashboard_spec.rb

require "rails_helper"
require "spec_helper"

describe "ProviderDashboard" , :type => :request do

  let!(:user) { Fabricate(:user) }
  let!(:invalid_user) { Fabricate(:invalid_user) }

  context "when failure" do
    # 401: Unauthorized - Authentication credentials were invalid.
    # 403: Forbidden - The resource requested is not accessible - in a Rails app, this would generally be based on permissions.
    # 404: Not Found - The resource doesn’t exist on the server.

    it "returns status: 401 Unauthorized with invalid or missing credentials" do
      post "api/v1/sessions", :params => {login: invalid_user.email, passowrd: invalid_user.password}
      # expect(response.code).to be('401')
      # expect(respone.body).to include('error: ')
    end
  end
end

user_fabricator.rb

require 'faker'
require 'ffaker'
Fabricator(:user, from: User) do
  # user
  first_name            { FFaker::Name.first_name }
  last_name             { FFaker::Name.last_name }
  dob                   { FFaker::Time.date }
  gender                { 'Male' }
  email                 Fabricate.sequence(:email) { |i| "test_#{i}@example.com" }
  password              { '123456' }
  password_digest       { '123456' }
  password_confirmation { '123456' }
  slug                  { "#{FFaker::Name.first_name} + #{FFaker::Name.last_name}" }
end

Fabricator(:invalid_user, from: User) do
  first_name             { FFaker::Name.first_name }
  last_name              { FFaker::Name.last_name }
  dob                    { '' }
  email                  { "[email protected]" }
  password               { '' }
  password_digest        { '' }
  password_confirmation  { '' }
end

spec_helper.rb

require 'capybara/rspec'
require 'pathname'
require 'request_helper'
.
.
.
RSpec.configure do |config|
  config.include Sorcery::TestHelpers::Rails::Controller, type: :controller
  config.include Sorcery::TestHelpers::Rails::Integration, type: :feature

  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end
  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
end

rails_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'shoulda/matchers'
require 'capybara/rails'
require 'ffaker'

RSpec.configure do |config|
  # Fabrication::Support.find_definitions
  config.include Sorcery::TestHelpers::Rails::Controller
  config.include Sorcery::TestHelpers::Rails::Integration
  config.include Rails.application.routes.url_helpers
  config.filter_rails_from_backtrace!

  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework :rspec
      with.library :rails
    end
  end

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
end

I'm having trouble understanding why #post is not accepting my url & hash as 2 arguments (located in provider_dashboard_spec.rb, first spec). I expect #post to visit the URI, using params as authentication and returning the 401.

Instead, I am receiving the ArgumentError: at least 2 arguments required. Am I not including the correct libraries in my spec or rails helper?

Update #1

I've changed the spec to include a header as recommended.

it "returns status: 401 Unauthorized with invalid or missing credentials" do
  params = {login: invalid_user.email, password: invalid_user.password}
  header = {"CONTENT_TYPE" => "text/json"}
  post "/api/v1/sessions", params, header
end

My error fires on the params assignment now but is the same error.

  1) ProvidersController when failure returns status: 401 Unauthorized with invalid or missing credentials
     Failure/Error: params = {login: invalid_user.login, password: invalid_user.password}

     ArgumentError:
       at least 2 arguments required
     # /home/barracus/.rvm/gems/ruby-2.3.8/gems/sorcery-0.9.1/lib/sorcery/model.rb:85:in `authenticate'
     # /home/barracus/.rvm/gems/ruby-2.3.8/gems/sorcery-0.9.1/lib/sorcery/controller.rb:33:in `login'
     # ./spec/requests/api/v1/providers/provider_dashboard_spec.rb:16:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:79:in `block (3 levels) in <top (required)>'
     # /home/barracus/.rvm/gems/ruby-2.3.8/gems/database_cleaner-1.7.0/lib/database_cleaner/generic/base.rb:16:in `cleaning'
     # /home/barracus/.rvm/gems/ruby-2.3.8/gems/database_cleaner-1.7.0/lib/database_cleaner/base.rb:100:in `cleaning'
     # /home/barracus/.rvm/gems/ruby-2.3.8/gems/database_cleaner-1.7.0/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
     # /home/barracus/.rvm/gems/ruby-2.3.8/gems/database_cleaner-1.7.0/lib/database_cleaner/configuration.rb:87:in `cleaning'
     # ./spec/rails_helper.rb:78:in `block (2 levels) in <top (required)>'

Finished in 1.14 seconds (files took 1.65 seconds to load)
1 example, 1 failure

Final Update

Turns out I had another typo invalid_user.login instead of invalid_user.email and must provide keyword args for params, headers, env & xhr format.

Thanks for the assist!

Additional source: Top answer in this SO post


Solution

    • You are probably seeing an ArgumentError because it wants arguments for params and headers in the request but it's only receiving params. If that doesn't resolve the issue, then please update your post with the error message in its entirety.
    • You are misspelling password in your POST request as passowrd
    • Recommendation: replace your commented-out status code examples with HTTP status matcher examples