Làm cách nào để đặt HTTP_REFERER khi kiểm tra trong Rails?


88

Tôi đang cố gắng kiểm tra bộ điều khiển và tôi gặp lỗi này. Tôi hiểu lỗi, nhưng không biết làm thế nào để sửa chữa nó.

test: on CREATE to :user with completely invalid email should respond with 
  redirect
(UsersControllerTest):ActionController::RedirectBackError: 
  No HTTP_REFERER was set in the request to this action, 
  so redirect_to :back could not be called successfully. 
If this is a test, make sure to specify request.env["HTTP_REFERER"].

Chỉ định nó ở đâu? Tôi đã thử điều này:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
  { 'referer' => '/sessions/new' } }

Nhưng bị lỗi tương tự.

Chỉ định nó với những gì, chính xác? Tôi đoán URI của chế độ xem mà tôi muốn nó quay trở lại:

'/sessions/new'

Đó có phải là những gì họ muốn nói?


Được rồi, hóa ra ý họ là làm thế này:

setup do
  @request.env['HTTP_REFERER'] = 'http://localhost:3000/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }, {}
end

Ai đó có thể cho tôi biết nơi đó được ghi lại không? Tôi muốn đọc về bối cảnh của thông tin đó.

Điều gì sẽ xảy ra nếu miền không phải là "localhost: 3000"? Điều gì sẽ xảy ra nếu đó là "localhost: 3001" hoặc một cái gì đó? Bất kỳ cách nào để dự đoán điều đó?

Tại sao điều này không hoạt động:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
  { 'referer' => '/sessions/new' } }

Tài liệu Rails nói cụ thể đó là cách bạn đặt tiêu đề.

Câu trả lời:


91

Đề xuất của họ chuyển thành như sau:

setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end

1
bạn có thể thoát khỏi chỉ cần chỉ định đường dẫn tương đối, như trong '/ session / new'.
Martin Faartoft

Điều này không hiệu quả với tôi vì tôi đang sử dụng https => 'on'. Làm gì bây giờ?
Robert Reiz

47

Câu trả lời được chấp nhận không hoạt động đối với các bài kiểm tra tích hợp vì @requestbiến không tồn tại.

Theo RailsGuides , bạn có thể chuyển tiêu đề cho những người trợ giúp.

Đường ray <= 4:

test "blah" do
  get root_path, {}, {'HTTP_REFERER' => 'http://foo.com'}
  ...
end

Đường ray> = 5:

test "blah" do
  get root_path, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://foo.com" }
  ...
end

2
Cảm ơn nhiều. Tôi đã tìm kiếm giải pháp trong 1 giờ. Bài viết của bạn làm việc cho tôi!
Robert Reiz

9
Trên Rails 5, tiêu đề được chỉ định như: get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" } source
golfadas

9

Để trả lời câu hỏi:

Tại sao điều này không hoạt động:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
{ 'referer' => '/sessions/new' } }

Nó không hoạt động vì tài liệu Rails bạn đã liên kết với tài liệu khác lớp với tài liệu bạn có thể đang sử dụng.

Bạn đã liên kết với ActionController::Integration:Session. Tôi đoán rằng bạn đang viết một bài kiểm tra chức năng (nếu bạn đang sử dụng Test :: Unit) hoặc một bài kiểm tra bộ điều khiển (nếu bạn đang sử dụng Rspec). Dù bằng cách nào, có thể bạn đang sử dụng ActionController::TestCasehoặc một lớp con của nó. Đến lượt nó, bao gồm mô-đun ActionController::TestProcess.

ActionController::TestProcesscung cấp một getphương thức với các tham số khác với getphương thức được cung cấp bởi ActionController::Integration:Session. (Khó chịu hả?) Chữ ký của phương thức là:

 def get(action, parameters = nil, session = nil, flash = nil)

Đáng buồn thay, không có tham số tiêu đề. Nhưng ít nhất thiết lập @request.env['HTTP_REFERER']hoạt động.


1

Trong Rails3, tôi gặp lỗi tương tự:
Để loại bỏ điều này trong bộ điều khiển tương ứng, đã cung cấp giải pháp cứu cho "redirect_to: back"

Ví dụ:redirect_to :back rescue redirect_to required_path


0
setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end

Trong Rails 2.2.2, khối trên không bao giờ chạy thử nghiệm thực tế. Nói rằng

đăng: tạo, {: người dùng => {: email => 'không hợp lệ @ abc'}}

dòng không chạy. Bạn chỉ cần thoát khỏi khối thiết lập và sử dụng

@request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
post :create, { :user => { :email => 'invalid@abc' } }

thay thế. Và nó sẽ đặt trình giới thiệu


0

Giải pháp thẳng thắn nhất cho vấn đề trên là thực hiện yêu cầu với các tiêu đề liên quan. Rails sẽ tự động đọc tiêu đề này.

post '/your-custom-route', {}, {'HTTP_REFERER': 'http://www.your-allowed-domain.com'}

0

Hiện tại, tôi đã sử dụng Rails 5.2.1, cách tiếp cận của tôi với trình giới thiệu yêu cầu sơ khai bên trong bộ điều khiển như dưới đây:

let(:stub_referer) { some_path(some_param) }
before do
  request.headers.merge! referer: stub_referer
  get :some_action, format: :html
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.