d78644d173
agentpr manages PRs/comments/whoami as unkin-agent (Vault AppRole -> gitea creds -> Gitea API), fixing tea's post-as-Ben default. watchpr polls PRs and alerts only on merge/close, human comment, CI failure, or lost mergeability. - cobra multi-binary layout mirroring node-lookup (cmd/ + internal/) - Makefile (build, patch|minor|major, completions, rpm), nfpm RPM with both binaries + bash/zsh/fish completions, woodpecker CI publishing to rpm-internal - unit tests for parsing, meaningful-change detection, and the Vault+Gitea client
117 lines
2.9 KiB
Go
117 lines
2.9 KiB
Go
package agent
|
|
|
|
import "testing"
|
|
|
|
func base() PRState {
|
|
return PRState{
|
|
Ref: PRRef{Owner: "unkin", Repo: "repo", Number: 1},
|
|
State: "open",
|
|
Merged: false,
|
|
HeadSHA: "abc123",
|
|
Mergeable: true,
|
|
CIStatus: "pending",
|
|
NonAgentComments: 0,
|
|
}
|
|
}
|
|
|
|
func TestMeaningfulChange(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mutate func(s *PRState)
|
|
wantChange bool
|
|
}{
|
|
{
|
|
name: "no change",
|
|
mutate: func(s *PRState) {},
|
|
wantChange: false,
|
|
},
|
|
{
|
|
name: "CI pending to success is benign",
|
|
mutate: func(s *PRState) { s.CIStatus = "success" },
|
|
wantChange: false,
|
|
},
|
|
{
|
|
name: "open to merged alerts",
|
|
mutate: func(s *PRState) { s.Merged = true; s.State = "closed" },
|
|
wantChange: true,
|
|
},
|
|
{
|
|
name: "open to closed without merge alerts",
|
|
mutate: func(s *PRState) { s.State = "closed" },
|
|
wantChange: true,
|
|
},
|
|
{
|
|
name: "new non-agent comment alerts",
|
|
mutate: func(s *PRState) { s.NonAgentComments = 1 },
|
|
wantChange: true,
|
|
},
|
|
{
|
|
name: "CI to failure alerts",
|
|
mutate: func(s *PRState) { s.CIStatus = "failure" },
|
|
wantChange: true,
|
|
},
|
|
{
|
|
name: "CI to error alerts",
|
|
mutate: func(s *PRState) { s.CIStatus = "error" },
|
|
wantChange: true,
|
|
},
|
|
{
|
|
name: "lost mergeability alerts",
|
|
mutate: func(s *PRState) { s.Mergeable = false },
|
|
wantChange: true,
|
|
},
|
|
{
|
|
name: "new head sha alone is benign",
|
|
mutate: func(s *PRState) { s.HeadSHA = "def456" },
|
|
wantChange: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
prev := base()
|
|
cur := base()
|
|
tt.mutate(&cur)
|
|
got, reason := MeaningfulChange(prev, cur)
|
|
if got != tt.wantChange {
|
|
t.Errorf("MeaningfulChange() = %v (%q), want %v", got, reason, tt.wantChange)
|
|
}
|
|
if got && reason == "" {
|
|
t.Errorf("change reported without a reason")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// A comment that only the agent posts must not alert: the non-agent count is
|
|
// unchanged, so MeaningfulChange sees nothing.
|
|
func TestMeaningfulChangeAgentCommentIgnored(t *testing.T) {
|
|
prev := base()
|
|
cur := base() // agent commented, but NonAgentComments stayed 0
|
|
if got, _ := MeaningfulChange(prev, cur); got {
|
|
t.Errorf("agent-only comment should not alert")
|
|
}
|
|
}
|
|
|
|
// Once CI is already failing, staying failed must not re-alert.
|
|
func TestMeaningfulChangeStaysFailed(t *testing.T) {
|
|
prev := base()
|
|
prev.CIStatus = "failure"
|
|
cur := base()
|
|
cur.CIStatus = "failure"
|
|
if got, _ := MeaningfulChange(prev, cur); got {
|
|
t.Errorf("CI staying failed should not re-alert")
|
|
}
|
|
}
|
|
|
|
func TestCountNonAgentComments(t *testing.T) {
|
|
comments := []Comment{
|
|
{User: User{Login: "unkin-agent"}},
|
|
{User: User{Login: "ben"}},
|
|
{User: User{Login: "unkin-agent"}},
|
|
{User: User{Login: "reviewer"}},
|
|
}
|
|
if n := countNonAgentComments(comments, "unkin-agent"); n != 2 {
|
|
t.Errorf("countNonAgentComments = %d, want 2", n)
|
|
}
|
|
}
|