610 lines · 26.1 KB · Go
RawDownload
// Copyright 2020 The Gitea Authors. All rights reserved.// SPDX-License-Identifier: MIT package integration import (	"fmt"	"net/http"	"testing" 	auth_model "forgejo.org/models/auth"	"forgejo.org/models/db"	issues_model "forgejo.org/models/issues"	repo_model "forgejo.org/models/repo"	"forgejo.org/models/unittest"	user_model "forgejo.org/models/user"	"forgejo.org/modules/json"	api "forgejo.org/modules/structs"	issue_service "forgejo.org/services/issue"	"forgejo.org/tests" 	"github.com/stretchr/testify/assert"	"github.com/stretchr/testify/require"	"xorm.io/builder") func TestAPIPullReviewCreateDeleteComment(t *testing.T) {	defer tests.PrepareTestEnv(t)()	pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})	require.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}) 	username := "user2"	session := loginUser(t, username)	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 	// as of e522e774cae2240279fc48c349fc513c9d3353ee	// There should be no reason for CreateComment to behave differently	// depending on the event associated with the review. But the logic of the implementation	// at this point in time is very involved and deserves these seemingly redundant	// test.	for _, event := range []api.ReviewStateType{		api.ReviewStatePending,		api.ReviewStateRequestChanges,		api.ReviewStateApproved,		api.ReviewStateComment,	} {		t.Run("Event_"+string(event), func(t *testing.T) {			path := "README.md"			var review api.PullReview			var reviewLine int64 = 1 			// cleanup			{				session := loginUser(t, "user1")				token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll) 				req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index).AddTokenAuth(token)				resp := MakeRequest(t, req, http.StatusOK)				var reviews []*api.PullReview				DecodeJSON(t, resp, &reviews)				for _, review := range reviews {					if review.State == api.ReviewStateRequestReview {						continue					}					req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d", repo.FullName(), pullIssue.Index, review.ID).						AddTokenAuth(token)					MakeRequest(t, req, http.StatusNoContent)				}			} 			requireReviewCount := func(count int) {				req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index).AddTokenAuth(token)				resp := MakeRequest(t, req, http.StatusOK)				var reviews []*api.PullReview				DecodeJSON(t, resp, &reviews)				require.Len(t, reviews, count)			} 			{				req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index), &api.CreatePullReviewOptions{					Body:  "body1",					Event: event,				}).AddTokenAuth(token)				resp := MakeRequest(t, req, http.StatusOK)				DecodeJSON(t, resp, &review)				require.EqualValues(t, string(event), review.State)				require.Equal(t, 0, review.CodeCommentsCount)			} 			{				req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews/%d", repo.FullName(), pullIssue.Index, review.ID).					AddTokenAuth(token)				resp := MakeRequest(t, req, http.StatusOK)				var getReview api.PullReview				DecodeJSON(t, resp, &getReview)				require.Equal(t, getReview, review)			}			requireReviewCount(2) 			newCommentBody := "first new line"			var reviewComment api.PullReviewComment 			{				req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/pulls/%d/reviews/%d/comments", repo.FullName(), pullIssue.Index, review.ID), &api.CreatePullReviewCommentOptions{					Path:       path,					Body:       newCommentBody,					OldLineNum: reviewLine,				}).AddTokenAuth(token)				resp := MakeRequest(t, req, http.StatusOK)				DecodeJSON(t, resp, &reviewComment)				assert.Equal(t, review.ID, reviewComment.ReviewID)				assert.Equal(t, newCommentBody, reviewComment.Body)				assert.EqualValues(t, reviewLine, reviewComment.OldLineNum)				assert.EqualValues(t, 0, reviewComment.LineNum)				assert.Equal(t, path, reviewComment.Path)			} 			{				req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews/%d/comments/%d", repo.FullName(), pullIssue.Index, review.ID, reviewComment.ID).					AddTokenAuth(token)				resp := MakeRequest(t, req, http.StatusOK) 				var comment api.PullReviewComment				DecodeJSON(t, resp, &comment)				assert.Equal(t, reviewComment, comment)			} 			{				req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d/comments/%d", repo.FullName(), pullIssue.Index, review.ID, reviewComment.ID).					AddTokenAuth(token)				MakeRequest(t, req, http.StatusNoContent)			} 			{				req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews/%d/comments/%d", repo.FullName(), pullIssue.Index, review.ID, reviewComment.ID).					AddTokenAuth(token)				MakeRequest(t, req, http.StatusNotFound)			} 			{				req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d", repo.FullName(), pullIssue.Index, review.ID).					AddTokenAuth(token)				MakeRequest(t, req, http.StatusNoContent)			}			requireReviewCount(1)		})	}} func TestAPIPullReview(t *testing.T) {	defer tests.PrepareTestEnv(t)()	pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})	require.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}) 	// test ListPullReviews	session := loginUser(t, "user2")	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)	req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index).		AddTokenAuth(token)	resp := MakeRequest(t, req, http.StatusOK) 	var reviews []*api.PullReview	DecodeJSON(t, resp, &reviews)	if !assert.Len(t, reviews, 8) {		return	}	for _, r := range reviews {		assert.Equal(t, pullIssue.HTMLURL(), r.HTMLPullURL)	}	assert.EqualValues(t, 8, reviews[3].ID)	assert.EqualValues(t, "APPROVED", reviews[3].State)	assert.Equal(t, 0, reviews[3].CodeCommentsCount)	assert.True(t, reviews[3].Stale)	assert.False(t, reviews[3].Official) 	assert.EqualValues(t, 10, reviews[5].ID)	assert.EqualValues(t, "REQUEST_CHANGES", reviews[5].State)	assert.Equal(t, 1, reviews[5].CodeCommentsCount)	assert.EqualValues(t, -1, reviews[5].Reviewer.ID) // ghost user	assert.False(t, reviews[5].Stale)	assert.True(t, reviews[5].Official) 	// test GetPullReview	req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, reviews[3].ID).		AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	var review api.PullReview	DecodeJSON(t, resp, &review)	assert.Equal(t, *reviews[3], review) 	req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, reviews[5].ID).		AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &review)	assert.Equal(t, *reviews[5], review) 	// test GetPullReviewComments	comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7})	req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments", repo.OwnerName, repo.Name, pullIssue.Index, 10).		AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	var reviewComments []*api.PullReviewComment	DecodeJSON(t, resp, &reviewComments)	assert.Len(t, reviewComments, 1)	assert.Equal(t, "Ghost", reviewComments[0].Poster.UserName)	assert.Equal(t, "a review from a deleted user", reviewComments[0].Body)	assert.Equal(t, comment.ID, reviewComments[0].ID)	assert.EqualValues(t, comment.UpdatedUnix, reviewComments[0].Updated.Unix())	assert.Equal(t, comment.HTMLURL(db.DefaultContext), reviewComments[0].HTMLURL) 	// test CreatePullReview	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{		Body: "body1",		// Event: "" # will result in PENDING		Comments: []api.CreatePullReviewComment{			{				Path:       "README.md",				Body:       "first new line",				OldLineNum: 0,				NewLineNum: 1,			}, {				Path:       "README.md",				Body:       "first old line",				OldLineNum: 1,				NewLineNum: 0,			}, {				Path:       "iso-8859-1.txt",				Body:       "this line contains a non-utf-8 character",				OldLineNum: 0,				NewLineNum: 1,			},		},	}).AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &review)	assert.EqualValues(t, 6, review.ID)	assert.EqualValues(t, "PENDING", review.State)	assert.Equal(t, 3, review.CodeCommentsCount) 	// test SubmitPullReview	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.SubmitPullReviewOptions{		Event: "APPROVED",		Body:  "just two nits",	}).AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &review)	assert.EqualValues(t, 6, review.ID)	assert.EqualValues(t, "APPROVED", review.State)	assert.Equal(t, 3, review.CodeCommentsCount) 	// test dismiss review	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.DismissPullReviewOptions{		Message: "test",	}).AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &review)	assert.EqualValues(t, 6, review.ID)	assert.True(t, review.Dismissed) 	// test dismiss review	req = NewRequest(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/undismissals", repo.OwnerName, repo.Name, pullIssue.Index, review.ID)).		AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &review)	assert.EqualValues(t, 6, review.ID)	assert.False(t, review.Dismissed) 	// test DeletePullReview	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{		Body:  "just a comment",		Event: "COMMENT",	}).AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &review)	assert.EqualValues(t, "COMMENT", review.State)	assert.Equal(t, 0, review.CodeCommentsCount)	req = NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID).		AddTokenAuth(token)	MakeRequest(t, req, http.StatusNoContent) 	// test CreatePullReview Comment without body but with comments	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{		// Body:  "",		Event: "COMMENT",		Comments: []api.CreatePullReviewComment{			{				Path:       "README.md",				Body:       "first new line",				OldLineNum: 0,				NewLineNum: 1,			}, {				Path:       "README.md",				Body:       "first old line",				OldLineNum: 1,				NewLineNum: 0,			},		},	}).AddTokenAuth(token)	var commentReview api.PullReview 	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &commentReview)	assert.EqualValues(t, "COMMENT", commentReview.State)	assert.Equal(t, 2, commentReview.CodeCommentsCount)	assert.Empty(t, commentReview.Body)	assert.False(t, commentReview.Dismissed) 	// test CreatePullReview Comment with body but without comments	commentBody := "This is a body of the comment."	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{		Body:     commentBody,		Event:    "COMMENT",		Comments: []api.CreatePullReviewComment{},	}).AddTokenAuth(token) 	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &commentReview)	assert.EqualValues(t, "COMMENT", commentReview.State)	assert.Equal(t, 0, commentReview.CodeCommentsCount)	assert.Equal(t, commentBody, commentReview.Body)	assert.False(t, commentReview.Dismissed) 	// test CreatePullReview Comment without body and no comments	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{		Body:     "",		Event:    "COMMENT",		Comments: []api.CreatePullReviewComment{},	}).AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusUnprocessableEntity)	errMap := make(map[string]any)	json.Unmarshal(resp.Body.Bytes(), &errMap)	assert.Equal(t, "review event COMMENT requires a body or a comment", errMap["message"].(string)) 	// test get review requests	// to make it simple, use same api with get review	pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12})	require.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext))	repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}) 	req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews", repo3.OwnerName, repo3.Name, pullIssue12.Index).		AddTokenAuth(token)	resp = MakeRequest(t, req, http.StatusOK)	DecodeJSON(t, resp, &reviews)	assert.EqualValues(t, 11, reviews[0].ID)	assert.EqualValues(t, "REQUEST_REVIEW", reviews[0].State)	assert.Equal(t, 0, reviews[0].CodeCommentsCount)	assert.False(t, reviews[0].Stale)	assert.True(t, reviews[0].Official)	assert.Equal(t, "test_team", reviews[0].ReviewerTeam.Name) 	assert.EqualValues(t, 12, reviews[1].ID)	assert.EqualValues(t, "REQUEST_REVIEW", reviews[1].State)	assert.Equal(t, 0, reviews[0].CodeCommentsCount)	assert.False(t, reviews[1].Stale)	assert.True(t, reviews[1].Official)	assert.EqualValues(t, 1, reviews[1].Reviewer.ID)} func TestAPIPullReviewRequest(t *testing.T) {	defer tests.PrepareTestEnv(t)()	pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})	require.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}) 	// Test add Review Request	session := loginUser(t, "user2")	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)	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{"user4@example.com", "user8"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusCreated) 	// poster of pr can't be reviewer	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{"user1"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusUnprocessableEntity) 	// test user not exist	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{"testOther"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusNotFound) 	// Test Remove Review Request	session2 := loginUser(t, "user4")	token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteRepository) 	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user4"},	}).AddTokenAuth(token2)	MakeRequest(t, req, http.StatusNoContent) 	// doer is not admin	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user8"},	}).AddTokenAuth(token2)	MakeRequest(t, req, http.StatusUnprocessableEntity) 	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user8"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusNoContent) 	// a collaborator can add/remove a review request	pullIssue21 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 21})	require.NoError(t, pullIssue21.LoadAttributes(db.DefaultContext))	pull21Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue21.RepoID}) // repo60	user38Session := loginUser(t, "user38")	user38Token := getTokenForLoggedInUser(t, user38Session, auth_model.AccessTokenScopeWriteRepository)	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", pull21Repo.OwnerName, pull21Repo.Name, pullIssue21.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user4@example.com"},	}).AddTokenAuth(user38Token)	MakeRequest(t, req, http.StatusCreated) 	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", pull21Repo.OwnerName, pull21Repo.Name, pullIssue21.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user4@example.com"},	}).AddTokenAuth(user38Token)	MakeRequest(t, req, http.StatusNoContent) 	// the poster of the PR can add/remove a review request	user39Session := loginUser(t, "user39")	user39Token := getTokenForLoggedInUser(t, user39Session, auth_model.AccessTokenScopeWriteRepository)	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", pull21Repo.OwnerName, pull21Repo.Name, pullIssue21.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user8"},	}).AddTokenAuth(user39Token)	MakeRequest(t, req, http.StatusCreated) 	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", pull21Repo.OwnerName, pull21Repo.Name, pullIssue21.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user8"},	}).AddTokenAuth(user39Token)	MakeRequest(t, req, http.StatusNoContent) 	// user with read permission on pull requests unit can add/remove a review request	pullIssue22 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 22})	require.NoError(t, pullIssue22.LoadAttributes(db.DefaultContext))	pull22Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue22.RepoID}) // repo61	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", pull22Repo.OwnerName, pull22Repo.Name, pullIssue22.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user38"},	}).AddTokenAuth(user39Token) // user39 is from a team with read permission on pull requests unit	MakeRequest(t, req, http.StatusCreated) 	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", pull22Repo.OwnerName, pull22Repo.Name, pullIssue22.Index), &api.PullReviewRequestOptions{		Reviewers: []string{"user38"},	}).AddTokenAuth(user39Token) // user39 is from a team with read permission on pull requests unit	MakeRequest(t, req, http.StatusNoContent) 	// Test team review request	pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12})	require.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext))	repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}) 	// Test add Team Review Request	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{		TeamReviewers: []string{"team1", "owners"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusCreated) 	// Test add Team Review Request to not allowned	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{		TeamReviewers: []string{"test_team"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusUnprocessableEntity) 	// Test add Team Review Request to not exist	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{		TeamReviewers: []string{"not_exist_team"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusNotFound) 	// Test Remove team Review Request	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{		TeamReviewers: []string{"team1"},	}).AddTokenAuth(token)	MakeRequest(t, req, http.StatusNoContent) 	// empty request test	req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{}).		AddTokenAuth(token)	MakeRequest(t, req, http.StatusCreated) 	req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{}).		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})	require.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)

Lines 1–500 of 610.