RSpec: All tests failing - ruby-on-rails

I am following the Ruby on Rails tutorial by Michael Hartl. My tests were all passing till I migrated the database and added the last 2 test. Something got messed up since all the tests are failing now even if I remove the last 2 tests. I am not sure if I made some mistake with the migrate or something else.
This is what I used:
$ bundle exec rake db:migrate
$ bundle exec rake db:test:prepare
$ bundle exec rspec spec/
Here's the user_spec file which fails completely:
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com", password: "foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " "}
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a"*51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo. foo#bar_baz.com foo#bar_baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
#user.should_not be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
#user.should be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when password is not present" do
before { #user.password = #user.password_confirmation = " " }
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "when password confirmation is nil" do
before { #user.password_confirmation = nil }
it { should_not be_valid }
end
end
And here is the migration file:
class AddPassswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
EDIT2 - I just removed password: "foobar", password_confirmation: "foobar" from the first line of the spec and now I only get 5 errors (which is right as those related to password should fail)
EDIT1 - Here are the failing tests
Running all specs
Running tests with args ["--drb", "-f", "progress", "-r", "/home/niranjan/.rvm/gems/ruby-1.9.3-p194/gems/guard-rspec-1.2.1/lib/guard/rspec/formatters/notification_rspec.rb", "-f", "Guard::RSpec::Formatter::NotificationRSpec", "--out", "/dev/null", "--failure-exit-code", "2", "spec"]...
..FFFFFFFFFFFFFFF.........
Failures:
1) User
Failure/Error: #user = User.new(name: "Example User", email: "user#example.com", password: "foobar", password_confirmation: "foobar")
ActiveRecord::UnknownAttributeError:
unknown attribute: password
# ./spec/models/user_spec.rb:16:in `new'
# ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'
2) User
Failure/Error: #user = User.new(name: "Example User", email: "user#example.com", password: "foobar", password_confirmation: "foobar")
ActiveRecord::UnknownAttributeError:
unknown attribute: password
# ./spec/models/user_spec.rb:16:in `new'
# ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'
3) User
Failure/Error: #user = User.new(name: "Example User", email: "user#example.com", password: "foobar", password_confirmation: "foobar")
ActiveRecord::UnknownAttributeError:
unknown attribute: password
# ./spec/models/user_spec.rb:16:in `new'
# ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'
4) User
Failure/Error: #user = User.new(name: "Example User", email: "user#example.com", password: "foobar", password_confirmation: "foobar")
ActiveRecord::UnknownAttributeError:
unknown attribute: password
# ./spec/models/user_spec.rb:16:in `new'
# ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'
.... and so on

From the book:
Putting everything together gives the (failing) tests in Listing 6.28. We’ll get them to pass in Section 6.3.4.
The tests should be failing. They will pass as soon as the password implementation is done, later on the tutorial.
Now, to explain why they are failing:
On the line where you create the user (your before block), you are passing the password attribute to the constructor, but that attribute doesn't exist yet, so your model complains with the errors you are seeing. On the tutorial this attribute is created a little later.

Related

User authenticate not passing rspec testing

