Why does rspec-rails skip the middleware? - ruby-on-rails-3

I have a Rails app (3.2.12) that I wanted to add locale switching via HTTP Accept-Language header.
What I did to achieve that:
I added rack-contrib to my Gemfile:
gem 'rack-contrib', require: 'rack/contrib'
ran bundle install, added the middleware to my config/application.rb:
config.middleware.use Rack::Locale
and inspect the request env my controller:
puts request.env.keys.select{|v| v=~/rack/ }
The spec I run is a controller spec, it has render_views in it.
My problem:
There's no rack.locale key in the request environment. I double-checked rake middlware, it lists Rack::Locale toward the end, right before run MyApp::Application.routes.
After some debugging I found out that the middleware is never called when I run
rspec spec/controllers/authentication_controller_spec.rb
BUT: Running the same code in script/rails s thin gives me more keys in the request env, namely:
rack.request.cookie_string
rack.locale
rack.request.query_string
rack.request.query_hash
So, I guess the question is: Why does RSpec refuse to pick up a Rack middleware?

Controller specs do not go through the stack, they pretty much call directly on the controller itself. You'll probably want to use Rspec's request type tests for this.

Related

Rails friendly_id: undefined method `slug` on production

I'm trying to introduce dynamic_sitemaps over resources with friendly_id. The issue is the production rails (rake / rails c) doesn't see the slug method. I've try to specify it by force by specifying an attr_accessible :slug, but it doesn't help either.
$ rake sitemap:generate
Generating sitemap...
rake aborted!
undefined method `slug' for #<Article:0xa9e4d14>
The funny thing it works smoothly on the local environment, and it should not be so much different with the capistrano/rvm deployment.
The column exists in the DB and is used by the rails app itself (which works fine too).
Added: it should be tied to either the environment or the specific gem version issue, but I'm not sure which one is the trouble, and how to debug it. The same pair works good for a different project with a pretty similar libraries bundle.
As the capistrano always do the dirty work, I forgot about the RAILS_ENV environment variable - so the console and cron job tried to operate against the dev DB and obviously failed.

How to set sinatra-authentication to use erb instead of haml?

I'm trying to set up the sinatra-authentication gem in a simple sinatra app, and running into an issue where sinatra can't find the correct views. I understand that sinatra-authentication uses haml by default, but I'm using erb in this app.
This in mind, I found in the sinatra-authenticaiton docs that there is a setting which allows you to change the template engine, by adding the following to your app file:
configure do
set :template_engine, :erb # for example
end
I've added this to my app.rb file, and sinatra is still looking for the signup.haml when I try to hit the /signup route in my app.
A couple of notes:
I've included the gem in my Gemfile, and successfuly run a bundle install on my app.
source 'https://rubygems.org'
gem 'sinatra'
gem 'data_mapper'
gem 'pg'
gem 'dm-postgres-adapter'
gem 'sinatra-authentication'
I saw something in the documentation that suggested that I may need to specify the location of my view files, so I added the following to my configuration block.
set :sinatra_authentication_view_path, Pathname(__FILE__).dirname.expand_path + "views/"
**I think I've required the gem accurately in my app file by adding
require "sinatra-authentication"
use Rack::Session::Cookie, :secret => 'mys3cr3tk3y'
This gist is a current representation of my app.rb file in the root of my sinatra app. https://gist.github.com/rriggin/5378641#file-gistfile1-txt
Here is a screenshot of the error sinatra throws: http://cl.ly/image/0y041t0K3u3O
When I run the app locally, a 'dm-users' table is created in my local db as expected.
Is there another configuration setting that I'm missing in order to get sinatra-authentication to properly look for the erb templates rather than haml files. Any help would be greatly appreciated.
Thanks
The specs don't test that the template_engine setting works, and looking at the way the setting is called, I believe it's not correct, i.e.
send settings.template_engine, get_view_as_string("index.#{settings.template_engine}"), :layout => use_layout?
might better work as:
send app.settings.template_engine, get_view_as_string("index.#{app.settings.template_engine}"), :layout => use_layout?
that's what I reckon. If you fork the project, change the line and add it to your Gemfile and it works then consider writing a quick spec for it and you'll have improved the mainline of that project as well as fixed your problem.

Routing error when updating to Rails 3.2.6 or Rspec 2.11.0

After upgrading to Rails 3.2.6 or Rspec 2.11.0, my specs starts to show routing errors like the following:
4) UsersController GET activate activation code not exist
Failure/Error: subject{ get :activate }
ActionController::RoutingError:
No route matches {:controller=>"users", :action=>"activate"}
There is also a after each hook error
An error occurred in an after(:each) hook
RSpec::Mocks::MockExpectationError: (#<EmailSubscriber[...]>).update_attributes({:enable=>true})
expected: 1 time
received: 0 times
occurred at [...]/spec/controllers/users_controller_spec.rb:75:in `block (3 levels) in <top (required)>'
The application in development mode still runs fine.
Both Rspec 2.11.0 and Rails 3.2.6 uses the latest Journey gem (1.0.4). It has some problems, and by explictly lock it to the previous version the spec error disappears.
gem 'journey', '1.0.3'
UPDATE
I recently updated Rails to 3.2.11 with Journey 1.0.4, and all spec passed. My Rspec is 2.11.0
Therefore there is no need to downlock journey anymore, just update Rails.
It appears that the environment is stricter in functional tests than it is in production or development.
In the latter two, it is unable to "know" the parameter names beforehand as they are determined by looking at the according/matching route definition.
In a test, however, one provides the parameter name explicitly. This allows the environment to be more picky.
As that behaviour drifts away from the principle of having a test-env match a prod-env as closely as possible, I consider it a bug and filed an issue accordingly (https://github.com/rails/journey/issues/59).
In order to work around the problem for now, make sure your parameter names match your routes exactly.
I suggest adding the according routes until an outcome is decided in regards to the filed issue. That way, if it's consired a bug and resolved, you just need to remove the routes again - instead of fiddling with your production logic on controller level (which is working flawlessly already).

Testing the asset pipeline with Capybara

I want to do simple request specs in my Rails 3.1 application with Capybara. The standard cases all work as expected, but when I want to test CSS generated by the asset pipeline, I receive the following error:
Failure/Error: visit '/assets/main.css'
ActionController::RoutingError:
No route matches [GET] "/assets/main.css"
I think the problem is that the test environment does not provide a complete server and so also no Sprockets middleware delivering the assets.
Is there a solution to this problem?
EDIT: Now possible!
We updated to Rails 3.2.12 and Capybara 2.0.2, now the assets are also available in the feature specs.
The Phusion guys blogged about a possibility to render an asset to a string:
MyApp::Application.assets.find_asset('main.css').body
You can also use this in tests. The solution is not ideal and/since Capybara isn't involved anymore, but it helps in my specific case to validate CSS. Better approaches are welcome!

Undefined Method error 'has_content?' with rspec/capybara/rails3

I am getting an undefined method 'has_content?' error on an rspec controller_spec file.
I found a thread with similar issues though that thread said the issue was fixed in rspec2.0beta (it was a fairly old thread) but I'm getting this with a more recent version. Some threads on rspec shows that capybara doesn't work in view specs, but I'm working in the controller specs so that shouldn't be the issue...
My Gemfile info looks like this:
rspec-rails+ dependecies 2.6.0.rc6
capybara 0.4.1.2
rails 3.0.7
I am trying to do a simple assert like
response.body.should have_content("Project A")
Thanks for the response,
Tony
Capybara is only included in Rspec request specs by default. Change this file to a be a request spec (put it in the request specs directory, change the title of it...)
Read the capybara Readme section 'Using Capybara with RSpec'
https://github.com/jnicklas/capybara
Also, if these are the types of asserts you're looking to do, this qualifies as a request spec more than it is a controller spec.