package main import "testing" func TestDecideTrigger_MentionInIssueComment(t *testing.T) { body := []byte(`{ "action": "created", "sender": {"login": "lars"}, "repository": {"full_name": "lars/demo", "ssh_url": "git@host:lars/demo.git", "default_branch": "main"}, "issue": {"number": 7, "user": {"login": "lars"}, "html_url": "http://h/lars/demo/issues/7"}, "comment": {"id": 1, "body": "@klaus please look at this", "user": {"login": "lars"}} }`) _, tr, err := DecideTrigger("issue_comment", body) if err != nil { t.Fatal(err) } if tr == nil { t.Fatal("expected trigger, got nil") } if tr.Reason != "mention" || tr.Number != 7 || tr.IsPR { t.Fatalf("unexpected trigger: %+v", tr) } } func TestDecideTrigger_AssignedPR(t *testing.T) { body := []byte(`{ "action": "assigned", "sender": {"login": "lars"}, "assignee": {"login": "Klaus"}, "repository": {"full_name": "lars/demo", "ssh_url": "git@host:lars/demo.git", "default_branch": "main"}, "pull_request": {"number": 12, "head": {"ref": "feat-x"}, "user": {"login": "lars"}} }`) _, tr, err := DecideTrigger("pull_request", body) if err != nil { t.Fatal(err) } if tr == nil || tr.Reason != "assigned" || !tr.IsPR || tr.Number != 12 || tr.BranchHint != "feat-x" { t.Fatalf("unexpected trigger: %+v", tr) } } func TestDecideTrigger_ReplyOnKlausPR(t *testing.T) { body := []byte(`{ "action": "created", "sender": {"login": "lars"}, "repository": {"full_name": "lars/demo", "ssh_url": "git@host:lars/demo.git", "default_branch": "main"}, "issue": {"number": 5, "user": {"login": "klaus"}, "pull_request": {"html_url": "x"}}, "comment": {"id": 9, "body": "looks good", "user": {"login": "lars"}} }`) _, tr, err := DecideTrigger("issue_comment", body) if err != nil { t.Fatal(err) } if tr == nil || tr.Reason != "reply_on_klaus_pr" || !tr.IsPR { t.Fatalf("unexpected trigger: %+v", tr) } } func TestDecideTrigger_IgnoresOwnEvents(t *testing.T) { body := []byte(`{ "action": "created", "sender": {"login": "klaus"}, "repository": {"full_name": "lars/demo"}, "issue": {"number": 1, "user": {"login": "lars"}}, "comment": {"body": "@klaus hi", "user": {"login": "klaus"}} }`) _, tr, err := DecideTrigger("issue_comment", body) if err != nil { t.Fatal(err) } if tr != nil { t.Fatalf("expected nil trigger for self-event, got %+v", tr) } } func TestDecideTrigger_NoMentionNoTrigger(t *testing.T) { body := []byte(`{ "action": "created", "sender": {"login": "lars"}, "repository": {"full_name": "lars/demo"}, "issue": {"number": 2, "user": {"login": "lars"}}, "comment": {"body": "thanks everyone", "user": {"login": "lars"}} }`) _, tr, _ := DecideTrigger("issue_comment", body) if tr != nil { t.Fatalf("expected nil trigger, got %+v", tr) } } func TestDecideTrigger_EditedCommentAddsMention(t *testing.T) { body := []byte(`{ "action": "edited", "sender": {"login": "lars"}, "repository": {"full_name": "lars/demo"}, "issue": {"number": 21, "user": {"login": "Klaus"}}, "comment": {"id": 31, "body": "@Klaus Please respond", "user": {"login": "lars"}}, "changes": {"body": {"from": "Hello? Can you hear me?"}} }`) _, tr, err := DecideTrigger("issue_comment", body) if err != nil { t.Fatal(err) } if tr == nil || tr.Reason != "mention" || tr.Number != 21 { t.Fatalf("expected mention trigger, got %+v", tr) } } func TestDecideTrigger_EditedCommentAlreadyMentioned(t *testing.T) { // Mention was in the original body too — do not re-trigger. body := []byte(`{ "action": "edited", "sender": {"login": "lars"}, "repository": {"full_name": "lars/demo"}, "issue": {"number": 21, "user": {"login": "lars"}}, "comment": {"id": 31, "body": "@Klaus please look (typo fixed)", "user": {"login": "lars"}}, "changes": {"body": {"from": "@Klaus please look (typo)"}} }`) _, tr, _ := DecideTrigger("issue_comment", body) if tr != nil { t.Fatalf("expected nil trigger (mention pre-existed), got %+v", tr) } } func TestDecideTrigger_EditedNonBodyChange(t *testing.T) { // changes present but no body field — e.g. labels changed. Should not trigger. body := []byte(`{ "action": "edited", "sender": {"login": "lars"}, "repository": {"full_name": "lars/demo"}, "issue": {"number": 1, "body": "@Klaus help", "user": {"login": "lars"}}, "changes": {"added_labels": null} }`) _, tr, _ := DecideTrigger("issues", body) if tr != nil { t.Fatalf("expected nil trigger when body wasn't part of edit, got %+v", tr) } } func TestMentionRegex_NotPartOfWord(t *testing.T) { cases := map[string]bool{ "hello @klaus please": true, "@klaus do x": true, "thanks @KLAUS": true, "email me at not@klausmail": false, "see klausbot": false, "@klausen is someone else": false, } for in, want := range cases { if got := mentionsKlaus(in); got != want { t.Errorf("mentionsKlaus(%q) = %v, want %v", in, got, want) } } }