When running my tests, javascript isn't getting executed. I tried switching from the :selenium driver to the :webkit driver, but still no luck.
It works fine in the browser. When the test runs and the page opens, the page is blank
Is there something else I need to do to get it to execute javascript during test runs?
business_integration_test.rb
require 'minitest_helper'
require 'ruby-debug'
describe "Business integration" do
before :each do
#business = Factory.build(:business)
Capybara.javascript_driver = :webkit
end
it "Should show error if business name is blank" do
visit admin_business_path
fill_in 'Name', :with => ''
click_button 'Save'
page.save_and_open_page
page.text.must_include("can't be blank")
end
end
businesses_controller.rb
class Admin::BusinessesController < Admin::AdminController
def update
#business = resource
respond_to do |format|
if #business.update_attributes(params[:business])
flash[:notice] = "Your business was updated successfully."
else
flash[:notice] = "Your business failed to update."
end
format.js { render :template => "admin/businesses/edit" }
end
end
end
edit.js.erb
$("#page-businesses #main").html("<%= escape_javascript(render :partial => 'edit_information') %>");
Related
My personal website is being built on rails but I'm stuck with the User.count for the login area not updating. Been sitting with this for a day trying to get it to work but no luck so far. I've included all the code if someone could spot my error as I can't see it.
class UsersControllerTest < ActionController::TestCase
setup do
#user = users(:one)
#input_attributes = {
name: 'luchia',
password: 'secret',
password_confirmation: 'secret'
}
end
test "should create user" do
assert_difference('User.count') do
post :create, user: #input_attributes
end
assert_redirected_to users_path
end
Then there is my User Controller
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to users_url, notice: "User #{#user.name} was successfully created." }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
And my Terminal error:
$ rake test
Run options: --seed 11633
# Running tests:
....[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
....................F......
Finished tests in 1.143021s, 27.1211 tests/s, 45.4935 assertions/s.
1) Failure:
UsersControllerTest#test_should_create_user [/Users/lucybloomfield/Documents/luchia /test/controllers/users_controller_test.rb:25]:
"User.count" didn't change by 1.
Expected: 3
Actual: 2
31 tests, 52 assertions, 1 failures, 0 errors, 0 skips
Would appreciate anyone's help.
////////////////
Mmkay, this is what I ended up coming up with but it's not very concise. Rake test is completing with this so I guess it will have to do.
test "should create user" do
assert_difference('User.count') do
post :create, {:user => {'name' => 'luchia', 'password' => 'secret', 'password_confirmation' => 'secret'}}
.to change(User, :count).by(1)
end
assert_redirected_to users_path
end
//////////////
Edit again, the above bit of code fails on the second rake test.
Example with capybara and cucumber
describe "new" do
before do
visit new_user_path
end
it { should have_title(I18n.t("user.new")) }
describe "with invalid information" do
before { find("form#new_user").submit_form! }
it { should have_title(I18n.t("user.new")) }
it { should have_selector("div#alerts") }
end
describe "with valid information" do
before do
fill_in "user_name", :with => "user_name"
fill_in "user_email", :with => "user#example.com"
fill_in "user_password", :with => "123456"
fill_in "user_password_confirmation", :with => "123456"
find("form#new_user").submit_form!
end
it { should have_content(I18n.t("user.success"))}
end
end
You have to do a
puts YAML::dump(#user.save!)
in your method create of UsersControlller
def create
#user = User.new(user_params)
puts YAML::dump(#user.save!)
...
end
To see why it doesn't save.
Then check your user_params permit if it necessary
set
I18n.enforce_available_locales = false
to your config/application.rb
inside as exampled:
module MyApp
class Application < Rails::Application
...
I18n.enforce_available_locales = false
end
end
and restart server
I have written this controller code in Ruby on Rails
class PostsController < ApplicationController
before_filter :authenticate_user!
def index
#posts = Post.all(:order => "created_at DESC")
respond_to do |format|
format.html
end
end
def create
#post = Post.create(:message => params[:message])
respond_to do |format|
if #post.save
format.html { redirect_to posts_path }
format.js
else
flash[:notice] = "Message failed to save."
format.html { redirect_to posts_path }
end
end
end
end
and corresponding to this I have written the following test case :-
require 'spec_helper'
describe PostsController do
describe "GET 'index'" do
it "returns http success" do
get 'index'
response.should be_success
end
end
describe "#create" do
it "creates a successful mesaage post" do
#post = Post.create(message: "Message")
#post.should be_an_instance_of Post
end
end
end
I am getting failures on both. Please take a look on the code and help me figure out.
I suspect you are not logged in since you are using Devise?
Maybe you need to include the devise testhelpers:
describe PostsController do
include Devise::TestHelpers
before(:each) do
#user = User.create(...)
sign_in #user
end
#assertions go here
end
As Tigraine states, it appears as though you probably are not logged in (with Devise) when the tests get executed. However, showing the failures would help in narrowing down the problem further.
On top of that, the second test isn't really an integration test and I would probably prefer something like the following to test the same condition. There are two types of test you could do:
# inside 'describe "#create"'
let(:valid_params) { {'post' => {'title' => 'Test Post'} }
it 'creates a new Post' do
expect {
post :create, valid_params
}.to change(Post, :count).by(1)
end
# and / or
it 'assigns a new Post' do
post :create, valid_params
assigns(:post).should be_a(Post)
assigns(:post).should be_persisted
end
Don't forget to add this line into your spec_helper.rb
require "devise/test_helpers"
include Devise::TestHelpers
Nevertheless, here is link for Devise wiki - How to test Controllers where you can find more info about this approach. I recommend writing the before method without (:each), what I remember it sometimes causes problems.
before do
#user = FactoryGirl.create(:user)
sign_in #user
end
Can always use:
puts response.inspect
To see how your response looks like.
I'm following this tutorial here, and everything has worked out very well so far.
But now that I've progressed to sessions, some simple rspec tests are failing:
describe SessionsController do
#[...]
describe "GET 'new'" do
it "should have the right title" do
get :new
response.should have_selector( "title", :content => "Sign in" )
end
end
#[...]
describe "POST 'create'" do
#[...]
it "should have the right title" do
post :create, :session => #attr
response.should have_selector("title", :content => "Sign in")
end
#[...]
end
end
When I run rspec, I always get:
1) SessionsController GET 'new' should
have the right title
Failure/Error: response.should have_selector( "title", :content =>
"Sign in
)
expected following output to contain a Sign in tag:
w3.org/TR/REC-html40/loose.dtd">
# ./spec/controllers/sessions_controller_spec.rb:14:in
`block (3 levels) in '
When I access the sessions/new page, the page contains a title tag like the following:
<title>Ruby on Rails Tutorial Sample App | Sign in</title>
Why do those tests fail, while all other similar (= tests for the title tag) tests work fine?
Here's the SessionController:
class SessionsController < ApplicationController
def new
#title = 'Sign in'
end
def create
user = User.authenticate( params[:session][:email], params[:session][:password] )
if user.nil?
flash.now[:error] = "Invalid email/password combination."
#title = 'Sign in'
render 'new'
else
sign_in user
redirect_to user
end
end
def destroy
sign_out
redirect_to root_path
end
end
What am I doing wrong here?
thx for your help
You need to add render_views to the top of the class. Without it, the actual html will not be generated and your have_selector tests will fail.
I'm writing an rspec scenario thats failing with:
(#<User:0x1056904f0>).update_attributes(#<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x105623648>)
expected: 1 time
received: 0 times
users_controller_spec.rb:
describe "Authenticated examples" do
before(:each) do
activate_authlogic
#user = Factory.create(:valid_user)
UserSession.create(#user)
end
describe "PUT update" do
it "updates the requested user" do
User.stub!(:current_user).and_return(#user)
#user.should_receive(:update_attributes).with(anything()).and_return(true)
put :update, :id => #user , :current_user => {'email' => 'Trippy'}
puts "Spec Object Id : " + "#{#user.object_id}"
end
users_controller.rb:
def update
#user = current_user
puts "Controller Object ID is : " + "#{#user.object_id}"
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to(root_url, :notice => 'Successfully updated profile.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
user.rb - factories
Factory.define :valid_user, :class => User do |u|
u.username "Trippy"
u.password "password"
u.password_confirmation "password"
u.email "elephant#gmail.com"
u.single_access_token "k3cFzLIQnZ4MHRmJvJzg"
u.id "37"
end
Authlogic's standard helper methods like current_user don't call User.find directly. I believe it does current_user_session.user, where current_user_session calls UserSession.find, so you're not calling User.find directly. You could do some fancy chain stubbing there, but my suggestion is just to add this to your controller spec instead of what you're currently stubbing:
stub!(:current_user).and_return(#user)
In RSpec2 you might have to do
controller.stub!(:current_user).and_return(#user)
Edit: This should be your whole spec file:
describe "Authenticated examples" do
before(:each) do
activate_authlogic
#user = Factory.create(:valid_user)
UserSession.create(#user)
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested user" do
stub!(:current_user).and_return(#user)
#user.should_receive(:update_attributes).with(anything()).and_return(true)
put :update, :id => #user , :current_user => {'email' => 'Trippy'}
end
end
I think you're confusing stubs with message expectations. The line
User.should_receive(:find)
tells Rspec to expect the User model to receive a find message. Whereas:
User.stub!(:find)
replaces the find method so that the test can pass. In your example the thing you're testing is whether update_attributes is called successfully, so that ought to be where the message expectation goes, and the job of all the other testing code is just to set up the prerequisites.
Try replacing that line with:
User.stub!(:find).and_return(#user)
Note that find returns the object, not just its id. Also, note that stubbing out find here serves only to speed things up. As written the example gets through should_receive(:find) successfully, and that is happening because you're using Factories to create users in the test database. You could take the stub out and the test should still work, but at the cost of hitting the database.
Another tip: if you're trying to figure out why a controller test isn't working, sometimes it's helpful to know if it is being blocked by before filters. You can check for this with:
controller.should_receive(:update)
If that fails, the update action is not being reached, probably because a before filter has redirected the request.
I'm having trouble understanding why I can't seem to stub this controller method :load_user, since all of my tests fail if I change the actual implementation of :load_user to not return and instance of #user.
Can anybody see why my stub (controller.stub!(:load_user).and_return(#user)) seems to fail to actually get called when RSpec makes a request to the controller?
require 'spec_helper'
describe TasksController do
before(:each) do
#user = Factory(:user)
sign_in #user
#task = Factory(:task)
User.stub_chain(:where, :first).and_return(#user)
controller.stub!(:load_user).and_return(#user)
end
#GET Index
describe "GET Index" do
before(:each) do
#tasks = 7.times{Factory(:task, :user => #user)}
#user.stub!(:tasks).and_return(#tasks)
end
it "should should find all of the tasks owned by a user" do
#user.should_receive(:tasks).and_return(#tasks)
get :index, :user_id => #user.id
end
it "should assign all of the user's tasks to the view" do
get :index, :user_id => #user.id
assigns[:tasks].should be(#tasks)
end
end
#GET New
describe "GET New" do
before(:each) do
#user.stub_chain(:tasks, :new).and_return(#task)
end
it "should return a new Task" do
#user.tasks.should_receive(:new).and_return(#task)
get :new, :user_id => #user.id
end
end
#POST Create
describe "POST Create" do
before(:each) do
#user.stub_chain(:tasks, :new).and_return(#task)
end
it "should create a new task" do
#user.tasks.should_receive(:new).and_return(#task)
post :create, :user_id => #user.id, :task => #task.to_s
end
it "saves the task" do
#task.should_receive(:save)
post :create, :user_id => #user.id, :task => #task
end
context "when the task is saved successfully" do
before(:each) do
#task.stub!(:save).and_return(true)
end
it "should set the flash[:notice] message to 'Task Added Successfully'"do
post :create, :user_id => #user.id, :task => #task
flash[:notice].should == "Task Added Successfully!"
end
it "should redirect to the user's task page" do
post :create, :user_id => #user.id, :task => #task
response.should redirect_to(user_tasks_path(#user.id))
end
end
context "when the task isn't saved successfully" do
before(:each) do
#task.stub(:save).and_return(false)
end
it "should return to the 'Create New Task' page do" do
post :create, :user_id => #user.id, :task => #task
response.should render_template('new')
end
end
end
it "should attempt to authenticate and load the user who owns the tasks" do
context "when the tasks belong to the currently logged in user" do
it "should set the user instance variable to the currently logged in user" do
pending
end
end
context "when the tasks belong to another user" do
it "should set the flash[:notice] to 'Sorry but you can't view other people's tasks.'" do
pending
end
it "should redirect to the home page" do
pending
end
end
end
end
class TasksController < ApplicationController
before_filter :load_user
def index
#tasks = #user.tasks
end
def new
#task = #user.tasks.new
end
def create
#task = #user.tasks.new
if #task.save
flash[:notice] = "Task Added Successfully!"
redirect_to user_tasks_path(#user.id)
else
render :action => 'new'
end
end
private
def load_user
if current_user.id == params[:user_id].to_i
#user = User.where(:id => params[:user_id]).first
else
flash[:notice] = "Sorry but you can't view other people's tasks."
redirect_to root_path
end
end
end
Can anybody see why my stub doesn't work? Like I said, my tests only pass if I make sure that load_user works, if not, all my tests fail which makes my think that RSpec isn't using the stub I created.
Stubbing out load_user breaks your tests because stubbing the method neuters it. When the controller calls load_user, it is no longer running your original code. It's now just returning whatever you specify in and_return(...) (which is getting returned to the ActionController callback stack, which ignores anything other than false).
Your controller code isn't using the return value of that method; it's using the variable instantiated within it. Since the original code for the load_user method isn't being run, the #user instance variable is never instantiated. (The #user variable in your tests is only visible to your tests.)
But with all the other stubs you have, I don't see any reason why you should need to stub out load_user at all. As long as you're stubbing current_user to return #user (which I assume is being done in the sign_in method), then there shouldn't be any need.
you can also try to verify that the stub works by doing an assertion like
controller.current_user.should == #user