From 9b5477c0511a20f0a2ab67eb6bed16041ec2310b Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 00:12:13 +0000 Subject: [PATCH] fix(api): ignore blank swagger metadata overrides Co-Authored-By: Virgil --- options.go | 32 +++++++++++++++----- swagger_test.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 8 deletions(-) diff --git a/options.go b/options.go index a1b6af5..f5e38fd 100644 --- a/options.go +++ b/options.go @@ -159,7 +159,9 @@ func WithSwagger(title, description, version string) Option { // api.WithSwaggerTermsOfService("https://example.com/terms") func WithSwaggerTermsOfService(url string) Option { return func(e *Engine) { - e.swaggerTermsOfService = url + if url != "" { + e.swaggerTermsOfService = url + } } } @@ -171,9 +173,15 @@ func WithSwaggerTermsOfService(url string) Option { // api.WithSwaggerContact("API Support", "https://example.com/support", "support@example.com") func WithSwaggerContact(name, url, email string) Option { return func(e *Engine) { - e.swaggerContactName = name - e.swaggerContactURL = url - e.swaggerContactEmail = email + if name != "" { + e.swaggerContactName = name + } + if url != "" { + e.swaggerContactURL = url + } + if email != "" { + e.swaggerContactEmail = email + } } } @@ -198,8 +206,12 @@ func WithSwaggerServers(servers ...string) Option { // api.WithSwaggerLicense("EUPL-1.2", "https://eupl.eu/1.2/en/") func WithSwaggerLicense(name, url string) Option { return func(e *Engine) { - e.swaggerLicenseName = name - e.swaggerLicenseURL = url + if name != "" { + e.swaggerLicenseName = name + } + if url != "" { + e.swaggerLicenseURL = url + } } } @@ -212,8 +224,12 @@ func WithSwaggerLicense(name, url string) Option { // api.WithSwaggerExternalDocs("Developer guide", "https://example.com/docs") func WithSwaggerExternalDocs(description, url string) Option { return func(e *Engine) { - e.swaggerExternalDocsDescription = description - e.swaggerExternalDocsURL = url + if description != "" { + e.swaggerExternalDocsDescription = description + } + if url != "" { + e.swaggerExternalDocsURL = url + } } } diff --git a/swagger_test.go b/swagger_test.go index 6623005..4807997 100644 --- a/swagger_test.go +++ b/swagger_test.go @@ -425,6 +425,85 @@ func TestSwagger_Good_UsesExternalDocsMetadata(t *testing.T) { } } +func TestSwagger_Good_IgnoresBlankMetadataOverrides(t *testing.T) { + gin.SetMode(gin.TestMode) + + e, err := api.New( + api.WithSwagger("Stable API", "Blank override test", "1.0.0"), + api.WithSwaggerTermsOfService("https://example.com/terms"), + api.WithSwaggerTermsOfService(""), + api.WithSwaggerContact("API Support", "https://example.com/support", "support@example.com"), + api.WithSwaggerContact("", "", ""), + api.WithSwaggerLicense("EUPL-1.2", "https://eupl.eu/1.2/en/"), + api.WithSwaggerLicense("", ""), + api.WithSwaggerExternalDocs("Developer guide", "https://example.com/docs"), + api.WithSwaggerExternalDocs("", ""), + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + srv := httptest.NewServer(e.Handler()) + defer srv.Close() + + resp, err := http.Get(srv.URL + "/swagger/doc.json") + if err != nil { + t.Fatalf("request failed: %v", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatalf("failed to read body: %v", err) + } + + var doc map[string]any + if err := json.Unmarshal(body, &doc); err != nil { + t.Fatalf("invalid JSON: %v", err) + } + + info := doc["info"].(map[string]any) + if info["termsOfService"] != "https://example.com/terms" { + t.Fatalf("expected termsOfService to survive blank override, got %v", info["termsOfService"]) + } + + contact, ok := info["contact"].(map[string]any) + if !ok { + t.Fatal("expected contact metadata in swagger doc") + } + if contact["name"] != "API Support" { + t.Fatalf("expected contact name to survive blank override, got %v", contact["name"]) + } + if contact["url"] != "https://example.com/support" { + t.Fatalf("expected contact url to survive blank override, got %v", contact["url"]) + } + if contact["email"] != "support@example.com" { + t.Fatalf("expected contact email to survive blank override, got %v", contact["email"]) + } + + license, ok := info["license"].(map[string]any) + if !ok { + t.Fatal("expected license metadata in swagger doc") + } + if license["name"] != "EUPL-1.2" { + t.Fatalf("expected license name to survive blank override, got %v", license["name"]) + } + if license["url"] != "https://eupl.eu/1.2/en/" { + t.Fatalf("expected license url to survive blank override, got %v", license["url"]) + } + + externalDocs, ok := doc["externalDocs"].(map[string]any) + if !ok { + t.Fatal("expected externalDocs metadata in swagger doc") + } + if externalDocs["description"] != "Developer guide" { + t.Fatalf("expected externalDocs description to survive blank override, got %v", externalDocs["description"]) + } + if externalDocs["url"] != "https://example.com/docs" { + t.Fatalf("expected externalDocs url to survive blank override, got %v", externalDocs["url"]) + } +} + func TestSwagger_Good_UsesServerMetadata(t *testing.T) { gin.SetMode(gin.TestMode)