Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialNelly Nelly
7,134 Pointscan't run the users_controller_spec.rb
Hi again,
My scaffolding has generated different files compared to Jason's and now I am stuck again... Just in case, My git repo: https://github.com/knopfler81/odot/tree/user_auth
sample from Jason's version
describe "GET new" do
it "assigns a new user as @user" do
get :new, {}, valid_session
assigns(:user).should be_a_new(User)
end
end
sample from my version
describe "GET #new" do
it "assigns a new user as @user" do
get :new, params: {}, session: valid_session
expect(assigns(:user)).to be_a_new(User)
end
end
I don't know how to set the :valid_session
to make my test pass
let(:valid_session) {
skip("I don't know what to put in there!!!!")
}
my full file : users_controller_spec.rb
require 'rails_helper'
RSpec.describe UsersController, type: :controller do
# This should return the minimal set of attributes required to create a valid
# User. As you add validations to User, be sure to
# adjust the attributes here as well.
let(:valid_attributes) {{
first_name: "Jason",
last_name: "Seifer",
email: "jason@teamtreehouse.com",
password: "password12345",
password_confirmation: "password12345"
}}
let(:invalid_attributes) {
skip("Add a hash of attributes invalid for your model")
}
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# UsersController. Be sure to keep this updated too.
let(:valid_session) {
skip("I don't know what to put in there!!!!")
}
describe "GET #new" do
it "assigns a new user as @user" do
get :new, params: {}, session: valid_session
expect(assigns(:user)).to be_a_new(User)
end
end
describe "GET #edit" do
it "assigns the requested user as @user" do
user = User.create! valid_attributes
get :edit, params: {id: user.to_param}, session: valid_session
expect(assigns(:user)).to eq(user)
end
end
describe "POST #create" do
context "with valid params" do
it "creates a new User" do
expect {
post :create, params: {user: valid_attributes}, session: valid_session
}.to change(User, :count).by(1)
end
it "assigns a newly created user as @user" do
post :create, params: {user: valid_attributes}, session: valid_session
expect(assigns(:user)).to be_a(User)
expect(assigns(:user)).to be_persisted
end
it "redirects to the created user" do
post :create, params: {user: valid_attributes}, session: valid_session
expect(response).to redirect_to(User.last)
end
it "sets the session user_id to the created user" do
post :create, params: {user: valid_attributes}, session: valid_session
expect(session[:user_id]).to eq(User.find(email: valid_attributes["email"]).id)
end
end
context "with invalid params" do
it "assigns a newly created but unsaved user as @user" do
post :create, params: {user: invalid_attributes}, session: valid_session
expect(assigns(:user)).to be_a_new(User)
end
it "re-renders the 'new' template" do
post :create, params: {user: invalid_attributes}, session: valid_session
expect(response).to render_template("new")
end
end
end
describe "PUT #update" do
context "with valid params" do
let(:new_attributes) {
skip("Add a hash of attributes valid for your model")
}
it "updates the requested user" do
user = User.create! valid_attributes
put :update, params: {id: user.to_param, user: new_attributes}, session: valid_session
user.reload
skip("Add assertions for updated state")
end
it "assigns the requested user as @user" do
user = User.create! valid_attributes
put :update, params: {id: user.to_param, user: valid_attributes}, session: valid_session
expect(assigns(:user)).to eq(user)
end
it "redirects to the user" do
user = User.create! valid_attributes
put :update, params: {id: user.to_param, user: valid_attributes}, session: valid_session
expect(response).to redirect_to(user)
end
end
context "with invalid params" do
it "assigns the user as @user" do
user = User.create! valid_attributes
put :update, params: {id: user.to_param, user: invalid_attributes}, session: valid_session
expect(assigns(:user)).to eq(user)
end
it "re-renders the 'edit' template" do
user = User.create! valid_attributes
put :update, params: {id: user.to_param, user: invalid_attributes}, session: valid_session
expect(response).to render_template("edit")
end
end
end
describe "DELETE #destroy" do
it "destroys the requested user" do
user = User.create! valid_attributes
expect {
delete :destroy, params: {id: user.to_param}, session: valid_session
}.to change(User, :count).by(-1)
end
it "redirects to the users list" do
user = User.create! valid_attributes
delete :destroy, params: {id: user.to_param}, session: valid_session
expect(response).to redirect_to(users_url)
end
end
end
19 Answers
Steve Hunter
57,712 PointsHi Nelly, You scaffolding is using a later version of RSpec (v 3) than the course which, I think used v.2. One effect of this is to change the assertions. For example:
require 'spec'
describe 'new RSpec syntax' do
it "uses the new assertion syntax" do
expect(1 + 1).to eq(2)
end
it "uses the old syntax - now deprecated" do
(1 + 1).should == 2 # moved away from 'should'
end
end
In my ODOT code, the :valid_session
test doesn't amount to much:
let(:valid_session) { {} }
describe "GET new" do
it "assigns a new user as @user" do
.
.
Try that and let me know how you get on.
I hope that helps!
Steve.
Nelly Nelly
7,134 PointsHello Steve,
if I leave
let(:valid_session){ {} }
it fails
I believe like for :valid_attributes
there is something to do but I can't figure out...
let(:valid_attributes) {{
first_name: "Jason",
last_name: "Seifer",
email: "jason@teamtreehouse.com",
password: "password12345",
password_confirmation: "password12345"
}}
Steve Hunter
57,712 PointsI think to create a valid session for an existing user you just need an email address and a password? Remember_me is optional?
let(:valid_session) {
{ email: "jason@teamtreehouse.com",
password: "password12345" }
}
Sorry, I've not touched this project in ages - I am rusty!
Steve.
Nelly Nelly
7,134 PointsI tried earlier with this syntax which is I beleive the correct syntax two pairs or currly braces {{}}
let!(:valid_session) {
{ email: "jason@teamtreehouse.com",
password: "password12345"}
}
but I still have errors here are for exemple the two first: It seems that it ask for an id... but can't figure out how to set it :(
1) UsersController GET #edit assigns the requested user as @user
Failure/Error: get :edit, params: {id: user.to_param}, session: valid_session
ActionController::UrlGenerationError:
No route matches {:action=>"edit", :controller=>"users", :params=>{:id=>"2"}, :session=>{:email=>"jason@teamtreehouse.com", :password=>"password12345"}}
# ./spec/controllers/users_controller_spec.rb:57:in `block (3 levels) in <top (required)>'
2) UsersController POST #create with valid params creates a new User
Failure/Error: params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
ActionController::ParameterMissing:
param is missing or the value is empty: user
# ./app/controllers/users_controller.rb:63:in `user_params'
# ./app/controllers/users_controller.rb:17:in `create'
# ./spec/controllers/users_controller_spec.rb:66:in `block (5 levels) in <top (required)>'
# ./spec/controllers/users_controller_spec.rb:65:in `block (4 levels) in <top (required)>'
Steve Hunter
57,712 PointsLet's try the GET #edit thing first. And, yes, you're correct about the curly braces.
You have one line different to me:
get :edit, params: {id: user.to_param}, session: valid_session
I have a slightly different thing:
get :edit, { :id => user.to_param }, valid_session
I'm pretty sure they're basically the same thing - worth a try, though! My test is then in old format but does pretty much the same thing. The issue is that your controller doesn't have an edit route. I'm not sure why that would be ... what does typing rake routes
in terminal give you?
The second issue, to do with POST
, is failing because there's no instance of the User
class. We need to figure out why not! Probably to do with the :valid_session
thing too ...
Nelly Nelly
7,134 Pointsrake routes gives this
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
user_sessions POST /user_sessions(.:format) user_sessions#create
new_user_session GET /user_sessions/new(.:format) user_sessions#new
complete_todo_list_todo_item PATCH /todo_lists/:todo_list_id/todo_items/:id/complete(.:format) todo_items#complete
todo_list_todo_items GET /todo_lists/:todo_list_id/todo_items(.:format) todo_items#index
POST /todo_lists/:todo_list_id/todo_items(.:format) todo_items#create
new_todo_list_todo_item GET /todo_lists/:todo_list_id/todo_items/new(.:format) todo_items#new
edit_todo_list_todo_item GET /todo_lists/:todo_list_id/todo_items/:id/edit(.:format) todo_items#edit
todo_list_todo_item GET /todo_lists/:todo_list_id/todo_items/:id(.:format) todo_items#show
PATCH /todo_lists/:todo_list_id/todo_items/:id(.:format) todo_items#update
PUT /todo_lists/:todo_list_id/todo_items/:id(.:format) todo_items#update
DELETE /todo_lists/:todo_list_id/todo_items/:id(.:format) todo_items#destroy
todo_lists GET /todo_lists(.:format) todo_lists#index
POST /todo_lists(.:format) todo_lists#create
new_todo_list GET /todo_lists/new(.:format) todo_lists#new
edit_todo_list GET /todo_lists/:id/edit(.:format) todo_lists#edit
todo_list GET /todo_lists/:id(.:format) todo_lists#show
PATCH /todo_lists/:id(.:format) todo_lists#update
PUT /todo_lists/:id(.:format) todo_lists#update
DELETE /todo_lists/:id(.:format) todo_lists#destroy
root GET / todo_lists#index
Steve Hunter
57,712 PointsTry using hash rockets for the assignment:
let(:valid_attributes) { }
"first_name" => "Jason",
"last_name" => "Seifer", ...
And the same with the session hash.
let(:valid_session) {
{ "email" => "jason@teamtreehouse.com",
"password" => "password12345" }
}
Steve Hunter
57,712 PointsSo, rake routes
shows the user#edit
route but states the access is of a certain URL. This is malformed, according to the error the test throws.
I'd start with changing the :edit
code to:
get :edit, { :id => user.to_param }, valid_session
That might clean up the url formation? I hope!!
Nelly Nelly
7,134 PointsSince you made me change this line
get :edit, { :id => user.to_param }, valid_session
This is green :D :D ( we are on the good way !!)
UsersController
GET #new
assigns a new user as @user
GET #edit
assigns the requested user as @user
the rest still red =(
POST #create
with valid params
creates a new User (FAILED - 1)
assigns a newly created user as @user (FAILED - 2)
redirects to the created user (FAILED - 3)
sets the session user_id to the created user (FAILED - 4)
with invalid params
assigns a newly created but unsaved user as @user (PENDING: Add a hash of attributes invalid for your model)
re-renders the 'new' template (PENDING: Add a hash of attributes invalid for your model)
PUT #update
with valid params
updates the requested user (PENDING: Add a hash of attributes valid for your model)
assigns the requested user as @user (FAILED - 5)
redirects to the user (FAILED - 6)
with invalid params
assigns the user as @user (PENDING: Add a hash of attributes invalid for your model)
re-renders the 'edit' template (PENDING: Add a hash of attributes invalid for your model)
DELETE #destroy
destroys the requested user (FAILED - 7)
redirects to the users list (FAILED - 8)
Pending: (Failures listed here are expected and do not affect your suite's status)
1) UsersController POST #create with invalid params assigns a newly created but unsaved user as @user
# Add a hash of attributes invalid for your model
# ./spec/controllers/users_controller_spec.rb:87
2) UsersController POST #create with invalid params re-renders the 'new' template
# Add a hash of attributes invalid for your model
# ./spec/controllers/users_controller_spec.rb:92
3) UsersController PUT #update with valid params updates the requested user
# Add a hash of attributes valid for your model
# ./spec/controllers/users_controller_spec.rb:105
4) UsersController PUT #update with invalid params assigns the user as @user
# Add a hash of attributes invalid for your model
# ./spec/controllers/users_controller_spec.rb:126
5) UsersController PUT #update with invalid params re-renders the 'edit' template
# Add a hash of attributes invalid for your model
# ./spec/controllers/users_controller_spec.rb:132
Steve Hunter
57,712 PointsThis is progress ... let me look at those errors ... GET
is working but POST
is unhappy ... this might be a simple fix. crosses fingers
Nelly Nelly
7,134 PointsThank you so much for your help ! I reaaaaallly appreciate :)
Steve Hunter
57,712 PointsIn all your POST
tests, change:
post :create, params: {user: valid_attributes}, session: valid_session
to just:
post :create, { :user => valid_attributes }, valid_session
Let's just do the first POST
test first, see if that goes green.
Steve Hunter
57,712 PointsSo, change:
describe "POST #create" do
context "with valid params" do
it "creates a new User" do
expect {
post :create, params: {user: valid_attributes}, session: valid_session
}.to change(User, :count).by(1)
end
to:
describe "POST #create" do
context "with valid params" do
it "creates a new User" do
expect {
post :create, { :user => valid_attributes }, valid_session
}.to change(User, :count).by(1)
end
Just that one line ...
Nelly Nelly
7,134 Pointsthat works :)
Nelly Nelly
7,134 PointsI've changed this part too:
context "with invalid params" do
it "assigns a newly created but unsaved user as @user" do
post :create, {:user => invalid_attributes}, valid_session
expect(assigns(:user)).to be_a_new(User)
end
it "re-renders the 'new' template" do
post :create, {:user => invalid_attributes}, valid_session
expect(response).to render_template("new")
end
end
I believe I have to change also put and delete
Steve Hunter
57,712 PointsYes, but you have POST
and the invalid attributes first too. That needs a hash setting up for invalid atrributes, or just pass some in as a hash:
context "with invalid params" do
it "assigns a newly created but unsaved user as @user" do
post :create, { user => { "first_name" => "invalid value" } }, valid_session
expect(assigns(:user)).to be_a_new(User)
end
it "re-renders the 'new' template" do
post :create, { user => { "first_name" => "invalid value" } }, valid_session
expect(response).to render_template("new")
end
end
Steve Hunter
57,712 PointsSorry - that's what you did ... I was looking at two things at once!!!
Steve Hunter
57,712 PointsExcellent - so, one-by-one change that line in each of the tests where it appears. See if there's any errors once you've done that.
Nelly Nelly
7,134 PointsI will post once it's finished
Steve Hunter
57,712 PointsCool - I think it is fairly clear what needs changing now. There's a couple of skip
commands to take out, but the user hash and session attributes just need to be simplified. It should work after all that!!
Nelly Nelly
7,134 Pointssigh one is failing :(
1) UsersController POST #create with valid params sets the session user_id to the created user
Failure/Error: expect (valid_session[:user_id]).to eq(User.find(email: valid_attributes["email"]).id)
ActiveRecord::RecordNotFound:
Couldn't find User with 'id'={:email=>nil}
# ./spec/controllers/users_controller_spec.rb:87:in `block (4 levels) in <top (required)>'
it "sets the session user_id to the created user" do
post :create, { user: valid_attributes }, valid_session
expect (valid_session[:user_id]).to eq(User.find(email: valid_attributes["email"]).id)
end
Steve Hunter
57,712 PointsSo very close!!
Try using the find_by
method on the User
class, not the find
method.
expect (valid_session[:user_id]).to eq(User.find_by(email: valid_attributes["email"]).id)
When you're not passing a straight :id
to find something, use find_by
else it looks for an instance id of { :email => nil }
which is nonsense!!
That should work ... ?
Nelly Nelly
7,134 PointsThat's what I got with the update abow
1) UsersController POST #create with valid params sets the session user_id to the created user
Failure/Error: params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, params[:id])
ActionController::ParameterMissing:
param is missing or the value is empty: user
# ./app/controllers/users_controller.rb:63:in `user_params'
# ./app/controllers/users_controller.rb:17:in `create'
# ./spec/controllers/users_controller_spec.rb:86:in `block (4 levels) in <top (required)>'
Steve Hunter
57,712 PointsMy fault - I missed that you were using the wrong type of session so that threw an invalid user
. Try changing valid_session
to just session
here:
expect (valid_session[:user_id]).to eq(User.find_by(email: valid_attributes["email"]).id)
# change to
expect (session[:user_id]).to eq(User.find_by(email: valid_attributes["email"]).id)
Sorry about that!
Nelly Nelly
7,134 Pointsyou will hate me :sad:
Failures:
1) UsersController POST #create with valid params sets the session user_id to the created user
Failure/Error: expect (session[:user_id]).to eq(User.find_by(email: valid_attributes["email"]).id)
NoMethodError:
undefined method `id' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:87:in `block (4 levels) in <top (required)>'
Steve Hunter
57,712 PointsDammit!! lol.
THat's going to bug me .... I've got to go out for a bit. Back later.
I'm wondering why we're using the sessions user, then comparing that to the valid_attributes
. It sort of makes sense. Try changing [
"email
"]
to [:email]
, just to be consistent with how you created the hash; it should make no difference at all.
Nelly Nelly
7,134 PointsI really don't understand anything anymore lol I become nuts lol I believe we are comparing the user session to the valid_attributes to make sure that the user were well registred ( with the valid attributes...?
btw has you expected ther eis no difference
it "sets the session user_id to the created user" do
post :create,{ user: valid_attributes }, valid_session
expect (session[:user_id]).to eq(User.find_by(email: valid_attributes[:email]).id)
end
Nelly Nelly
7,134 PointsA f**** space.... between expect and ( session...) arggg I think I need a break now)
it "sets the session user_id to the created user" do
post :create,{ user: valid_attributes }, valid_session
expect(session[:user_id]).to eq(User.find_by(email: valid_attributes[:email]).id)
end
it's all green now !!
UsersController
GET #new
assigns a new user as @user
GET #edit
assigns the requested user as @user
POST #create
with valid params
creates a new User
assigns a newly created user as @user
redirects to the created user
sets the session user_id to the created user
with invalid params
assigns a newly created but unsaved user as @user
re-renders the 'new' template
PUT #update
with valid params
updates the requested user
assigns the requested user as @user
redirects to the user
with invalid params
assigns the user as @user
re-renders the 'edit' template
DELETE #destroy
destroys the requested user
redirects to the users list
Steve Hunter
57,712 PointsRemember what I said about random spacing issues a little earlier; there you go. They are the worst things to spot! So, well done!!
Nelly Nelly
7,134 PointsTHANK YOU SO MUCH FOR YOUR PATIENCE AND YOUR HELP !!!
Steve Hunter
57,712 PointsHey - no problem!
Glad you got it fixed!!!
Shout if you need help with other Rails issues; you can @ mention me in here to get a direct response. Nelly Nelly <-- like that ...
Nelly Nelly
7,134 PointsI will very soon thanks a lot ! I have a new issue.....
Steve Hunter
57,712 PointsHave you opened a new post? Tag me if you have - happy to have a look if I can help!
Nelly Nelly
7,134 PointsI am about to :) Steve Hunter