2012-01-23 4 views
0

저는 RoR-Learner입니다. Michael Hartl이 RoR-Tutorial을 만들었지 만 실제로 10.4 장의 문제에 직면하고 있습니다. 모든 리스팅을 10.42 개까지 만들었지 만, 내 Rspec 테스트 중 3 개가 실패했습니다.RoR 튜토리얼 (10.4 장) - 관리자 속성 테스트가 실패했습니다.

은 말한다 :

1) Users admin attribute should respond to admin Failure/Error: @user = User.create!(@attr) ActiveRecord::RecordInvalid: Validation failed: Name can't be blank, Email can't be blank, Email is invalid, Password can't be blank, Password is too short (minimum is 6 characters) ./spec/requests/users_spec.rb:52:in `block (3 levels) in

2) Users admin attribute should not be an admin by default Failure/Error: @user = User.create!(@attr) ActiveRecord::RecordInvalid: Validation failed: Name can't be blank, Email can't be blank, Email is invalid, Password can't be blank, Password is too short (minimum is 6 characters) ./spec/requests/users_spec.rb:52:in `block (3 levels) in

3) Users admin attribute should be convertible to an admin Failure/Error: @user = User.create!(@attr) ActiveRecord::RecordInvalid: Validation failed: Name can't be blank, Email can't be blank, Email is invalid, Password can't be blank, Password is too short (minimum is 6 characters) ./spec/requests/users_spec.rb:52:in `block (3 levels) in

나는 이미 내 users_controllers_spec.rb 내 user_spec.rb에 신중한 모습을했다,하지만 난 실수에 대한 설명을 찾을 수 없습니다. 누구나 아이디어가 있습니까?

require 'spec_helper' 

