Skip to content

Commit 7a6c3c8

Browse files
authored
Fix swagger path generation: remove trailing slash for root routes with prefix (#5212)
1 parent 875fec3 commit 7a6c3c8

File tree

2 files changed

+95
-1
lines changed

2 files changed

+95
-1
lines changed

tools/goctl/api/swagger/path.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ func spec2Paths(ctx Context, srv apiSpec.Service) *spec.Paths {
1919
for _, route := range group.Routes {
2020
routPath := pathVariable2SwaggerVariable(ctx, route.Path)
2121
if len(prefix) > 0 && prefix != "." {
22-
routPath = "/" + path.Clean(prefix) + routPath
22+
if routPath == "/" {
23+
routPath = "/" + path.Clean(prefix)
24+
} else {
25+
routPath = "/" + path.Clean(prefix) + routPath
26+
}
2327
}
2428
pathItem := spec2Path(ctx, group, route)
2529
existPathItem, ok := paths.Paths[routPath]
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package swagger
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/zeromicro/go-zero/tools/goctl/api/spec"
8+
)
9+
10+
func TestSpec2PathsWithRootRoute(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
prefix string
14+
routePath string
15+
expectedPath string
16+
}{
17+
{
18+
name: "prefix with root route",
19+
prefix: "/api/v1/shoppings",
20+
routePath: "/",
21+
expectedPath: "/api/v1/shoppings",
22+
},
23+
{
24+
name: "prefix with sub route",
25+
prefix: "/api/v1/shoppings",
26+
routePath: "/list",
27+
expectedPath: "/api/v1/shoppings/list",
28+
},
29+
{
30+
name: "empty prefix with root route",
31+
prefix: "",
32+
routePath: "/",
33+
expectedPath: "/",
34+
},
35+
{
36+
name: "empty prefix with sub route",
37+
prefix: "",
38+
routePath: "/list",
39+
expectedPath: "/list",
40+
},
41+
{
42+
name: "prefix with trailing slash and root route",
43+
prefix: "/api/v1/shoppings/",
44+
routePath: "/",
45+
expectedPath: "/api/v1/shoppings",
46+
},
47+
{
48+
name: "prefix without leading slash and root route",
49+
prefix: "api/v1/shoppings",
50+
routePath: "/",
51+
expectedPath: "/api/v1/shoppings",
52+
},
53+
{
54+
name: "single level prefix with root route",
55+
prefix: "/api",
56+
routePath: "/",
57+
expectedPath: "/api",
58+
},
59+
}
60+
61+
for _, tt := range tests {
62+
t.Run(tt.name, func(t *testing.T) {
63+
srv := spec.Service{
64+
Groups: []spec.Group{
65+
{
66+
Annotation: spec.Annotation{
67+
Properties: map[string]string{
68+
propertyKeyPrefix: tt.prefix,
69+
},
70+
},
71+
Routes: []spec.Route{
72+
{
73+
Method: "get",
74+
Path: tt.routePath,
75+
Handler: "TestHandler",
76+
},
77+
},
78+
},
79+
},
80+
}
81+
82+
ctx := testingContext(t)
83+
paths := spec2Paths(ctx, srv)
84+
85+
assert.Contains(t, paths.Paths, tt.expectedPath,
86+
"Expected path %s not found in generated paths. Got: %v",
87+
tt.expectedPath, paths.Paths)
88+
})
89+
}
90+
}

0 commit comments

Comments
 (0)