opencode-provider-switch/internal/app/service_test.go
2026-04-18 20:49:54 +08:00

121 lines
2.8 KiB
Go

package app
import (
"context"
"net"
"net/http"
"path/filepath"
"strconv"
"testing"
"time"
"github.com/Apale7/opencode-provider-switch/internal/config"
)
func TestSaveDesktopPrefsPersistsToConfig(t *testing.T) {
t.Parallel()
path := filepath.Join(t.TempDir(), "ocswitch.json")
svc := NewService(path)
prefs, err := svc.SaveDesktopPrefs(context.Background(), DesktopPrefsInput{
LaunchAtLogin: true,
MinimizeToTray: true,
Notifications: true,
})
if err != nil {
t.Fatalf("SaveDesktopPrefs() error = %v", err)
}
if !prefs.LaunchAtLogin || !prefs.MinimizeToTray || !prefs.Notifications {
t.Fatalf("SaveDesktopPrefs() = %#v", prefs)
}
cfg, err := config.Load(path)
if err != nil {
t.Fatalf("config.Load() error = %v", err)
}
if !cfg.Desktop.LaunchAtLogin || !cfg.Desktop.MinimizeToTray || !cfg.Desktop.Notifications {
t.Fatalf("persisted desktop prefs = %#v", cfg.Desktop)
}
}
func TestStartStopProxyUpdatesStatus(t *testing.T) {
t.Parallel()
path := filepath.Join(t.TempDir(), "ocswitch.json")
cfgPathPort := freePort(t)
cfg, err := config.Load(path)
if err != nil {
t.Fatalf("config.Load() error = %v", err)
}
cfg.Server.Port = cfgPathPort
cfg.Server.Host = "127.0.0.1"
cfg.Server.APIKey = config.DefaultLocalAPIKey
if err := cfg.Save(); err != nil {
t.Fatalf("cfg.Save() error = %v", err)
}
svc := NewService(path)
if err := svc.StartProxy(context.Background()); err != nil {
t.Fatalf("StartProxy() error = %v", err)
}
t.Cleanup(func() {
_ = svc.StopProxy(context.Background())
})
status, err := svc.GetProxyStatus(context.Background())
if err != nil {
t.Fatalf("GetProxyStatus() error = %v", err)
}
if !status.Running {
t.Fatalf("status.Running = false, want true")
}
assertEventually(t, func() bool {
resp, err := http.Get("http://127.0.0.1:" + itoa(cfgPathPort) + "/healthz")
if err != nil {
return false
}
defer resp.Body.Close()
return resp.StatusCode == http.StatusOK
})
if err := svc.StopProxy(context.Background()); err != nil {
t.Fatalf("StopProxy() error = %v", err)
}
status, err = svc.GetProxyStatus(context.Background())
if err != nil {
t.Fatalf("GetProxyStatus() after stop error = %v", err)
}
if status.Running {
t.Fatalf("status.Running = true, want false")
}
}
func assertEventually(t *testing.T, fn func() bool) {
t.Helper()
deadline := time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {
if fn() {
return
}
time.Sleep(20 * time.Millisecond)
}
t.Fatal("condition not satisfied before timeout")
}
func freePort(t *testing.T) int {
t.Helper()
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("net.Listen() error = %v", err)
}
defer listener.Close()
return listener.Addr().(*net.TCPAddr).Port
}
func itoa(v int) string {
return strconv.Itoa(v)
}