describe UsersController do 
    render_views 

    describe "GET 'index'" do 

    describe "for non-signed-in users" do 
     it "should deny access" do 
     get :index 
     response.should redirect_to(signin_path) 
     flash[:notice].should =~ /sign in/i 
     end 
    end 

    describe "for signed-in users" do 

     before(:each) do 
     @user = test_sign_in(Factory(:user)) 
     second = Factory(:user, :name => "Bob", :email => "[email protected]") 
     third = Factory(:user, :name => "Ben", :email => "[email protected]") 
     #@users = [@user, second, third] 
     @users = [@user, second, third] 
     30.times do 
      @users << Factory(:user, :name => Factory.next(:name), 
            :email => Factory.next(:email)) 
     end 
     end 


     it "should be successful" do 
     get :index 
     response.should be_success 
     end 

     it "should have the right title" do 
     get :index 
     response.should have_selector("title", :content => "All users") 
     end 

    it "should have an element for each user" do 
     get :index 
     @users[0..2].each do |user| 
      response.should have_selector("li", :content => user.name) 
     end 
     end 

     it "should paginate users" do 
     get :index 
     response.should have_selector("div.pagination") 
     response.should have_selector("span.disabled", :content => "Previous") 
     response.should have_selector("a", :href => "/users?escape=false&page=2", 
              :content => "2") 
     response.should have_selector("a", :href => "/users?escape=false&page=2", 
              :content => "Next") 
     end 
    end 
    end 



    describe "GET 'show'" do 

     before(:each) do 
      @user = Factory(:user) 
     end 

     it "should be successful" do 
      get :show, :id => @user 
      response.should be_success 
     end 

     it "should find the right user" do 
      get :show, :id => @user 
      assigns(:user).should == @user 
     end 

    it "should have the right title" do 
      get :show, :id => @user 
      response.should have_selector("title", :content => @user.name) 
     end 

     it "should include the user's name" do 
      get :show, :id => @user 
      response.should have_selector("h1", :content => @user.name) 
     end 

     it "should have a profile image" do 
      get :show, :id => @user 
      response.should have_selector("h1>img", :class => "gravatar") 
     end 
     end 

     describe "GET 'new'" do 
     it "should be successful" do 
      get 'new' 
      response.should be_success 
     end 

     it "should have the right title" do 
      get 'new' 
      response.should have_selector("title", :content => "Sign up") 
     end 
     end 
     describe "POST 'create'" do 

     describe "failure" do 

      before(:each) do 
      @attr = { :name => "", :email => "", :password => "", 
         :password_confirmation => "" } 
      end 

      it "should not create a user" do 
      lambda do 
       post :create, :user => @attr 
      end.should_not change(User, :count) 
      end 

      it "should have the right title" do 
      post :create, :user => @attr 
      response.should have_selector("title", :content => "Sign up") 
      end 

      it "should render the 'new' page" do 
      post :create, :user => @attr 
      response.should render_template('new') 
      end 
     end 


     describe "success" do 

      before(:each) do 
      @attr = { :name => "New User", :email => "[email protected]", 
         :password => "foobar", :password_confirmation => "foobar" } 
      end 

      it "should create a user" do 
      lambda do 
       post :create, :user => @attr 
      end.should change(User, :count).by(1) 
      end 

      it "should redirect to the user show page" do 
      post :create, :user => @attr 
      response.should redirect_to(user_path(assigns(:user))) 
      end  

      it "should have a welcome message" do 
      post :create, :user => @attr 
      flash[:success].should =~ /welcome to the sample app/i 
      end 

      it "should sign the user in" do 
      post :create, :user => @attr 
      controller.should be_signed_in 
      end 


     end 
     end 
    describe "GET 'edit'" do 

     before(:each) do 
      @user = Factory(:user) 
      test_sign_in(@user) 
     end 

     it "should be successful" do 
      get :edit, :id => @user 
      response.should be_success 
     end 

     it "should have the right title" do 
      get :edit, :id => @user 
      response.should have_selector("title", :content => "Edit user") 
     end 

     it "should have a link to change the Gravatar" do 
      get :edit, :id => @user 
      gravatar_url = "http://gravatar.com/emails" 
      response.should have_selector("a", :href => gravatar_url, 
              :content => "change") 
     end 
     end 
    describe "PUT 'update'" do 

     before(:each) do 
      @user = Factory(:user) 
      test_sign_in(@user) 
     end 

     describe "failure" do 

      before(:each) do 
      @attr = { :email => "", :name => "", :password => "", 
         :password_confirmation => "" } 
      end 

      it "should render the 'edit' page" do 
      put :update, :id => @user, :user => @attr 
      response.should render_template('edit') 
      end 

      it "should have the right title" do 
      put :update, :id => @user, :user => @attr 
      response.should have_selector("title", :content => "Edit user") 
      end 
     end 

     describe "success" do 

      before(:each) do 
      @attr = { :name => "New Name", :email => "[email protected]", 
         :password => "barbaz", :password_confirmation => "barbaz" } 
      end 

      it "should change the user's attributes" do 
      put :update, :id => @user, :user => @attr 
      @user.reload 
      @user.name.should == @attr[:name] 
      @user.email.should == @attr[:email] 
      end 

      it "should redirect to the user show page" do 
      put :update, :id => @user, :user => @attr 
      response.should redirect_to(user_path(@user)) 
      end 

      it "should have a flash message" do 
      put :update, :id => @user, :user => @attr 
      flash[:success].should =~ /updated/ 
      end 
     end 
     end 
    describe "authentication of edit/update pages" do 

     before(:each) do 
      @user = Factory(:user) 
     end 

     describe "for non-signed-in users" do 

      it "should deny access to 'edit'" do 
      get :edit, :id => @user 
      response.should redirect_to(signin_path) 
      end 

      it "should deny access to 'update'" do 
      put :update, :id => @user, :user => {} 
      response.should redirect_to(signin_path) 
      end 
     end 

     describe "for signed-in users" do 

      before(:each) do 
      wrong_user = Factory(:user, :email => "[email protected]") 
      test_sign_in(wrong_user) 
      end 

      it "should require matching users for 'edit'" do 
      get :edit, :id => @user 
      response.should redirect_to(root_path) 
      end 

      it "should require matching users for 'update'" do 
      put :update, :id => @user, :user => {} 
      response.should redirect_to(root_path) 
      end 
     end 
     end 

    describe "DELETE 'destroy'" do 

     before(:each) do 
      @user = Factory(:user) 
     end 

     describe "as a non-signed-in user" do 
      it "should deny access" do 
      delete :destroy, :id => @user 
      response.should redirect_to(signin_path) 
      end 
     end 

     describe "as a non-admin user" do 
      it "should protect the page" do 
      test_sign_in(@user) 
      delete :destroy, :id => @user 
      response.should redirect_to(root_path) 
      end 
     end 

     describe "as an admin user" do 

      before(:each) do 
      admin = Factory(:user, :email => "[email protected]", :admin => true) 
      test_sign_in(admin) 
      end 

      it "should destroy the user" do 
      lambda do 
       delete :destroy, :id => @user 
      end.should change(User, :count).by(-1) 
      end 

      it "should redirect to the users page" do 
      delete :destroy, :id => @user 
      response.should redirect_to(users_path) 
      end 
     end 
     end 
    end 

