简体   繁体   English

在 RSpec Rails 中测试 HTTPS (SSL) 请求

[英]Test an HTTPS (SSL) request in RSpec Rails

I'd like to take advantage of the force_ssl feature in rails 3.1rc4.我想利用 rails 3.1rc4 中的force_ssl功能

class ApplicationController < ActionController::Base
  force_ssl
end

Problem is this breaks most/all of my existing RSpec controller specs.问题是这破坏了我现有的大部分/所有 RSpec controller 规格。 For example, this fails:例如,这会失败:

describe "GET 'index'" do
  it "renders the Start page" do
    get :index
    response.should render_template 'index'
  end
end

Instead of rendering the page the response is a 301 redirect to https://test.host/ .响应不是呈现页面,而是 301 重定向到https://test.host/

How can I change my specs to simulate an HTTPS GET/POST?如何更改我的规格以模拟 HTTPS GET/POST?

And do I have to change each test manually or is there an easier way?我必须手动更改每个测试还是有更简单的方法? (I realise I could invoke force_ssl only in production, but that's not ideal. Really, I should be testing that force_ssl does indeed redirect to https:// when expected.) (我意识到我只能在生产中调用force_ssl ,但这并不理想。真的,我应该测试force_ssl确实在预期时重定向到 https://。)

To instruct RSpec to make SSL requests in a controller spec use:要指示 RSpec 在 controller 规范中发出 SSL 请求,请使用:

request.env['HTTPS'] = 'on'

In your example this looks like:在您的示例中,这看起来像:

describe "GET 'index'" do
  it "renders the Start page" do
    request.env['HTTPS'] = 'on'
    get :index
    response.should render_template 'index'
  end
end

For rspec 3 syntax, https://stackoverflow.com/a/28361428/1107433对于 rspec 3 语法, https://stackoverflow.com/a/28361428/1107433

get :index, protocol: 'https://'

There may be a slight different version that above code doesn't work.上面的代码可能有一个稍微不同的版本不起作用。 So use code below:所以使用下面的代码:

get:index, protocol: :https

For reference I'm currently running Rails 5.2.4 and RSpec 4.作为参考,我目前正在运行 Rails 5.2.4 和 RSpec 4。

The best solution as given in this answer is to change from using the _path helper to using the _url helper.此答案中给出的最佳解决方案是从使用_path帮助程序更改为使用_url帮助程序。

Then you can pass the protocol param to generate the HTTPS URL:然后您可以传递protocol参数以生成 HTTPS URL:

get login_url(protocol: :https)

Note that you cannot pass protocol to the _path helper:请注意,您不能将protocol传递给_path助手:

# NOTE: THIS IS WRONG. Doesn't work with the `_path` helper:
# get login_path(protocol: :https)

An alternative option given in carp's comment above is to pass the "HTTPS" header with the fake request. 上面 carp 的评论中给出的另一种选择是通过虚假请求传递"HTTPS" header。

So if you're using strings/symbols or the _path helper for the request path:因此,如果您使用字符串/符号或请求路径的_path助手:

get login_path, headers: {"HTTPS" => "on"}

get '/login', headers: {"HTTPS" => "on"}

Here is carp's full comment:这是鲤鱼的完整评论:

For actual request specs (as opposed to the now deprecated controller specs), it works like this: get "/path", headers: { "HTTPS" => "on" } .对于实际的请求规范(与现在已弃用的 controller 规范相反),它的工作方式如下: get "/path", headers: { "HTTPS" => "on" } The HTTPS header will be picked up by Rack::Request, telling everything down the line to consider the request to be an SSL/TLS one. HTTPS header 将被 Rack::Request 拾取,告诉下线的一切考虑该请求是 SSL/TLS 请求。

If you need SSL at all, anywhere in your application, you should use it everywhere in your application.如果您在应用程序的任何地方都需要 SSL,那么您应该在应用程序的任何地方使用它。 Then all you need is to use the rack-ssl gem and add the Rack::SSL middleware to your config/environments/production.rb .然后,您只需要使用rack-ssl gem 并将Rack::SSL中间件添加到您的config/environments/production.rb中。 No additional testing needed;无需额外测试; no breakage;无破损; problem solved.问题解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM