ActsAsTenant current_tenant + Capybara + RSpec testing

501 Views Asked by At

I am trying to create an integration test with Capybara/RSpec that has a valid current_user (using the Warden.test_mode! trick) and I have also created a valid current_tenant by doing this in the test:

ActsAsTenant.current_tenant = Account.first

When the test is ran it comes up with a "undefined method for nil:NilClass" error that is characteristic of the current_tenant not being set. I have verified that Account.first does in fact have what I expect in it.

What might be the problem and how can I fix it?

3

There are 3 best solutions below

0
On

You might need to create the Account. If you're using FactoryBot, that might look like:

ActsAsTenant.current_tenant = FactoryBot.create :account

You might also consider using:

ActsAsTenant.without_tenant do
  # more testy things
end
0
On

Although this this question is 8 years old, it's the only relevant result I found when searching for help getting capybara + rspec working with acts as tenant. Hopefully this is helpful to someone else, or more likely future me when I forget how I solved this.

My problem was that, while the official docs worked fine for unit tests, it would fail during system tests as the second request (such as an update or create action) would have a nil tenant.

In config/environment/test.rb I include middleware according to the official docs, but I also force capybara to access the server using the localhost domain.

  config.middleware.use ActsAsTenant::TestTenantMiddleware

  config.after_initialize do
    # Use localhost as the server and app host for Capybara tests
    Capybara.server_host = "localhost"
    Capybara.app_host = "http://localhost"
  end

In rails_helper.rb I create an account with the localhost domain. The before suite filter runs outside of a transaction, so it must be manually deleted after the suite has completed, which can be done in the at_exit block.

I also modified it check for the system example type as well as request.

  config.before(:suite) do |example|
    $default_account = FactoryBot.create(:account, domain: "localhost")
  end

  config.before(:each) do |example|
    if [:system, :request].include?(example.metadata[:type])
      ActsAsTenant.test_tenant = $default_account
    else
      ActsAsTenant.current_tenant = $default_account
    end
  end

  config.after(:each) do |example|
    ActsAsTenant.current_tenant = nil
    ActsAsTenant.test_tenant = nil
  end

  at_exit do
    $default_account.destroy
  end
end
0
On

You can check the gem 'act_as_tent' doc over here https://github.com/ErwinM/acts_as_tenant#testing