내 user_spec.rb

require 'spec_helper' 

describe User do 

    before(:each) do 
    @attr = { 
     :name => "Example User", 
     :email => "[email protected]", 
     :password => "foobar", 
     :password_confirmation => "foobar" 
    } 
    end 

    it "should create a new instance given valid attributes" do 
    User.create!(@attr) 
    end 
    it "should require a name" do 
    no_name_user = User.new(@attr.merge(:name => "")) 
    no_name_user.should_not be_valid 
    end 

    it "should require an email address" do 
    no_email_user = User.new(@attr.merge(:email => "")) 
    no_email_user.should_not be_valid 
    end 

    it "should reject names that are too long" do 
    long_name = "a" * 51 
    long_name_user = User.new(@attr.merge(:name => long_name)) 
    long_name_user.should_not be_valid 
    end 

    it "should accept valid email addresses" do 
    addresses = %w[[email protected] [email protected] [email protected]] 
    addresses.each do |address| 
     valid_email_user = User.new(@attr.merge(:email => address)) 
     valid_email_user.should be_valid 
    end 
    end 

    it "should reject invalid email addresses" do 
    addresses = %w[[email protected],com user_at_foo.org [email protected]] 
    addresses.each do |address| 
     invalid_email_user = User.new(@attr.merge(:email => address)) 
     invalid_email_user.should_not be_valid 
    end 
    end 

    it "should reject duplicate email addresses" do 
    # Put a user with given email address into the database. 
    User.create!(@attr) 
    user_with_duplicate_email = User.new(@attr) 
    user_with_duplicate_email.should_not be_valid 
    end 

    it "should reject email addresses identical up to case" do 
    upcased_email = @attr[:email].upcase 
    User.create!(@attr.merge(:email => upcased_email)) 
    user_with_duplicate_email = User.new(@attr) 
    user_with_duplicate_email.should_not be_valid 
    end 


    describe "password validations" do 

    it "should require a password" do 
     User.new(@attr.merge(:password => "", :password_confirmation => "")). 
     should_not be_valid 
    end 

    it "should require a matching password confirmation" do 
     User.new(@attr.merge(:password_confirmation => "invalid")). 
     should_not be_valid 
    end 

    it "should reject short passwords" do 
     short = "a" * 5 
     hash = @attr.merge(:password => short, :password_confirmation => short) 
     User.new(hash).should_not be_valid 
    end 

    it "should reject long passwords" do 
     long = "a" * 41 
     hash = @attr.merge(:password => long, :password_confirmation => long) 
     User.new(hash).should_not be_valid 
    end 
    end 

    describe "password encryption" do 

    before(:each) do 
     @user = User.create!(@attr) 
    end 

    it "should have an encrypted password attribute" do 
     @user.should respond_to(:encrypted_password) 
    end 

    it "should set the encrypted password" do 
     @user.encrypted_password.should_not be_blank 
    end 

    describe "has_password? method" do 

     it "should be true if the passwords match" do 
     @user.has_password?(@attr[:password]).should be_true 
     end  

     it "should be false if the passwords don't match" do 
     @user.has_password?("invalid").should be_false 
     end 
    end 
    end  
    describe "authenticate method" do 

     it "should return nil on email/password mismatch" do 
     wrong_password_user = User.authenticate(@attr[:email], "wrongpass") 
     wrong_password_user.should be_nil 
     end 

     it "should return nil for an email address with no user" do 
     nonexistent_user = User.authenticate("[email protected]", @attr[:password]) 
     nonexistent_user.should be_nil 
     end 

     it "should return the user on email/password match" do 
     matching_user = User.authenticate(@attr[:email], @attr[:password]) 
     matching_user.should == @user 
     end 
    end 

    describe "admin attribute" do 

    before(:each) do 
     @user = User.create!({ 
     :name => "Example User", 
     :email => "[email protected]", 
     :password => "foobar", 
     :password_confirmation => "foobar" 
    })#(@attr) 

