Try create rspec test for get method throught ajax - ruby-on-rails

Try create rspec test for get method throught ajax. Retruns 302 status but expect 200. Test for Post method returns the same results.
user_pages_spec.rb
require 'spec_helper'
describe "ProgectPage" do
subject { page }
let(:user) { FactoryGirl.create(:user) }
before(:each) do
visit signin_path
fill_in "Email", with: user.email.upcase
fill_in "Password", with: user.password
click_button "Sign in"
end
describe "createProgect" do
describe "vith invalid data" do
before do
click_link "Add TODO list"
fill_in "progect_title", with: 'Progect new'
fill_in "progect_date_end", with: ''
click_button "Save"
end
it { should have_selector('div.alert.alert-error') }
end
describe "vith valid data" do
before do
click_link "Add TODO list"
fill_in "progect_title", with: 'Progect new'
fill_in "progect_date_end", with: '2014-10-10'
end
it "should increment the progect count" do
expect do
click_button "Save"
end.to change(user.progects, :count).by(1)
end
end
end
it "has a 200 status code" do
#p user.inspect
xhr :get, '/users/1'
# p response.inspect
response.code.should == "200"
end
# it "has a 200 status code" do
# xhr :post, '/progects', progect: {title: "First Progect", date_end: "2014-10-11", user_id: 1}
# p response.inspect
# response.code.should == "200"
# end
end
rake routes
Prefix Verb URI Pattern Controller#Action
duties_new GET /duties/new(.:format) duties#new
users_new GET /users/new(.:format) users#new
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
progects POST /progects(.:format) progects#create
progect DELETE /progects/:id(.:format) progects#destroy
duties POST /duties(.:format) duties#create
duty DELETE /duties/:id(.:format) duties#destroy
root GET / sessions#new
signin GET /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
PUT /duties/:id(.:format) duties#update
duties_updpos POST /duties/updpos(.:format) duties#updpos
PUT /progects/:id(.:format) progects#update
bundle exec rspec spec/requests/user_pages_spec.rb
F..
Failures:
1) ProgectPage has a 200 status code
Failure/Error: response.code.should == "200"
expected: "200"
got: "302" (using ==)
# ./spec/requests/user_pages_spec.rb:45:in `block (2 levels) in <top (required)>'
Finished in 0.6253 seconds
3 examples, 1 failure
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:41 # ProgectPage has a 200 status code
UPD
it "has a 200 status code" do
xhr :get, :show, id: 1
response.code.should == "200"
end
have error
F..
Failures:
1) ProgectPage has a 200 status code
Failure/Error: xhr :get, :show, id: 1
ArgumentError:
bad argument (expected URI object or URI string)
# ./spec/requests/user_pages_spec.rb:44:in `block (2 levels) in <top (required)>'
Finished in 0.6102 seconds
3 examples, 1 failure
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:41 # ProgectPage has a 200 status code
Randomized with seed 13402

Check you log file to be sure but I think you'll find that the 302 response you are getting is your login system redirecting you to the signup page.
The problem is that you are mixing 2 things in your specs: capybara (which you are using for logging in) and the rails integration testing helpers (when you call xhr). While they appear similar they are quite separate - one cannot see the cookies set by the other so your ajax request is denied for not being logged in. In general mixing the two in a single spec doesn't end well (I wouldn't even use both in the same file, maybe even same project because of the potential for confusion).
If you choose to fix this by going down the capybara way then, rather than making the ajax request directly, you would trigger it be clicking on a button (or whatever ui action should trigger it) and checking that the DOM changes in some way.
If you go down the integration testing route then you need to be making your login requests with the integration testing methods (get, post etc) or even by fiddling with the session directly. You might even decide that a controller spec is more suited to what you want to test

Related

Rspec request spec ActionController::RoutingError

