0

Ruby on Rails に関する Michael Hartl の優れたチュートリアルに従っています。ActionDispatch::Responseの仕組みを理解しようとして困っています。これは、第 9 章の演習 9 (Rails バージョン 3.2.3) から派生しています。

特に、管理者ユーザーがUser#destroy自分自身にアクセスできないようにするよう求められます。私はそれを行う方法を考えていますが、TDD の方法論に従おうとしているので、最初にテストを作成しています。

これは私のテストに関連するスニペットです:

describe "authorization" do
    describe "as non-admin user" do
        let(:admin) {FactoryGirl.create(:admin)}
        let(:non_admin) {FactoryGirl.create(:user)}

        before{valid_signin non_admin}

        describe "submitting a DELETE request to the Users#destroy action" do
            before do
                delete user_path(admin)
                #puts response.message
                puts response.succes?
            end
            specify{ response.should redirect_to(root_path) }
            specify{ response.should_not be_success }
        end
    end
    #Exercise 9.6-9 prevent admin from destroying himself
    describe "as admin user" do
        let(:admin){FactoryGirl.create(:admin)}
        let(:non_admin){FactoryGirl.create(:user)}

        before do 
            valid_signin admin
        end
        it "should be able to delete another user" do
            expect { delete user_path(non_admin) }.to change(User, :count).by(-1)
        end

        describe "can destroy others" do
            before do 
                puts admin.admin?
                delete user_path(non_admin)
                puts response.success?
            end
            #specify{response.should be_success}
            specify{response.should_not be_redirect}
        end 

        describe "cannot destroy himself" do
            before do
                delete user_path(admin)
                puts response.success?
            end
            #specify{response.should_not be_success}
            specify{response.should be_redirect}
        end 
    end

.
.
.
end

テストを除くすべてのテストに合格し"can destroy others"ます。

ただしputs response.success?すべてのdeleteリクエストの後に常に を取得するFalseと、リクエストはどれも「成功」しません。

手動で webapp とやり取りしてユーザーを削除することは問題なく機能するため、 (またはその問題に関する要求が) 成功しなかったresponse.successことを意味するのではなく、別のことを意味すると思います。HTTP レスポンス 200/302/400detroyの違いと関係があると読みましたが、完全にはわかりません。

記録のために、これは私のものUser#destroyです:

def destroy
    User.find(params[:id]).destroy
    flash[:success]="User destroyed."
    redirect_to users_path
end

これについて何か光がありますか?ありがとう!

編集

これは私の工場です:

FactoryGirl.define do
    factory :user do
        sequence(:name){ |n| "Person #{n}" }
        sequence(:email){ |n| "person_#{n}@example.com"}
        password "foobar"
        password_confirmation "foobar"

        factory :admin do
            admin true
        end
    end

end

@Peter Alfvinの提案に従って2を編集し、行を変更しました

let(:user){FactoryGirl.create(:user)}

let(:admin){FactoryGirl.create(:admin)}

そして、すべて一般useradminに。リクエストのputs admin.admin?前にa も追加しました。deleteまだ動作していません!

編集 3

テスト"can destroy others"を次のように変更します。

describe "can destroy others" do
  before do 
    puts admin.admin?
    delete user_path(non_admin)
    puts response.success?
  end

  #specify{response.should be_success}
  specify{response.should_not be_redirect}

end

どちらも役に立たないようです。

4

3 に答える 3

1

「管理者」の場合、管理者ユーザーではなく「通常の」ユーザーとして作成およびログインしているため、他のユーザーを破壊することはできません。

于 2013-09-24T19:51:57.463 に答える
1

response.success は確かに HTTP 応答コードを参照しています。デフォルトでは、これは 200 の範囲にあると思います。redirect_to は 300 の範囲にあります。

于 2013-09-24T19:55:08.590 に答える
0

ユーザーファクトリーにこの行が含まれていることを確認してください

factory :user do
  #your user factory code
  factory :admin do 
    admin true
  end
end

次にFactoryGirl.create(:admin)、管理者ユーザーを返すかuser.toggle!(:admin)、標準ユーザーを管理者ユーザーに切り替えることもできます。

それからこれを試してください

describe "as admin user" do
    let(:admin){FactoryGirl.create(:admin)}
    let(:non_admin){FactoryGirl.create(:user)}

    before do 
        valid_signin admin
    end
    it "should be able to delete another user" do
        expect { delete user_path(non_admin) }.to change(User, :count).by(-1)
    end

    it "can destroy others" do  #
        before do 
            puts admin.admin?
            delete user_path(non_admin)
            puts response.success?
        end
        #specify{response.should be_success}
        specify{response.should_not be_redirect}
    end 

    it "cannot destroy himself" do
        before do
            delete user_path(admin)
            puts response.success?
        end
        #specify{response.should_not be_success}
        specify{response.should be_redirect}
    end 
end

describe はマジック クラスを作成し、私の理解では describe クラスのサブクラスになります。Rails にはこの魔法がたくさんあり、混乱を招く可能性があります。また、私はあなたのコントローラを見たことがありませんが、チュートリアルに従った場合delete、ブラウザを介して送信destroyされるリダイレクトがあるため、ユーザーを破棄すると何が起こると予想されますか?コントローラーではなく仕様が間違っているため、常に失敗します。UsersControllerredirect_to users_urlresponse.should_not be_redirect

于 2013-09-24T20:35:57.300 に答える