Skip to content

Commit 7cf56a4

Browse files
committed
test(router): fix test to exercise parent-walk code path
The previous test registered RouteNotFound("/*") which creates an anyKind wildcard node at the root. The router's normal backtracking algorithm already finds that node without the parent-walk fix, so the tests passed on unpatched v5.0.4. The real scenario that requires the fix is when RouteNotFound is registered on an exact prefix (no wildcard suffix) — e.g., e.RouteNotFound("/api", ...) or g.RouteNotFound("", ...). In that case there is no anyKind child to backtrack into, and the router must walk the parent chain of the matched node to discover the handler. Updated test cases: - Use e.RouteNotFound("/api") and g.RouteNotFound("") instead of "/*" - Removed unused 'expectCode' field from test struct - Improved comments to explain why the wildcard variant is insufficient - All four scenarios (root handler, group handler, param route, fallback) are retained Signed-off-by: lyydsheep <2230561977@qq.com>
1 parent c070e25 commit 7cf56a4

1 file changed

Lines changed: 41 additions & 25 deletions

File tree

router_test.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3624,42 +3624,56 @@ func TestPathValues_GetOr(t *testing.T) {
36243624
// TestRouterRouteNotFoundHandlerInGroup verifies that a RouteNotFound handler registered
36253625
// at a parent (root or group) level is properly invoked for sub-paths when the route exists
36263626
// but the HTTP method is not registered. This is the scenario described in issue #2485.
3627+
//
3628+
// The critical test cases use exact-prefix RouteNotFound registrations (not wildcard "/*")
3629+
// to exercise the parent-node walking fix. A RouteNotFound("/*") would create an anyKind
3630+
// node that the router already finds via normal backtracking even without the fix; the bug
3631+
// only manifests when the RouteNotFound is registered on an exact path or group prefix
3632+
// (no anyKind child), so the router must walk the parent chain to find it.
36273633
func TestRouterRouteNotFoundHandlerInGroup(t *testing.T) {
36283634
var testCases = []struct {
3629-
name string
3630-
whenMethod string
3631-
whenURL string
3632-
expectHandlerID string
3633-
expectCode int
3634-
registerRootNotFound bool
3635+
name string
3636+
whenMethod string
3637+
whenURL string
3638+
expectHandlerID string
3639+
registerRootNotFound bool
36353640
registerGroupNotFound bool
36363641
}{
36373642
{
3638-
name: "root RouteNotFound handler fires for group sub-path with wrong method",
3639-
whenMethod: http.MethodPost,
3640-
whenURL: "/api/users",
3641-
expectHandlerID: "root-not-found",
3643+
// Root registers RouteNotFound on "/api" (exact prefix, no wildcard).
3644+
// Without the parent-walk fix the router falls back to methodNotAllowedHandler
3645+
// because the anyKind /* node does not exist and no backtracking reaches the
3646+
// root RouteNotFound. With the fix, the parent chain is walked from /api/users
3647+
// up to /api and the handler is found.
3648+
name: "root RouteNotFound on exact prefix fires for group sub-path with wrong method",
3649+
whenMethod: http.MethodPost,
3650+
whenURL: "/api/users",
3651+
expectHandlerID: "root-not-found",
36423652
registerRootNotFound: true,
36433653
},
36443654
{
3645-
name: "group RouteNotFound handler fires for group sub-path with wrong method",
3655+
// Group registers its own RouteNotFound on "/api" (exact prefix, no wildcard).
3656+
// Same reasoning: parent-walk is required to find the handler.
3657+
name: "group RouteNotFound on exact prefix fires for group sub-path with wrong method",
36463658
whenMethod: http.MethodPost,
36473659
whenURL: "/api/users",
36483660
expectHandlerID: "group-not-found",
36493661
registerGroupNotFound: true,
36503662
},
36513663
{
3652-
name: "root RouteNotFound fires when no group-level handler defined",
3653-
whenMethod: http.MethodDelete,
3654-
whenURL: "/api/items/123",
3655-
expectHandlerID: "root-not-found",
3664+
// Root registers RouteNotFound on "/api" (exact prefix).
3665+
// Wrong method on a param route inside the group still triggers the handler.
3666+
name: "root RouteNotFound fires for param sub-route with wrong method",
3667+
whenMethod: http.MethodDelete,
3668+
whenURL: "/api/items/123",
3669+
expectHandlerID: "root-not-found",
36563670
registerRootNotFound: true,
36573671
},
36583672
{
3659-
name: "fallback to methodNotAllowed when no RouteNotFound handler defined",
3660-
whenMethod: http.MethodPost,
3661-
whenURL: "/api/users",
3662-
// no RouteNotFound registered → method not allowed
3673+
// No RouteNotFound registered anywhere → standard 405 methodNotAllowedHandler.
3674+
name: "fallback to methodNotAllowed when no RouteNotFound handler defined",
3675+
whenMethod: http.MethodPost,
3676+
whenURL: "/api/users",
36633677
expectHandlerID: "method-not-allowed",
36643678
},
36653679
}
@@ -3669,7 +3683,7 @@ func TestRouterRouteNotFoundHandlerInGroup(t *testing.T) {
36693683
e := New()
36703684
handlerID := ""
36713685

3672-
// Register a GET route inside a group
3686+
// Register GET routes inside the /api group.
36733687
g := e.Group("/api")
36743688
g.GET("/users", func(c *Context) error {
36753689
handlerID = "users-get"
@@ -3680,17 +3694,19 @@ func TestRouterRouteNotFoundHandlerInGroup(t *testing.T) {
36803694
return nil
36813695
})
36823696

3683-
// Optionally register RouteNotFound at root level
3697+
// Register RouteNotFound on the exact group prefix "/api" (no trailing wildcard).
3698+
// This means the only way the router can find this handler when a sub-path is
3699+
// requested is by walking up the parent node tree — the scenario this fix covers.
36843700
if tc.registerRootNotFound {
3685-
e.RouteNotFound("/*", func(c *Context) error {
3701+
// Root-level handler registered on the group prefix path, not on "/*".
3702+
e.RouteNotFound("/api", func(c *Context) error {
36863703
handlerID = "root-not-found"
36873704
return nil
36883705
})
36893706
}
3690-
3691-
// Optionally register RouteNotFound at group level
36923707
if tc.registerGroupNotFound {
3693-
g.RouteNotFound("/*", func(c *Context) error {
3708+
// Group-level handler using the group's own prefix (no wildcard suffix).
3709+
g.RouteNotFound("", func(c *Context) error {
36943710
handlerID = "group-not-found"
36953711
return nil
36963712
})

0 commit comments

Comments
 (0)