147 lines
4.0 KiB
Go
147 lines
4.0 KiB
Go
package audit
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.yeij.top/AskaEth/Cyrene_v2/internal/logger"
|
|
)
|
|
|
|
// newSilentApprover builds an Approver whose audit log is discarded.
|
|
func newSilentApprover() *Approver {
|
|
return NewApprover(logger.New(logger.Options{Out: io.Discard}))
|
|
}
|
|
|
|
func TestReviewAndApprove_Records(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ap, err := newSilentApprover().ReviewAndApprove(context.Background(), "worker", "run ls", "list the project dir")
|
|
if err != nil {
|
|
t.Fatalf("ReviewAndApprove unexpected error: %v", err)
|
|
}
|
|
if ap.Actor != "worker" {
|
|
t.Fatalf("Actor = %q, want worker", ap.Actor)
|
|
}
|
|
if ap.Action != "run ls" {
|
|
t.Fatalf("Action = %q, want run ls", ap.Action)
|
|
}
|
|
if ap.Description != "list the project dir" {
|
|
t.Fatalf("Description = %q, want list the project dir", ap.Description)
|
|
}
|
|
if !ap.Allowed {
|
|
t.Fatal("Allowed = false, want true")
|
|
}
|
|
if ap.Reviewer != "main" {
|
|
t.Fatalf("Reviewer = %q, want main", ap.Reviewer)
|
|
}
|
|
if ap.At.IsZero() {
|
|
t.Fatal("At is zero, want a timestamp")
|
|
}
|
|
}
|
|
|
|
func TestApproval_Explain_Allowed(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ap := Approval{Actor: "worker", Allowed: true}
|
|
if got, want := ap.Explain(), "「worker 想要干什么,我审查后批准了」"; got != want {
|
|
t.Fatalf("Explain() = %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestApproval_Explain_Denied(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ap := Approval{Actor: "worker", Allowed: false}
|
|
if got, want := ap.Explain(), "「worker 想要干什么,我审查后拒绝了」"; got != want {
|
|
t.Fatalf("Explain() = %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestReviewAndApprove_Validation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
actor string
|
|
action string
|
|
desc string
|
|
wantErr error
|
|
}{
|
|
{name: "blank actor", actor: "", action: "run ls", desc: "list dir", wantErr: ErrUnknownActor},
|
|
{name: "space actor", actor: " ", action: "run ls", desc: "list dir", wantErr: ErrUnknownActor},
|
|
{name: "blank action", actor: "worker", action: "", desc: "list dir", wantErr: ErrActionMissing},
|
|
{name: "blank explain", actor: "worker", action: "run ls", desc: "", wantErr: ErrExplainMissing},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
ap, err := newSilentApprover().ReviewAndApprove(context.Background(), tt.actor, tt.action, tt.desc)
|
|
if err == nil {
|
|
t.Fatalf("ReviewAndApprove returned nil error, want %v", tt.wantErr)
|
|
}
|
|
if !errors.Is(err, tt.wantErr) {
|
|
t.Fatalf("error = %v, want Is(%v)", err, tt.wantErr)
|
|
}
|
|
if ap != nil {
|
|
t.Fatalf("Approval = %+v, want nil on validation failure", ap)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReviewAndApprove_WritesAuditLog(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var buf bytes.Buffer
|
|
ap := NewApprover(logger.New(logger.Options{Level: "debug", Format: "json", Out: &buf}))
|
|
|
|
_, err := ap.ReviewAndApprove(context.Background(), "worker", "run command", "delete prod db")
|
|
if err != nil {
|
|
t.Fatalf("ReviewAndApprove unexpected error: %v", err)
|
|
}
|
|
|
|
got := buf.String()
|
|
for _, want := range []string{
|
|
`"source":"orchestration/audit"`,
|
|
`"actor":"worker"`,
|
|
`"action":"run command"`,
|
|
`"explain":"delete prod db"`,
|
|
`"allowed":true`,
|
|
`"reviewer":"main"`,
|
|
} {
|
|
if !strings.Contains(got, want) {
|
|
t.Fatalf("audit log missing %s, got: %s", want, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReviewAndApprove_CanceledContext(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
|
|
_, err := newSilentApprover().ReviewAndApprove(ctx, "worker", "run ls", "list dir")
|
|
if !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("error = %v, want context.Canceled", err)
|
|
}
|
|
}
|
|
|
|
func TestNewApprover_NilLogger(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ap, err := NewApprover(nil).ReviewAndApprove(context.Background(), "worker", "run ls", "list dir")
|
|
if err != nil {
|
|
t.Fatalf("ReviewAndApprove with nil logger returned error: %v", err)
|
|
}
|
|
if ap == nil || ap.Actor != "worker" || !ap.Allowed {
|
|
t.Fatalf("Approval with nil logger not recorded: %+v", ap)
|
|
}
|
|
}
|