package web import ( "bytes" "testing" "time" "github.com/owen/vibeproxy/internal/database" "github.com/owen/vibeproxy/internal/models" "github.com/owen/vibeproxy/internal/stats" ) func mustRender(t *testing.T, name string, data PageData) { t.Helper() var buf bytes.Buffer if err := templates.ExecuteTemplate(&buf, name, data); err != nil { t.Fatalf("render %s: %v", name, err) } if buf.Len() == 0 { t.Fatalf("render %s: empty output", name) } } func TestRenderAllPages(t *testing.T) { now := time.Now() aid := int64(1) host := models.ProxyHost{ ID: 1, Name: "example", Type: models.ProxyHostTypeProxy, Domains: []string{"example.com"}, ForwardScheme: "http", LoadBalancingMethod: "round_robin", CertificateID: &aid, AccessListID: &aid, Backends: []models.Backend{{ID: 1, Host: "10.0.0.1", Port: 8080, Weight: 1, Enabled: true, HealthCheckType: models.HealthCheckTCP}}, CustomHeaders: []models.CustomHeader{{Direction: models.HeaderDirectionRequest, Action: models.HeaderActionSet, Name: "X-Test", Value: "1"}}, Enabled: true, CreatedAt: now, UpdatedAt: now, } redirectHost := host redirectHost.Type = models.ProxyHostTypeRedirect redirectHost.RedirectTargetURL = "https://new.example.com" redirectHost.RedirectCode = 301 acl := models.AccessList{ID: 1, Name: "Internal", DefaultAllow: false, Rules: []models.AccessRule{{Action: models.AccessAllow, CIDR: "10.0.0.0/8"}}, BasicAuthUsers: []models.AccessListUser{{Username: "bob", PasswordHash: "hash"}}, } cert := models.Certificate{ID: 1, Name: "example", Type: models.CertTypeLetsEncrypt, Domains: []string{"example.com"}, NotAfter: &now} stream := models.Stream{ID: 1, Protocol: models.StreamTCP, ListenIP: "0.0.0.0", ListenPort: 25565, DestinationHost: "10.0.0.1", DestinationPort: 25565, Enabled: true} reqLog := models.RequestLog{ID: 1, Timestamp: now, ProxyHostName: "example", ClientIP: "1.2.3.4", Method: "GET", Host: "example.com", Path: "/", Status: 200, ResponseSize: 100, Backend: "10.0.0.1:8080", ResponseTimeMS: 12} auditLog := models.AuditLog{ID: 1, Timestamp: now, Actor: "admin", Action: "proxy_created", Target: "example", Details: "domains=[example.com]"} token := models.APIToken{ID: 1, Name: "ci", Prefix: "vp_abcd12", CreatedAt: now} tests := []struct { name string pd PageData }{ {"dashboard", PageData{Data: &stats.Dashboard{ BackendHealth: []stats.BackendHealthEntry{{ProxyHost: "example", Backend: "10.0.0.1", Healthy: true}}, StatusBreakdown: []database.StatusCount{{Status: 200, Count: 5}}, TopHosts: []database.HostCount{{Host: "example.com", Count: 5}}, TopClients: []database.HostCount{{Host: "1.2.3.4", Count: 5}}, CertsExpiringSoon: []models.Certificate{cert}, RecentErrors: []models.RequestLog{reqLog}, }}}, {"proxy_hosts", PageData{CSRFToken: "tok", Data: map[string]any{ "Hosts": []models.ProxyHost{host, redirectHost}, "AccessLists": []models.AccessList{acl}, "Certificates": []models.Certificate{cert}, }}}, {"proxy_host_form", PageData{CSRFToken: "tok", Data: proxyHostFormData{Host: host, AccessLists: []models.AccessList{acl}, Certificates: []models.Certificate{cert}, IsNew: false}}}, {"proxy_host_form", PageData{CSRFToken: "tok", Data: proxyHostFormData{Host: redirectHost, AccessLists: []models.AccessList{acl}, Certificates: []models.Certificate{cert}, IsNew: true}}}, {"streams", PageData{CSRFToken: "tok", Data: []models.Stream{stream}}}, {"stream_form", PageData{CSRFToken: "tok", Data: map[string]any{"Stream": stream, "IsNew": false}}}, {"backends", PageData{Data: []backendRow{{ProxyHostID: 1, ProxyHostName: "example", Host: "10.0.0.1", Port: 8080, Weight: 1, Enabled: true, Healthy: true, HealthCheck: "tcp"}}}}, {"certificates", PageData{CSRFToken: "tok", Data: []models.Certificate{cert}}}, {"access_lists", PageData{CSRFToken: "tok", Data: []models.AccessList{acl}}}, {"access_list_form", PageData{CSRFToken: "tok", Data: map[string]any{"List": acl, "IsNew": false}}}, {"logs", PageData{Data: map[string]any{"Logs": []models.RequestLog{reqLog}, "Total": 1, "Page": 1, "TotalPages": 1, "Query": "", "Status": 0}}}, {"logs_audit", PageData{Data: map[string]any{"Logs": []models.AuditLog{auditLog}, "Total": 1, "Page": 1, "TotalPages": 1}}}, {"settings", PageData{CSRFToken: "tok", Data: models.Settings{AdminUsername: "admin", TrustedProxyCIDRs: []string{"10.0.0.0/8"}}}}, {"api_tokens", PageData{CSRFToken: "tok", Data: []models.APIToken{token}}}, } for _, tc := range tests { mustRender(t, tc.name, tc.pd) } }