Files
GitOcean-Old/internal/app/cli_auth_test.go
T
2026-06-08 15:03:41 -05:00

108 lines
3.0 KiB
Go

package app
import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func withStdin(t *testing.T, input string, fn func()) {
t.Helper()
old := os.Stdin
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
if _, err := w.WriteString(input); err != nil {
t.Fatal(err)
}
_ = w.Close()
os.Stdin = r
defer func() { os.Stdin = old }()
fn()
}
func TestCLIAuthWorkflowCommands(t *testing.T) {
configFile := filepath.Join(t.TempDir(), "client.json")
t.Setenv("GITOOCEAN_CONFIG", configFile)
var logoutAuth string
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method + " " + r.URL.Path {
case "POST /api/register":
writeJSON(w, http.StatusCreated, User{ID: 1, Email: "alice@example.com", Username: "alice", IsAdmin: true})
case "POST /api/login":
writeJSON(w, http.StatusOK, map[string]any{"user": User{ID: 1, Email: "alice@example.com", Username: "alice", IsAdmin: true}, "token": "tok", "expires_at": time.Now().UTC().Add(tokenTTL)})
case "GET /api/me":
if r.Header.Get("Authorization") != "Bearer tok" {
t.Fatalf("missing whoami auth: %q", r.Header.Get("Authorization"))
}
writeJSON(w, http.StatusOK, User{ID: 1, Email: "alice@example.com", Username: "alice", IsAdmin: true})
case "POST /api/logout":
logoutAuth = r.Header.Get("Authorization")
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
default:
t.Fatalf("unexpected auth request %s %s", r.Method, r.URL.Path)
}
}))
defer ts.Close()
out := captureStdout(t, func() {
withStdin(t, "alice@example.com\nalice\npassword123\n", func() {
if err := cliRegister([]string{"--server", ts.URL}); err != nil {
t.Fatal(err)
}
})
})
if !strings.Contains(out, "Registered alice") || !strings.Contains(out, "admin account") {
t.Fatalf("register output: %s", out)
}
out = captureStdout(t, func() {
withStdin(t, "alice\npassword123\n", func() {
if err := cliLogin([]string{"--server", ts.URL}); err != nil {
t.Fatal(err)
}
})
})
if !strings.Contains(out, "logged in as alice") {
t.Fatalf("login output: %s", out)
}
cfg, err := loadConfig()
if err != nil {
t.Fatal(err)
}
if cfg.Server != ts.URL || cfg.Token != "tok" || cfg.Username != "alice" {
t.Fatalf("unexpected saved config: %#v", cfg)
}
out = captureStdout(t, func() {
if err := cliWhoami(nil); err != nil {
t.Fatal(err)
}
})
if !strings.Contains(out, "Username: alice") || !strings.Contains(out, "Admin: true") {
t.Fatalf("whoami output: %s", out)
}
out = captureStdout(t, func() {
if err := cliLogout(nil); err != nil {
t.Fatal(err)
}
})
if logoutAuth != "Bearer tok" || !strings.Contains(out, "logged out") {
t.Fatalf("logout auth=%q output=%s", logoutAuth, out)
}
if _, err := os.Stat(configFile); !os.IsNotExist(err) {
t.Fatalf("expected config file removed, stat err=%v", err)
}
}
func TestCLICloneUsage(t *testing.T) {
if err := cliClone(nil); err == nil || !strings.Contains(err.Error(), "usage") {
t.Fatalf("expected clone usage, got %v", err)
}
}