4

Capybara 1.1.2、Rails 3.1.3、rspec-rails 2.9.0、Ruby1.9.3p0を使用しています。

標準ユーザーとaccount_adminユーザーがいるアプリを想定します。標準ユーザーは別の標準ユーザーを作成できますが、標準ユーザーはaccount_adminユーザーを作成できません。

もちろん、UIには、標準ユーザーにアカウント管理者を作成するオプションはありません。ただし、Firebugを使用すると30秒で、ユーザーはHTMLを書き直して、POSTリクエストを送信してaccount_adminを作成できます。

私のアプリがこの種の単純なハッキングを防ぐことをテストするにはどうすればよいですか?

通常の標準ユーザーテストは次のようになります。

context "when standard user is signed in" do

  before do
    login_as standard_user
    visit users_path       # go to index
    click_link('Add user') # click link like user would
  end

  describe "when fields are filled in" do

    let(:new_email) { "new_user@example.com" }

    before do
      fill_in "Email", with: new_email
      fill_in "Password", with: "password"
      fill_in "Password confirmation", with: "password"
      choose "Standard user" # radio button for Role
    end

    it "should create a user" do
      expect { click_button submit }.to change(User, :count).by(1)
    end

  end

end

フォームで許可されていない値を取得するようにテストを「だます」方法はありますか?ラジオボタンをテキストフィールドのように扱ってみましたが、Capybaraはそれを存在しないフィールドとして拒否します。

fill_in "Role", with: "account_admin" # doesn't work

paramsハッシュの直接変更も機能しません。

params[:role] = "account_admin" # doesn't work

これをコントローラーテストのように、直接呼び出す必要がありpost :createますか?

4

1 に答える 1

2

Capybaraの作者であるjnicklasは、CapybaraがUIから利用できないことをアプリに実行させることはできないことをここで確認しました。彼は、承認のためにコントローラーテストを推奨しています。

ただし、Capybara構文を使用せずにRSpecで記述されたリクエスト仕様では、 RSpecおよびRailsのドキュメントで概説されているように、HTML動詞(およびいくつかの追加のヘルパー)を直接使用できます。したがって、Capybaraのディレクティブとfill_inオブジェクトではなく、属性ハッシュ、、、、などの動詞、およびオブジェクトを使用できます。これはコントローラーテストに似ていますが、Railsのルーティングを使用して、提供されたパスに基づいて適切なコントローラーアクションを選択します。後者の手法の例を次に示します。click_linkpagegetpostpost_via_redirectresponse.body

describe "when standard user attempts to create account_admin user" do

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

  let(:attr) { { email: "account_admin@example.com",
                 password: "password",
                 password_confirmation: "password",
                 role: "account_admin" }
              }

  before do
    login_as standard_user
    get new_user_path
  end

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

  describe "after user posts invalid create" do
    before { post_via_redirect users_path, user: attr }

    # redirect to user's profile page
    it { response.body.should have_selector('title', text: 'User Profile') }
    it { response.body.should have_selector('div.alert.alert-error', text: 'not authorized') }
  end

end  
于 2012-04-26T23:45:18.630 に答える