Как проверить cookie.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 #
Как проверить подписанные файлы cookie в Rails 3?
Ответы
Ответ 1
Я столкнулся с этим вопросом, в то время как Googling для решения подобной проблемы, поэтому я опубликую здесь. Я надеялся установить подписанный файл 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 ...
Ответ 2
В rails 3 ActionControlller:: TestCase вы можете установить подписанные постоянные файлы cookie в объекте запроса так:
@request.cookies.permanent.signed[:foo] = "bar"
И возвращенные подписанные файлы cookie из действия, предпринятого в контроллере, могут быть протестированы, сделав это
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]
, но читать unsigned cookie jar[:foo]
. Только тогда мы получим зашифрованное значение cookie, необходимое для сравнения в assert_equal
.
Ответ 3
После просмотра кода 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)
Немного хакерский, возможно, но он выполняет эту работу для меня.
Ответ 4
Проблема (по крайней мере, на поверхности) заключается в том, что в контексте функционального теста (ActionController:: TestCase) объектом "cookie" является хэш, тогда как при работе с контроллерами это ActionDispatch:: Файлы cookie:: CookieJar. Поэтому нам нужно преобразовать его в объект CookieJar, чтобы мы могли использовать "подписанный" метод для его преобразования в SignedCookieJar.
В свои функциональные тесты (после запроса на получение) вы можете поместить следующие файлы для конвертирования файлов cookie из объекта Hash в объект CookieJar.
@request.cookies.merge!(cookies)
cookies = ActionDispatch::Cookies::CookieJar.build(@request)
Ответ 5
Проблема также является вашими испытаниями.
Вот какой код и тесты я использовал для 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
Обратите внимание, что строка refut_nil, куки файлы - это строка... это одна вещь, которая также заставляла этот тест не проходить, помещал символ в cookies[:reference]
, тест не понравился, поэтому я не делал что.