Lots more changes

This commit is contained in:
2026-06-01 01:29:47 -05:00
parent 8bec7f0dda
commit 050ec138f3
20 changed files with 1773 additions and 689 deletions
+104 -7
View File
@@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"io"
"log"
@@ -31,6 +32,18 @@ func repoRoot(t *testing.T) string {
return filepath.Clean(filepath.Join(filepath.Dir(file), "..", ".."))
}
func writeConfigKeyFile(t *testing.T, configPath string) {
t.Helper()
keyPath := filepath.Join(filepath.Dir(configPath), "config.key")
key, err := config.GenerateEncryptionKey()
if err != nil {
t.Fatalf("GenerateEncryptionKey() error = %v", err)
}
if err := os.WriteFile(keyPath, []byte(key+"\n"), 0o600); err != nil {
t.Fatalf("WriteFile(config.key) error = %v", err)
}
}
func TestMainProcessSuccess(t *testing.T) {
t.Parallel()
@@ -48,7 +61,15 @@ storage:
security:
allowed_ips: []
trust_proxy_headers: false
rate_limit:
rate_limit_ui:
enabled: true
requests_per_minute: 10
burst: 1
rate_limit_api_read:
enabled: true
requests_per_minute: 10
burst: 1
rate_limit_api_write:
enabled: true
requests_per_minute: 10
burst: 1
@@ -56,6 +77,7 @@ security:
if err := os.WriteFile(cfgPath, []byte(cfg), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
writeConfigKeyFile(t, cfgPath)
cmd := exec.Command(os.Args[0], "-test.run=TestMainHelperProcess")
cmd.Dir = repoRoot(t)
@@ -104,7 +126,15 @@ storage:
security:
allowed_ips: []
trust_proxy_headers: false
rate_limit:
rate_limit_ui:
enabled: true
requests_per_minute: 10
burst: 1
rate_limit_api_read:
enabled: true
requests_per_minute: 10
burst: 1
rate_limit_api_write:
enabled: true
requests_per_minute: 10
burst: 1
@@ -112,6 +142,7 @@ security:
if err := os.WriteFile(cfgPath, []byte(cfg), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
writeConfigKeyFile(t, cfgPath)
cmd := exec.Command(os.Args[0], "-test.run=TestMainHelperProcess")
cmd.Dir = repoRoot(t)
@@ -198,8 +229,26 @@ func TestGenerateConfigCommandWritesDefaultYAML(t *testing.T) {
if cfg.Storage.DataDir != "./data" {
t.Fatalf("storage.data_dir = %q, want %q", cfg.Storage.DataDir, "./data")
}
if cfg.Security.RateLimit.RequestsPerMinute != 30 {
t.Fatalf("security.rate_limit.requests_per_minute = %d, want %d", cfg.Security.RateLimit.RequestsPerMinute, 30)
if cfg.Storage.EncryptionKeyFile != "config.key" {
t.Fatalf("storage.encryption_key_file = %q, want %q", cfg.Storage.EncryptionKeyFile, "config.key")
}
if cfg.Security.RateLimitUI.RequestsPerMinute != 360 {
t.Fatalf("security.rate_limit_ui.requests_per_minute = %d, want %d", cfg.Security.RateLimitUI.RequestsPerMinute, 360)
}
if cfg.Security.RateLimitUI.Enabled {
t.Fatalf("security.rate_limit_ui.enabled = %v, want false", cfg.Security.RateLimitUI.Enabled)
}
if cfg.Security.RateLimitAPIRead.RequestsPerMinute != 300 {
t.Fatalf("security.rate_limit_api_read.requests_per_minute = %d, want %d", cfg.Security.RateLimitAPIRead.RequestsPerMinute, 300)
}
if cfg.Security.RateLimitAPIRead.Enabled {
t.Fatalf("security.rate_limit_api_read.enabled = %v, want false", cfg.Security.RateLimitAPIRead.Enabled)
}
if cfg.Security.RateLimitAPIWrite.RequestsPerMinute != 30 {
t.Fatalf("security.rate_limit_api_write.requests_per_minute = %d, want %d", cfg.Security.RateLimitAPIWrite.RequestsPerMinute, 30)
}
if !cfg.Security.RateLimitAPIWrite.Enabled {
t.Fatalf("security.rate_limit_api_write.enabled = %v, want true", cfg.Security.RateLimitAPIWrite.Enabled)
}
}
@@ -216,6 +265,45 @@ func TestGenerateConfigCommandRejectsUnexpectedArgs(t *testing.T) {
}
}
func TestGenerateKeyCommandWritesKey(t *testing.T) {
t.Parallel()
cmd := newRootCmd()
var out bytes.Buffer
cmd.SetOut(&out)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"generate-key"})
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute() error = %v", err)
}
raw := strings.TrimSpace(out.String())
if raw == "" {
t.Fatalf("generate-key output is empty")
}
keyBytes, err := base64.StdEncoding.DecodeString(raw)
if err != nil {
t.Fatalf("generate-key output is not valid base64: %v", err)
}
if len(keyBytes) != 32 {
t.Fatalf("decoded key length = %d, want 32", len(keyBytes))
}
}
func TestGenerateKeyCommandRejectsUnexpectedArgs(t *testing.T) {
t.Parallel()
cmd := newRootCmd()
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"generate-key", "extra"})
if err := cmd.Execute(); err == nil {
t.Fatalf("expected error for unexpected args")
}
}
func TestLiveServerEndToEndHTTP(t *testing.T) {
tmp := t.TempDir()
cfgPath := filepath.Join(tmp, "config.yaml")
@@ -231,7 +319,15 @@ storage:
security:
allowed_ips: []
trust_proxy_headers: false
rate_limit:
rate_limit_ui:
enabled: true
requests_per_minute: 30
burst: 10
rate_limit_api_read:
enabled: true
requests_per_minute: 30
burst: 10
rate_limit_api_write:
enabled: true
requests_per_minute: 30
burst: 10
@@ -239,13 +335,14 @@ security:
if err := os.WriteFile(cfgPath, []byte(cfgRaw), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
writeConfigKeyFile(t, cfgPath)
cfg, err := config.Load(cfgPath)
if err != nil {
t.Fatalf("config.Load() error = %v", err)
}
logger := log.New(io.Discard, "", 0)
store, err := storage.NewFilesystemStore(cfg.Storage.DataDir)
store, err := storage.NewFilesystemStore(cfg.Storage.DataDir, cfg.Storage.EncryptionKeyBytes)
if err != nil {
t.Fatalf("NewFilesystemStore() error = %v", err)
}
@@ -261,7 +358,7 @@ security:
_ = os.Chdir(wd)
}()
srv, err := httpapi.NewServer(cfg, store, logger)
srv, err := httpapi.NewServer(cfg, store, logger, logger)
if err != nil {
t.Fatalf("httpapi.NewServer() error = %v", err)
}