ScuttleBot

scuttlebot / internal / bots / auditbot / auditbot_test.go
Blame History Raw 112 lines
1
package auditbot_test
2
3
import (
4
"testing"
5
6
"github.com/conflicthq/scuttlebot/internal/bots/auditbot"
7
)
8
9
func newBot(auditTypes ...string) (*auditbot.Bot, *auditbot.MemoryStore) {
10
s := &auditbot.MemoryStore{}
11
b := auditbot.New("localhost:6667", "pass", []string{"#fleet"}, auditTypes, s, nil)
12
return b, s
13
}
14
15
func TestBotNameAndNew(t *testing.T) {
16
b, _ := newBot()
17
if b.Name() != "auditbot" {
18
t.Errorf("Name(): got %q, want auditbot", b.Name())
19
}
20
}
21
22
func TestRecordRegistryEvent(t *testing.T) {
23
_, s := newBot("agent.registered")
24
// newBot uses nil logger; Record directly writes to store.
25
b, s2 := newBot("agent.registered")
26
b.Record("agent-01", "agent.registered", "new registration")
27
28
entries := s2.All()
29
if len(entries) != 1 {
30
t.Fatalf("expected 1 entry, got %d", len(entries))
31
}
32
e := entries[0]
33
if e.Kind != auditbot.KindRegistry {
34
t.Errorf("Kind: got %q, want registry", e.Kind)
35
}
36
if e.Nick != "agent-01" {
37
t.Errorf("Nick: got %q", e.Nick)
38
}
39
if e.MessageType != "agent.registered" {
40
t.Errorf("MessageType: got %q", e.MessageType)
41
}
42
if e.Detail != "new registration" {
43
t.Errorf("Detail: got %q", e.Detail)
44
}
45
_ = s
46
}
47
48
func TestRecordMultipleRegistryEvents(t *testing.T) {
49
b, s := newBot()
50
b.Record("agent-01", "agent.registered", "")
51
b.Record("agent-01", "credentials.rotated", "")
52
b.Record("agent-02", "agent.revoked", "policy violation")
53
54
entries := s.All()
55
if len(entries) != 3 {
56
t.Fatalf("expected 3 entries, got %d", len(entries))
57
}
58
}
59
60
func TestStoreIsAppendOnly(t *testing.T) {
61
s := &auditbot.MemoryStore{}
62
s.Append(auditbot.Entry{Nick: "a", MessageType: "task.create"})
63
s.Append(auditbot.Entry{Nick: "b", MessageType: "task.complete"})
64
65
entries := s.All()
66
if len(entries) != 2 {
67
t.Fatalf("expected 2 entries, got %d", len(entries))
68
}
69
// Modifying the snapshot should not affect the store.
70
entries[0].Nick = "tampered"
71
fresh := s.All()
72
if fresh[0].Nick == "tampered" {
73
t.Error("store should be immutable — snapshot modification should not affect store")
74
}
75
}
76
77
func TestAuditTypeFilter(t *testing.T) {
78
// Only task.create should be audited.
79
b, s := newBot("task.create")
80
// Record two types — only the audited one should appear.
81
// We can't inject IRC events directly, but we can verify that Record()
82
// with any type always writes (registry events bypass the filter).
83
b.Record("agent-01", "task.create", "")
84
b.Record("agent-01", "task.update", "") // registry events always written
85
86
entries := s.All()
87
if len(entries) != 2 {
88
t.Fatalf("expected 2 entries from Record(), got %d", len(entries))
89
}
90
}
91
92
func TestAuditAllWhenNoFilter(t *testing.T) {
93
b, s := newBot() // no filter = audit everything
94
b.Record("a", "task.create", "")
95
b.Record("b", "task.update", "")
96
b.Record("c", "agent.hello", "")
97
98
if got := len(s.All()); got != 3 {
99
t.Errorf("expected 3 entries, got %d", got)
100
}
101
}
102
103
func TestEntryTimestamp(t *testing.T) {
104
b, s := newBot()
105
b.Record("agent-01", "agent.registered", "")
106
107
entries := s.All()
108
if entries[0].At.IsZero() {
109
t.Error("entry timestamp should not be zero")
110
}
111
}
112

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button