RoR Tutorial (глава 10.4) - тесты атрибутов администратора не пройдены - PullRequest
0 голосов
/ 23 января 2012

Я учусь на RoR и прошел путь к RoR-Tutorial от Michael Hartl, но на самом деле я столкнулся с проблемой в главе 10.4.Я выполнил все листинги до 10.42, но 3 из моих Rspec-тестов провалились.

Там написано:

1) Атрибут администратора пользователя должен реагировать на ошибку администратора. Ошибка / ошибка: @user = User.create! (@ Attr) ActiveRecord :: RecordInvalid: Ошибка проверки:Имя не может быть пустым, электронная почта не может быть пустой, электронная почта недействительна, пароль не может быть пустым, пароль слишком короткий (минимум 6 символов) ./spec/requests/users_spec.rb:52:in `block(3 уровня) в

2) Атрибут администратора пользователя по умолчанию не должен быть администратором. Ошибка / Ошибка: @user = User.create! (@ Attr) ActiveRecord :: RecordInvalid: Ошибка проверки: имя не можетбыть пустым, адрес электронной почты не может быть пустым, адрес электронной почты недействителен, пароль не может быть пустым, пароль слишком короткий (минимум 6 символов) ./spec/requests/users_spec.rb:52:in `block (3 уровня)в

3) Атрибут администратора пользователя должен быть преобразован в администратора. Ошибка / Ошибка: @user = User.create! (@ attr) ActiveRecord :: RecordInvalid: Ошибка проверки: имя не может быть пустым, электронная почта можетне должно быть пустым, адрес электронной почты недействителен, пароль не может быть пустым, пароль слишком короткий (миминимум 6 символов) ./spec/requests/users_spec.rb:52:in `блок (3 уровня) в

Я уже внимательно посмотрел на свои 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 => "another@example.com")
        third  = Factory(:user, :name => "Ben", :email => "another@example.net")
        #@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 => "user@example.com",
                      :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 => "user@example.org",
                      :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 => "user@example.net")
            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 => "admin@example.com", :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 => "user@example.com",
      :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[user@foo.com THE_USER@foo.bar.org first.last@foo.jp]
    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[user@foo,com user_at_foo.org example.user@foo.]
    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("bar@foo.com", @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 => "user@example.com",
      :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+\-.]+@[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

Если некоторые важные детали отсутствуютПожалуйста, спросите, я готов обновить этот пост (просто не хотел его перегружать, потому что код уже достаточно большой).

Спасибо за ваше внимание!

Ответы [ 2 ]

1 голос
/ 26 января 2012

Я только недавно столкнулся с этой же проблемой и решил ее, удалив взрыв (!) из вызова метода create:

@user = User.create(@attr)

HTH

0 голосов
/ 23 января 2012

Ваш user_spec.rb не совпадает с тем, что приведен в листинге 10.34 в руководстве.Более конкретно, блок before(:each).

your user_spec.rb:

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

Листинг 10.34:

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