10

CanCanを使用してリソースを承認するRailsプロジェクトに取り組んでいます。ユーザーがサインインしておらず、(ajaxフォーム送信を介して)「トーク」を送信しようとすると、CanCan{"status":"error","message":"You must be logged in to do that!"}は応答として401を正しく発生させます(これはブラウザでfirebugを使用して確認しました)。ただし、私のテストでは、401ではなく302応答コードを取得します。

class TalksController < ApplicationController
  authorize_resource

  def create
    @talk = current_user.talks.build(params[:talk])

    respond_to do |format|
      if @talk.save
        response = { :redirect => talk_path(@talk) }
        format.html { redirect_to @talk, notice: 'Talk was successfully created.' }
        format.json { render json: response, status: :created,  }
      else
        format.html { render action: "new" }
        format.json { render json: @talk.errors, status: :unprocessable_entity }
      end
    end
  end
end

talks_controller_spec.rb:

describe TalksController do
  describe "POST create" do
    context "when not signed in" do
      it "should not assign talk" do
        post :create
        assigns[:talk].should be_nil
      end
      it "should respond with a 401" do
        post :create
        response.response_code.should == 401
      end
    end
  end
end

ここに含まれる最初の例は成功しますが(assigns [:talk]は割り当てられません)、2番目の例は成功しません。

1) TalksController POST create when not signed in should respond with a 401
     Failure/Error: response.response_code.should == 401
       expected: 401
            got: 302 (using ==)
     # ./spec/controllers/talks_controller_spec.rb:53:in `block (4 levels) in <top (required)>'

何が起こっているのか正確にはわかりません。ブラウザに返される実際の応答コードをテストする方法はありますか?または、承認をテストするためのより良い方法はありますか?

4

1 に答える 1

9

結局のところ、私のプロジェクトは次の関数を使用してCanCanからの承認例外を救出しました。この関数は、リクエストがajaxの場合にのみ401を発生させる(そしてそれ以外の場合はリダイレクトする)ため、ブラウザーで401を取得していましたが、テストでは取得していませんでした。

# Handle authorization exceptions
rescue_from CanCan::AccessDenied do |exception|
  if request.xhr?
    if signed_in?
      render json: {:status => :error, :message => "You don't have permission to #{exception.action} #{exception.subject.class.to_s.pluralize}"}, :status => 403
    else
      render json: {:status => :error, :message => "You must be logged in to do that!"}, :status => 401
    end
  else
    render :file => "public/401.html", :status => :unauthorized
  end
end

リクエストの違いが明らかになったので、テストログをチェックすることを提案してくれたzeteticに感謝します。

于 2011-10-11T02:33:31.537 に答える