Rails 3 - Rendering layout corrupts tests - ruby-on-rails

I define a function called location on wsp_controller:
def location
#title ="Edit account"
#page_name = "edit"
end
And it works fine. But when I try to render a layout like this:
def location
#title ="Edit account"
#page_name = "edit"
render :layout => 'signup_login'
end
RSpec tests start to fail. However, the app does what is supposed but the tests fail.
I have javascript code in the layout that I need to run when I go to /location, if I put the javascripts on the application layout, it works (tests and app), however there's no need to put it there, so I want a new layout and render it.
How can I do that?
Edit: Here's what I have in the routes.rb
match '/wsps/:id/location', :to =>'wsps#location'
Thanks.
Edit:
Some of the RSpec errors:
Failures:
1) WspsController GET 'index' for non-signed-in wsps should deny access to 'index'
Failure/Error: get :index
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.errors
It simple doesn't pass the tests when I render the layout. But it's only in that method.

You might need to provide a bit more info about the failures that you're getting. You mention that you have javascript that needs to run when the page is rendered? Don't forget that in your functional tests the page is rendered as html, but there isn't a real browser used, so no javascript is run. For tests that involve javascript you should look at something like Cucumber to define some acceptance tests, combined with something like Watir, or Selenium to drive a browser.

Related

Rspec test to render no layout

I can test my controller to render a certain layout with
expect { get :index }.to render_template(layout: 'my_layout')
But how can I test the controller to render NO layout?
The following first expectation passes, but be careful: the second expectation also passes! (testing the same code)
expect { get :index }.to render_template(layout: false)
expect { get :index }.to render_template(layout: true)
In Nov 2008, #david-chelimsky said:
One way I've handled this successfully is to integrate_views for this
one example (in its own group) and specify that html elements from the
layout are not present in the form. It's a brittle example, but it's
only one.
I dont want to check the rendered view, but I did not find any better solution so far.
Does someone has a good approach?
In my tests when there is no layout I just check if it is not loading "application" layout
expect { get :index }.to_not render_template(layout: "application")
While not a pretty one liner (you can always add a helper method), I've found that you can do this:
get :index
#templates.keys.should include(nil)
I tested this and it only works when I set layout false. Based on the implementation of assert_template it gathers some information in to instance variables. The relevant ones are #templates and #layouts - each is a hash keyed by a string corresponding with how many times it was rendered.
#templates will contain the template used for your action (e.g "users/show") but #layouts will only list layouts. If no layout was used, it looks like {nil=>1}. This seems the only thing you can tap in to.
So maybe it might be nice to make a helper method or custom matcher to do this.
I did it using this one liner
expect { get :index }.to render_template(layout: [])
Versions: Rspec = 3.4.0 , Rails ~> 4.2.5

Ruby on rails: Cucumber w/Capybara goes to ApplicationController on redirect_to

I'm trying to set up a RESTful API to a database of redirect links. I have set up a lot of tests in cucumber one of which is when a user does a GET on /links/:id. This is supposed to redirect the user to the link. It works in the browser but I'm having some trouble setting up this test in cucumber.
Given /^The link id part of the URL matches an existing entry in the links table$/ do
FactoryGirl.create(:users)
FactoryGirl.create(:links, :OWNER_USERID => Users.first.id)
Users.count.should==1
Links.count.should==1
end
When /^you use GET on link$/ do
visit link_path(Links.first.id)
end
The link_path specified sends me to this show method:
def show
redir=Links.find_by_id(params[:id])
redirect_to redir.target, :status=>307
end
The problem is just that cucumber fails on the When part complaining that I doesn't have a template for application/index. For some reason it does not redirect me but rather goes to root_path of my own site. Anyone knows how to check if such a redirect actually works?
Have you tried testing it in RSpec instead of Cucumber? Try something like this and see if it works:
describe "testing links" do
subject { page }
describe "use GET on link" do
let(:links) { Links.first }
before { get link_path(Links.first.id) }
specify { response.should redirect_to("http://example.com") }
end
end
Also make sure your test database if properly configured and populated before doing the tests.
rake db:migrate and rake db:test:prepare

