server/internal/handlers/excluded_targets_test.go
Rama main · réplica de lectura del repositorio original.
package handlers
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"blackbox/server/internal/db"
"blackbox/server/internal/models"
"blackbox/shared/types"
"github.com/go-chi/chi/v5"
"gorm.io/gorm"
)
func setupExcludeDB(t *testing.T) *gorm.DB {
t.Helper()
database, err := db.Init(":memory:")
if err != nil {
t.Fatalf("Init: %v", err)
}
return database
}
func TestListExcludedTargetsEmpty(t *testing.T) {
database := setupExcludeDB(t)
req := httptest.NewRequest(http.MethodGet, "/api/admin/excluded-targets", nil)
rr := httptest.NewRecorder()
ListExcludedTargets(database)(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", rr.Code)
}
var targets []models.ExcludedTarget
if err := json.NewDecoder(rr.Body).Decode(&targets); err != nil {
t.Fatalf("decode: %v", err)
}
if len(targets) != 0 {
t.Fatalf("expected empty slice, got %d items", len(targets))
}
}
func TestCreateExcludedTargetDuplicate(t *testing.T) {
database := setupExcludeDB(t)
body := []byte(`{"type":"container","name":"nginx"}`)
req := httptest.NewRequest(http.MethodPost, "/api/admin/excluded-targets", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
CreateExcludedTarget(database)(rr, req)
if rr.Code != http.StatusCreated {
t.Fatalf("expected 201, got %d: %s", rr.Code, rr.Body.String())
}
req = httptest.NewRequest(http.MethodPost, "/api/admin/excluded-targets", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
rr = httptest.NewRecorder()
CreateExcludedTarget(database)(rr, req)
if rr.Code != http.StatusConflict {
t.Fatalf("expected 409, got %d", rr.Code)
}
}
func TestDeleteExcludedTarget(t *testing.T) {
database := setupExcludeDB(t)
target := models.ExcludedTarget{ID: "01TESTID00001", Type: "stack", Name: "mystack", CreatedAt: time.Now().UTC()}
if err := database.Create(&target).Error; err != nil {
t.Fatalf("create: %v", err)
}
rctx := chi.NewRouteContext()
rctx.URLParams.Add("id", target.ID)
req := httptest.NewRequest(http.MethodDelete, "/api/admin/excluded-targets/"+target.ID, nil)
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
rr := httptest.NewRecorder()
DeleteExcludedTarget(database)(rr, req)
if rr.Code != http.StatusNoContent {
t.Fatalf("expected 204, got %d", rr.Code)
}
}
func TestIsExcludedContainerAndStack(t *testing.T) {
database := setupExcludeDB(t)
if err := database.Create(&models.ExcludedTarget{ID: "01EXCL001", Type: "container", Name: "noise-agent", CreatedAt: time.Now().UTC()}).Error; err != nil {
t.Fatalf("create container: %v", err)
}
if err := database.Create(&models.ExcludedTarget{ID: "01EXCL002", Type: "stack", Name: "ci-stack", CreatedAt: time.Now().UTC()}).Error; err != nil {
t.Fatalf("create stack: %v", err)
}
if !isExcluded(database, types.Entry{Source: "docker", Service: "noise-agent", Metadata: "{}"}) {
t.Fatal("expected container exclusion")
}
meta := `{"Actor":{"Attributes":{"com.docker.compose.project":"ci-stack"}}}`
if !isExcluded(database, types.Entry{Source: "docker", Service: "runner", Metadata: meta}) {
t.Fatal("expected stack exclusion")
}
if isExcluded(database, types.Entry{Source: "files", Service: "noise-agent", Metadata: "{}"}) {
t.Fatal("non-docker sources must not be excluded")
}
}