Pulse/pkg/proxmox/client_api_more4_test.go
rcourtman 96b7370f7b test: improve coverage for API, AI, Alerts, and Frontend Utils
- Add comprehensive tests for internal/api/config_handlers.go (Phases 1-3)
- Improve test coverage for AI tools, chat service, and session management
- Enhance alert and notification tests (ResolvedAlert, Webhook)
- Add frontend unit tests for utils (searchHistory, tagColors, temperature, url)
- Add proximity client API tests
2026-01-20 15:52:39 +00:00

164 lines
4.9 KiB
Go

package proxmox
import (
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestClient_AuthenticateJSON_Success(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api2/json/access/ticket" {
t.Errorf("expected path /api2/json/access/ticket, got %s", r.URL.Path)
}
if r.Header.Get("Content-Type") != "application/json" {
t.Errorf("expected Content-Type application/json, got %s", r.Header.Get("Content-Type"))
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":{"ticket":"PVE:user@pve:ticket","CSRFPreventionToken":"TOKEN"}}`)
}))
defer server.Close()
client := &Client{
baseURL: server.URL + "/api2/json",
httpClient: http.DefaultClient,
auth: auth{
user: "user",
realm: "pve",
},
config: ClientConfig{
Password: "password",
},
}
err := client.authenticate(context.Background())
if err != nil {
t.Fatalf("authenticate failed: %v", err)
}
if client.auth.ticket != "PVE:user@pve:ticket" {
t.Errorf("expected ticket PVE:user@pve:ticket, got %s", client.auth.ticket)
}
if client.auth.csrfToken != "TOKEN" {
t.Errorf("expected CSRF token TOKEN, got %s", client.auth.csrfToken)
}
}
func TestClient_AuthenticateFallbackToForm(t *testing.T) {
jsonCalled := false
formCalled := false
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Content-Type") == "application/json" {
jsonCalled = true
w.WriteHeader(http.StatusBadRequest) // Trigger fallback
fmt.Fprint(w, `{"error":"use form"}`)
return
}
if r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
formCalled = true
body, _ := io.ReadAll(r.Body)
if !strings.Contains(string(body), "username=user%40pve") {
t.Errorf("expected username in form data, got %s", string(body))
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":{"ticket":"form-ticket","CSRFPreventionToken":"form-token"}}`)
return
}
}))
defer server.Close()
client := &Client{
baseURL: server.URL + "/api2/json",
httpClient: http.DefaultClient,
auth: auth{
user: "user",
realm: "pve",
},
config: ClientConfig{
Password: "password",
},
}
err := client.authenticate(context.Background())
if err != nil {
t.Fatalf("authenticate failed: %v", err)
}
if !jsonCalled || !formCalled {
t.Errorf("expected both JSON and Form to be called, got json=%v, form=%v", jsonCalled, formCalled)
}
}
func TestClient_GetVMs(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":[{"vmid":100,"name":"vm1","status":"running"},{"vmid":101,"name":"vm2","status":"stopped"}]}`)
}))
defer server.Close()
client, _ := NewClient(ClientConfig{Host: server.URL, TokenName: "u@p!t", TokenValue: "v"})
vms, err := client.GetVMs(context.Background(), "node1")
if err != nil {
t.Fatalf("GetVMs failed: %v", err)
}
if len(vms) != 2 {
t.Errorf("expected 2 VMs, got %d", len(vms))
}
}
func TestClient_GetContainers(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":[{"vmid":200,"name":"ct1","status":"running"}]}`)
}))
defer server.Close()
client, _ := NewClient(ClientConfig{Host: server.URL, TokenName: "u@p!t", TokenValue: "v"})
cts, err := client.GetContainers(context.Background(), "node1")
if err != nil {
t.Fatalf("GetContainers failed: %v", err)
}
if len(cts) != 1 {
t.Errorf("expected 1 container, got %d", len(cts))
}
}
func TestClient_GetStorage(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":[{"storage":"local","type":"dir","total":1000,"used":500}]}`)
}))
defer server.Close()
client, _ := NewClient(ClientConfig{Host: server.URL, TokenName: "u@p!t", TokenValue: "v"})
storage, err := client.GetStorage(context.Background(), "node1")
if err != nil {
t.Fatalf("GetStorage failed: %v", err)
}
if len(storage) != 1 {
t.Errorf("expected 1 storage, got %d", len(storage))
}
}
func TestClient_GetContainerConfig_Empty(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":null}`)
}))
defer server.Close()
client, _ := NewClient(ClientConfig{Host: server.URL, TokenName: "u@p!t", TokenValue: "v"})
config, err := client.GetContainerConfig(context.Background(), "node1", 200)
if err != nil {
t.Fatalf("GetContainerConfig failed: %v", err)
}
if config == nil {
t.Fatal("expected non-nil config")
}
}