internal/server/certificate_auto_domains_test.go
Rama main · réplica de lectura del repositorio original.
// SPDX-License-Identifier: Apache-2.0
package server
import (
"testing"
"github.com/X4Applegate/caddyui/internal/models"
)
// v2.36.2 (issue #65): the Certificates page's "Caddy-managed (ACME)" list
// must include Advanced routes' hostnames under the same rule as proxy hosts
// and redirects — enabled, no custom certificate — with the same wildcard
// mapping and lifecycle status, and without listing anything twice.
func TestAutoManagedDomainsIncludeAdvancedRoutes(t *testing.T) {
certs := []models.Certificate{
{ID: 7, Name: "Example wildcard", Source: models.CertSourceManaged, Domains: "*.example.com"},
}
states := []models.CertificateLifecycleStatus{
{Identifier: "health.example.net", Phase: "active", Level: "INFO", Message: "certificate obtained successfully"},
}
hosts := []models.ProxyHost{{Domains: "app.example.org", Enabled: true, SSLEnabled: true}}
redirs := []models.RedirectionHost{{Domains: "old.example.org", Enabled: true, SSLEnabled: true}}
route := func(host string) string {
return `{"match":[{"host":["` + host + `"]}],"handle":[{"handler":"static_response","status_code":200}]}`
}
raws := []models.RawRoute{
{Enabled: true, JSONData: route("health.example.net")}, // must appear
{Enabled: true, JSONData: route("api.example.com")}, // must appear, covered by the wildcard
{Enabled: true, JSONData: route("app.example.org")}, // same domain as the proxy host: listed once
{Enabled: false, JSONData: route("off.example.net")}, // disabled: absent
{Enabled: true, CertificateID: 3, JSONData: route("custom.example.net")}, // custom cert: absent (it's a custom cert row instead)
{Enabled: true, JSONData: `{"match":[{"path":["/lbhealthcheck"]}],"handle":[{"handler":"static_response","status_code":200}]}`}, // no host: nothing to secure
}
got := collectAutoManagedDomains(certs, states, hosts, redirs, raws)
wantOrder := []string{"app.example.org", "old.example.org", "health.example.net", "api.example.com"}
if len(got) != len(wantOrder) {
t.Fatalf("got %d auto-managed domains %v, want %v", len(got), domainsOf(got), wantOrder)
}
byDomain := map[string]autoDomainView{}
for i, v := range got {
byDomain[v.Domain] = v
if v.Domain != wantOrder[i] {
t.Errorf("position %d = %q, want %q (proxy → redirect → Advanced route order)", i, v.Domain, wantOrder[i])
}
}
for _, absent := range []string{"off.example.net", "custom.example.net"} {
if _, ok := byDomain[absent]; ok {
t.Errorf("%s must not be listed as Caddy-managed", absent)
}
}
if v := byDomain["health.example.net"]; v.Lifecycle == nil || v.Lifecycle.Phase != "active" {
t.Errorf("lifecycle status not attached to an Advanced route's domain: %+v", v.Lifecycle)
} else if v.UsesWildcard || v.CertificateName != "Direct certificate" {
t.Errorf("health.example.net should be a direct certificate, got %+v", v)
}
if v := byDomain["api.example.com"]; !v.UsesWildcard || v.CertificateName != "Example wildcard" {
t.Errorf("api.example.com should map to the managed wildcard, got %+v", v)
}
}
func domainsOf(views []autoDomainView) []string {
out := make([]string, 0, len(views))
for _, v := range views {
out = append(out, v.Domain)
}
return out
}