I'm trying to rewrite my tests in Rspec and am stuck on trying to make an update to a user.
I'm sure this is a silly thing I'm overlooking, but I've looked everywhere and can't find an answer.
Here's myspec file:
require 'spec_helper'
describe UsersController, type: [:request, :controller] do
before(:each) { host! 'localhost:3000/' }
describe "#update" do
it "doesn't update user" do
form_params = {
params: {
id: 1,
email: "hello#example",
name: "hello"
}
}
patch :update, params: form_params
end
end
end
It seems like the :update portion is wrong but as far as I can see in my routes, there's no other way to call it.
Here's the error:
ActionController::RoutingError: No route matches [PATCH] "/update"
Here's my routes:
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
Here's my old test:
test "should redirect update when not logged in" do
patch user_path(#user), params: { user: { name: #user.name, email: #user.email } }
assert_not flash.empty?
assert_redirected_to login_url
end
And if you guys possibly know - how do I convert assert_not flash.empty? to Rspec?
Thanks so much in advance!
At first, you can't to use multiple types in type: [:request, :controller]. If you want to write request specs you have to specify named route (user_path) or url ("/users/:id")
require 'spec_helper'
describe UsersController, type: :request do
describe "#update" do
let(:user) { create :user } # or use fixtures here
# I'm just a bit confused here, why it should not update?
it "doesn't update user" do
patch user_path(user), email: "hello#example", name: "hello"
expect(flash.empty?).to eq false
expect(response).to redirect_to login_path
end
end
end

Hartl Ruby on Rails Tutorial - Chapter 8 failed test

I am currently working on Michael Hartl's Ruby on Rails tutorial. I've been getting 4 separate errors during this chapter and would greatly appreciate your help with resolving them.
$ bundle exec rake test
1) Error:
SiteLayoutTest#test_layout_links:
NoMethodError: undefined method `full_title' for #<SiteLayoutTest:0x000000049fd568>
test/integration/site_layout_test.rb:13:in `block in <class:SiteLayoutTest>'
2) Error:
UsersLoginTest#test_login_with_remembering:
ActionController::RoutingError: No route matches [POST] "/login"
test/test_helper.rb:18:in `log_in_as'
test/integration/users_login_test.rb:31:in `block in <class:UsersLoginTest>'
3) Error:
UsersLoginTest#test_login_with_valid_information_followed_by_logout:
ActionController::RoutingError: No route matches [POST] "/login"
test/integration/users_login_test.rb:11:in `block in <class:UsersLoginTest>'
4) Error:
UsersLoginTest#test_login_without_remembering:
ActionController::RoutingError: No route matches [POST] "/login"
test/test_helper.rb:18:in `log_in_as'
test/integration/users_login_test.rb:36:in `block in <class:UsersLoginTest>'
23 runs, 39 assertions, 0 failures, 4 errors, 0 skips
$ bundle exec rake routes
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
signup GET /signup(.:format) users#new
login GET /login(.:format) sessions#new
GET /login(.:format) sessions#create
logout GET /logout(.:format) sessions#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
config/routes.rb
Rails.application.routes.draw do
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
get 'login' => 'sessions#create'
get 'logout' => 'sessions#destroy'
resources :users
end
test/integration/users_login_test.rb
require 'test_helper'
class UsersLoginTest < ActionDispatch::IntegrationTest
def setup
#user = users(:michael)
end
test "login with valid information followed by logout" do
get login_path
post login_path, session: { email: #user.email, password: 'password' }
assert is_logged_in?
assert_redirected_to #user
follow_redirect!
assert_template 'users/show'
assert_select "a[href=?]", login_path, count: 0
assert_select "a[href=?]", logout_path
assert_select "a[href=?]", user_path(#user)
delete logout_path
assert_not is_logged_in?
assert_redirected_to root_url
# Simulate a user clicking logout in a second window.
delete logout_path
follow_redirect!
assert_select "a[href=?]", login_path
assert_select "a[href=?]", logout_path, count: 0
assert_select "a[href=?]", user_path(#user), count: 0
end
test "login with remembering" do
log_in_as(#user, remember_me: '1')
assert_not_nil cookies['remember_token']
end
test "login without remembering" do
log_in_as(#user, remember_me: '0')
assert_nil cookies['remember_token']
end
end
test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
fixtures :all
# Returns true if a test user is logged in.
def is_logged_in?
!session[:user_id].nil?
end
# Logs in a test user.
def log_in_as(user, options = {})
password = options[:password] || 'password'
remember_me = options[:remember_me] || '1'
if integration_test?
post login_path, session: { email: user.email,
password: password,
remember_me: remember_me }
else
session[:user_id] = user.id
end
end
private
# Returns true inside an integration test.
def integration_test?
defined?(post_via_redirect)
end
end
test/integration/site_layout_test.rb
require 'test_helper'
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
get root_path
assert_template 'static_pages/home'
assert_select "a[href=?]", root_path, count: 2
assert_select "a[href=?]", help_path
assert_select "a[href=?]", about_path
assert_select "a[href=?]", contact_path
get signup_path
assert_select "title", full_title("Sign up")
end
end
I made a mess..ugh. Any and all help is much appreciated!
Edit: Also, i'm fairly new to all this, so if I'm supposed to be deleting the old tests as they test GREEN, please let me know. I'm not sure if these failed tests go RED because I'm doing something wrong or if I'm supposed to be deleting them as I go through the tutorial. Thank you!
In your routes.rb
get 'login' => 'sessions#new'
get 'login' => 'sessions#create'
that looks weird. I guess it should be
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'

Rails user_path routing to users/index instead of users/id

I am trying to work through the Rails tutorial at railstutorial.org and am stuck at this problem. My user_path in the test is supposed to go to the individual user's profile page, but is instead going to users/index (which I haven't created yet, on purpose).
/* My test code */
describe "profile page" do
#let(user) { FactoryGirl.create(:user) }
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
before { visit user_path(#user) }
it { should have_content(user.name) }
it { shoult have_title(user.name) }
end
/* Failures: */
1) UserPages profile page
←[31mFailure/Error:←[0m ←[31mbefore { visit user_path(#user) }←[0m
←[31mActionView::MissingTemplate←[0m:
←[31mMissing template users/index, application/index with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffe
}. Searched in:←[0m
←[31m * "C:/Users/rajeshch/Documents/Projects/sample_app/app/views"←[0m
[36m # C:in `find_template'←[0m
[36m # ./spec/requests/user_pages_spec.rb:19:in `block (3 levels) in <top (required)>'←[0m
The routes file shows that user_path should give me users/{id} or so
> rake routes
Prefix Verb URI Pattern Controller#Action
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show <<<------
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / static_pages#home
signup GET /signup(.:format) users#new
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
/* users_controller.rb*/
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
end
end
/* config/routes.rb */
SampleApp::Application.routes.draw do
resources :users
root 'static_pages#home'
match '/signup', to: 'users#new', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
end
You should save the User first with #user.save! before calling visit user_path(#user)
Because until you save the user it wont persist in the database and will not have any id.
describe "profile page" do
#let(user) { FactoryGirl.create(:user) }
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
# Add this to your code ..
#user.save!
before { visit user_path(#user) }
it { should have_content(user.name) }
it { shoult have_title(user.name) }
end
Have you checked if #user has a value?
user_path(#user) will go to /users/<#user.id> but if #user is nil, it will try to go /users/. Given you haven't created the index method and views yet, that will probably be why it fails.
Thanks for the test code. Firstly your user is not in the database - change the .new to .create or add a #user.save. Secondly your params[:id] is not populated in the test code so the find will fail (add controller.params[:id] = #user.id to your test). (Thirdly you have a typo shoult instead of should in the last test.)
It doesn't seem like you included your test code, which would be immensely helpful in figuring out this problem. Most likely, you have #user set as nil in the test, fixing that will solve the problem.

Updated to Capybara 2.1.0.rc, now having trouble with current_path in my feature specs

So it seems like I've used current_path many times in request specs. However, Capybara now requires specs to be in the features directory in order to use the Capybara DSL (page & visit)
# creating_posts_spec.rb
require "spec_helper"
feature "creating posts" do
scenario "creating posts with valid info is successful" do
visit new_post_path
fill_in 'Title', with: "This is a title test"
fill_in 'Content', with: "This is a content test"
click_button 'Create Post'
page.should have_content 'Post was successfully created.'
page.current_path.should == post_path(post)
end
end
Its a simple post controller and the page lands on show after the post is rendered just fine in the browser.
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root / posts#index
Why am i getting an error: undefined local variable or method 'post'?
I just don't remember ever having this trouble.
Anyone have a suggestion or reason? or am I missing something obvious? It's late
Because post is undefined.... You don't set it anywhere in the entire scenario.

Rspec no route matches

I'm getting the following error with rspec:
1) LandingController landing#index returns http success
Failure/Error: get :index
ActionController::RoutingError:
No route matches {:controller=>"landing"}
# ./spec/controllers/landing_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
This is the test
require 'spec_helper'
describe LandingController do
describe "landing#index" do
it "returns http success" do
get :index
response.should be_success
end
end
end
I mounted it as root :to => 'landing#index'. All other tests are passing, only this one is failing, can someone help me to understand why?
For completeness this is the output from rake routes
root / landing#index
auth_google_oauth2_callback /auth/google_oauth2/callback(.:format) sessions#create
signout /signout(.:format) sessions#destroy
dashboard /dashboard(.:format) dashboard#index
If you are using Spork you may need to restart the server if you updated routes.
did you try to access the root page with get '/'? should work.

Resources