From 5b0f3b893df5ef81c5f002551bb83bd83adf40a1 Mon Sep 17 00:00:00 2001 From: Daniel Alfaro Date: Thu, 15 Jun 2023 11:03:09 -0500 Subject: [PATCH] Add host option to `with_request_url` test helper - This allows testing components that use path helpers that are constrained by a subdomain in routes.rb. --- docs/CHANGELOG.md | 4 ++++ docs/api.md | 10 +++++++++- docs/guide/testing.md | 20 +++++++++++++++++++ lib/view_component/test_helpers.rb | 6 +++++- .../app/components/url_for_component.html.erb | 2 +- .../app/components/url_for_component.rb | 3 +++ test/sandbox/test/rendering_test.rb | 16 +++++++++++++++ 7 files changed, 58 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8963edf1f..b042323ba 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,10 @@ nav_order: 5 ## main +* Allow Setting host when using the `with_request_url` test helper. + + *Daniel Alfaro* + ## 3.2.0 * Fix viewcomponent.org Axe violations. diff --git a/docs/api.md b/docs/api.md index b0459df91..f557e2506 100644 --- a/docs/api.md +++ b/docs/api.md @@ -332,7 +332,7 @@ with_controller_class(UsersController) do end ``` -### `#with_request_url(path)` +### `#with_request_url(path, host: nil)` Set the URL of the current request (such as when using request-dependent path helpers): @@ -342,6 +342,14 @@ with_request_url("/users/42") do end ``` +To use a specific host, pass the host param: + +```ruby +with_request_url("/users/42", host: "app.example.com") do + render_inline(MyComponent.new) +end +``` + ### `#with_variant(variant)` Set the Action Pack request variant for the given block: diff --git a/docs/guide/testing.md b/docs/guide/testing.md index eef741f1f..291c5dc91 100644 --- a/docs/guide/testing.md +++ b/docs/guide/testing.md @@ -183,6 +183,26 @@ class ExampleComponentTest < ViewComponent::TestCase end ``` +## Setting `request.host` + +Since 3.3.0 +{: .label } + +Rails routes that have a subdomain constraint require `request.host` to be set correctly. + +To set `request.host` for a test case, use `with_request_url` from `ViewComponent::TestHelpers`: + +```ruby +class ExampleComponentTest < ViewComponent::TestCase + def test_with_request_url + with_request_url "/products/42", host: "app.example.com" do + render_inline ExampleComponent.new # contains i.e. `products_path` that is constrained to the 'app' subdomain + assert_link "Products", href: "/products" + end + end +end +``` + ### Query parameters Since 2.41.0 diff --git a/lib/view_component/test_helpers.rb b/lib/view_component/test_helpers.rb index 9866e4549..a3989e026 100644 --- a/lib/view_component/test_helpers.rb +++ b/lib/view_component/test_helpers.rb @@ -156,7 +156,9 @@ def with_controller_class(klass) # ``` # # @param path [String] The path to set for the current request. - def with_request_url(path) + # @param host [String] The host to set for the current request. + def with_request_url(path, host: nil) + old_request_host = vc_test_request.host old_request_path_info = vc_test_request.path_info old_request_path_parameters = vc_test_request.path_parameters old_request_query_parameters = vc_test_request.query_parameters @@ -164,12 +166,14 @@ def with_request_url(path) old_controller = defined?(@vc_test_controller) && @vc_test_controller path, query = path.split("?", 2) + vc_test_request.host = host if host vc_test_request.path_info = path vc_test_request.path_parameters = Rails.application.routes.recognize_path_with_request(vc_test_request, path, {}) vc_test_request.set_header("action_dispatch.request.query_parameters", Rack::Utils.parse_nested_query(query)) vc_test_request.set_header(Rack::QUERY_STRING, query) yield ensure + vc_test_request.host = old_request_host vc_test_request.path_info = old_request_path_info vc_test_request.path_parameters = old_request_path_parameters vc_test_request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters) diff --git a/test/sandbox/app/components/url_for_component.html.erb b/test/sandbox/app/components/url_for_component.html.erb index 709863369..fa294eb1a 100644 --- a/test/sandbox/app/components/url_for_component.html.erb +++ b/test/sandbox/app/components/url_for_component.html.erb @@ -1 +1 @@ -<%= url_for({ key: "value" }.merge(request.query_parameters)) %> +<%= url_for(only_path: @only_path, params: { key: "value" }.merge(request.query_parameters)) %> diff --git a/test/sandbox/app/components/url_for_component.rb b/test/sandbox/app/components/url_for_component.rb index 8e43ee49b..51d3abcd9 100644 --- a/test/sandbox/app/components/url_for_component.rb +++ b/test/sandbox/app/components/url_for_component.rb @@ -1,4 +1,7 @@ # frozen_string_literal: true class UrlForComponent < ViewComponent::Base + def initialize(only_path: true) + @only_path = only_path + end end diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index 6e25e53eb..89008eddf 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -862,6 +862,22 @@ def test_with_request_url_with_query_parameters end end + def test_with_request_url_with_host + with_request_url "/", host: "app.example.com" do + render_inline UrlForComponent.new(only_path: false) + assert_text "http://app.example.com/?key=value" + end + + with_request_url "/products", host: "app.example.com" do + render_inline UrlForComponent.new(only_path: false) + assert_text "http://app.example.com/products?key=value" + end + + with_request_url "/products", host: "app.example.com" do + assert_equal "app.example.com", vc_test_request.host + end + end + def test_components_share_helpers_state PartialHelper::State.reset