Compare commits

...

32 Commits

Author SHA1 Message Date
6543
b0849207ef
Merge a48eb669ecdeeb4ae7fb9a54e90bf06f90cb163d into b907b9fb1a1a792b9bc25112fa3eb3f8d2fb4397 2025-10-02 02:42:50 +00:00
m.huber
a48eb669ec optional 2025-10-02 04:42:44 +02:00
6543
cf290d4fdd
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-10-01 23:17:04 +02:00
silverwind
b907b9fb1a
Enable a few more tsconfig options (#35553)
Enable a few more useful options in tsconfig. `noImplicitReturns` had
two cases which I've fixed. Also, partially sort the file.
2025-09-30 21:43:41 -07:00
dependabot[bot]
c5d74e5869
Bump github.com/wneessen/go-mail from 0.6.2 to 0.7.1 (#35557) 2025-10-01 00:14:53 +00:00
6543
b6f88a77d5
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-21 01:57:13 +02:00
6543
e04b429038
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-18 09:49:55 +02:00
m.huber
dbfba370a7 fix and extend test 2025-09-17 01:24:56 +02:00
6543
14bd6af454 make tests pass again 2025-09-16 20:14:03 +02:00
6543
4ddb6545f8
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-16 16:24:36 +02:00
6543
7b2bb24d32 moved to https://github.com/go-gitea/gitea/pull/35500 2025-09-16 16:24:01 +02:00
6543
90c79728d2
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-14 12:28:17 +02:00
6543
557fe10ded
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-08 09:24:55 +02:00
6543
c8ecc758cb
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-07 14:32:38 +02:00
6543
c2e67a92c7
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-04 07:08:52 +02:00
6543
acfe4ba67e
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-01 19:52:54 +02:00
6543
9154b6c9c2
Update models/issues/pull_test.go
Signed-off-by: 6543 <6543@obermui.de>
2025-09-01 16:21:34 +02:00
m.huber
a9c3366f44 adjust tests (4) 2025-09-01 16:20:04 +02:00
m.huber
9afe171113 adjust tests (3) 2025-09-01 16:05:23 +02:00
6543
bfb4f02a1d
Apply suggestions from code review
Signed-off-by: 6543 <6543@obermui.de>
2025-09-01 15:47:35 +02:00
m.huber
64800836c0 adjust tests (2) 2025-09-01 15:44:24 +02:00
m.huber
3d5913bdfd adjust tests (1) 2025-09-01 15:42:37 +02:00
m.huber
1f70222aec add error edgecase where dismissed is before an review request 2025-09-01 14:59:24 +02:00
m.huber
ce22adfc52 fixtures add dismissed review case 2025-09-01 14:44:59 +02:00
6543
d232dbca3b
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-09-01 14:33:15 +02:00
6543
50b9ea0c30
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-08-20 14:11:46 +02:00
6543
5df9e30ffb
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-08-19 19:40:16 +02:00
6543
84bcdbf6ea
Merge branch 'main' into fix-remove-stale-reviewrequests 2025-08-18 18:11:42 +02:00
m.huber
e28f23a072 fix 2025-08-18 16:57:20 +02:00
m.huber
5cd8a64a80 Merge branch 'main' into fix-remove-stale-reviewrequests 2025-08-18 16:57:11 +02:00
m.huber
86dde8219e Merge branch 'main' into fix-remove-stale-reviewrequests 2025-08-11 13:48:41 +02:00
m.huber
823518f8ae filter dismissed via sql more & make it possible to have review requests falsly stayed in DB deleted 2025-01-22 16:18:26 +01:00
13 changed files with 120 additions and 55 deletions

6
go.mod
View File

@ -109,7 +109,7 @@ require (
github.com/ulikunitz/xz v0.5.15
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
github.com/urfave/cli/v3 v3.4.1
github.com/wneessen/go-mail v0.6.2
github.com/wneessen/go-mail v0.7.1
github.com/xeipuuv/gojsonschema v1.2.0
github.com/yohcop/openid-go v1.0.1
github.com/yuin/goldmark v1.7.13
@ -120,9 +120,9 @@ require (
golang.org/x/image v0.30.0
golang.org/x/net v0.43.0
golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.16.0
golang.org/x/sync v0.17.0
golang.org/x/sys v0.35.0
golang.org/x/text v0.28.0
golang.org/x/text v0.29.0
google.golang.org/grpc v1.75.0
google.golang.org/protobuf v1.36.8
gopkg.in/ini.v1 v1.67.0

17
go.sum
View File

@ -765,8 +765,8 @@ github.com/urfave/cli/v3 v3.4.1/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZ
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/wneessen/go-mail v0.6.2 h1:c6V7c8D2mz868z9WJ+8zDKtUyLfZ1++uAZmo2GRFji8=
github.com/wneessen/go-mail v0.6.2/go.mod h1:L/PYjPK3/2ZlNb2/FjEBIn9n1rUWjW+Toy531oVmeb4=
github.com/wneessen/go-mail v0.7.1 h1:rvy63sp14N06/kdGqCYwW8Na5gDCXjTQM1E7So4PuKk=
github.com/wneessen/go-mail v0.7.1/go.mod h1:+TkW6QP3EVkgTEqHtVmnAE/1MRhmzb8Y9/W3pweuS+k=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
@ -837,7 +837,6 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -930,9 +929,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -974,7 +972,6 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
@ -987,7 +984,6 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1003,9 +999,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=

View File

@ -207,6 +207,17 @@
-
id: 22
type: 1
reviewer_id: 5
issue_id: 3
content: "review accepted of user5 but dismissed"
original_author_id: 0
updated_unix: 946684000
created_unix: 946684000
dismissed: true
-
id: 23
type: 4
reviewer_id: 5
issue_id: 3
@ -214,3 +225,26 @@
original_author_id: 0
updated_unix: 946684817
created_unix: 946684817
-
id: 24
type: 3
reviewer_id: 5
issue_id: 3
content: "review rejected of user5 but dismissed"
original_author_id: 0
updated_unix: 946684827
created_unix: 946684827
dismissed: true
-
id: 25
type: 3
reviewer_id: 15
reviewer_team_id: 0
issue_id: 3
content: "review rejected by user15 but dismissed"
original_author_id: 0
updated_unix: 946684899
created_unix: 946684899
dismissed: true

View File

@ -52,12 +52,12 @@ func TestPullRequestList_LoadReviews(t *testing.T) {
}
reviewList, err := prs.LoadReviews(t.Context())
assert.NoError(t, err)
// 1, 7, 8, 9, 10, 22
// 1, 7, 8, 9, 10, 23
assert.Len(t, reviewList, 6)
assert.EqualValues(t, 1, reviewList[0].ID)
assert.EqualValues(t, 7, reviewList[1].ID)
assert.EqualValues(t, 8, reviewList[2].ID)
assert.EqualValues(t, 9, reviewList[3].ID)
assert.EqualValues(t, 10, reviewList[4].ID)
assert.EqualValues(t, 22, reviewList[5].ID)
assert.EqualValues(t, 23, reviewList[5].ID)
}

View File

@ -348,6 +348,22 @@ func TestGetApprovers(t *testing.T) {
approvers := pr.GetApprovers(t.Context())
expected := "Reviewed-by: User Five <user5@example.com>\nReviewed-by: Org Six <org6@example.com>\n"
assert.Equal(t, expected, approvers)
// comment-type and pending reviews should be ignored
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
assert.EqualValues(t, 3, pr.IssueID)
setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly = false
approvers = pr.GetApprovers(t.Context())
expected = "Reviewed-by: User Five <user5@example.com>\nReviewed-by: user4 <user4@example.com>\n"
assert.Equal(t, expected, approvers)
// un-official reviews should now be ignored too
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
assert.EqualValues(t, 3, pr.IssueID)
setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly = true
approvers = pr.GetApprovers(t.Context())
expected = ""
assert.Equal(t, expected, approvers)
}
func TestGetPullRequestByMergedCommit(t *testing.T) {

View File

@ -17,6 +17,7 @@ import (
access_model "code.gitea.io/gitea/models/perm/access"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
@ -390,6 +391,7 @@ func GetCurrentReview(ctx context.Context, reviewer *user_model.User, issue *Iss
Types: []ReviewType{ReviewTypePending},
IssueID: issue.ID,
ReviewerID: reviewer.ID,
Dismissed: optional.Some(false),
})
if err != nil {
return nil, err
@ -532,12 +534,18 @@ func SubmitReview(ctx context.Context, doer *user_model.User, issue *Issue, revi
}
// GetReviewByIssueIDAndUserID get the latest review of reviewer for a pull request
func GetReviewByIssueIDAndUserID(ctx context.Context, issueID, userID int64) (*Review, error) {
func GetReviewByIssueIDAndUserID(ctx context.Context, issueID, userID int64, dismissed optional.Option[bool]) (*Review, error) {
review := new(Review)
has, err := db.GetEngine(ctx).Where(
builder.In("type", ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
And(builder.Eq{"issue_id": issueID, "reviewer_id": userID, "original_author_id": 0})).
cond := builder.In("type", ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
And(builder.Eq{"issue_id": issueID, "reviewer_id": userID, "original_author_id": 0})
// apply optional filter for dismissed
if dismissed.Has() {
cond = cond.And(builder.Eq{"dismissed": dismissed.Value()})
}
has, err := db.GetEngine(ctx).Where(cond).
Desc("id").
Get(review)
if err != nil {
@ -647,7 +655,7 @@ func AddReviewRequest(ctx context.Context, issue *Issue, reviewer, doer *user_mo
return db.WithTx2(ctx, func(ctx context.Context) (*Comment, error) {
sess := db.GetEngine(ctx)
review, err := GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID)
review, err := GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID, optional.None[bool]())
if err != nil && !IsErrReviewNotExist(err) {
return nil, err
}
@ -717,7 +725,7 @@ func AddReviewRequest(ctx context.Context, issue *Issue, reviewer, doer *user_mo
// RemoveReviewRequest remove a review request from one reviewer
func RemoveReviewRequest(ctx context.Context, issue *Issue, reviewer, doer *user_model.User) (*Comment, error) {
return db.WithTx2(ctx, func(ctx context.Context) (*Comment, error) {
review, err := GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID)
review, err := GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID, optional.Some(false))
if err != nil && !IsErrReviewNotExist(err) {
return nil, err
}
@ -752,7 +760,7 @@ func RemoveReviewRequest(ctx context.Context, issue *Issue, reviewer, doer *user
// Recalculate the latest official review for reviewer
func restoreLatestOfficialReview(ctx context.Context, issueID, reviewerID int64) error {
review, err := GetReviewByIssueIDAndUserID(ctx, issueID, reviewerID)
review, err := GetReviewByIssueIDAndUserID(ctx, issueID, reviewerID, optional.None[bool]())
if err != nil && !IsErrReviewNotExist(err) {
return err
}
@ -844,7 +852,7 @@ func RemoveTeamReviewRequest(ctx context.Context, issue *Issue, reviewer *organi
if official {
// recalculate which is the latest official review from that team
review, err := GetReviewByIssueIDAndUserID(ctx, issue.ID, -reviewer.ID)
review, err := GetReviewByIssueIDAndUserID(ctx, issue.ID, -reviewer.ID, optional.None[bool]())
if err != nil && !IsErrReviewNotExist(err) {
return nil, err
}

View File

@ -163,7 +163,7 @@ func GetReviewsByIssueID(ctx context.Context, issueID int64) (latestReviews, mig
reviews := make([]*Review, 0, 10)
// Get all reviews for the issue id
if err := db.GetEngine(ctx).Where("issue_id=?", issueID).OrderBy("updated_unix ASC").Find(&reviews); err != nil {
if err := db.GetEngine(ctx).Where("issue_id=? AND dismissed=?", issueID, false).OrderBy("updated_unix ASC").Find(&reviews); err != nil {
return nil, nil, err
}
@ -175,7 +175,7 @@ func GetReviewsByIssueID(ctx context.Context, issueID int64) (latestReviews, mig
reviewTeamsMap := make(map[int64][]*Review) // key is reviewer team id
countedReivewTypes := []ReviewType{ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest}
for _, review := range reviews {
if review.ReviewerTeamID == 0 && slices.Contains(countedReivewTypes, review.Type) && !review.Dismissed {
if review.ReviewerTeamID == 0 && slices.Contains(countedReivewTypes, review.Type) {
if review.OriginalAuthorID != 0 {
originalReviewersMap[review.OriginalAuthorID] = append(originalReviewersMap[review.OriginalAuthorID], review)
} else {

View File

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
notify_service "code.gitea.io/gitea/services/notify"
)
@ -116,7 +117,7 @@ func isValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User,
}
}
lastReview, err := issues_model.GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID)
lastReview, err := issues_model.GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID, optional.None[bool]())
if err != nil && !issues_model.IsErrReviewNotExist(err) {
return err
}

View File

@ -30,6 +30,7 @@ import (
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
@ -1086,6 +1087,7 @@ func GetPullCommits(ctx context.Context, baseGitRepo *git.Repository, doer *user
issues_model.ReviewTypeComment,
issues_model.ReviewTypeReject,
},
Dismissed: optional.Some(false),
})
if err != nil && !issues_model.IsErrReviewNotExist(err) {

View File

@ -40,23 +40,28 @@ func TestAPIPullReview(t *testing.T) {
var reviews []*api.PullReview
DecodeJSON(t, resp, &reviews)
require.Len(t, reviews, 8)
require.Len(t, reviews, 11)
for _, r := range reviews {
assert.Equal(t, pullIssue.HTMLURL(t.Context()), 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)
if assert.EqualValues(t, 8, reviews[4].ID) {
assert.EqualValues(t, "APPROVED", reviews[4].State)
assert.Equal(t, 0, reviews[4].CodeCommentsCount)
assert.True(t, reviews[4].Stale)
assert.False(t, reviews[4].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)
if assert.EqualValues(t, 10, reviews[6].ID) {
assert.EqualValues(t, "REQUEST_CHANGES", reviews[6].State)
assert.Equal(t, 1, reviews[6].CodeCommentsCount)
assert.EqualValues(t, -1, reviews[6].Reviewer.ID) // ghost user
assert.False(t, reviews[6].Stale)
assert.True(t, reviews[6].Official)
}
if assert.EqualValues(t, 25, reviews[10].ID) {
assert.True(t, reviews[10].Dismissed)
}
// 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).

View File

@ -1,7 +1,7 @@
{
"include": [
"${configDir}/.*",
"${configDir}/*",
"${configDir}/.*",
"${configDir}/tests/e2e/**/*",
"${configDir}/tests/e2e/**/.*",
"${configDir}/tools/**/*",
@ -17,27 +17,31 @@
"allowImportingTsExtensions": true,
"allowJs": true,
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"alwaysStrict": true,
"erasableSyntaxOnly": true,
"esModuleInterop": true,
"exactOptionalPropertyTypes": false,
"isolatedModules": true,
"libReplacement": false,
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noPropertyAccessFromIndexSignature": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"verbatimModuleSyntax": true,
"stripInternal": true,
"sourceMap": true,
"strict": false,
"strictBindCallApply": true,
"strictBuiltinIteratorReturn": true,
"strictFunctionTypes": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noPropertyAccessFromIndexSignature": false,
"exactOptionalPropertyTypes": false,
"sourceMap": true,
"stripInternal": true,
"verbatimModuleSyntax": true,
"types": [
"vitest/globals",
"./web_src/js/globals.d.ts",

View File

@ -10,7 +10,7 @@ export function initTableSort() {
}
function tableSort(normSort: string, revSort: string, isDefault: string) {
if (!normSort) return false;
if (!normSort) return;
if (!revSort) revSort = '';
const url = new URL(window.location.href);

View File

@ -43,7 +43,7 @@ type ToastOpts = {
type ToastifyElement = HTMLElement & {_giteaToastifyInstance?: Toast};
/** See https://github.com/apvarun/toastify-js#api for options */
function showToast(message: string, level: Intent, {gravity, position, duration, useHtmlBody, preventDuplicates = true, ...other}: ToastOpts = {}): Toast {
function showToast(message: string, level: Intent, {gravity, position, duration, useHtmlBody, preventDuplicates = true, ...other}: ToastOpts = {}): Toast | null {
const body = useHtmlBody ? message : htmlEscape(message);
const parent = document.querySelector('.ui.dimmer.active') ?? document.body;
const duplicateKey = preventDuplicates ? (preventDuplicates === true ? `${level}-${body}` : preventDuplicates) : '';
@ -56,7 +56,7 @@ function showToast(message: string, level: Intent, {gravity, position, duration,
showElem(toastDupNumEl);
toastDupNumEl.textContent = String(Number(toastDupNumEl.textContent) + 1);
animateOnce(toastDupNumEl, 'pulse-1p5-200');
return;
return null;
}
}
@ -83,15 +83,15 @@ function showToast(message: string, level: Intent, {gravity, position, duration,
return toast;
}
export function showInfoToast(message: string, opts?: ToastOpts): Toast {
export function showInfoToast(message: string, opts?: ToastOpts): Toast | null {
return showToast(message, 'info', opts);
}
export function showWarningToast(message: string, opts?: ToastOpts): Toast {
export function showWarningToast(message: string, opts?: ToastOpts): Toast | null {
return showToast(message, 'warning', opts);
}
export function showErrorToast(message: string, opts?: ToastOpts): Toast {
export function showErrorToast(message: string, opts?: ToastOpts): Toast | null {
return showToast(message, 'error', opts);
}