Как проверить cookies.permanent.signed в Rails 3

У меня есть действие в каком-то контроллере, который устанавливает какое-то значение в постоянном подписанном cookie, как это:


def some_action
    cookies.permanent.signed[:cookie_name] = "somevalue"
end

И в каком-то функциональном тесте я пытаюсь проверить, правильно ли настроен файл cookie:


test "test cookies" do
    assert_equal "somevalue", cookies.permanent.signed[:cookie_name]
end

Однако, когда я запускаю тест, я получил следующую ошибку:


NoMethodError: undefined method `permanent' for #

Если я попробую только:


test "test cookies" do
    assert_equal "somevalue", cookies.signed[:cookie_name]
end

Я получил:


NoMethodError: undefined method `signed' for #

Как проверить подписанные куки в Rails 3?

5 ответов

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

jar = ActionDispatch::Cookies::CookieJar.build(@request)
jar.signed[:some_key] = "some value"
@request.cookies['some_key'] = jar[:some_key]
get :show ...

Обратите внимание, что следующее не сработало:

# didn't work; the controller didn't see the signed cookie
@request.cookie_jar.signed[:some_key] = "some value"
get :show ...

В ActionControlller::TestCase rails 3 вы можете установить подписанные постоянные файлы cookie в объекте запроса следующим образом:

 @request.cookies.permanent.signed[:foo] = "bar"

И возвращенные подписанные куки-файлы от действия, предпринятого в контроллере, можно проверить, выполнив

 test "do something" do
     get :index # or whatever
     jar = @request.cookie_jar
     jar.signed[:foo] = "bar"
     assert_equal jar[:foo], @response.cookies['foo'] #should both be some enc of 'bar'
 end 

Обратите внимание, что нам нужно установить подписанный cookie jar.signed[:foo], но читать неподписанные куки jar[:foo], Только тогда мы получаем зашифрованное значение cookie, необходимое для сравнения в assert_equal,

Посмотрев код Rails, который обрабатывает это, я создал тестовый помощник для этого:

  def cookies_signed(name, opts={})
    verifier = ActiveSupport::MessageVerifier.new(request.env["action_dispatch.secret_token".freeze])
    if opts[:value]
      @request.cookies[name] = verifier.generate(opts[:value])
    else
      verifier.verify(cookies[name])
    end
  end

Добавьте это в test_help.rb, затем вы можете установить подписанный файл cookie с помощью:

cookies_signed(:foo, :value => 'bar')

И читать это с:

cookies_signed(:foo)

Может быть, немного хакерский, но это делает работу для меня.

Проблема (по крайней мере, на первый взгляд) заключается в том, что в контексте функционального теста (ActionController::TestCase) объект "cookies" представляет собой Hash, тогда как при работе с контроллерами это ActionDispatch::Cookies::CookieJar объект. Поэтому нам нужно преобразовать его в объект CookieJar, чтобы мы могли использовать для него "подписанный" метод, чтобы преобразовать его в SignedCookieJar.

Вы можете поместить следующее в свои функциональные тесты (после запроса get) для преобразования файлов cookie из объекта Hash в объект CookieJar.

@request.cookies.merge!(cookies)
cookies = ActionDispatch::Cookies::CookieJar.build(@request)

Проблема также заключается в ваших тестах.

Вот некоторый код и тесты, которые я использовал для TDD ситуации, когда вы хотите установить значение cookie из передачи значения params в представление.

Функциональный тест:

test "reference get set in cookie when visiting the site" do
  get :index, {:reference => "121212"}
  refute_nil cookies["reference"]
end

SomeController:

before_filter :get_reference_code

ApplicationController:

def get_reference_code
  cookies.signed[:reference] ||= params[:reference]
end

Обратите внимание, что строка refute_nil, cookie - это строка... это то, что также сделало этот тест не пройденным, поместив символ в cookies[:reference] тест не понравился, поэтому я этого не делал.

Другие вопросы по тегам