ruby-on-railsrspecgrape-api

RSpec undefined method `each' in call


In my Grape API I've got an endpoint which is responsible of receiving data from CMS webhook - it works well but below specs are failed:

describe ::Webhooks::Cms::ReceiveWebhook, type: :request do
  subject(:call) { post endpoint, params: params, headers: basic_authorized_headers(auth_params) }

  let(:endpoint) { 'webhooks/Cms' }
  let(:params) { { some: 'params' } }
  let(:auth_params) do
    {
      username: Rails.application.credentials.cms_user,
      password: Rails.application.credentials.cms_password,
    }
  end

  it 'returns a successful response' do
    call
    expect(response).to be_successful
  end
end

helper with basic_authorized_headers method from headers:

module AuthRequestHelpers
  def basic_authorized_headers(username: nil, password: nil)
    "#{username}:#{password}"
  end
end

I'm getting error:

 Failure/Error: subject(:call) { post endpoint, params: params, headers: basic_authorized_headers(auth_params) }

 NoMethodError:
   undefined method `each' for "test@test.com:password":String

Here is my controller:

module Cms
  class ReceiveWebhook < Base
    desc 'Receive data of CRUD actions from CMS webhook'

    http_basic do |user, password|
      user == Rails.application.credentials.cms_user &&
        password == Rails.application.credentials.cms_password
    end

    post :cms do
      status 200
    end
  end
end

Solution

  • post expects a hash for the headers param, you're passing a string.

    subject(:call) { post endpoint, params: params, headers: { 'Authorization' => basic_authorized_headers(auth_params) } }
    

    Also, usually basic auth requires the "Basic" keyword, and that the credentials be encoded in Base64:

    module AuthRequestHelpers
      def basic_authorized_headers(username: nil, password: nil)
        encoded_credentials = Base64.encode64("#{username}:#{password}")
        "Basic #{encoded_credentials}"
      end
    end