fix(api): snapshot swagger groups
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
2c87fa02cb
commit
ffbb6d83d0
2 changed files with 98 additions and 18 deletions
41
swagger.go
41
swagger.go
|
|
@ -11,6 +11,7 @@ import (
|
|||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"github.com/swaggo/swag"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// swaggerSeq provides unique instance names so multiple Engine instances
|
||||
|
|
@ -26,6 +27,13 @@ type swaggerSpec struct {
|
|||
doc string
|
||||
}
|
||||
|
||||
func newSwaggerSpec(builder *SpecBuilder, groups []RouteGroup) *swaggerSpec {
|
||||
return &swaggerSpec{
|
||||
builder: builder,
|
||||
groups: slices.Clone(groups),
|
||||
}
|
||||
}
|
||||
|
||||
// ReadDoc returns the OpenAPI 3.1 JSON document for this spec.
|
||||
func (s *swaggerSpec) ReadDoc() string {
|
||||
s.once.Do(func() {
|
||||
|
|
@ -41,24 +49,21 @@ func (s *swaggerSpec) ReadDoc() string {
|
|||
|
||||
// registerSwagger mounts the Swagger UI and doc.json endpoint.
|
||||
func registerSwagger(g *gin.Engine, title, description, version, graphqlPath, termsOfService, contactName, contactURL, contactEmail string, servers []string, licenseName, licenseURL, externalDocsDescription, externalDocsURL string, groups []RouteGroup) {
|
||||
spec := &swaggerSpec{
|
||||
builder: &SpecBuilder{
|
||||
Title: title,
|
||||
Description: description,
|
||||
Version: version,
|
||||
GraphQLPath: graphqlPath,
|
||||
TermsOfService: termsOfService,
|
||||
ContactName: contactName,
|
||||
ContactURL: contactURL,
|
||||
ContactEmail: contactEmail,
|
||||
Servers: servers,
|
||||
LicenseName: licenseName,
|
||||
LicenseURL: licenseURL,
|
||||
ExternalDocsDescription: externalDocsDescription,
|
||||
ExternalDocsURL: externalDocsURL,
|
||||
},
|
||||
groups: groups,
|
||||
}
|
||||
spec := newSwaggerSpec(&SpecBuilder{
|
||||
Title: title,
|
||||
Description: description,
|
||||
Version: version,
|
||||
GraphQLPath: graphqlPath,
|
||||
TermsOfService: termsOfService,
|
||||
ContactName: contactName,
|
||||
ContactURL: contactURL,
|
||||
ContactEmail: contactEmail,
|
||||
Servers: servers,
|
||||
LicenseName: licenseName,
|
||||
LicenseURL: licenseURL,
|
||||
ExternalDocsDescription: externalDocsDescription,
|
||||
ExternalDocsURL: externalDocsURL,
|
||||
}, groups)
|
||||
name := fmt.Sprintf("swagger_%d", swaggerSeq.Add(1))
|
||||
swag.Register(name, spec)
|
||||
g.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.NewHandler(), ginSwagger.InstanceName(name)))
|
||||
|
|
|
|||
75
swagger_internal_test.go
Normal file
75
swagger_internal_test.go
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type swaggerSnapshotGroup struct {
|
||||
name string
|
||||
basePath string
|
||||
descs []RouteDescription
|
||||
}
|
||||
|
||||
func (g *swaggerSnapshotGroup) Name() string { return g.name }
|
||||
func (g *swaggerSnapshotGroup) BasePath() string { return g.basePath }
|
||||
func (g *swaggerSnapshotGroup) RegisterRoutes(_ *gin.RouterGroup) {}
|
||||
func (g *swaggerSnapshotGroup) Describe() []RouteDescription {
|
||||
return g.descs
|
||||
}
|
||||
|
||||
func TestSwaggerSpec_ReadDoc_Good_SnapshotsGroups(t *testing.T) {
|
||||
original := &swaggerSnapshotGroup{
|
||||
name: "first",
|
||||
basePath: "/first",
|
||||
descs: []RouteDescription{
|
||||
{
|
||||
Method: "GET",
|
||||
Path: "/ping",
|
||||
Summary: "First group",
|
||||
Response: map[string]any{
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
replacement := &swaggerSnapshotGroup{
|
||||
name: "second",
|
||||
basePath: "/second",
|
||||
descs: []RouteDescription{
|
||||
{
|
||||
Method: "GET",
|
||||
Path: "/pong",
|
||||
Summary: "Second group",
|
||||
Response: map[string]any{
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups := []RouteGroup{original}
|
||||
spec := newSwaggerSpec(&SpecBuilder{
|
||||
Title: "Test",
|
||||
Version: "1.0.0",
|
||||
}, groups)
|
||||
|
||||
groups[0] = replacement
|
||||
|
||||
var doc map[string]any
|
||||
if err := json.Unmarshal([]byte(spec.ReadDoc()), &doc); err != nil {
|
||||
t.Fatalf("invalid JSON: %v", err)
|
||||
}
|
||||
|
||||
paths := doc["paths"].(map[string]any)
|
||||
if _, ok := paths["/first/ping"]; !ok {
|
||||
t.Fatal("expected original group path to remain in the spec")
|
||||
}
|
||||
if _, ok := paths["/second/pong"]; ok {
|
||||
t.Fatal("did not expect mutated group path to leak into the spec")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue