Как мне протестировать приложение Rails с управлением правами? - PullRequest
0 голосов
/ 13 августа 2010

Я работаю над приложением Rails, которое требует, чтобы вы вошли в систему, чтобы увидеть что-нибудь.Для модульных тестов это не проблема, поскольку они взаимодействуют с моделью напрямую.Для интеграционных тестов это не большая проблема, так как я могу просто войти в соответствующий пользовательский метод Rails 'post.Кажется, имеет смысл поместить все чувствительные к правам тесты в интеграционные тесты (например, проверить, что пользователь не может редактировать чужие комментарии).

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

Неэффективное решение, которое я пробовал, состояло бы в том, чтобы поместить этот журнал в запрос в * 1006.* метод, но тестер Rails пытался получить доступ к действию, а не к пути.В частности, у меня было

def setup
  post /sessions/create, {:username => 'testdbadmin', :password => 'password}
end

Но согласно журналам, он просто пытался получить доступ к SomeController # / session / create, что явно не является намерением.Мне не хватает какого-то большого встроенного способа сделать это.Пожалуйста, сообщите.

Ответы [ 2 ]

4 голосов
/ 13 августа 2010

Я делаю это в своих функциональных тестах, просто устанавливая действительные данные сеанса вошедшего в систему в моей настройке, эффективно моделируя запрос, когда пользователь уже аутентифицировался (или не имеет, в зависимости от ситуации).

У меня есть вспомогательный метод в моем test_helper.rb:

def login(typ = :user, options = {})
    user = Factory.create(typ, {:username => "Joe"}.merge(options))
    session["user_id"] = user.id.to_s
  end

А потом в моем функциональном тесте:

class AccountsControllerTest < ActionController::TestCase
  context "Fresh session" do
    setup do
      @user = Factory.create(:user)
    end

    should "be redirected to the login page if not logged in" do
      get :show
      assert_redirected_to login_path
    end

  context "Logged in user with profile" do
    setup do
      @user = login
    end

    should "get the account home page" do
      get :show
      assert_response :success
    end
  end
end
1 голос
/ 13 августа 2010

Вместо того, чтобы тестировать все это в функциональном тесте, я бы использовал функциональные тесты и функции Cucumber в комбинации. Вы хотите проверить, что когда пользователь входит в систему, он может получить доступ к различным частям приложения. Это особенность огурца. Затем вы хотите проверить, что, когда пользователь не вошел в систему, он не может получить доступ к этим частям. Это функциональный тест.

Я бы написал функцию огурца следующим образом:

Feature: Viewing accounts
  In order to update my account information
  As a user
  I want to access my profile page

  Background:
    Given a user exists:
      | login | password      |
      | Radar | superpassword |
    And I am logged in as them

  Scenario: My profile page
    When I follow "Account"
    Then I should see "Profile Information"

Я предполагаю пару вещей здесь. Сначала ваши пользователи авторизуются, используя логин и пароль. У вас может быть это как электронная почта и пароль, но я уверен, что вы понимаете суть.

Шаг "Я вошел в систему как они" на самом деле не устанавливает сеанс, а фактически проходит процесс входа в систему пользователя. Я хотел бы написать эти два шага фона, как это *:

Given /^a user exists:$/ do |table|
  table.hashes.each do |user|
    @user = User.create!(user)
  end
end


Given /^I am logged in as them$/ do 
  steps(%Q{
    Given I am on the homepage
    And I follow "Login"
    And I fill in "Login" with "#{@user.login}"
    And I fill in "Password" with "#{@user.password}"
    And I press "Login"
    Then I should see "Login successful."
  })
end

С этими шагами будет определен сценарий. Здесь я предполагаю, что у вас есть ссылка где-то на странице, где действие входа в систему перенаправляет на сообщение «Аккаунт». Когда эта ссылка нажата, я также предполагаю, что она переходит на страницу с надписью «Информация профиля».

* Это немного надуманный пример. Шаг «пользователь существует» может занимать несколько строк.


Теперь для функционального теста. Я парень из RSpec, поэтому я бы написал так.

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe AccountsController do

  context "not logged in users" do
    it "cannot access the profile action" do
      get :profile
      flash[:alert].should eql("You must be logged in to access that action.")
      response.should redirect_to(login_path)
    end
  end
end

before_filter, который проверяет, что пользователь вошел в систему, будет проверен этим функциональным тестом. Поскольку это метод private (это метод private, верно?), Его не следует тестировать напрямую. Здесь я снова делаю пару предположений, например, что когда этот before_filter "терпит неудачу", он устанавливает flash[:alert] для определенного сообщения и перенаправляет на login_path.


Итак, подведем итоги: протестируйте все, что пользователь может делать, щелкая и заполняя формы на сайте, используя Cucumber, но для таких вещей, как переход к защищенным действиям или отсутствующим ресурсам, используйте функциональную проверку / спецификацию контроллера. *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...