修复审计日志字段格式与列表标识并补充回归测试
This commit is contained in:
parent
fcad812c85
commit
c4136cd8f3
@ -332,3 +332,57 @@ func TestIssueDomainSanitizesDeploymentReportWithoutTaskRepository(t *testing.T)
|
||||
t.Fatalf("直接证书申请响应未返回稳定部署错误摘要:%s", response.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuditLogResponseUsesDashboardFieldNames(t *testing.T) {
|
||||
server, _, auditRepo, closeDB := newTaskAPITestServer(t, nil)
|
||||
defer closeDB()
|
||||
ctx := context.Background()
|
||||
createdAt := time.Date(2026, 9, 24, 12, 0, 0, 0, time.UTC)
|
||||
for _, status := range []string{"success", "error"} {
|
||||
if err := auditRepo.CreateAuditLog(ctx, repository.AuditLog{
|
||||
Action: "login", ResourceType: "auth", ResourceID: "admin",
|
||||
Status: status, Message: "login", CreatedAt: createdAt,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
response := httptest.NewRecorder()
|
||||
serveAdminHTTP(server, response, httptest.NewRequest(http.MethodGet, "/api/v1/audit-logs?limit=2", nil))
|
||||
if response.Code != http.StatusOK {
|
||||
t.Fatal(response.Code, response.Body.String())
|
||||
}
|
||||
var payload struct {
|
||||
Items []map[string]json.RawMessage `json:"items"`
|
||||
}
|
||||
if err := json.Unmarshal(response.Body.Bytes(), &payload); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(payload.Items) != 2 {
|
||||
t.Fatal(response.Body.String())
|
||||
}
|
||||
var previousID int64
|
||||
for i, item := range payload.Items {
|
||||
for _, field := range []string{"id", "action", "resource_type", "resource_id", "status", "message", "created_at"} {
|
||||
if _, ok := item[field]; !ok {
|
||||
t.Fatal(field, response.Body.String())
|
||||
}
|
||||
}
|
||||
if len(item) != 7 {
|
||||
t.Fatal(response.Body.String())
|
||||
}
|
||||
var id int64
|
||||
if err := json.Unmarshal(item["id"], &id); err != nil || id <= 0 || (i > 0 && id >= previousID) {
|
||||
t.Fatal(id, previousID, err)
|
||||
}
|
||||
previousID = id
|
||||
for field, expected := range map[string]string{
|
||||
"action": "login", "resource_type": "auth", "resource_id": "admin",
|
||||
"status": []string{"error", "success"}[i], "message": "login", "created_at": createdAt.Format(time.RFC3339),
|
||||
} {
|
||||
var actual string
|
||||
if err := json.Unmarshal(item[field], &actual); err != nil || actual != expected {
|
||||
t.Fatal(field, actual, expected, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ func (r *SQLAuditRepository) ListAuditLogs(ctx context.Context, limit int) ([]Au
|
||||
if limit <= 0 || limit > 200 {
|
||||
limit = 50
|
||||
}
|
||||
rows, err := r.db.QueryContext(ctx, r.query(`SELECT action, resource_type, resource_id, status, message, created_at FROM audit_logs ORDER BY created_at DESC, id DESC LIMIT `+fmt.Sprintf("%d", limit)))
|
||||
rows, err := r.db.QueryContext(ctx, r.query(`SELECT id, action, resource_type, resource_id, status, message, created_at FROM audit_logs ORDER BY created_at DESC, id DESC LIMIT `+fmt.Sprintf("%d", limit)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询审计日志失败:%w", err)
|
||||
}
|
||||
@ -26,7 +26,7 @@ func (r *SQLAuditRepository) ListAuditLogs(ctx context.Context, limit int) ([]Au
|
||||
logs := make([]AuditLog, 0)
|
||||
for rows.Next() {
|
||||
var item AuditLog
|
||||
if err := rows.Scan(&item.Action, &item.ResourceType, &item.ResourceID, &item.Status, &item.Message, &item.CreatedAt); err != nil {
|
||||
if err := rows.Scan(&item.ID, &item.Action, &item.ResourceType, &item.ResourceID, &item.Status, &item.Message, &item.CreatedAt); err != nil {
|
||||
return nil, fmt.Errorf("读取审计日志失败:%w", err)
|
||||
}
|
||||
item.CreatedAt = item.CreatedAt.UTC()
|
||||
|
||||
@ -10,12 +10,13 @@ import (
|
||||
)
|
||||
|
||||
type AuditLog struct {
|
||||
Action string
|
||||
ResourceType string
|
||||
ResourceID string
|
||||
Status string
|
||||
Message string
|
||||
CreatedAt time.Time
|
||||
ID int64 `json:"id"`
|
||||
Action string `json:"action"`
|
||||
ResourceType string `json:"resource_type"`
|
||||
ResourceID string `json:"resource_id"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type AuditRepository interface {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user