mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 11:30:15 +00:00
109 lines
3.3 KiB
Go
109 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
|
)
|
|
|
|
func TestSecurityTokens_ListCreateDelete(t *testing.T) {
|
|
cfg := &config.Config{}
|
|
persistence := config.NewConfigPersistence(t.TempDir())
|
|
router := &Router{
|
|
config: cfg,
|
|
persistence: persistence,
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/security/tokens", nil)
|
|
rr := httptest.NewRecorder()
|
|
router.handleListAPITokens(rr, req)
|
|
if rr.Code != http.StatusMethodNotAllowed {
|
|
t.Fatalf("expected status %d, got %d", http.StatusMethodNotAllowed, rr.Code)
|
|
}
|
|
|
|
req = httptest.NewRequest(http.MethodPost, "/api/security/tokens", strings.NewReader("{bad"))
|
|
rr = httptest.NewRecorder()
|
|
router.handleCreateAPIToken(rr, req)
|
|
if rr.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected status %d, got %d", http.StatusBadRequest, rr.Code)
|
|
}
|
|
|
|
req = httptest.NewRequest(http.MethodPost, "/api/security/tokens", strings.NewReader(`{"name":"test","scopes":["monitoring:read"]}`))
|
|
rr = httptest.NewRecorder()
|
|
router.handleCreateAPIToken(rr, req)
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("expected status %d, got %d", http.StatusOK, rr.Code)
|
|
}
|
|
|
|
var createResp struct {
|
|
Token string `json:"token"`
|
|
Record apiTokenDTO `json:"record"`
|
|
}
|
|
if err := json.NewDecoder(rr.Body).Decode(&createResp); err != nil {
|
|
t.Fatalf("decode create response: %v", err)
|
|
}
|
|
if createResp.Token == "" {
|
|
t.Fatal("expected raw token in response")
|
|
}
|
|
if createResp.Record.Name != "test" {
|
|
t.Fatalf("expected record name 'test', got %q", createResp.Record.Name)
|
|
}
|
|
if len(cfg.APITokens) != 1 {
|
|
t.Fatalf("expected token stored in config")
|
|
}
|
|
|
|
req = httptest.NewRequest(http.MethodGet, "/api/security/tokens", nil)
|
|
rr = httptest.NewRecorder()
|
|
router.handleListAPITokens(rr, req)
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("expected status %d, got %d", http.StatusOK, rr.Code)
|
|
}
|
|
|
|
var listResp struct {
|
|
Tokens []apiTokenDTO `json:"tokens"`
|
|
}
|
|
if err := json.NewDecoder(rr.Body).Decode(&listResp); err != nil {
|
|
t.Fatalf("decode list response: %v", err)
|
|
}
|
|
if len(listResp.Tokens) != 1 {
|
|
t.Fatalf("expected 1 token, got %d", len(listResp.Tokens))
|
|
}
|
|
|
|
req = httptest.NewRequest(http.MethodDelete, "/api/security/tokens/", nil)
|
|
rr = httptest.NewRecorder()
|
|
router.handleDeleteAPIToken(rr, req)
|
|
if rr.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected status %d, got %d", http.StatusBadRequest, rr.Code)
|
|
}
|
|
|
|
req = httptest.NewRequest(http.MethodDelete, "/api/security/tokens/missing", nil)
|
|
rr = httptest.NewRecorder()
|
|
router.handleDeleteAPIToken(rr, req)
|
|
if rr.Code != http.StatusNotFound {
|
|
t.Fatalf("expected status %d, got %d", http.StatusNotFound, rr.Code)
|
|
}
|
|
|
|
// Test deletion of migrated env token suppression
|
|
record := config.APITokenRecord{
|
|
ID: "migrated",
|
|
Name: "Migrated from .env token",
|
|
Hash: "hash-migrated",
|
|
CreatedAt: time.Now(),
|
|
}
|
|
cfg.APITokens = append(cfg.APITokens, record)
|
|
|
|
req = httptest.NewRequest(http.MethodDelete, "/api/security/tokens/migrated", nil)
|
|
rr = httptest.NewRecorder()
|
|
router.handleDeleteAPIToken(rr, req)
|
|
if rr.Code != http.StatusNoContent {
|
|
t.Fatalf("expected status %d, got %d", http.StatusNoContent, rr.Code)
|
|
}
|
|
if !cfg.IsEnvMigrationSuppressed("hash-migrated") {
|
|
t.Fatalf("expected env migration suppression to be recorded")
|
|
}
|
|
}
|