Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nav_order: 6

## main

* Restore request-dependent URL generation when using `render_preview` inside `with_request_url`.

*Joel Hawksley*

* Speed up cold cache digests by skipping the `# Template Dependency:` scan for sources that declare none, and by not translating class names in synthetic templates, which only declare paths.

*Erik Axel Nielsen*
Expand Down
9 changes: 9 additions & 0 deletions docs/guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ class ExampleComponentTest < ViewComponent::TestCase
end
```

`with_request_url` also applies to request-dependent URL generation inside `render_preview`:

```ruby
with_request_url "/products/42" do
render_preview(:default, from: ExampleComponentPreview)
assert_link "French", href: "/products/42?locale=fr"
end
```

## Setting `request.host`

Since 3.3.0
Expand Down
12 changes: 7 additions & 5 deletions lib/view_component/test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,16 @@ def render_preview(name, from: __vc_test_helpers_preview_class, params: {})
controller_class = Rails.application.config.view_component.previews.controller.constantize
request = ActionDispatch::TestRequest.new(vc_test_request.env.dup)
query_parameters = vc_test_request.query_parameters.deep_dup.merge(params.stringify_keys)
request.path_parameters = vc_test_request.path_parameters.except(*params.keys.map(&:to_sym)).merge(
controller: controller_class.controller_path,
action: "previews",
path: "#{from.preview_name}/#{name}"
)
request.path_parameters = vc_test_request.path_parameters.deep_dup
request.set_header("action_dispatch.request.query_parameters", query_parameters)
request.set_header(Rack::QUERY_STRING, query_parameters.to_query)
previews_controller = __vc_test_helpers_build_controller(controller_class, request: request)
# Dispatch the preview without replacing the request's URL generation context.
previews_controller.params = request.parameters.merge(params.stringify_keys).merge(
"controller" => controller_class.controller_path,
"action" => "previews",
"path" => "#{from.preview_name}/#{name}"
)
previews_controller.set_response!(ActionDispatch::Response.new)
previews_controller.process(:previews)
@rendered_content = previews_controller.response.body
Expand Down
6 changes: 5 additions & 1 deletion test/sandbox/app/components/request_url_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

class RequestUrlComponent < ViewComponent::Base
def call
content_tag(:span, request.path, class: "path") + content_tag(:span, request.fullpath, class: "fullpath")
content_tag(:span, request.path, class: "path") +
content_tag(:span, request.fullpath, class: "fullpath") +
content_tag(:span, content, class: "content") +
link_to("Request-dependent link", url_for(bar: "baz")) +
link_to("Absolute request-dependent link", url_for(bar: "baz", only_path: false))
end
end
1 change: 1 addition & 0 deletions test/sandbox/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
get :content, to: "integration_examples#content"
get :variants, to: "integration_examples#variants"
get :products, to: "integration_examples#products"
get "products/:id", to: "integration_examples#products"
get :inline_products, to: "integration_examples#inline_products"
get :cached, to: "integration_examples#cached"
get :render_check, to: "integration_examples#render_check"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class RequestUrlComponentPreview < ViewComponent::Preview
def default
render(RequestUrlComponent.new)
end

def with_id(id:)
render(RequestUrlComponent.new) { id }
end
end
39 changes: 39 additions & 0 deletions test/sandbox/test/components/render_preview_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,45 @@ def test_render_preview_preserves_the_original_request_parameters
end
end

def test_render_preview_uses_the_request_url_for_request_dependent_links
with_request_url("/products") do
fragment = render_preview(:default, from: RequestUrlComponentPreview)

assert_equal "/products", vc_test_request.path
assert_selector(".path", text: "/products")
assert_equal "/products?bar=baz", fragment.at_css("a")["href"]
end
end

def test_render_preview_preserves_route_parameters_when_preview_parameters_overlap
with_request_url("/products/42?id=query-id") do
render_preview(:with_id, from: RequestUrlComponentPreview, params: {id: "preview-id"})

assert_selector(".content", exact_text: "preview-id")
assert_link "Request-dependent link", href: "/products/42?bar=baz", exact: true
assert_equal "42", vc_test_request.path_parameters[:id]
assert_equal "query-id", vc_test_request.query_parameters["id"]
end
end

def test_render_preview_parameters_override_request_query_parameters
with_request_url("/products?title=Query+title") do
render_preview(:with_params, from: PreviewComponentPreview, params: {title: "Preview title"})

assert_text "Preview title"
assert_no_text "Query title"
assert_equal "Query title", vc_test_request.query_parameters["title"]
end
end

def test_render_preview_preserves_the_request_host_and_protocol_for_links
with_request_url("/products/42", host: "app.example.com:8443", protocol: :https) do
render_preview(:default, from: RequestUrlComponentPreview)

assert_link "Absolute request-dependent link", href: "https://app.example.com:8443/products/42?bar=baz"
end
end

def test_render_preview_runs_locale_callbacks_and_restores_the_locale
render_args = PreviewComponentPreview.method(:render_args)
locales = []
Expand Down
4 changes: 2 additions & 2 deletions test/sandbox/test/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ def test_inherited_component_with_call_method_does_not_recompile_superclass
assert_select "div", "hello world"
assert_response :success
ensure
UncompilableComponent.singleton_class.silence_redefinition_of_method(:__vc_compile)
UncompilableComponent.define_singleton_method(:__vc_compile, original_method)
original_method.receiver.singleton_class.silence_redefinition_of_method(:__vc_compile)
original_method.receiver.define_singleton_method(:__vc_compile, original_method)
end
end

Expand Down
Loading