I have a gem I'm working on that uses a railtie to add a middleware. Very simple stuff, followed the rails guides section almost exactly. Works fine in development/staging/production.
The middleware initializes a hash-like object in the env
at a particular key.
But in my capybara tests, this key is only sometimes initialized. I added a debugger to the middleware and found that it isn't called every time I use the visit
method.
What's more is that in this particular spec file, there are 4 examples, and each example calls visit
once. But when I run the spec file, the middleware is sometimes called 3 times and sometimes called 2 times. Obviously the middleware stack should be called for every request.
tl;dr: sometimes calling visit
in my capybara feature specs (with rack-test driver) does not result in my middleware stack being called.
Help?
- ruby 2.0.0-p353
- rails 4.0.2
- capybara 2.2.1
- rack-test 0.6.2
EDIT: This is some of the relevant code here: how the middleware is added and what it does. MyGem::Middleware#call is only sometimes called when using Capybara's visit
method.
# railtie.rb
module MyGem
class Railtie < Rails::Railtie
initializer "my_gem.configure_rails_initialization" do |app|
app.middleware.use MyGem::Middleware
end
end
end
# middleware.rb
module MyGem
class Middleware
def initialize(app, options={})
@app = app
# options unused
end
def call(env)
# using a special internal version of the Rack::Session::Cookie class
session = MyGem::Rack::Session::Cookie.new(
@app,
:coder => MyGem::Rack::Session::Cookie::Base64::Marshal.new,
:key => ENV_SESSION_KEY,
:path => '/',
:domain => domain(env),
:expire_after => 6.weeks.to_i, # seconds till this expires
:secret => 'my_gem_secret_14f1c4ad25a6be00fe53f5fd2d746167',
)
# use Rack::Session:Cookie method
session.context(env, @app)
end
end
end
Figured it out!
I was also adding a Warden hook that expected the env key to be added after signing users in and out, and if the Warden::Manager middleware was added prior to my gem's middleware, then it would error out when running my hook that expected that env key to be set.
Solution was to do this in my railtie: