fix(api): normalise runtime metadata snapshots

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 16:48:37 +00:00
parent 0022931eff
commit 1491e16f9e
3 changed files with 96 additions and 12 deletions

View file

@ -235,6 +235,8 @@ func authentikMiddleware(cfg AuthentikConfig, publicPaths func() []string) gin.H
func cloneAuthentikConfig(cfg AuthentikConfig) AuthentikConfig {
out := cfg
out.Issuer = strings.TrimSpace(out.Issuer)
out.ClientID = strings.TrimSpace(out.ClientID)
out.PublicPaths = normalisePublicPaths(cfg.PublicPaths)
return out
}

View file

@ -204,9 +204,9 @@ func WithSunset(sunsetDate, replacement string) Option {
// api.New(api.WithSwagger("Service", "Public API", "1.0.0"))
func WithSwagger(title, description, version string) Option {
return func(e *Engine) {
e.swaggerTitle = title
e.swaggerDesc = description
e.swaggerVersion = version
e.swaggerTitle = strings.TrimSpace(title)
e.swaggerDesc = strings.TrimSpace(description)
e.swaggerVersion = strings.TrimSpace(version)
e.swaggerEnabled = true
}
}
@ -218,7 +218,7 @@ func WithSwagger(title, description, version string) Option {
// api.WithSwaggerSummary("Service overview")
func WithSwaggerSummary(summary string) Option {
return func(e *Engine) {
if summary != "" {
if summary = strings.TrimSpace(summary); summary != "" {
e.swaggerSummary = summary
}
}
@ -244,7 +244,7 @@ func WithSwaggerPath(path string) Option {
// api.WithSwaggerTermsOfService("https://example.com/terms")
func WithSwaggerTermsOfService(url string) Option {
return func(e *Engine) {
if url != "" {
if url = strings.TrimSpace(url); url != "" {
e.swaggerTermsOfService = url
}
}
@ -258,13 +258,13 @@ 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) {
if name != "" {
if name = strings.TrimSpace(name); name != "" {
e.swaggerContactName = name
}
if url != "" {
if url = strings.TrimSpace(url); url != "" {
e.swaggerContactURL = url
}
if email != "" {
if email = strings.TrimSpace(email); email != "" {
e.swaggerContactEmail = email
}
}
@ -291,10 +291,10 @@ 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) {
if name != "" {
if name = strings.TrimSpace(name); name != "" {
e.swaggerLicenseName = name
}
if url != "" {
if url = strings.TrimSpace(url); url != "" {
e.swaggerLicenseURL = url
}
}
@ -340,10 +340,10 @@ func WithSwaggerSecuritySchemes(schemes map[string]any) Option {
// api.WithSwaggerExternalDocs("Developer guide", "https://example.com/docs")
func WithSwaggerExternalDocs(description, url string) Option {
return func(e *Engine) {
if description != "" {
if description = strings.TrimSpace(description); description != "" {
e.swaggerExternalDocsDescription = description
}
if url != "" {
if url = strings.TrimSpace(url); url != "" {
e.swaggerExternalDocsURL = url
}
}

View file

@ -9,6 +9,7 @@ import (
"time"
"github.com/gin-gonic/gin"
"slices"
api "dappco.re/go/core/api"
)
@ -340,6 +341,87 @@ func TestEngine_Good_SwaggerConfigCarriesEngineMetadata(t *testing.T) {
}
}
func TestEngine_Good_SwaggerConfigTrimsRuntimeMetadata(t *testing.T) {
gin.SetMode(gin.TestMode)
e, err := api.New(
api.WithSwagger(" Engine API ", " Engine metadata ", " 2.0.0 "),
api.WithSwaggerSummary(" Engine overview "),
api.WithSwaggerTermsOfService(" https://example.com/terms "),
api.WithSwaggerContact(" API Support ", " https://example.com/support ", " support@example.com "),
api.WithSwaggerLicense(" EUPL-1.2 ", " https://eupl.eu/1.2/en/ "),
api.WithSwaggerExternalDocs(" Developer guide ", " https://example.com/docs "),
api.WithAuthentik(api.AuthentikConfig{
Issuer: " https://auth.example.com ",
ClientID: " core-client ",
TrustedProxy: true,
PublicPaths: []string{" /public/ ", " docs ", "/public"},
}),
)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
swagger := e.SwaggerConfig()
if swagger.Title != "Engine API" {
t.Fatalf("expected trimmed title Engine API, got %q", swagger.Title)
}
if swagger.Description != "Engine metadata" {
t.Fatalf("expected trimmed description Engine metadata, got %q", swagger.Description)
}
if swagger.Version != "2.0.0" {
t.Fatalf("expected trimmed version 2.0.0, got %q", swagger.Version)
}
if swagger.Summary != "Engine overview" {
t.Fatalf("expected trimmed summary Engine overview, got %q", swagger.Summary)
}
if swagger.TermsOfService != "https://example.com/terms" {
t.Fatalf("expected trimmed termsOfService, got %q", swagger.TermsOfService)
}
if swagger.ContactName != "API Support" || swagger.ContactURL != "https://example.com/support" || swagger.ContactEmail != "support@example.com" {
t.Fatalf("expected trimmed contact metadata, got %+v", swagger)
}
if swagger.LicenseName != "EUPL-1.2" || swagger.LicenseURL != "https://eupl.eu/1.2/en/" {
t.Fatalf("expected trimmed licence metadata, got %+v", swagger)
}
if swagger.ExternalDocsDescription != "Developer guide" || swagger.ExternalDocsURL != "https://example.com/docs" {
t.Fatalf("expected trimmed external docs metadata, got %+v", swagger)
}
auth := e.AuthentikConfig()
if auth.Issuer != "https://auth.example.com" {
t.Fatalf("expected trimmed issuer, got %q", auth.Issuer)
}
if auth.ClientID != "core-client" {
t.Fatalf("expected trimmed client ID, got %q", auth.ClientID)
}
if want := []string{"/public", "/docs"}; !slices.Equal(auth.PublicPaths, want) {
t.Fatalf("expected trimmed public paths %v, got %v", want, auth.PublicPaths)
}
builder := e.OpenAPISpecBuilder()
data, err := builder.Build(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
var spec map[string]any
if err := json.Unmarshal(data, &spec); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
info, ok := spec["info"].(map[string]any)
if !ok {
t.Fatal("expected info object in generated spec")
}
if info["title"] != "Engine API" || info["description"] != "Engine metadata" || info["version"] != "2.0.0" || info["summary"] != "Engine overview" {
t.Fatalf("expected trimmed OpenAPI info block, got %+v", info)
}
if info["termsOfService"] != "https://example.com/terms" {
t.Fatalf("expected trimmed termsOfService in spec, got %v", info["termsOfService"])
}
}
func TestEngine_Good_TransportConfigCarriesEngineMetadata(t *testing.T) {
gin.SetMode(gin.TestMode)