package bot import ( "testing" "git.folja.dev/awayatan/yaju-is-always-watching-you/internal/detector" "git.folja.dev/awayatan/yaju-is-always-watching-you/internal/forgejo" ) type fakeClient struct { comments []string corrections []string prs int fileContent map[string]string } func (f *fakeClient) ReplyToIssue(owner, repo string, index int64, body string) error { f.comments = append(f.comments, body) return nil } func (f *fakeClient) FileContent(owner, repo, ref, path string) (string, string, error) { return f.fileContent[path], "sha-" + path, nil } func (f *fakeClient) CommitCorrection(owner, repo, baseBranch, newBranch, path, sha, newContent, message string) error { f.corrections = append(f.corrections, path) return nil } func (f *fakeClient) OpenCorrectionPR(owner, repo, head, base, title, body string) error { f.prs++ return nil } func newTestBot(fc *fakeClient) *Bot { det := detector.New([]string{"しょうもな"}) return New(fc, det, "yaju-keisatsu-bot", "bot/goroku-fix/", nil) } func TestHandleIssueComment_Flagged(t *testing.T) { fc := &fakeClient{} b := newTestBot(fc) err := b.HandleIssueComment(forgejo.IssueCommentPayload{ Action: "created", Issue: forgejo.WebhookIssue{Number: 1}, Comment: forgejo.WebhookComment{Body: "それはしょうもな", User: forgejo.WebhookUser{Login: "alice"}}, Repository: forgejo.WebhookRepository{Name: "repo", Owner: forgejo.WebhookUser{Login: "owner"}}, Sender: forgejo.WebhookUser{Login: "alice"}, }) if err != nil { t.Fatalf("HandleIssueComment() error = %v", err) } if len(fc.comments) != 1 { t.Fatalf("expected 1 warning comment, got %d", len(fc.comments)) } } func TestHandleIssueComment_IgnoresSelf(t *testing.T) { fc := &fakeClient{} b := newTestBot(fc) err := b.HandleIssueComment(forgejo.IssueCommentPayload{ Action: "created", Comment: forgejo.WebhookComment{Body: "それはしょうもな", User: forgejo.WebhookUser{Login: "yaju-keisatsu-bot"}}, Repository: forgejo.WebhookRepository{Name: "repo", Owner: forgejo.WebhookUser{Login: "owner"}}, }) if err != nil { t.Fatalf("HandleIssueComment() error = %v", err) } if len(fc.comments) != 0 { t.Fatalf("bot must not reply to its own comments, got %d replies", len(fc.comments)) } } func TestHandleIssueComment_Clean(t *testing.T) { fc := &fakeClient{} b := newTestBot(fc) err := b.HandleIssueComment(forgejo.IssueCommentPayload{ Action: "created", Comment: forgejo.WebhookComment{Body: "普通のコメントです", User: forgejo.WebhookUser{Login: "alice"}}, Repository: forgejo.WebhookRepository{Name: "repo", Owner: forgejo.WebhookUser{Login: "owner"}}, Sender: forgejo.WebhookUser{Login: "alice"}, }) if err != nil { t.Fatalf("HandleIssueComment() error = %v", err) } if len(fc.comments) != 0 { t.Fatalf("expected no reply for clean comment, got %d", len(fc.comments)) } } func TestHandlePush_OpensCorrectionPR(t *testing.T) { fc := &fakeClient{fileContent: map[string]string{ "README.md": "これはしょうもな話だ", }} b := newTestBot(fc) err := b.HandlePush(forgejo.PushPayload{ Ref: "refs/heads/main", After: "abcdef1234567890", Commits: []forgejo.WebhookCommit{ {ID: "abcdef1234567890", Modified: []string{"README.md"}}, }, Repository: forgejo.WebhookRepository{Name: "repo", Owner: forgejo.WebhookUser{Login: "owner"}}, Pusher: forgejo.WebhookUser{Login: "alice"}, }) if err != nil { t.Fatalf("HandlePush() error = %v", err) } if len(fc.corrections) != 1 || fc.corrections[0] != "README.md" { t.Fatalf("expected a correction commit for README.md, got %v", fc.corrections) } if fc.prs != 1 { t.Fatalf("expected 1 correction PR, got %d", fc.prs) } } func TestHandlePush_IgnoresSelf(t *testing.T) { fc := &fakeClient{fileContent: map[string]string{"README.md": "しょうもな"}} b := newTestBot(fc) err := b.HandlePush(forgejo.PushPayload{ Ref: "refs/heads/main", After: "abc", Commits: []forgejo.WebhookCommit{{ID: "abc", Modified: []string{"README.md"}}}, Repository: forgejo.WebhookRepository{Name: "repo", Owner: forgejo.WebhookUser{Login: "owner"}}, Pusher: forgejo.WebhookUser{Login: "yaju-keisatsu-bot"}, }) if err != nil { t.Fatalf("HandlePush() error = %v", err) } if fc.prs != 0 { t.Fatalf("bot must not react to its own pushes, got %d PRs", fc.prs) } } func TestHandlePush_CleanFileNoOp(t *testing.T) { fc := &fakeClient{fileContent: map[string]string{"README.md": "普通のREADMEです"}} b := newTestBot(fc) err := b.HandlePush(forgejo.PushPayload{ Ref: "refs/heads/main", After: "abc", Commits: []forgejo.WebhookCommit{{ID: "abc", Modified: []string{"README.md"}}}, Repository: forgejo.WebhookRepository{Name: "repo", Owner: forgejo.WebhookUser{Login: "owner"}}, Pusher: forgejo.WebhookUser{Login: "alice"}, }) if err != nil { t.Fatalf("HandlePush() error = %v", err) } if fc.prs != 0 || len(fc.corrections) != 0 { t.Fatalf("expected no correction for clean file, got prs=%d corrections=%v", fc.prs, fc.corrections) } }