Files
Pulse/internal/api/config_profiles_additional_test.go
2026-01-25 21:08:44 +00:00

200 lines
6.3 KiB
Go

package api
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
)
func newConfigProfileHandler(t *testing.T) (*ConfigProfileHandler, *config.ConfigPersistence) {
t.Helper()
tempDir := t.TempDir()
mtp := config.NewMultiTenantPersistence(tempDir)
persistence, err := mtp.GetPersistence("default")
if err != nil {
t.Fatalf("GetPersistence: %v", err)
}
handler := NewConfigProfileHandler(mtp)
return handler, persistence
}
func createProfile(t *testing.T, handler *ConfigProfileHandler, name string, cfg models.AgentConfigMap) models.AgentProfile {
t.Helper()
profile := models.AgentProfile{
Name: name,
Config: cfg,
}
body, _ := json.Marshal(profile)
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(body))
req = req.WithContext(context.WithValue(req.Context(), "username", "tester"))
rec := httptest.NewRecorder()
handler.CreateProfile(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("CreateProfile status = %d, body=%s", rec.Code, rec.Body.String())
}
var created models.AgentProfile
if err := json.NewDecoder(rec.Body).Decode(&created); err != nil {
t.Fatalf("decode create response: %v", err)
}
return created
}
func TestConfigProfileHandler_GetProfile(t *testing.T) {
handler, _ := newConfigProfileHandler(t)
created := createProfile(t, handler, "Profile One", models.AgentConfigMap{"interval": "10s"})
req := httptest.NewRequest(http.MethodGet, "/"+created.ID, nil)
rec := httptest.NewRecorder()
handler.GetProfile(rec, req, created.ID)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", rec.Code)
}
var got models.AgentProfile
if err := json.NewDecoder(rec.Body).Decode(&got); err != nil {
t.Fatalf("decode response: %v", err)
}
if got.ID != created.ID {
t.Fatalf("profile ID = %s, want %s", got.ID, created.ID)
}
}
func TestConfigProfileHandler_GetChangeLog_Filtered(t *testing.T) {
handler, persistence := newConfigProfileHandler(t)
created := createProfile(t, handler, "Profile Log", models.AgentConfigMap{"log_level": "debug"})
change := models.ProfileChangeLog{
ID: "log-1",
ProfileID: created.ID,
ProfileName: created.Name,
Action: "create",
NewVersion: 1,
User: "tester",
}
if err := persistence.AppendProfileChangeLog(change); err != nil {
t.Fatalf("AppendProfileChangeLog: %v", err)
}
req := httptest.NewRequest(http.MethodGet, "/changelog?profile_id="+created.ID, nil)
rec := httptest.NewRecorder()
handler.GetChangeLog(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", rec.Code)
}
var logs []models.ProfileChangeLog
if err := json.NewDecoder(rec.Body).Decode(&logs); err != nil {
t.Fatalf("decode response: %v", err)
}
if len(logs) == 0 {
t.Fatalf("expected change log entries")
}
if logs[0].ProfileID != created.ID {
t.Fatalf("profile_id = %s, want %s", logs[0].ProfileID, created.ID)
}
}
func TestConfigProfileHandler_DeploymentStatusLifecycle(t *testing.T) {
handler, _ := newConfigProfileHandler(t)
created := createProfile(t, handler, "Profile Deploy", models.AgentConfigMap{"feature": true})
update := models.ProfileDeploymentStatus{
AgentID: "agent-1",
ProfileID: created.ID,
AssignedVersion: created.Version,
DeployedVersion: created.Version,
DeploymentStatus: "deployed",
}
body, _ := json.Marshal(update)
req := httptest.NewRequest(http.MethodPost, "/deployments", bytes.NewReader(body))
rec := httptest.NewRecorder()
handler.UpdateDeploymentStatus(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", rec.Code)
}
req = httptest.NewRequest(http.MethodGet, "/deployments?agent_id=agent-1", nil)
rec = httptest.NewRecorder()
handler.GetDeploymentStatus(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", rec.Code)
}
var statuses []models.ProfileDeploymentStatus
if err := json.NewDecoder(rec.Body).Decode(&statuses); err != nil {
t.Fatalf("decode response: %v", err)
}
if len(statuses) != 1 {
t.Fatalf("statuses = %d, want 1", len(statuses))
}
if statuses[0].AgentID != "agent-1" {
t.Fatalf("agent_id = %s, want agent-1", statuses[0].AgentID)
}
}
func TestConfigProfileHandler_VersionsAndRollback(t *testing.T) {
handler, _ := newConfigProfileHandler(t)
created := createProfile(t, handler, "Profile Versioned", models.AgentConfigMap{"log_level": "debug"})
update := models.AgentProfile{
Name: "Profile Versioned",
Config: models.AgentConfigMap{"log_level": "info"},
}
updateBody, _ := json.Marshal(update)
updateReq := httptest.NewRequest(http.MethodPut, "/"+created.ID, bytes.NewReader(updateBody))
updateReq = updateReq.WithContext(context.WithValue(updateReq.Context(), "username", "tester"))
updateRec := httptest.NewRecorder()
handler.UpdateProfile(updateRec, updateReq, created.ID)
if updateRec.Code != http.StatusOK {
t.Fatalf("UpdateProfile status = %d, body=%s", updateRec.Code, updateRec.Body.String())
}
req := httptest.NewRequest(http.MethodGet, "/"+created.ID+"/versions", nil)
rec := httptest.NewRecorder()
handler.GetProfileVersions(rec, req, created.ID)
if rec.Code != http.StatusOK {
t.Fatalf("GetProfileVersions status = %d", rec.Code)
}
var versions []models.AgentProfileVersion
if err := json.NewDecoder(rec.Body).Decode(&versions); err != nil {
t.Fatalf("decode versions: %v", err)
}
if len(versions) < 2 {
t.Fatalf("expected multiple versions, got %d", len(versions))
}
rollbackReq := httptest.NewRequest(http.MethodPost, "/"+created.ID+"/rollback/1", nil)
rollbackReq = rollbackReq.WithContext(context.WithValue(rollbackReq.Context(), "username", "tester"))
rollbackRec := httptest.NewRecorder()
handler.RollbackProfile(rollbackRec, rollbackReq, created.ID, "1")
if rollbackRec.Code != http.StatusOK {
t.Fatalf("RollbackProfile status = %d, body=%s", rollbackRec.Code, rollbackRec.Body.String())
}
var rolled models.AgentProfile
if err := json.NewDecoder(rollbackRec.Body).Decode(&rolled); err != nil {
t.Fatalf("decode rollback response: %v", err)
}
if rolled.Version != created.Version+2 {
t.Fatalf("version = %d, want %d", rolled.Version, created.Version+2)
}
if rolled.Config["log_level"] != "debug" {
t.Fatalf("config log_level = %v, want debug", rolled.Config["log_level"])
}
}