mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Workaround to clean up old reviews on creating a new one (#28554)
close #28542 blocks #28544 --- *Sponsored by Kithara Software GmbH*
This commit is contained in:
		| @@ -13,11 +13,14 @@ import ( | ||||
| 	issues_model "code.gitea.io/gitea/models/issues" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/json" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	issue_service "code.gitea.io/gitea/services/issue" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"xorm.io/builder" | ||||
| ) | ||||
|  | ||||
| func TestAPIPullReview(t *testing.T) { | ||||
| @@ -314,3 +317,126 @@ func TestAPIPullReviewRequest(t *testing.T) { | ||||
| 		AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| } | ||||
|  | ||||
| func TestAPIPullReviewStayDismissed(t *testing.T) { | ||||
| 	// This test against issue https://github.com/go-gitea/gitea/issues/28542 | ||||
| 	// where old reviews surface after a review request got dismissed. | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) | ||||
| 	assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}) | ||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 	session2 := loginUser(t, user2.LoginName) | ||||
| 	token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteRepository) | ||||
| 	user8 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 8}) | ||||
| 	session8 := loginUser(t, user8.LoginName) | ||||
| 	token8 := getTokenForLoggedInUser(t, session8, auth_model.AccessTokenScopeWriteRepository) | ||||
|  | ||||
| 	// user2 request user8 | ||||
| 	req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ | ||||
| 		Reviewers: []string{user8.LoginName}, | ||||
| 	}).AddTokenAuth(token2) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check we have only one review request", | ||||
| 		pullIssue.ID, user8.ID, 0, 1, 1, false) | ||||
|  | ||||
| 	// user2 request user8 again, it is expected to be ignored | ||||
| 	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ | ||||
| 		Reviewers: []string{user8.LoginName}, | ||||
| 	}).AddTokenAuth(token2) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check we have only one review request, even after re-request it again", | ||||
| 		pullIssue.ID, user8.ID, 0, 1, 1, false) | ||||
|  | ||||
| 	// user8 reviews it as accept | ||||
| 	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ | ||||
| 		Event: "APPROVED", | ||||
| 		Body:  "lgtm", | ||||
| 	}).AddTokenAuth(token8) | ||||
| 	MakeRequest(t, req, http.StatusOK) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check we have one valid approval", | ||||
| 		pullIssue.ID, user8.ID, 0, 0, 1, true) | ||||
|  | ||||
| 	// emulate of auto-dismiss lgtm on a protected branch that where a pull just got an update | ||||
| 	_, err := db.GetEngine(db.DefaultContext).Where("issue_id = ? AND reviewer_id = ?", pullIssue.ID, user8.ID). | ||||
| 		Cols("dismissed").Update(&issues_model.Review{Dismissed: true}) | ||||
| 	assert.NoError(t, err) | ||||
|  | ||||
| 	// user2 request user8 again | ||||
| 	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ | ||||
| 		Reviewers: []string{user8.LoginName}, | ||||
| 	}).AddTokenAuth(token2) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check we have no valid approval and one review request", | ||||
| 		pullIssue.ID, user8.ID, 1, 1, 2, false) | ||||
|  | ||||
| 	// user8 dismiss review | ||||
| 	_, err = issue_service.ReviewRequest(db.DefaultContext, pullIssue, user8, user8, false) | ||||
| 	assert.NoError(t, err) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check new review request is now dismissed", | ||||
| 		pullIssue.ID, user8.ID, 1, 0, 1, false) | ||||
|  | ||||
| 	// add a new valid approval | ||||
| 	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ | ||||
| 		Event: "APPROVED", | ||||
| 		Body:  "lgtm", | ||||
| 	}).AddTokenAuth(token8) | ||||
| 	MakeRequest(t, req, http.StatusOK) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check that old reviews requests are deleted", | ||||
| 		pullIssue.ID, user8.ID, 1, 0, 2, true) | ||||
|  | ||||
| 	// now add a change request witch should dismiss the approval | ||||
| 	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ | ||||
| 		Event: "REQUEST_CHANGES", | ||||
| 		Body:  "please change XYZ", | ||||
| 	}).AddTokenAuth(token8) | ||||
| 	MakeRequest(t, req, http.StatusOK) | ||||
|  | ||||
| 	reviewsCountCheck(t, | ||||
| 		"check that old reviews are dismissed", | ||||
| 		pullIssue.ID, user8.ID, 2, 0, 3, false) | ||||
| } | ||||
|  | ||||
| func reviewsCountCheck(t *testing.T, name string, issueID, reviewerID int64, expectedDismissed, expectedRequested, expectedTotal int, expectApproval bool) { | ||||
| 	t.Run(name, func(t *testing.T) { | ||||
| 		unittest.AssertCountByCond(t, "review", builder.Eq{ | ||||
| 			"issue_id":    issueID, | ||||
| 			"reviewer_id": reviewerID, | ||||
| 			"dismissed":   true, | ||||
| 		}, expectedDismissed) | ||||
|  | ||||
| 		unittest.AssertCountByCond(t, "review", builder.Eq{ | ||||
| 			"issue_id":    issueID, | ||||
| 			"reviewer_id": reviewerID, | ||||
| 		}, expectedTotal) | ||||
|  | ||||
| 		unittest.AssertCountByCond(t, "review", builder.Eq{ | ||||
| 			"issue_id":    issueID, | ||||
| 			"reviewer_id": reviewerID, | ||||
| 			"type":        issues_model.ReviewTypeRequest, | ||||
| 		}, expectedRequested) | ||||
|  | ||||
| 		approvalCount := 0 | ||||
| 		if expectApproval { | ||||
| 			approvalCount = 1 | ||||
| 		} | ||||
| 		unittest.AssertCountByCond(t, "review", builder.Eq{ | ||||
| 			"issue_id":    issueID, | ||||
| 			"reviewer_id": reviewerID, | ||||
| 			"type":        issues_model.ReviewTypeApprove, | ||||
| 			"dismissed":   false, | ||||
| 		}, approvalCount) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user