89 lines
2.9 KiB
Go
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")
|
|
}
|
|
}
|