Rails rspec set subdomain

21,103

Solution 1

I figured out how to sort this issue.

In my before block in my specs I simply added:

before(:each) do
  @request.host = "#{mock_subdomain}.example.com"
end

This setups up the request.subdomains.first to be the value of the mock_subdomain.

Hope someone finds this useful as its not explained very well anywhere else on the net.

Solution 2

I know this is a relatively old question, but I've found that this depends on what kind of test you're running. I'm also running Rails 4 and RSpec 3.2, so I'm sure some things have changed since this question was asked.

Request Specs

before { host! "#{mock_subdomain}.example.com" }

Feature Specs with Capybara

before { Capybara.default_host = "http://#{mock_subdomain}.example.com" }
after  { Capybara.default_host = "http://www.example.com" }

I usually create modules in spec/support that look something like this:

# spec/support/feature_subdomain_helpers.rb
module FeatureSubdomainHelpers
  # Sets Capybara to use a given subdomain.
  def within_subdomain(subdomain)
    before { Capybara.default_host = "http://#{subdomain}.example.com" }
    after  { Capybara.default_host = "http://www.example.com" }
    yield
  end
end

# spec/support/request_subdomain_helpers.rb
module RequestSubdomainHelpers
  # Sets host to use a given subdomain.
  def within_subdomain(subdomain)
    before { host! "#{subdomain}.example.com" }
    after  { host! "www.example.com" }
    yield
  end
end

Include in spec/rails_helper.rb:

RSpec.configure do |config|
  # ...

  # Extensions
  config.extend FeatureSubdomainHelpers, type: :feature
  config.extend RequestSubdomainHelpers, type: :request
end

Then you can call within your spec like so:

feature 'Admin signs in' do
  given!(:admin) { FactoryGirl.create(:user, :admin) }

  within_subdomain :admin do
    scenario 'with valid credentials' do
      # ...
    end

    scenario 'with invalid password' do
      # ...
    end
  end
end

Solution 3

In rails 3 everything I tried to manually set the host didn't work, but looking the code I noticed how nicely they parsed the path you pass to the request helpers like get. Sure enough if your controller goes and fetches the user mentioned in the subdomain and stores it as @king_of_the_castle

it "fetches the user of the subomain" do
  get "http://#{mock_subdomain}.example.com/rest_of_the_path"
  assigns[:king_of_the_castle].should eql(User.find_by_name mock_subdomain)
end

Solution 4

  • Rspec - 3.6.0
  • Capybara - 2.15.1

Chris Peters' answer worked for me for Request specs, but for Feature specs, I had to make the following changes:

rails_helper:

Capybara.app_host = 'http://lvh.me'
Capybara.always_include_port = true

feature_subdomain_helpers:

module FeatureSubdomainHelpers
    def within_subdomain(subdomain)
        before { Capybara.app_host = "http://#{subdomain}.lvh.me" }
        after  { Capybara.app_host = "http://lvh.me" }
        yield
    end
end
Share:
21,103
RailsSon
Author by

RailsSon

Attempted coder

Updated on December 01, 2020

Comments

  • RailsSon
    RailsSon over 3 years

    I am using rSpec for testing my application. In my application controller I have a method like so:

    def set_current_account
      @current_account ||= Account.find_by_subdomain(request.subdomains.first)
    end
    

    Is it possible to set the request.subdomain in my spec? Maybe in the before block? I am new to rSpec so any advice on this would be great thanks.

    Eef