Expand test coverage across server, agent, and web; fix bugs found during audit.
Adds hundreds of unit/integration/e2e tests, fixes WS bcrypt auth, config merge, fleet analytics, agent schedule/log tail, and documents stale PROBLEMS items. Updates PROBLEMS.md, README, and test scripts; ignores local spread-kits and coverage dirs.
This commit is contained in:
161
server/main_test.go
Normal file
161
server/main_test.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResolveDataDirAbsolute(t *testing.T) {
|
||||
abs := filepath.Join(t.TempDir(), "data")
|
||||
got := resolveDataDir(abs, "C:\\project")
|
||||
if got != abs {
|
||||
t.Fatalf("absolute data dir unchanged: got %q want %q", got, abs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDataDirRelativeWithProjectRoot(t *testing.T) {
|
||||
root := filepath.Join(t.TempDir(), "repo")
|
||||
got := resolveDataDir("data", root)
|
||||
want := filepath.Join(root, "data")
|
||||
if got != want {
|
||||
t.Fatalf("got %q want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDataDirRelativeWithoutProjectRoot(t *testing.T) {
|
||||
got := resolveDataDir("data", "")
|
||||
if !filepath.IsAbs(got) {
|
||||
t.Fatalf("expected absolute path when project root empty, got %q", got)
|
||||
}
|
||||
if filepath.Base(got) != "data" {
|
||||
t.Fatalf("expected basename data, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDataDirDotProjectRoot(t *testing.T) {
|
||||
got := resolveDataDir("data", ".")
|
||||
if !filepath.IsAbs(got) {
|
||||
t.Fatalf("expected absolute path, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindProjectRootFromServerDir(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root := findProjectRoot()
|
||||
runBat := filepath.Join(root, "run.bat")
|
||||
if _, err := os.Stat(runBat); err != nil {
|
||||
t.Fatalf("findProjectRoot=%q missing run.bat: %v", root, err)
|
||||
}
|
||||
// When tests run from server/, root should be parent of cwd or cwd itself.
|
||||
if root != cwd && root != filepath.Dir(cwd) {
|
||||
t.Logf("findProjectRoot=%q cwd=%q (acceptable if run.bat layout differs)", root, cwd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindAgentSourceDir(t *testing.T) {
|
||||
dir := findAgentSourceDir()
|
||||
goMod := filepath.Join(dir, "go.mod")
|
||||
if _, err := os.Stat(goMod); err != nil {
|
||||
t.Fatalf("agent source %q missing go.mod: %v", dir, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindWebRoot(t *testing.T) {
|
||||
dir := findWebRoot()
|
||||
if dir == "" {
|
||||
t.Fatal("findWebRoot returned empty string")
|
||||
}
|
||||
index := filepath.Join(dir, "index.html")
|
||||
if _, err := os.Stat(index); err != nil {
|
||||
t.Fatalf("web root %q missing index.html: %v", dir, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigProviderPublicURL(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.Server.PublicURL = "https://forge.example"
|
||||
p := &serverConfigProvider{config: cfg}
|
||||
if got := p.PublicURL(); got != "https://forge.example" {
|
||||
t.Fatalf("PublicURL: got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigProviderGetConfigJSON(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.Port = 7777
|
||||
p := &serverConfigProvider{config: cfg}
|
||||
raw := p.GetConfigJSON()
|
||||
var decoded Config
|
||||
if err := json.Unmarshal(raw, &decoded); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if decoded.Port != 7777 {
|
||||
t.Fatalf("port in JSON: got %d", decoded.Port)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigProviderUpdateConfigFromJSON(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
cfg := DefaultConfig()
|
||||
cfg.DataDir = dir
|
||||
cfg.Wallet.Address = "48keep"
|
||||
p := &serverConfigProvider{config: cfg}
|
||||
|
||||
if err := p.UpdateConfigFromJSON([]byte(`{"port":8888}`)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Port != 8888 {
|
||||
t.Fatalf("port not updated: %d", cfg.Port)
|
||||
}
|
||||
if cfg.Wallet.Address != "48keep" {
|
||||
t.Fatalf("partial update must preserve wallet: %q", cfg.Wallet.Address)
|
||||
}
|
||||
|
||||
raw, err := os.ReadFile(filepath.Join(dir, "config.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var saved Config
|
||||
if err := json.Unmarshal(raw, &saved); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if saved.Port != 8888 {
|
||||
t.Fatalf("saved port: got %d", saved.Port)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigProviderUpdateConfigInvalidJSON(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
p := &serverConfigProvider{config: cfg}
|
||||
err := p.UpdateConfigFromJSON([]byte(`{not json`))
|
||||
if err == nil {
|
||||
t.Fatal("expected error for invalid JSON")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigProviderOnSavedCallback(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
cfg := DefaultConfig()
|
||||
cfg.DataDir = dir
|
||||
called := false
|
||||
p := &serverConfigProvider{
|
||||
config: cfg,
|
||||
onSaved: func(c *Config) {
|
||||
called = true
|
||||
if c.Port != 6666 {
|
||||
t.Fatalf("callback port: got %d", c.Port)
|
||||
}
|
||||
},
|
||||
}
|
||||
if err := p.UpdateConfigFromJSON([]byte(`{"port":6666}`)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !called {
|
||||
t.Fatal("onSaved callback not invoked")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user