//EDIT: I tried both, the fill-in by hand an the original code with (@attr) --> nothing changes, still the same mistake 

    end 

    it "should respond to admin" do 
     @user.should respond_to(:admin) 
    end 

    it "should not be an admin by default" do 
     @user.should_not be_admin 
    end 

    it "should be convertible to an admin" do 
     @user.toggle!(:admin) 
     @user.should be_admin 
    end 
    end 
end 

편집이다 : User.rb

== Schema Information 

Table name: users 

    id   :integer   not null, primary key 
    name  :string(255) 
    email  :string(255) 
    created_at :datetime 
    updated_at :datetime 
//it's outcommented 

class User < ActiveRecord::Base 
attr_accessor :password 
    attr_accessible :name, :email, :password, :password_confirmation 

email_regex = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 


validates :name, :presence => true, 
:length => { :maximum => 50 } 

validates :email, :presence => true, 
:format => { :with => email_regex }, 
:uniqueness => { :case_sensitive => false } 

validates :password, :presence  => true, 
         :confirmation => true, 
         :length  => { :within => 6..40 } 

    before_save :encrypt_password 

    def has_password?(submitted_password) 
    encrypted_password == encrypt(submitted_password) 
    end 

    def self.authenticate_with_salt(id, cookie_salt) 
    user = find_by_id(id) 
    (user && user.salt == cookie_salt) ? user : nil 
    end 

    def self.authenticate(email, submitted_password) 
    user = find_by_email(email) 
    return nil if user.nil? 
    return user if user.has_password?(submitted_password) 
    end 

    def self.authenticate(email, submitted_password) 
    user = find_by_email(email) 
    return nil if user.nil? 
    return user if user.has_password?(submitted_password) 
    end 

    private 

    def encrypt_password 
     self.salt = make_salt unless has_password?(password) 
     self.encrypted_password = encrypt(password) 
    end 

    def encrypt(string) 
     secure_hash("#{salt}--#{string}") 
    end 

    def make_salt 
     secure_hash("#{Time.now.utc}--#{password}") 
    end 

    def secure_hash(string) 
     Digest::SHA2.hexdigest(string) 
    end 



end 

몇 가지 중요한 사항이없는 경우, 나는이 게시물을 업데이트 할 준비를하겠습니다, 문의하시기 바랍니다 (코드가 이미 충분히 거대하기 때문에 과부하를 원하지 않았습니다.)

감사합니다.

답변

1

나는 최근이 같은 문제가 건너와 작성 메소드 호출에서 뱅 (!)를 제거하여 해결 한 :

@user = User.create(@attr) 

HTH

,
+0

실마리가 없습니다. 왜, 그러나 그것은 작동합니다! 감사합니다. –

0

귀하의 user_spec.rb가 자습서의 목록 10.34에있는 것과 일치하지 않습니다. 구체적으로는 before(:each) 블록입니다.

당신의 user_spec.rb :

before(:each) do 
    @user = User.create!({ 
    :name => "Example User", 
    :email => "[email protected]", 
    :password => "foobar", 
    :password_confirmation => "foobar" 
    })#(@attr) 
end 

는 10.34 목록 :

before(:each) do 
    @user = User.create!(@attr) 
end 
+0

글쎄, 그 전에 (# (@ attr)),하지만 작동하지 않았다. 그래서 실수로 변경되었는지 확인하기 위해 직접 채워 보려고했습니다. 그러나 그것들은 절대적으로 동일하며 또한 (@attr)과 함께 있습니다. (내가 이미 시도한 것을 보여주고 싶었습니다.) –

+0

실제로 나는 이전 예제에서 작동하는 것 같아 이상하게 생각하고'@ attr'이 어디서든 변경되고 있다는 것을 알 수 없습니다. 어쩌면 당신은'{'와'} '를 속성, 그게 차이가 있는지 확실하지 않다. – jlundqvist

+0

그게, 나도 이해가 안돼 :/어떻게 와서 (@attr)가 갑자기 작동하지 않는거야? 그냥 {그리고} 밖으로 나가려고했지만 당신은 맞습니다. 차이는 없습니다. –

관련 문제