在 Rails 5 控制器集成测试中设置 cookie.signed

2024-05-05

想象一下这样的场景,有一个控制器集成测试调用一个控制器方法,其中cookie.signed用于一些完整性检查。

控制器

# app/controllers/foo_controller.rb

def index
  entity = FooEntity.find_by_id(params[:id])
  if entity.nil?
    raise ActionController::BadRequest, 'Could not find requested entity.'
  else
    @is_authorized = entity.token == cookies.signed[:token]
    if @is_authorized
      # Success! The path to be tested.
    else
      raise ActionController::BadRequest, 'Unauthorized cookie token.'
    end
  end
end

控制器测试

# app/test/controllers/foo_test.rb

require 'test_helper'

class FooControllerTest < ActionDispatch::IntegrationTest
  test 'should be working' do
    cookies.signed[:token] = '7e5201169ef160e31058d2a1976a5552'
    get '/foobar/123'
  end
end

但是,我不知道如何获得cookie.signed测试中的设置。上面的测试代码抛出异常:

NoMethodError:Rack::Test::CookieJar:0x007fe90965ccd8 的未定义方法“签名”

试图寻找解决方案,但我能找到的最接近的是这篇文章,https://sikac.hu/reconstruct-a-cookie-jar-and-read-signed-cookie-in-capybara-f71df387f9ff https://sikac.hu/reconstruct-a-cookie-jar-and-read-signed-cookie-in-capybara-f71df387f9ff,但不知道如何构建ActionDispatch::Request object.


这似乎是一个已知错误 https://github.com/rails/rails/issues/27145在 Rails 5 中及以上(链接的问题是关于cookies.encrypted但这同样适用于cookies.signed)。问题是在控制器测试中,cookie jar 是Rack::Test::CookieJar类实例其中不支持签名/加密的cookie。另一方面,在应用程序本身中,cookie jar 是一个ActionDispatch::Cookies::CookieJar支持这两种特殊 cookie 类型的类实例。

不过,要在控制器测试中构建签名 cookie,您可以手动创建一个ActionDispatch请求 cookie jar 并使用它检索签名的 cookie 值:

# app/test/controllers/foo_test.rb

require 'test_helper'

class FooControllerTest < ActionDispatch::IntegrationTest
  test 'should be working' do
    my_cookies = ActionDispatch::Request.new(Rails.application.env_config.deep_dup).cookie_jar
    my_cookies.signed[:token] = '7e5201169ef160e31058d2a1976a5552'

    cookies[:token] = my_cookies[:token]
    get '/foobar/123'
  end
end

第一条测试线创建一个新的ActionDispatch请求应用程序请求默认环境设置(它们定义例如用于签名 cookie 的秘密)并返回它的 cookie jar。然后你只需设置:token为所需值签名的 cookie(此 cookie 罐doessigned方法定义为ActionDispatch::Cookies::CookieJar, not Rack::Test::CookieJar)。最后,你检索签名的 cookie 值通过访问它without the signed访问器并设置同名测试cookie使用这个值。

现在,当测试到达控制器代码时,控制器应该在cookies.signed[:token] cookie.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Rails 5 控制器集成测试中设置 cookie.signed 的相关文章

随机推荐