Ctrl K
ComunidadGuías…

internal/adminapi/admin_commands_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package adminapi

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"telesrv/internal/domain"
)

type captureAuditService struct {
	fakeService
	limit  int
	actor  string
	cmds   []domain.AdminCommand
	err    error
}

func (s *captureAuditService) ListRecentAdminCommands(_ context.Context, limit int, actor string) ([]domain.AdminCommand, error) {
	if s.err != nil {
		return nil, s.err
	}
	s.limit, s.actor = limit, actor
	return s.cmds, nil
}

func auditRequest(method, target, token string) *http.Request {
	req, _ := http.NewRequest(method, target, nil)
	if token != "" {
		req.Header.Set("Authorization", "Bearer "+token)
	}
	return req
}

func TestAdminCommandsListHonoursLimitActorAndTrimsFields(t *testing.T) {
	completed := time.Now().UTC().Truncate(time.Second)
	svc := &captureAuditService{cmds: []domain.AdminCommand{{
		CommandID: "bot-abc", Actor: "777", Action: "set_phone", TargetUserID: 42,
		DryRun: false, Status: domain.AdminCommandCompleted, Reason: "Admin number bind",
		Error: "", CreatedAt: completed,
	}}}
	srv := httptest.NewServer((&Server{token: "master", svc: svc}).routes())
	defer srv.Close()

	res, err := srv.Client().Do(auditRequest(http.MethodGet, srv.URL+"/v1/admin-commands?limit=5&actor=777", "master"))
	if err != nil {
		t.Fatalf("request: %v", err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		t.Fatalf("status %d, want 200", res.StatusCode)
	}
	if svc.limit != 5 {
		t.Fatalf("limit forwarded is %d, want 5", svc.limit)
	}
	if svc.actor != "777" {
		t.Fatalf("actor forwarded is %q, want 777", svc.actor)
	}
	var body struct {
		Commands []map[string]any `json:"commands"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		t.Fatalf("decode: %v", err)
	}
	if len(body.Commands) != 1 {
		t.Fatalf("got %d commands, want 1", len(body.Commands))
	}
	item := body.Commands[0]
	for key, want := range map[string]any{
		"command_id":     "bot-abc",
		"actor":          "777",
		"action":         "set_phone",
		"dry_run":        false,
		"status":         "completed",
		"target_user_id": float64(42),
		"reason":         "Admin number bind",
		"created_at":     completed.Format(time.RFC3339),
	} {
		if item[key] != want {
			t.Fatalf("field %q = %#v, want %#v", key, item[key], want)
		}
	}
	if _, leaked := item["result"]; leaked {
		t.Fatal("audit response must not include the request/result payloads")
	}
	if _, leaked := item["request"]; leaked {
		t.Fatal("audit response must not include the request/result payloads")
	}
}

func TestAdminCommandsListRequiresAuth(t *testing.T) {
	srv := httptest.NewServer((&Server{token: "master", svc: &captureAuditService{}}).routes())
	defer srv.Close()
	res, err := srv.Client().Do(auditRequest(http.MethodGet, srv.URL+"/v1/admin-commands", ""))
	if err != nil {
		t.Fatalf("request: %v", err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusUnauthorized {
		t.Fatalf("status %d, want 401", res.StatusCode)
	}
}

func TestAdminCommandsListServiceError(t *testing.T) {
	svc := &captureAuditService{err: context.DeadlineExceeded}
	srv := httptest.NewServer((&Server{token: "master", svc: svc}).routes())
	defer srv.Close()
	res, err := srv.Client().Do(auditRequest(http.MethodGet, srv.URL+"/v1/admin-commands", "master"))
	if err != nil {
		t.Fatalf("request: %v", err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusInternalServerError {
		t.Fatalf("status %d, want 500", res.StatusCode)
	}
}