Add Go rewrite with Postgres 17 and Dokploy Docker Compose
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"amnezia-share/internal/config"
|
||||
"amnezia-share/internal/models"
|
||||
"amnezia-share/internal/share"
|
||||
"amnezia-share/internal/web"
|
||||
)
|
||||
|
||||
// TestRenderAllPages executes every page template against a realistic view
|
||||
// struct (as built by the real handlers) without needing a database. It
|
||||
// catches execution-time template errors (bad field/method names, nil
|
||||
// dereferences) that plain `go build` and template parsing cannot catch.
|
||||
func TestRenderAllPages(t *testing.T) {
|
||||
tmpl, err := web.LoadTemplates(config.Config{WebDir: "../../../web"})
|
||||
if err != nil {
|
||||
t.Fatalf("LoadTemplates: %v", err)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
future := now.Add(48 * time.Hour)
|
||||
note := "test note"
|
||||
linkID := 7
|
||||
email := "user@example.com"
|
||||
validityDays := 30
|
||||
|
||||
serverInfo := models.ServerInfo{ID: 1, Label: "Germany", Protocols: []string{"wireguard", "awg2"}, Flag: "de", Speed: "1 Gbps"}
|
||||
|
||||
sampleLink := models.ShareLink{
|
||||
ID: 1, Token: "abc123", MaxUses: 5, UseCount: 2, CreatedAt: now,
|
||||
ExpiresAt: &future, ValidityDays: &validityDays,
|
||||
AllowedServerIDs: json.RawMessage(`[1,2]`),
|
||||
}
|
||||
|
||||
bundle := share.Bundle{
|
||||
Base: "peer1",
|
||||
Conf: &share.FilePart{Filename: "peer1.conf", Body: "conf-body", Mime: "text/plain"},
|
||||
Vpn: &share.FilePart{Filename: "peer1.vpn", Body: "vpn-body", Mime: "text/plain"},
|
||||
CreationID: 42,
|
||||
CreatedAt: now,
|
||||
Protocol: "wireguard",
|
||||
ConnectionName: "peer1",
|
||||
ServerID: 1,
|
||||
}
|
||||
|
||||
adminUser := &models.User{ID: 1, Username: "admin"}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
data any
|
||||
}{
|
||||
{"page_install", installView{}},
|
||||
{"page_install", installView{Installed: true}},
|
||||
{"page_install", installView{Error: "test error"}},
|
||||
{"page_login", loginView{PocketEnabled: true, NoAdmins: false}},
|
||||
{"page_login", loginView{Error: "bad creds", NoAdmins: true}},
|
||||
{"page_cabinet_auth", cabinetAuthView{}},
|
||||
{"page_cabinet_auth", cabinetAuthView{Error: "bad creds"}},
|
||||
{"page_cabinet", cabinetView{
|
||||
Member: &models.Member{ID: 1, Username: "member1", Email: &email, CreatedAt: now},
|
||||
Sub: &models.MemberSubscription{MemberID: 1, ExpiresAt: &future, MaxConfigs: 5, ConfigCount: 2},
|
||||
SubLabel: "до " + future.Format("2006-01-02"),
|
||||
ConfigsRemaining: 3,
|
||||
Servers: []models.ServerInfo{serverInfo},
|
||||
Bundles: []share.Bundle{bundle},
|
||||
OK: "ok message",
|
||||
}},
|
||||
{"page_cabinet", cabinetView{
|
||||
Member: &models.Member{ID: 1, Username: "member1", CreatedAt: now},
|
||||
Error: "some error",
|
||||
}},
|
||||
{"page_share", shareView{Token: "abc123", NotFound: true}},
|
||||
{"page_share", shareView{
|
||||
Token: "abc123",
|
||||
Link: &sampleLink,
|
||||
Servers: []models.ServerInfo{serverInfo},
|
||||
Bundles: []share.Bundle{bundle},
|
||||
OK: "created",
|
||||
}},
|
||||
{"page_share", shareView{
|
||||
Token: "abc123",
|
||||
Link: &sampleLink,
|
||||
Servers: []models.ServerInfo{serverInfo},
|
||||
Expired: true,
|
||||
LimitReached: true,
|
||||
Error: "some error",
|
||||
}},
|
||||
{"page_faq", faqView{Items: []faqEntry{{Question: "Q1", Answer: "A1"}}}},
|
||||
{"page_rules", nil},
|
||||
{"page_status", statusView{Servers: []serverStatus{{ServerInfo: serverInfo, Alive: true, Ms: 42}, {ServerInfo: serverInfo, Alive: false, Err: "timeout"}}}},
|
||||
{"page_admin_index", adminIndexView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "index"},
|
||||
TotalLinks: 10, ActiveLinks: 5, ExpiredLinks: 2, CleanedLinks: 1, LimitLinks: 2,
|
||||
CodesCount: 3, PanelURL: "https://panel.example.com", PanelOK: true, Maintenance: false,
|
||||
}},
|
||||
{"page_admin_index", adminIndexView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "index"},
|
||||
PanelErr: "connection refused",
|
||||
}},
|
||||
{"page_admin_links", adminLinksView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "links", OK: "saved"},
|
||||
StatusFilter: "active",
|
||||
Page: 1,
|
||||
Total: 1,
|
||||
PerPage: 20,
|
||||
AllowedDurations: []int{7, 30, 90},
|
||||
Links: []linkRow{
|
||||
{ShareLink: sampleLink, Status: share.StatusActive, ActiveConfigs: 2},
|
||||
},
|
||||
Detail: &sampleLink,
|
||||
DetailStatus: share.StatusActive,
|
||||
Creations: []models.ShareCreation{{ID: 42, ShareLinkID: 1, ServerID: 1, Protocol: "wireguard", ConnectionName: "peer1", CreatedAt: now}},
|
||||
DeletedCreations: []models.ShareCreation{{ID: 41, ShareLinkID: 1, ServerID: 1, Protocol: "wireguard", ConnectionName: "peer0", CreatedAt: now}},
|
||||
AllowedServerIDs: []int{1, 2},
|
||||
AllServers: []models.ServerInfo{serverInfo},
|
||||
}},
|
||||
{"page_admin_links", adminLinksView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "links"},
|
||||
PerPage: 20,
|
||||
}},
|
||||
{"page_admin_renewal", adminRenewalView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "renewal"},
|
||||
Codes: []models.RenewalCode{
|
||||
{ID: 1, Code: "ABCD1234", AddDays: 30, MaxUses: 1, UseCount: 0, ShareLinkID: &linkID, CodeExpiresAt: &future, Note: ¬e, CodeTarget: "guest", CreatedAt: now},
|
||||
{ID: 2, Code: "WXYZ9999", AddDays: 30, MaxUses: 5, UseCount: 1, CodeTarget: "member", CreatedAt: now},
|
||||
},
|
||||
}},
|
||||
{"page_admin_renewal", adminRenewalView{adminLayout: adminLayout{Admin: adminUser, Active: "renewal"}}},
|
||||
{"page_admin_configs", adminConfigsView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "configs"},
|
||||
Rows: []configRow{
|
||||
{ShareCreation: models.ShareCreation{ID: 42, ShareLinkID: 1, ServerID: 1, Protocol: "wireguard", ConnectionName: "peer1", CreatedAt: now}, LinkID: 1, LinkToken: "abc123"},
|
||||
},
|
||||
LinkIDFilter: 1,
|
||||
Truncated: true,
|
||||
}},
|
||||
{"page_admin_configs", adminConfigsView{adminLayout: adminLayout{Admin: adminUser, Active: "configs"}}},
|
||||
{"page_admin_servers", adminServersView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "servers"},
|
||||
AllProtocols: share.GuestProtocols,
|
||||
Rows: []serverRow{
|
||||
{ID: 1, Title: "Germany", Protocols: []string{"wireguard", "awg2"}, Flag: "🇩🇪", Speed: "1 Gbps", Disabled: false, PanelName: "de-1", PanelHost: "1.2.3.4"},
|
||||
{ID: 2, Title: "France", Protocols: nil, Disabled: true},
|
||||
},
|
||||
PanelReachable: true,
|
||||
}},
|
||||
{"page_admin_servers", adminServersView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "servers"},
|
||||
AllProtocols: share.GuestProtocols,
|
||||
PanelErr: "connection refused",
|
||||
}},
|
||||
{"page_admin_settings", adminSettingsView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "settings"},
|
||||
PanelURL: "https://panel.example.com",
|
||||
APIToken: "awp_secret",
|
||||
ServerLabelsJSON: `{"1":"Germany"}`,
|
||||
TrafficNotices: `{}`,
|
||||
Maintenance: true,
|
||||
PocketURL: "https://id.example.com",
|
||||
PocketClientID: "client-id",
|
||||
PocketSecret: "secret",
|
||||
MemberDays: "30",
|
||||
MemberMaxUses: "5",
|
||||
TestResult: "Соединение установлено. Серверов обнаружено: 3.",
|
||||
}},
|
||||
{"page_admin_settings", adminSettingsView{
|
||||
adminLayout: adminLayout{Admin: adminUser, Active: "settings"},
|
||||
TestError: "connection refused",
|
||||
}},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
clone, err := tmpl.Clone()
|
||||
if err != nil {
|
||||
t.Fatalf("clone: %v", err)
|
||||
}
|
||||
if err := clone.ExecuteTemplate(io.Discard, c.name, c.data); err != nil {
|
||||
t.Errorf("case %d (%s): execute failed: %v", i, c.name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user