@@ -13,11 +13,14 @@ import (
1313 issues_model "code.gitea.io/gitea/models/issues"
1414 repo_model "code.gitea.io/gitea/models/repo"
1515 "code.gitea.io/gitea/models/unittest"
16+ user_model "code.gitea.io/gitea/models/user"
1617 "code.gitea.io/gitea/modules/json"
1718 api "code.gitea.io/gitea/modules/structs"
19+ issue_service "code.gitea.io/gitea/services/issue"
1820 "code.gitea.io/gitea/tests"
1921
2022 "github.com/stretchr/testify/assert"
23+ "xorm.io/builder"
2124)
2225
2326func TestAPIPullReview (t * testing.T ) {
@@ -314,3 +317,126 @@ func TestAPIPullReviewRequest(t *testing.T) {
314317 AddTokenAuth (token )
315318 MakeRequest (t , req , http .StatusNoContent )
316319}
320+
321+ func TestAPIPullReviewStayDismissed (t * testing.T ) {
322+ // This test against issue https://github.com/go-gitea/gitea/issues/28542
323+ // where old reviews surface after a review request got dismissed.
324+ defer tests .PrepareTestEnv (t )()
325+ pullIssue := unittest .AssertExistsAndLoadBean (t , & issues_model.Issue {ID : 3 })
326+ assert .NoError (t , pullIssue .LoadAttributes (db .DefaultContext ))
327+ repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {ID : pullIssue .RepoID })
328+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 })
329+ session2 := loginUser (t , user2 .LoginName )
330+ token2 := getTokenForLoggedInUser (t , session2 , auth_model .AccessTokenScopeWriteRepository )
331+ user8 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 8 })
332+ session8 := loginUser (t , user8 .LoginName )
333+ token8 := getTokenForLoggedInUser (t , session8 , auth_model .AccessTokenScopeWriteRepository )
334+
335+ // user2 request user8
336+ req := NewRequestWithJSON (t , http .MethodPost , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers" , repo .OwnerName , repo .Name , pullIssue .Index ), & api.PullReviewRequestOptions {
337+ Reviewers : []string {user8 .LoginName },
338+ }).AddTokenAuth (token2 )
339+ MakeRequest (t , req , http .StatusCreated )
340+
341+ reviewsCountCheck (t ,
342+ "check we have only one review request" ,
343+ pullIssue .ID , user8 .ID , 0 , 1 , 1 , false )
344+
345+ // user2 request user8 again, it is expected to be ignored
346+ req = NewRequestWithJSON (t , http .MethodPost , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers" , repo .OwnerName , repo .Name , pullIssue .Index ), & api.PullReviewRequestOptions {
347+ Reviewers : []string {user8 .LoginName },
348+ }).AddTokenAuth (token2 )
349+ MakeRequest (t , req , http .StatusCreated )
350+
351+ reviewsCountCheck (t ,
352+ "check we have only one review request, even after re-request it again" ,
353+ pullIssue .ID , user8 .ID , 0 , 1 , 1 , false )
354+
355+ // user8 reviews it as accept
356+ req = NewRequestWithJSON (t , http .MethodPost , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls/%d/reviews" , repo .OwnerName , repo .Name , pullIssue .Index ), & api.CreatePullReviewOptions {
357+ Event : "APPROVED" ,
358+ Body : "lgtm" ,
359+ }).AddTokenAuth (token8 )
360+ MakeRequest (t , req , http .StatusOK )
361+
362+ reviewsCountCheck (t ,
363+ "check we have one valid approval" ,
364+ pullIssue .ID , user8 .ID , 0 , 0 , 1 , true )
365+
366+ // emulate of auto-dismiss lgtm on a protected branch that where a pull just got an update
367+ _ , err := db .GetEngine (db .DefaultContext ).Where ("issue_id = ? AND reviewer_id = ?" , pullIssue .ID , user8 .ID ).
368+ Cols ("dismissed" ).Update (& issues_model.Review {Dismissed : true })
369+ assert .NoError (t , err )
370+
371+ // user2 request user8 again
372+ req = NewRequestWithJSON (t , http .MethodPost , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers" , repo .OwnerName , repo .Name , pullIssue .Index ), & api.PullReviewRequestOptions {
373+ Reviewers : []string {user8 .LoginName },
374+ }).AddTokenAuth (token2 )
375+ MakeRequest (t , req , http .StatusCreated )
376+
377+ reviewsCountCheck (t ,
378+ "check we have no valid approval and one review request" ,
379+ pullIssue .ID , user8 .ID , 1 , 1 , 2 , false )
380+
381+ // user8 dismiss review
382+ _ , err = issue_service .ReviewRequest (db .DefaultContext , pullIssue , user8 , user8 , false )
383+ assert .NoError (t , err )
384+
385+ reviewsCountCheck (t ,
386+ "check new review request is now dismissed" ,
387+ pullIssue .ID , user8 .ID , 1 , 0 , 1 , false )
388+
389+ // add a new valid approval
390+ req = NewRequestWithJSON (t , http .MethodPost , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls/%d/reviews" , repo .OwnerName , repo .Name , pullIssue .Index ), & api.CreatePullReviewOptions {
391+ Event : "APPROVED" ,
392+ Body : "lgtm" ,
393+ }).AddTokenAuth (token8 )
394+ MakeRequest (t , req , http .StatusOK )
395+
396+ reviewsCountCheck (t ,
397+ "check that old reviews requests are deleted" ,
398+ pullIssue .ID , user8 .ID , 1 , 0 , 2 , true )
399+
400+ // now add a change request witch should dismiss the approval
401+ req = NewRequestWithJSON (t , http .MethodPost , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls/%d/reviews" , repo .OwnerName , repo .Name , pullIssue .Index ), & api.CreatePullReviewOptions {
402+ Event : "REQUEST_CHANGES" ,
403+ Body : "please change XYZ" ,
404+ }).AddTokenAuth (token8 )
405+ MakeRequest (t , req , http .StatusOK )
406+
407+ reviewsCountCheck (t ,
408+ "check that old reviews are dismissed" ,
409+ pullIssue .ID , user8 .ID , 2 , 0 , 3 , false )
410+ }
411+
412+ func reviewsCountCheck (t * testing.T , name string , issueID , reviewerID int64 , expectedDismissed , expectedRequested , expectedTotal int , expectApproval bool ) {
413+ t .Run (name , func (t * testing.T ) {
414+ unittest .AssertCountByCond (t , "review" , builder.Eq {
415+ "issue_id" : issueID ,
416+ "reviewer_id" : reviewerID ,
417+ "dismissed" : true ,
418+ }, expectedDismissed )
419+
420+ unittest .AssertCountByCond (t , "review" , builder.Eq {
421+ "issue_id" : issueID ,
422+ "reviewer_id" : reviewerID ,
423+ }, expectedTotal )
424+
425+ unittest .AssertCountByCond (t , "review" , builder.Eq {
426+ "issue_id" : issueID ,
427+ "reviewer_id" : reviewerID ,
428+ "type" : issues_model .ReviewTypeRequest ,
429+ }, expectedRequested )
430+
431+ approvalCount := 0
432+ if expectApproval {
433+ approvalCount = 1
434+ }
435+ unittest .AssertCountByCond (t , "review" , builder.Eq {
436+ "issue_id" : issueID ,
437+ "reviewer_id" : reviewerID ,
438+ "type" : issues_model .ReviewTypeApprove ,
439+ "dismissed" : false ,
440+ }, approvalCount )
441+ })
442+ }
0 commit comments