Files
jbergner fe32431d21
Some checks failed
release-tag / release-image (push) Failing after 55s
init
2026-08-01 23:54:45 +02:00

89 lines
2.9 KiB
Go

package app
import (
"io"
"log/slog"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
"github.com/example/glpi-env-controller/internal/dockerctl"
)
func testTemplate(t *testing.T) string {
t.Helper()
data, err := os.ReadFile("../../cmd/env-controller/page.html")
if err != nil {
t.Fatal(err)
}
return string(data)
}
func TestSaveCreatesBackupAndKeepsUnrevealedSecret(t *testing.T) {
dir := t.TempDir()
envPath := filepath.Join(dir, ".env")
examplePath := filepath.Join(dir, ".env.example")
backupDir := filepath.Join(dir, "backups")
if err := os.WriteFile(envPath, []byte("A=1\nWEB_PASSWORD=top-secret\n"), 0o600); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(examplePath, []byte("A=0\nWEB_PASSWORD=placeholder\n"), 0o600); err != nil {
t.Fatal(err)
}
project := ProjectConfig{ID: "test", Title: "Test", EnvFile: envPath, ExampleFile: examplePath, BackupDir: backupDir}
cfg := Config{Username: "admin", MaxBackups: 10, DockerTimeout: "1s", Projects: []ProjectConfig{project}}
server, err := NewServer(cfg, "password", testTemplate(t), slog.New(slog.NewTextHandler(io.Discard, nil)))
if err != nil {
t.Fatal(err)
}
form := url.Values{"csrf": {server.csrf}, "v.A": {"2"}, "v.WEB_PASSWORD": {unchangedSecret}}
req := httptest.NewRequest(http.MethodPost, "/project/test/save", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetBasicAuth("admin", "password")
res := httptest.NewRecorder()
server.Handler().ServeHTTP(res, req)
if res.Code != http.StatusOK {
t.Fatalf("status %d: %s", res.Code, res.Body.String())
}
got, err := os.ReadFile(envPath)
if err != nil {
t.Fatal(err)
}
if string(got) != "A=2\nWEB_PASSWORD=top-secret\n" {
t.Fatalf("unexpected env: %q", got)
}
entries, err := os.ReadDir(backupDir)
if err != nil {
t.Fatal(err)
}
found := false
for _, entry := range entries {
if strings.HasSuffix(entry.Name(), ".env") {
found = true
}
}
if !found {
t.Fatal("expected backup")
}
}
func TestTargetPickerTemplateExecutes(t *testing.T) {
cfg := Config{Username: "admin", MaxBackups: 10, DockerTimeout: "1s", Projects: []ProjectConfig{{ID: "test"}}}
server, err := NewServer(cfg, "password", testTemplate(t), slog.New(slog.NewTextHandler(io.Discard, nil)))
if err != nil {
t.Fatal(err)
}
data := pageData{Title: "x", CSRF: server.csrf, Project: &projectView{Config: ProjectConfig{ID: "test"}, Targets: []targetView{{Target: dockerctl.Target{ContainerName: "agent", DisplayName: "Agent", AllowedActions: []string{"restart", "recreate"}, DefaultAction: "recreate", ApplyByDefault: true}, Status: dockerctl.Status{State: "running"}}}}}
var b strings.Builder
if err := server.tpl.ExecuteTemplate(&b, "page", data); err != nil {
t.Fatal(err)
}
if !strings.Contains(b.String(), "glpi") && !strings.Contains(b.String(), "agent") {
t.Fatal("target not rendered")
}
}