I am following the Ruby on Rails Tutorial Learn Rails by Example Michael Hartli and am getting this error during rspec testing for authenticating the password. i think the other two errors are because of the first one. so just need a little help understanding whats going wrong and a solution.
Rays-MBP:sample_app raycove$ bundle exec rspec spec/
............F...............FF..
Failures:
1) User return value of authenticate method with valid password
Failure/Error: it { should == found_user.authenticate(#user.password) }
expected: #<User id: 6, name: "Example User", email: "user#example.com", created_at: "2016-02-19 21:45:28", updated_at: "2016-02-19 21:45:28", password_digest: "$2a$04$mweZJiYW0O/iDts7bCwUS.hb9GUznoH3nSGSeWdMHuW...">
got: #<User id: nil, name: "Example User", email: "user#example.com", created_at: nil, updated_at: nil, password_digest: "$2a$04$juZNb6HH/yrXQUhYBd.tCeFqWYnwuQs2x.batWwMWhY..."> (using ==)
Diff:
## -1,9 +1,9 ##
-#<User:0x007fa71611a4f8
- id: 6,
+#<User:0x007fa7161b0f70
+ id: nil,
name: "Example User",
email: "user#example.com",
- created_at: Fri, 19 Feb 2016 21:45:28 UTC +00:00,
- updated_at: Fri, 19 Feb 2016 21:45:28 UTC +00:00,
+ created_at: nil,
+ updated_at: nil,
password_digest:
- "$2a$04$mweZJiYW0O/iDts7bCwUS.hb9GUznoH3nSGSeWdMHuWpxMMAV2W42">
+ "$2a$04$juZNb6HH/yrXQUhYBd.tCeFqWYnwuQs2x.batWwMWhYJQtIAKvTou">
# ./spec/models/user_spec.rb:108:in `block (4 levels) in <top (required)>'
2) User pages profile page
Failure/Error: let(:user) { FactoryGirl.create(:user) }
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken
# ./spec/requests/user_pages_spec.rb:8:in `block (3 levels) in <top (required)>'
# ./spec/requests/user_pages_spec.rb:9:in `block (3 levels) in <top (required)>'
3) User pages profile page
Failure/Error: let(:user) { FactoryGirl.create(:user) }
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken
# ./spec/requests/user_pages_spec.rb:8:in `block (3 levels) in <top (required)>'
# ./spec/requests/user_pages_spec.rb:9:in `block (3 levels) in <top (required)>'
Finished in 0.34838 seconds
32 examples, 3 failures
Failed examples:
rspec ./spec/models/user_spec.rb:108 # User return value of authenticate method with valid password
rspec ./spec/requests/user_pages_spec.rb:11 # User pages profile page
rspec ./spec/requests/user_pages_spec.rb:12 # User pages profile page
Randomized with seed 13988
My user_pages_spec
require 'spec_helper'
describe "User pages" do
subject { page }
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_selector('h1', text: user.name) }
it { should have_selector('title', text: user.name) }
end
describe "signup page" do
before { visit signup_path }
it { should have_selector('h1', text: 'Sign up') }
it { should have_selector('title', text: 'Sign up') }
end
end
My user_spec
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:authenticate) }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
#user.should_not be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
#user.should be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when password is not present" do
before { #user.password = #user.password_confirmation = " " }
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "when password confirmation is nil" do
before { #user.password_confirmation = nil }
it { should_not be_valid }
end
describe "with a password that's too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by_email(#user.email) }
describe "with valid password" do
it { should == found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end
end
My user.rb
class User < ActiveRecord::Base
private
# Using a private method to encapsulate the permissible parameters
# is just a good pattern since you'll be able to reuse the same
# permit list between create and update. Also, you can specialize
# this method with per-user checking of permissible attributes.
def user_params
params.require(:user).permit :name, :email, :password, :password_confirmation
end
has_secure_password
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
end
I belive what is happening is when it runs through and gets to the describe "return value of authenticate method" do section in user_spec
it changed the password or something as the passwords dont match but they are pre set so this cant be, any help is very much appreciated.

RoR rspec failing test with error 'block (2 levels) in <top (required)>

I am following Hartls Rails tutorial and I am stuck at the end of Chapter 6.
Suddenly some of my test are failing with the same error:
C:\Users\JMA\Projekte\sampleapp>bundle exec rspec spec/
.F......F...FFF....
Failures:
1) User
Failure/Error: it { should respond_to(:passwors_confirmation)}
expected #<User id: nil, name: "Example User", email: "user#example.com",
created_at: nil, updated_at: nil, password_digest: "$2a$04$OMnlZgC9yWhxbQizs8MG
9uPMCd8LmMlO5MZzkuQyM8it..."> to respond to :passwors_confirmation
# ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'
2) User when name is not present when email format is valid should be valid
Failure/Error: expect(#user).to be_valid
expected #<User id: nil, name: " ", email: "user#foo.COM", created_at: ni
l, updated_at: nil, password_digest: "$2a$04$PtGxi4DjJWFezLFYy1jW5eaI7C/xxyBLXAG
zPepflo8r..."> to be valid, but got errors: Name can't be blank
# ./spec/models/user_spec.rb:51:in `block (5 levels) in <top (required)>'
# ./spec/models/user_spec.rb:49:in `each'
# ./spec/models/user_spec.rb:49:in `block (4 levels) in <top (required)>'
3) User when name is not present return value of authenticate method with vali
d password
Failure/Error: before { #user.safe }
NoMethodError:
undefined method `safe' for #<User:0x502bc30>
# ./spec/models/user_spec.rb:86:in `block (4 levels) in <top (required)>'
4) User when name is not present return value of authenticate method with inva
lid password
Failure/Error: before { #user.safe }
NoMethodError:
undefined method `safe' for #<User:0x50333a0>
# ./spec/models/user_spec.rb:86:in `block (4 levels) in <top (required)>'
5) User when name is not present return value of authenticate method with inva
lid password
Failure/Error: before { #user.safe }
NoMethodError:
undefined method `safe' for #<User:0x503b848>
# ./spec/models/user_spec.rb:86:in `block (4 levels) in <top (required)>'
Finished in 0.52003 seconds
19 examples, 5 failures
Failed examples:
rspec ./spec/models/user_spec.rb:16 # User
rspec ./spec/models/user_spec.rb:47 # User when name is not present when email f
ormat is valid should be valid
rspec ./spec/models/user_spec.rb:90 # User when name is not present return value
of authenticate method with valid password
rspec ./spec/models/user_spec.rb:96 # User when name is not present return value
of authenticate method with invalid password
rspec ./spec/models/user_spec.rb:97 # User when name is not present return value
of authenticate method with invalid password
Randomized with seed 37132
My user_specs.rb looks like this:
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:passwors_confirmation)}
it { should be_valid }
describe"when name is not present" do
before { #user.name = " " }
it { should_not be_valid}
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid}
end
describe "when name is to long" do
before { #user.name = "a" * 51 }
it { should_not be_valid}
end
describe "when email format is invalid" do
it "should be invalid" do
adresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
adresses.each do |invalid_adress|
#user.email = invalid_adress
expect(#user).not_to be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
end
describe "when email adress is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it {should_not be_valid}
end
it { should respond_to(:authenticate) }
describe "when password is not present" do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: " ", password_confirmation: " ")
end
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "with a password that's to short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { #user.safe }
let(:found_user) { User.find_by(email: #user.email) }
describe "with valid password" do
it { should eq found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let (:user_for_inavlid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_inavlid_password }
specify { expect(user_for_inavlid_password).to be_false }
end
end
end
end
users.rb
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence:true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
end
It appeared after adding the password and password_confirmation attributes to the User model. The where passing untill then. I have continued the tutorial becasue I have read about this failure and that it will be dealt with at a later stage of the tutorial. Now my tests are still failing and I do not know why. Any ideas?
The stack trace says:
Failure/Error: before { #user.safe }
NoMethodError:
undefined method `safe' for #<User:0x503b848>
# ./spec/models/user_spec.rb:86:in `block (4 levels) in <top (required)>'
It's telling you some key pieces of information:
The problem is happening on line 86 of user_spec.rb.
The problematic line of code is before { #user.safe }.
The problem is a NoMethodError which means you're trying to call a method on an object for which that method is not defined.
It tells you specifically that there is no method safe for #<User:0x503b848> which is an instance of the User class. From the context you should be able to deduce that it's referring to the #user variable in this context.
This is way more than enough information to deduce what cause of the problem is: you're calling #user.safe on line 86, and there is no such method safe for #user.
The solution to the problem is you probably mean to call save, not safe.
You have a few other failures for a couple other reasons. See if you can read the information in the error messages to understand the causes of the problems, then it should be easy to figure out on your own how to fix those problems.

Ruby on Rails, Michael Hartl;s Tutorial chapter 6.31

I got two tests that are failing in my application. I see that the problem is with the user's ID but I don't know how to solve it.
1) User return value of authenticate method with valid password
Failure/Error: it { should eq found_user.authenticate(#user.password) }
expected: #<User id: 2, name: "Example User", email: "user#example.com", created_at: "2014-08-09 17:17:22", updated_at: "2014-08-09 17:17:22", password_digest: "$2a$04$kQk6PkLu3X6rbTPiDDPce.zy6VYtAZ2rxchGLSP27VaG...">
got: #<User id: nil, name: "Example User", email: "user#example.com", created_at: nil, updated_at: nil, password_digest: "$2a$04$dccvbYxyrCa2M1LjxmwQqOBEEhYLNKrFmUh0GlAxH1bH...">
(compared using ==)
Diff:
## -1,2 +1,2 ##
-#<User id: 2, name: "Example User", email: "user#example.com", created_at: "2014-08-09 17:17:22", updated_at: "2014-08-09 17:17:22", password_digest: "$2a$04$kQk6PkLu3X6rbTPiDDPce.zy6VYtAZ2rxchGLSP27VaG...">
+#<User id: nil, name: "Example User", email: "user#example.com", created_at: nil, updated_at: nil, password_digest: "$2a$04$dccvbYxyrCa2M1LjxmwQqOBEEhYLNKrFmUh0GlAxH1bH...">
# ./spec/models/user_spec.rb:102:in `block (4 levels) in <top (required)>'
2) User email address with mixed case should be saved as all lower-case
Failure/Error: expect(#user.reload.email).to eq mixed_case_email.downcase
ActiveRecord::RecordNotFound:
Couldn't find User without an ID
# ./spec/models/user_spec.rb:72:in `block (3 levels) in <top (required)>'
Here is my user_spec.rb file :
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
end
subject {#user}
it {should respond_to(:name)}
it {should respond_to(:email)}
it {should respond_to(:password_digest)}
it {should respond_to(:password)}
it {should respond_to(:password_confirmation)}
it {should respond_to(:authenticate)}
describe "When name is not present" do
before {#user.name = " "}
it {should_not be_valid}
end
describe "When email is not present" do
before {#user.email = " "}
it {should_not be_valid}
end
describe "When name is too long" do
before {#user.name = "a"*51}
it {should_not be_valid}
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
expect(#user).not_to be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "email address with mixed case" do
let(:mixed_case_email) { "Foo#ExAMPle.CoM" }
it "should be saved as all lower-case" do
#user.email = mixed_case_email
#user.save
expect(#user.reload.email).to eq mixed_case_email.downcase
end
end
#PASSWORD
describe "when password is not present" do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: " ", password_confirmation: " ")
it { should_not be_valid }
end
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "with a password that's too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by(email: #user.email) }
describe "with valid password" do
it { should eq found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_invalid_password }
specify { expect(user_for_invalid_password).to be_false }
end
end
end
And the user.rb file
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
end
Change
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
to
#user = User.create(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
new just creates a model but doesnt save it to DB whereas
create creates the model AND saves it to DB
other option is to use save
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
#user.save
(For the 2º test) You have to save the user in a before block
describe "email address with mixed case" do
let(:mixed_case_email) { "Foo#ExAMPle.CoM" }
before do
#user.email = mixed_case_email
#user.save
end
it "should be saved as all lower-case" do
expect(#user.reload.email).to eq mixed_case_email.downcase
end
end
That is the problem which causes "Couldn't find User without an ID"
The error is here:
specify { expect(user_for_invalid_password).to be_false }
this line is wrong, correct one is:
specify { expect(user_for_invalid_password).to be false }

undefined method Hartl chapter 6

I'm currently working on 6.3.3 of Hartl's tutorial http://www.railstutorial.org/book/modeling_users
after running rspec spec/ I'm getting the following failures - I'm sure I'm misunderstanding the instructions or something. I'm grateful for any insight into what I'm doing wrong:
leo$ rspec spec/
............FFF...................
Failures:
1) User return value of authenticate method with invalid password
Failure/Error: let(:user_for_invalid_password) { found_user.authenticate("invalid") }
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./spec/models/user_spec.rb:92:in `block (4 levels) in <top (required)>'
# ./spec/models/user_spec.rb:95:in `block (4 levels) in <top (required)>'
2) User return value of authenticate method with invalid password
Failure/Error: it { should_not eq user_for_invalid }
NameError:
undefined local variable or method `user_for_invalid' for # <RSpec::Core::ExampleGroup::Nested_2::Nested_10::Nested_2:0x007faed251c830>
# ./spec/models/user_spec.rb:94:in `block (4 levels) in <top (required)>'
3) User return value of authenticate method with valid password
Failure/Error: it { should eq found_user.authenticate(#user.password) }
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./spec/models/user_spec.rb:88:in `block (4 levels) in <top (required)>'
Finished in 0.24185 seconds
34 examples, 3 failures
Failed examples:
rspec ./spec/models/user_spec.rb:95 # User return value of authenticate method with invalid password
rspec ./spec/models/user_spec.rb:94 # User return value of authenticate method with invalid password
rspec ./spec/models/user_spec.rb:88 # User return value of authenticate method with valid password
here is what I have in my user_spec.rb file:
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:authenticate) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo. foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
expect(#user).not_to be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-er#f.b.org frst.1st#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when password is not present" do
before do
#user = User.new(name: "Example User", email: "user#example.com", password: " ", password_confirmation: " ")
end
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "with a password that's too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by(email: #user.password) }
describe "with valid password" do
it { should eq found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_invalid }
specify { expext(user_for_invalid_password).to be_false }
end
end
end
and here's what I have in my user.rb file:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum:6 }
end
Found your typo:
describe "return value of authenticate method" do
# should find by #user.email
let(:found_user) { User.find_by(email: #user.password) }
end

Rails: Unknown Attribute error in ruby on rails

I'm going through the railstutorial.org book and getting Unknown attribute error in code
My User.rb file code is
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class User < ActiveRecord::Base
attr_accessible :email, :name, :password, :password_confirmation
validates :name,presence:true,length: { maximum:50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email,presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness:{ :case_sensitive => false }
before_save { |user| user.email = email.downcase }
end
and my user_spec.rb file code is
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com" , password:"foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it {should respond_to(:password) }
it {should respond_to(:password_confirmation)}
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
#user.should_not be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
#user.should be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when password is not present" do
before { #user.password = #user.password_confirmation = " " }
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
end
and what is going in terminal is
ritesh#ritesh-desktop:~/projects/sample_app$ rails console
Loading development environment (Rails 3.2.9)
1.9.3p327 :001 > User.create(name: "Michael Hartl", email: "mhartl#example.com", password: "foobar", password_confirmation: nil)
ActiveRecord::UnknownAttributeError: unknown attribute: password
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/attribute_assignment.rb:88:in `block in assign_attributes'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/attribute_assignment.rb:78:in `each'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/base.rb:497:in `initialize'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/persistence.rb:44:in `new'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/persistence.rb:44:in `create'
from (irb):1
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.9/lib/rails/commands/console.rb:47:in `start'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.9/lib/rails/commands/console.rb:8:in `start'
from /home/ritesh/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.9/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
1.9.3p327 :002 >
please give some clue how to run rectify this error!!
Add a column by generating a migration:
rails generate migration AddPasswordToUsers password:string
Then run:
rake db:migrate
However, it looks like you're attempting to use has_secure_password, though you haven't added it to your User model. If this is the case, add the line has_secure_password to your User model and run this migration instead:
rails generate migration AddPasswordDigestToUsers password_digest:string
I faced this same issue when working on a Ruby on Rails application with a PostgreSQL database in production.
Here's how I solved it:
The issue was that I added some new columns to the table(s) in my development environment using migration files, but when I made a push to the production environment, I didn't create those new columns via migration.
All I had to do was to simply run a database migration in the production environment.
rails db:migrate
That's all.
I hope this helps

Resources