2a196bcdb2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
91 lines
2.4 KiB
Go
91 lines
2.4 KiB
Go
package web
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"antidrift/internal/settings"
|
|
)
|
|
|
|
// fakeApplier records the last settings it was asked to apply and can be told to
|
|
// reject with ErrInvalidBackend.
|
|
type fakeApplier struct {
|
|
called int
|
|
last settings.Settings
|
|
reject bool
|
|
}
|
|
|
|
func (f *fakeApplier) apply(s settings.Settings) error {
|
|
if f.reject {
|
|
return settings.ErrInvalidBackend
|
|
}
|
|
f.called++
|
|
f.last = s
|
|
return nil
|
|
}
|
|
|
|
func TestGetSettingsReturnsCurrent(t *testing.T) {
|
|
s := newTestServer(t)
|
|
cur := settings.Settings{AIBackend: "claude", MarvinCmd: "am", KnowledgePath: "/tmp/k.md"}
|
|
fa := &fakeApplier{}
|
|
s.SetSettings(filepath.Join(t.TempDir(), "settings.json"), cur, fa.apply)
|
|
r := s.Router()
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/settings", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want 200", w.Code)
|
|
}
|
|
var got settings.Settings
|
|
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
if got != cur {
|
|
t.Errorf("got %+v, want %+v", got, cur)
|
|
}
|
|
}
|
|
|
|
func TestPostSettingsValidAppliesAndSaves(t *testing.T) {
|
|
s := newTestServer(t)
|
|
path := filepath.Join(t.TempDir(), "settings.json")
|
|
fa := &fakeApplier{}
|
|
s.SetSettings(path, settings.Settings{}, fa.apply)
|
|
r := s.Router()
|
|
|
|
body := `{"ai_backend":"codex","marvin_cmd":"uv run am","knowledge_path":"/tmp/k.md"}`
|
|
w := post(t, r, "/settings", body)
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want 200 (body %s)", w.Code, w.Body.String())
|
|
}
|
|
if fa.called != 1 {
|
|
t.Fatalf("applier called %d times, want 1", fa.called)
|
|
}
|
|
if fa.last.AIBackend != "codex" {
|
|
t.Errorf("applied backend = %q, want codex", fa.last.AIBackend)
|
|
}
|
|
if _, err := os.Stat(path); err != nil {
|
|
t.Errorf("settings file not written: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPostSettingsInvalidBackendIs400AndNoSave(t *testing.T) {
|
|
s := newTestServer(t)
|
|
path := filepath.Join(t.TempDir(), "settings.json")
|
|
fa := &fakeApplier{reject: true}
|
|
s.SetSettings(path, settings.Settings{}, fa.apply)
|
|
r := s.Router()
|
|
|
|
w := post(t, r, "/settings", `{"ai_backend":"bogus"}`)
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Fatalf("status = %d, want 400", w.Code)
|
|
}
|
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
|
t.Errorf("settings file should not exist after rejected save, stat err = %v", err)
|
|
}
|
|
}
|