How do you test render_remote_content receives the correct locals

In a controller spec, I'm trying to test that a controller action calling render_remote_content renders the right partial with the correct.
Currently, I'm trying to do something like:
response.should render_template(partial: "path/to/_template", locals: {local_array: []})
This causes rspec to blow up in assert_template. I'd prefer to avoid stubbing render methods.
Anyone have any good ideas on how to accomplish this?
Rails 3.1
RSpec 2.7
When you are checking for locals, it appears that there is a bug in the rspec code, and you have to drop the underscore in the partial name.
Specifically:
response.should render_template(partial: "path/to/template", locals: {local_array: []})
will work, but your example will not.
EDIT:
This issue is actually in assert_template, since render_template delegates to that. This issue is being tracked here: https://github.com/rails/rails/issues/8516

Using Factory Girl with Rspec Views

So I want to test some views using Rspec and Factory Girl, but I don't know how to assign a factory to a view properly. All of the information I see online uses stubbing, and although stubbing is fine, I want to keep my rspec stuff somewhat consistent.
I want to use a factory for an edition model and associate that with the page when I render the page, but everything I've considered seems to be broken. Here's sort of a ridiculous example:
require 'spec_helper'
describe "catalog/editions/rationale.html.haml" do
before do
#edition = Factory.create(:edition)
assign(:editions, #edition)
render :action => 'rationale', :id => #edition
end
context "GET rationale" do
it "should not have the preamble to the United States constitution" do
rendered.should_not contain(/We the People of the United States/)
end
end
end
In this I've tried changing render :action => 'rationale', :id => #edition to just render, and other similar tweaks to the render action. I just have no idea where to start a factory_girl helped view. Any help would be greatly appreciated.
Versions:
Rails 3.0.10
RSpec 2.7
Factory_Girl 2.2
I think the error is that #editions is expecting an array, so you should write
assign(:editions, [#edition])
or, otherwise, if it should be a single element, you should write:
assign(:edition, #edition)
Secondly, unless your view is a partial that expects variables, you should just write
render
You do not have to give the action, rspec knows which view to render from the describe, and the view does not retrieve any data (so you don't have to set the id), you just have to set the instance variables correctly using the assigns. Testing the view does nothing more than rendering the view.
Hope this helps.
Now that you've got the answer, stop writing view specs. They are needlessly hard to write, and they really don't test enough to be at all worthwhile. Do your view and controller testing with Cucumber instead.

stubbing helpers using mocha

it "should have edit button if user has permission to edit" do
EntitiesHelper.stubs(:permission_to_edit_entity?).returns(true)
get :index
#entities[0..3].each do |entity|
response.should have_selector("form",
:method => "get",
:action => "/entities/edit/#{entity[:id]}") do |form|
form.should have_selector("input", :value => "Edit")
end
end
end
I am trying to write a simple test case which tests that an edit button is showed if the user has permission to edit. I am trying to use stubbing for this. However, it doesn't seem to work. The output view does not show the edit button next to every single entity which I would expect if the stubbing works. I am new to mocha and stubbing - I am doing something wrong here?
Thanks!
I assume EntitiesHelper is a plain-old rails helper that gets mixed into the controller - thus all it's instance methods (such as permission_to_edit_entity?) are available to the controller and views have access to these helper methods (via the controller) ... so You might stub the method on the controller :
controller.stubs(:permission_to_edit_entity?).returns(true)
in this particular case I would even consider changing the stub to mock since You expect the method to be called (although You're testing the button presence, it's good to know that the flow did not happen as expected) :
controller.expects(:permission_to_edit_entity?).returns(true)
but this of course is debatable and You should be fine either way ...

Resources