Pulse/internal/config/persistence_extended_test.go
rcourtman 3fdf753a5b Enhance devcontainer and CI workflows
- Add persistent volume mounts for Go/npm caches (faster rebuilds)
- Add shell config with helpful aliases and custom prompt
- Add comprehensive devcontainer documentation
- Add pre-commit hooks for Go formatting and linting
- Use go-version-file in CI workflows instead of hardcoded versions
- Simplify docker compose commands with --wait flag
- Add gitignore entries for devcontainer auth files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 22:29:15 +00:00

131 lines
3.6 KiB
Go

package config_test
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/internal/notifications"
)
func TestConfigPersistence_DataDir(t *testing.T) {
tempDir := t.TempDir()
cp := config.NewConfigPersistence(tempDir)
if cp.DataDir() != tempDir {
t.Errorf("Expected %s, got %s", tempDir, cp.DataDir())
}
}
func TestConfigPersistence_MigrateWebhooksIfNeeded(t *testing.T) {
tempDir := t.TempDir()
cp := config.NewConfigPersistence(tempDir)
// 1. Create legacy file
legacyFile := filepath.Join(tempDir, "webhooks.json")
legacyWebhooks := []notifications.WebhookConfig{
{ID: "webhook-1", URL: "http://example.com/legacy"},
}
data, _ := json.Marshal(legacyWebhooks)
os.WriteFile(legacyFile, data, 0644)
// 2. Migrate
if err := cp.MigrateWebhooksIfNeeded(); err != nil {
t.Fatalf("MigrateWebhooksIfNeeded failed: %v", err)
}
// 3. Verify encrypted file exists (since SaveWebhooks uses encryption if key exists)
// NewConfigPersistence generates a key if it doesn't exist, so encryption IS enabled by default.
loaded, err := cp.LoadWebhooks()
if err != nil {
t.Fatalf("LoadWebhooks failed: %v", err)
}
if len(loaded) != 1 || loaded[0].URL != "http://example.com/legacy" {
t.Errorf("Migration failed to preserve data: %+v", loaded)
}
}
func TestConfigPersistence_PatrolRunHistory(t *testing.T) {
tempDir := t.TempDir()
cp := config.NewConfigPersistence(tempDir)
runs := []config.PatrolRunRecord{
{
ID: "run-1",
StartedAt: time.Now().Add(-1 * time.Hour),
CompletedAt: time.Now().Add(-59 * time.Minute),
DurationMs: 60000,
Type: "quick",
ResourcesChecked: 10,
NewFindings: 2,
},
}
if err := cp.SavePatrolRunHistory(runs); err != nil {
t.Fatalf("SavePatrolRunHistory failed: %v", err)
}
history, err := cp.LoadPatrolRunHistory()
if err != nil {
t.Fatalf("LoadPatrolRunHistory failed: %v", err)
}
if len(history.Runs) != 1 || history.Runs[0].ID != "run-1" {
t.Errorf("Patrol history mismatch: %+v", history)
}
// Test non-existent file
cp2 := config.NewConfigPersistence(t.TempDir())
history2, err := cp2.LoadPatrolRunHistory()
if err != nil {
t.Fatalf("LoadPatrolRunHistory on empty dir failed: %v", err)
}
if len(history2.Runs) != 0 {
t.Errorf("Expected 0 runs, got %d", len(history2.Runs))
}
}
func TestConfigPersistence_UpdateEnvFile(t *testing.T) {
tempDir := t.TempDir()
envFile := filepath.Join(tempDir, ".env")
initialContent := `UPDATE_CHANNEL=stable
AUTO_UPDATE_ENABLED=false
POLLING_INTERVAL=10
CUSTOM_VAR=value`
os.WriteFile(envFile, []byte(initialContent), 0644)
cp := config.NewConfigPersistence(tempDir)
settings := config.SystemSettings{
UpdateChannel: "beta",
AutoUpdateEnabled: true,
AutoUpdateCheckInterval: 3600,
}
if err := cp.SaveSystemSettings(settings); err != nil {
t.Fatalf("SaveSystemSettings failed: %v", err)
}
updatedData, err := os.ReadFile(envFile)
if err != nil {
t.Fatalf("Failed to read .env file: %v", err)
}
updatedContent := string(updatedData)
if !strings.Contains(updatedContent, "UPDATE_CHANNEL=beta") {
t.Errorf("UPDATE_CHANNEL not updated. Content: %s", updatedContent)
}
if !strings.Contains(updatedContent, "AUTO_UPDATE_ENABLED=true") {
t.Errorf("AUTO_UPDATE_ENABLED not updated. Content: %s", updatedContent)
}
if strings.Contains(updatedContent, "POLLING_INTERVAL=") {
t.Error("POLLING_INTERVAL should have been removed")
}
if !strings.Contains(updatedContent, "CUSTOM_VAR=value") {
t.Error("CUSTOM_VAR should have been preserved")
}
}