mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix route from "(:a)(foo/:b)" when only given :b
Previously, when generating a root path from a route having nested
optional scopes where second-level or greater scopes had a static part,
and when providing only a second-level option, it would result in an
invalid path leading with "//". Ex. a path generated from the route
"(:a)(foo/:b)", given `b: 'bar'`, would return "//foo/bar".
Commit 7670d60977
introduced this bug while fixing the edge case of
empty strings returned when no options are passed to such routes.
A previous commit fixed this for simpler hierarchical cases like
"(:a)(:b)(:c)", and this fixes it for "(:a)(foo/:b)(bar/:c)".
This commit is contained in:
parent
c218233472
commit
b44740d48d
2 changed files with 50 additions and 1 deletions
|
@ -412,7 +412,9 @@ module ActionDispatch
|
|||
path.gsub!(%r{/(\(+)/?}, '\1/')
|
||||
# if a path is all optional segments, change the leading "(/" back to
|
||||
# "/(" so it evaluates to "/" when interpreted with no options.
|
||||
path.sub!(%r{^(\(+)/}, '/\1') if %r{^(\(+[^)]+\)){1,}$}.match?(path)
|
||||
# Unless, however, at least one secondary segment consists of a static
|
||||
# part, ex. "(/:locale)(/pages/:page)"
|
||||
path.sub!(%r{^(\(+)/}, '/\1') if %r{^(\(+[^)]+\))(\(+/:[^)]+\))*$}.match?(path)
|
||||
path
|
||||
end
|
||||
|
||||
|
|
|
@ -1412,6 +1412,53 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
assert_equal "projects#index", @response.body
|
||||
end
|
||||
|
||||
def test_optional_scoped_root_multiple_choice
|
||||
draw do
|
||||
scope "(:locale)" do
|
||||
scope "(p/:platform)" do
|
||||
scope "(b/:browser)" do
|
||||
root to: "projects#index"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Note, in this particular case where we rely on pattern matching instead
|
||||
# of hierarchy to match parameters in a root path, root_path returns ""
|
||||
# when given no path parameters.
|
||||
|
||||
assert_equal "/en", root_path(locale: "en")
|
||||
assert_equal "/p/osx", root_path(platform: "osx")
|
||||
assert_equal "/en/p/osx", root_path(locale: "en", platform: "osx")
|
||||
assert_equal "/b/chrome", root_path(browser: "chrome")
|
||||
assert_equal "/en/b/chrome", root_path(locale: "en", browser: "chrome")
|
||||
assert_equal "/p/osx/b/chrome",
|
||||
root_path(platform: "osx", browser: "chrome")
|
||||
assert_equal "/en/p/osx/b/chrome",
|
||||
root_path(locale: "en", platform: "osx", browser: "chrome")
|
||||
|
||||
get "/en"
|
||||
assert_equal "projects#index", @response.body
|
||||
|
||||
get "/p/osx"
|
||||
assert_equal "projects#index", @response.body
|
||||
|
||||
get "/en/p/osx"
|
||||
assert_equal "projects#index", @response.body
|
||||
|
||||
get "/b/chrome"
|
||||
assert_equal "projects#index", @response.body
|
||||
|
||||
get "/en/b/chrome"
|
||||
assert_equal "projects#index", @response.body
|
||||
|
||||
get "/p/osx/b/chrome"
|
||||
assert_equal "projects#index", @response.body
|
||||
|
||||
get "/en/p/osx/b/chrome"
|
||||
assert_equal "projects#index", @response.body
|
||||
end
|
||||
|
||||
def test_scope_with_format_option
|
||||
draw do
|
||||
get "direct/index", as: :no_format_direct, format: false
|
||||
|
|
Loading…
Reference in a new issue