Abhi Abhi - 5 months ago 54
Ruby Question

rpsec-rails with apartment Gem and Grape cannot set host with subdomain

I am using Rails 4.2.6, Ruby 2.2.1, rspec-rails 3.4.2, Grape 0.16.2, grape_token_auth 0.1.0. I installed apartment gem (1.0.2) for multitenancy and trying to write rspec tests for grape requests.

But I am getting the following error from rspec-rails response method every time irrespective of whatever solutions I tried.

@buf=["<!DOCTYPE html>\n<html>\n<head>\n <title>Apartment::TenantNotFound at /content/api/v1/questions</title>\n</head>\n<body>\n

The request is taking the host as 'www.example.com' all time. I tried so many solutions by googling it. But nothing works. you can see that in spec where I commented these lines. I want the url as 'http://g_m.lvh.me:3000' with the subdomain 'g_m'.

I tried this one:
But not works. I don't know why.

I tried this, but not working:
Rails: Wrong hostname for url helpers in rspec

and tried to set the host by:

host! "g_m.lvh.me:3000"
@request.host = 'g_m.lvh.me:3000'
request.host = 'g_m.lvh.me:3000'

Nothing works!

I created a test case like the following grape link says:

require 'rails_helper'

RSpec.describe ContentManager::QuestionAPI, :type => :request do
#before(:each) { Apartment::Tenant.switch!("g_m") }
#after(:each) { Apartment::Tenant.switch!("public") }

#before(:each) do
#client = FactoryGirl.create(:client, title: 'Sample title', subdomain: 'g_m')
#client = Client.create!(title: 'Sample title', subdomain: 'g_m')

#default_url_options[:host] = 'http://g_m.lvh.me:3000'
# request.host = "#{'g_m'}.lvh.me"

#before(:each) do
# if respond_to?(:default_url_options)
# default_url_options[:host] = 'http://g_m.lvh.me:3000'
# end

describe "GET /content/api/v1/questions" do
it "returns an empty array of questions" do
get "/content/api/v1/questions"
#puts "response.inspect: #{response.inspect}"
response.status.should == 200
JSON.parse(response.body).should == []

My configurations:

in spec/rails_helper.rb

config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/requests/

All time this request sent by rspec-rails with

url: '/content/api/v1/questions'
host: 'www.example.com'

My test result shows:

$ rspec spec/requests/



1) ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
Failure/Error: response.status.should == 200

expected: 200
got: 500 (using ==)
# ./spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'

Deprecation Warnings:

Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /home/vagrant/gauge-slcsl/spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'.

If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.

1 deprecation warning total

Finished in 6.19 seconds (files took 1.93 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/requests/question_spec.rb:26 # ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions


If anyone knows about the error and what I am doing wrong here, please reply/answer.


The error was because of, we have to say the apartment subdomain configuration that just exclude the 'www' word considering as a sub domain.

Add the following:

# config/initializers/apartment/subdomain_exclusions.rb
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']

I was using the better_errors gem in my development and test environment. This causes the rspec output as an better error generated html codes and difficult to understand the rspec failure reason.

I removed better errors from 'test' environment and I got the clue of this error where we have to exclude the 'www' considering as a subdomain.