package main import ( "bufio" "strings" "testing" "go.uber.org/mock/gomock" "src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common/gitea-generated/models" mock_main "src.opensuse.org/workflow-pr/mock" ) type pr_review map[string]struct { pr *models.PullRequest reviews []*models.PullReview maintainers []string } func TestReviewApproval(t *testing.T) { tests := []struct { name string prs pr_review approved bool }{ { name: "Maintainer not approved", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "nothing PR: foo/foo#10", Index: 10, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{}, maintainers: []string{"bingo"}, }, }, approved: false, }, { name: "Maintainer approved", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "", Index: 42, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateApproved, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, }, approved: true, }, { name: "Maintainer approval is missing", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "", Index: 42, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateApproved, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"kong", "bingo"}, }, }, approved: false, }, { name: "Maintainer dis-approved", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "", Index: 42, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateRequestChanges, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, }, approved: false, }, { name: "Maintainer review is stale", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "", Index: 42, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", Stale: true, State: common.ReviewStateApproved, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, }, approved: false, }, { name: "Part of ReviewSet is not approved", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "PR: foo/bar#10", Index: 42, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateApproved, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, "foo/bar#10": { pr: &models.PullRequest{ Body: "PR: org/repo#42", Index: 10, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "bar"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateRequestChanges, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, }, approved: false, }, { name: "Review set approved", prs: pr_review{ "org/repo#42": { pr: &models.PullRequest{ Body: "PR: foo/bar#10", Index: 42, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "repo"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateApproved, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, "foo/bar#10": { pr: &models.PullRequest{ Body: "PR: org/repo#42", Index: 10, RequestedReviewers: []*models.User{}, Base: &models.PRBranchInfo{ Repo: &models.Repository{ Owner: &models.User{UserName: "org"}, Name: "bar"}, }, }, reviews: []*models.PullReview{ &models.PullReview{ Body: "wow!", State: common.ReviewStateApproved, User: &models.User{ UserName: "king", }, }, }, maintainers: []string{"king", "bingo"}, }, }, approved: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { ctl := gomock.NewController(t) pr := mock_main.NewMockGiteaPRInterface(ctl) maintainership := mock_main.NewMockMaintainershipData(ctl) for params, prs := range test.prs { _, data := common.ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader("PR: " + params))) if len(data) != 1 { t.Fatal("bad test setup, fix") } pr.EXPECT().GetPullRequestAndReviews(data[0].Org, data[0].Repo, data[0].Num). Return(prs.pr, prs.reviews, nil) maintainership.EXPECT().ListPackageMaintainers(data[0].Repo).Return(prs.maintainers) } info, _ := NewReviewInstance(pr, maintainership, "org", "repo", 42) approved, _ := info.IsMaintainerApproved() if test.approved != approved { t.Error("Unexpected approval state:", approved) } }) } }