From 4317b416980c83970e4d741d1aa7dd86ef0ae85c Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Fri, 23 May 2025 10:38:10 +0200 Subject: [PATCH 1/9] Add sort option recentclose for issues and pulls --- models/fixtures/issue.yml | 54 ++++++++++++++++++++++++++++++++ models/fixtures/pull_request.yml | 30 ++++++++++++++++++ models/fixtures/repository.yml | 31 ++++++++++++++++++ models/issues/issue_search.go | 2 ++ models/issues/issue_test.go | 2 +- models/issues/pull_test.go | 46 +++++++++++++++++++++++++++ 6 files changed, 164 insertions(+), 1 deletion(-) diff --git a/models/fixtures/issue.yml b/models/fixtures/issue.yml index ca5b1c6cd1df5..29a302c705969 100644 --- a/models/fixtures/issue.yml +++ b/models/fixtures/issue.yml @@ -372,3 +372,57 @@ created_unix: 1707270422 updated_unix: 1707270422 is_locked: false + +- + id: 23 + repo_id: 63 + index: 1 + poster_id: 40 + original_author_id: 0 + name: repo62 pull1 + content: this pr is created, merged and updated first + milestone_id: 0 + priority: 0 + is_closed: true + is_pull: true + num_comments: 0 + created_unix: 1707270000 + updated_unix: 1707270001 + closed_unix: 1707270001 + is_locked: false + +- + id: 24 + repo_id: 63 + index: 2 + poster_id: 40 + original_author_id: 0 + name: repo62 pull2 + content: this pr is created and merged second but updated latest + milestone_id: 0 + priority: 0 + is_closed: true + is_pull: true + num_comments: 0 + created_unix: 1707270001 + updated_unix: 1707279999 + closed_unix: 1707271000 + is_locked: false + +- + id: 25 + repo_id: 63 + index: 3 + poster_id: 40 + original_author_id: 0 + name: repo62 pull3 + content: this pr is created, merged latest but updated before merge + milestone_id: 0 + priority: 0 + is_closed: true + is_pull: true + num_comments: 0 + created_unix: 1707279999 + updated_unix: 1707275555 + closed_unix: 1707279999 + is_locked: false diff --git a/models/fixtures/pull_request.yml b/models/fixtures/pull_request.yml index 9a16316e5a2b4..e18ca6d573386 100644 --- a/models/fixtures/pull_request.yml +++ b/models/fixtures/pull_request.yml @@ -117,3 +117,33 @@ index: 1 head_repo_id: 61 base_repo_id: 61 + +- + id: 11 + issue_id: 23 + type: 0 # gitea pull request + index: 1 + head_repo_id: 63 + base_repo_id: 63 + has_merged: true + merged_unix: 1707270001 + +- + id: 12 + issue_id: 24 + type: 0 # gitea pull request + index: 2 + head_repo_id: 63 + base_repo_id: 63 + has_merged: true + merged_unix: 1707271000 # merged before someone commented again + +- + id: 13 + issue_id: 25 + type: 0 # gitea pull request + index: 3 + head_repo_id: 63 + base_repo_id: 63 + has_merged: true + merged_unix: 1707279999 diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 552a78cbd2773..af7b56943d92d 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -1786,3 +1786,34 @@ size: 0 is_fsck_enabled: true close_issues_via_commit_in_any_branch: false + +- + id: 63 + owner_id: 42 + owner_name: org42 + lower_name: listprsort + name: listprsort + default_branch: master + num_watches: 0 + num_stars: 0 + num_forks: 0 + num_issues: 0 + num_closed_issues: 0 + num_pulls: 3 + num_closed_pulls: 3 + num_milestones: 0 + num_closed_milestones: 0 + num_projects: 0 + num_closed_projects: 0 + is_private: false + is_empty: false + is_archived: false + is_mirror: false + status: 0 + is_fork: false + fork_id: 0 + is_template: false + template_id: 0 + size: 0 + is_fsck_enabled: true + close_issues_via_commit_in_any_branch: false diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index f9e1fbeb146de..16f808acd14f5 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -88,6 +88,8 @@ func applySorts(sess *xorm.Session, sortType string, priorityRepoID int64) { sess.Asc("issue.created_unix").Asc("issue.id") case "recentupdate": sess.Desc("issue.updated_unix").Desc("issue.created_unix").Desc("issue.id") + case "recentclose": + sess.Desc("issue.closed_unix").Desc("issue.created_unix").Desc("issue.id") case "leastupdate": sess.Asc("issue.updated_unix").Asc("issue.created_unix").Asc("issue.id") case "mostcomment": diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 18571e3aaa1bc..8de0576c7e2ac 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -378,7 +378,7 @@ func TestCountIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{}) assert.NoError(t, err) - assert.EqualValues(t, 22, count) + assert.EqualValues(t, 25, count) } func TestIssueLoadAttributes(t *testing.T) { diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 8e09030215e0e..99925335d0ec4 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -76,6 +76,52 @@ func TestPullRequestsNewest(t *testing.T) { } } +func TestPullRequestsRecentClosed(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + prs, _, err := issues_model.PullRequests(db.DefaultContext, 63, &issues_model.PullRequestsOptions{ + ListOptions: db.ListOptions{ + Page: 1, + }, + State: "closed", + SortType: "recentclose", + }) + assert.NoError(t, err) + + // Pull ID | Closed At. | Updated At + // 11 | 1707270001 | 1707270001 + // 12 | 1707271000 | 1707279999 + // 13 | 1707279999 | 1707275555 + + if assert.Len(t, prs, 3) { + assert.EqualValues(t, 13, prs[0].ID) + assert.EqualValues(t, 12, prs[1].ID) + assert.EqualValues(t, 11, prs[2].ID) + } +} + +func TestPullRequestsRecentUpdate(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + prs, _, err := issues_model.PullRequests(db.DefaultContext, 63, &issues_model.PullRequestsOptions{ + ListOptions: db.ListOptions{ + Page: 1, + }, + State: "closed", + SortType: "recentupdate", + }) + assert.NoError(t, err) + + // Pull ID | Closed At. | Updated At + // 11 | 1707270001 | 1707270001 + // 12 | 1707271000 | 1707279999 + // 13 | 1707279999 | 1707275555 + + if assert.Len(t, prs, 3) { + assert.EqualValues(t, 12, prs[0].ID) + assert.EqualValues(t, 13, prs[1].ID) + assert.EqualValues(t, 11, prs[2].ID) + } +} + func TestLoadRequestedReviewers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) From b60950f412769a55f1cf511b55a5f62fd3e984b2 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Fri, 23 May 2025 11:12:21 +0200 Subject: [PATCH 2/9] Fix consistency tests --- models/fixtures/user.yml | 2 +- models/repo/repo_list_test.go | 6 +++--- modules/indexer/issues/indexer_test.go | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 976a236011cc9..9ea477e7f39d9 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -1549,7 +1549,7 @@ num_followers: 0 num_following: 0 num_stars: 0 - num_repos: 1 + num_repos: 2 num_teams: 0 num_members: 0 visibility: 0 diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go index ca6007f6c7882..d14c1ae6b1f83 100644 --- a/models/repo/repo_list_test.go +++ b/models/repo/repo_list_test.go @@ -138,12 +138,12 @@ func getTestCases() []struct { { name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: optional.Some(false)}, - count: 34, + count: 35, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: optional.Some(false)}, - count: 39, + count: 40, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName", @@ -158,7 +158,7 @@ func getTestCases() []struct { { name: "AllPublic/PublicRepositoriesOfOrganization", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: optional.Some(false), Template: optional.Some(false)}, - count: 34, + count: 35, }, { name: "AllTemplates", diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 3e38ac49b719c..61d3a45d29fc1 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -190,7 +190,7 @@ func searchIssueByID(t *testing.T) { { // NOTE: This tests no assignees filtering and also ToSearchOptions() to ensure it handles the filter correctly opts: *ToSearchOptions("", &issues.IssuesOptions{AssigneeID: "(none)"}), - expectedIDs: []int64{22, 21, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2}, + expectedIDs: []int64{25, 22, 21, 24, 23, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2}, }, { opts: SearchOptions{ @@ -255,7 +255,7 @@ func searchIssueIsPull(t *testing.T) { SearchOptions{ IsPull: optional.Some(true), }, - []int64{22, 21, 12, 11, 20, 19, 9, 8, 3, 2}, + []int64{25, 22, 21, 24, 23, 12, 11, 20, 19, 9, 8, 3, 2}, }, } for _, test := range tests { @@ -280,7 +280,7 @@ func searchIssueIsClosed(t *testing.T) { SearchOptions{ IsClosed: optional.Some(true), }, - []int64{5, 4}, + []int64{25, 24, 23, 5, 4}, }, } for _, test := range tests { @@ -299,7 +299,7 @@ func searchIssueIsArchived(t *testing.T) { SearchOptions{ IsArchived: optional.Some(false), }, - []int64{22, 21, 17, 16, 15, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, + []int64{25, 22, 21, 24, 23, 17, 16, 15, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, }, { SearchOptions{ @@ -361,7 +361,7 @@ func searchIssueByLabelID(t *testing.T) { SearchOptions{ ExcludedLabelIDs: []int64{1}, }, - []int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3}, + []int64{25, 22, 21, 24, 23, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3}, }, } for _, test := range tests { @@ -380,7 +380,7 @@ func searchIssueByTime(t *testing.T) { SearchOptions{ UpdatedAfterUnix: optional.Some(int64(0)), }, - []int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, + []int64{25, 22, 21, 24, 23, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, }, } for _, test := range tests { @@ -399,7 +399,7 @@ func searchIssueWithOrder(t *testing.T) { SearchOptions{ SortBy: internal.SortByCreatedAsc, }, - []int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 21, 22}, + []int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 23, 24, 21, 22, 25}, }, } for _, test := range tests { @@ -452,8 +452,8 @@ func searchIssueWithPaginator(t *testing.T) { PageSize: 5, }, }, - []int64{22, 21, 17, 16, 15}, - 22, + []int64{25, 22, 21, 24, 23}, + 25, }, } for _, test := range tests { From 6ea3918b4329e3af4d66d9e6e6d983bab64968e6 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Fri, 23 May 2025 11:23:52 +0200 Subject: [PATCH 3/9] Re-generate swagger --- routers/api/v1/repo/pull.go | 2 +- templates/swagger/v1_json.tmpl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index f1ba06dd4ab8a..d1bcaefb5227c 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -73,7 +73,7 @@ func ListPullRequests(ctx *context.APIContext) { // in: query // description: Type of sort // type: string - // enum: [oldest, recentupdate, leastupdate, mostcomment, leastcomment, priority] + // enum: [oldest, recentupdate, recentclose, leastupdate, mostcomment, leastcomment, priority] // - name: milestone // in: query // description: ID of the milestone diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index c97e52566050f..e4003816b4eeb 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -12871,6 +12871,7 @@ "enum": [ "oldest", "recentupdate", + "recentclose", "leastupdate", "mostcomment", "leastcomment", From 160a6dd295fb4071898702555c1cbee314385a4e Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Fri, 23 May 2025 12:23:00 +0200 Subject: [PATCH 4/9] Fix more integration tests --- tests/integration/api_issue_test.go | 4 ++-- tests/integration/api_nodeinfo_test.go | 2 +- tests/integration/api_repo_test.go | 6 +++--- tests/integration/issue_test.go | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index e035f7200b0bc..6c6453f33b4a7 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -313,7 +313,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 20) query.Add("limit", "10") @@ -321,7 +321,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 10) query = url.Values{"assigned": {"true"}, "state": {"all"}} diff --git a/tests/integration/api_nodeinfo_test.go b/tests/integration/api_nodeinfo_test.go index 916c2f1723102..aa0500b9bbd84 100644 --- a/tests/integration/api_nodeinfo_test.go +++ b/tests/integration/api_nodeinfo_test.go @@ -30,6 +30,6 @@ func TestNodeinfo(t *testing.T) { assert.True(t, nodeinfo.OpenRegistrations) assert.Equal(t, "gitea", nodeinfo.Software.Name) assert.Equal(t, 29, nodeinfo.Usage.Users.Total) - assert.Equal(t, 22, nodeinfo.Usage.LocalPosts) + assert.Equal(t, 25, nodeinfo.Usage.LocalPosts) assert.Equal(t, 3, nodeinfo.Usage.LocalComments) } diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index 672c2a2c8bf9b..df8de083ca087 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -94,9 +94,9 @@ func TestAPISearchRepo(t *testing.T) { }{ { name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{ - nil: {count: 36}, - user: {count: 36}, - user2: {count: 36}, + nil: {count: 37}, + user: {count: 37}, + user2: {count: 37}, }, }, { diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index b403b3cf175d3..6f60dafaada83 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -512,14 +512,14 @@ func TestSearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 2) + assert.Len(t, apiIssues, 5) query.Set("state", "all") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 20) query.Add("limit", "5") @@ -527,7 +527,7 @@ func TestSearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 5) query = url.Values{"assigned": {"true"}, "state": {"all"}} From 88dc237dfad49e8c718943b86d330e8342d5751a Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Fri, 23 May 2025 14:13:35 +0200 Subject: [PATCH 5/9] Fix search issues test --- tests/integration/api_issue_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index 6c6453f33b4a7..0f0892158a107 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -306,7 +306,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 2) + assert.Len(t, apiIssues, 5) query.Set("state", "all") link.RawQuery = query.Encode() From 3d58727138d8ad2455ed537300e2be63d8e5f7d2 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Sun, 25 May 2025 17:54:32 +0200 Subject: [PATCH 6/9] Remove new testdata --- models/fixtures/issue.yml | 54 ------------------ models/fixtures/pull_request.yml | 30 ---------- models/fixtures/repository.yml | 31 ----------- models/fixtures/user.yml | 2 +- models/issues/issue_test.go | 2 +- models/issues/pull_list.go | 3 +- models/issues/pull_test.go | 76 ++++++++++++-------------- models/repo/release.go | 61 ++++++++++++++++++--- models/repo/repo_list_test.go | 6 +- modules/indexer/issues/indexer_test.go | 18 +++--- tests/integration/api_issue_test.go | 6 +- tests/integration/api_nodeinfo_test.go | 2 +- tests/integration/api_repo_test.go | 6 +- tests/integration/issue_test.go | 6 +- 14 files changed, 116 insertions(+), 187 deletions(-) diff --git a/models/fixtures/issue.yml b/models/fixtures/issue.yml index 29a302c705969..ca5b1c6cd1df5 100644 --- a/models/fixtures/issue.yml +++ b/models/fixtures/issue.yml @@ -372,57 +372,3 @@ created_unix: 1707270422 updated_unix: 1707270422 is_locked: false - -- - id: 23 - repo_id: 63 - index: 1 - poster_id: 40 - original_author_id: 0 - name: repo62 pull1 - content: this pr is created, merged and updated first - milestone_id: 0 - priority: 0 - is_closed: true - is_pull: true - num_comments: 0 - created_unix: 1707270000 - updated_unix: 1707270001 - closed_unix: 1707270001 - is_locked: false - -- - id: 24 - repo_id: 63 - index: 2 - poster_id: 40 - original_author_id: 0 - name: repo62 pull2 - content: this pr is created and merged second but updated latest - milestone_id: 0 - priority: 0 - is_closed: true - is_pull: true - num_comments: 0 - created_unix: 1707270001 - updated_unix: 1707279999 - closed_unix: 1707271000 - is_locked: false - -- - id: 25 - repo_id: 63 - index: 3 - poster_id: 40 - original_author_id: 0 - name: repo62 pull3 - content: this pr is created, merged latest but updated before merge - milestone_id: 0 - priority: 0 - is_closed: true - is_pull: true - num_comments: 0 - created_unix: 1707279999 - updated_unix: 1707275555 - closed_unix: 1707279999 - is_locked: false diff --git a/models/fixtures/pull_request.yml b/models/fixtures/pull_request.yml index e18ca6d573386..9a16316e5a2b4 100644 --- a/models/fixtures/pull_request.yml +++ b/models/fixtures/pull_request.yml @@ -117,33 +117,3 @@ index: 1 head_repo_id: 61 base_repo_id: 61 - -- - id: 11 - issue_id: 23 - type: 0 # gitea pull request - index: 1 - head_repo_id: 63 - base_repo_id: 63 - has_merged: true - merged_unix: 1707270001 - -- - id: 12 - issue_id: 24 - type: 0 # gitea pull request - index: 2 - head_repo_id: 63 - base_repo_id: 63 - has_merged: true - merged_unix: 1707271000 # merged before someone commented again - -- - id: 13 - issue_id: 25 - type: 0 # gitea pull request - index: 3 - head_repo_id: 63 - base_repo_id: 63 - has_merged: true - merged_unix: 1707279999 diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index af7b56943d92d..552a78cbd2773 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -1786,34 +1786,3 @@ size: 0 is_fsck_enabled: true close_issues_via_commit_in_any_branch: false - -- - id: 63 - owner_id: 42 - owner_name: org42 - lower_name: listprsort - name: listprsort - default_branch: master - num_watches: 0 - num_stars: 0 - num_forks: 0 - num_issues: 0 - num_closed_issues: 0 - num_pulls: 3 - num_closed_pulls: 3 - num_milestones: 0 - num_closed_milestones: 0 - num_projects: 0 - num_closed_projects: 0 - is_private: false - is_empty: false - is_archived: false - is_mirror: false - status: 0 - is_fork: false - fork_id: 0 - is_template: false - template_id: 0 - size: 0 - is_fsck_enabled: true - close_issues_via_commit_in_any_branch: false diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 9ea477e7f39d9..976a236011cc9 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -1549,7 +1549,7 @@ num_followers: 0 num_following: 0 num_stars: 0 - num_repos: 2 + num_repos: 1 num_teams: 0 num_members: 0 visibility: 0 diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 8de0576c7e2ac..18571e3aaa1bc 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -378,7 +378,7 @@ func TestCountIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{}) assert.NoError(t, err) - assert.EqualValues(t, 25, count) + assert.EqualValues(t, 22, count) } func TestIssueLoadAttributes(t *testing.T) { diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go index b685175f8e324..84f9f6166d1fb 100644 --- a/models/issues/pull_list.go +++ b/models/issues/pull_list.go @@ -152,7 +152,8 @@ func PullRequests(ctx context.Context, baseRepoID int64, opts *PullRequestsOptio applySorts(findSession, opts.SortType, 0) findSession = db.SetSessionPagination(findSession, opts) prs := make([]*PullRequest, 0, opts.PageSize) - return prs, maxResults, findSession.Find(&prs) + found := findSession.Find(&prs) + return prs, maxResults, found } // PullRequestList defines a list of pull requests diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 99925335d0ec4..06f5b79c757db 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -4,6 +4,7 @@ package issues_test import ( + "github.com/stretchr/testify/require" "testing" "code.gitea.io/gitea/models/db" @@ -76,49 +77,44 @@ func TestPullRequestsNewest(t *testing.T) { } } -func TestPullRequestsRecentClosed(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - prs, _, err := issues_model.PullRequests(db.DefaultContext, 63, &issues_model.PullRequestsOptions{ - ListOptions: db.ListOptions{ - Page: 1, - }, - State: "closed", - SortType: "recentclose", - }) - assert.NoError(t, err) - - // Pull ID | Closed At. | Updated At - // 11 | 1707270001 | 1707270001 - // 12 | 1707271000 | 1707279999 - // 13 | 1707279999 | 1707275555 - - if assert.Len(t, prs, 3) { - assert.EqualValues(t, 13, prs[0].ID) - assert.EqualValues(t, 12, prs[1].ID) - assert.EqualValues(t, 11, prs[2].ID) +func TestPullRequests_Closed_RecentSortType(t *testing.T) { + // Issue ID | Closed At. | Updated At + // 2 | 1707270001 | 1707270001 + // 3 | 1707271000 | 1707279999 + // 11 | 1707279999 | 1707275555 + tests := []struct { + sortType string + expectedIssueIdOrder []int64 + }{ + {"recentupdate", []int64{3, 11, 2}}, + {"recentclose", []int64{11, 3, 2}}, } -} -func TestPullRequestsRecentUpdate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, _, err := issues_model.PullRequests(db.DefaultContext, 63, &issues_model.PullRequestsOptions{ - ListOptions: db.ListOptions{ - Page: 1, - }, - State: "closed", - SortType: "recentupdate", - }) - assert.NoError(t, err) - - // Pull ID | Closed At. | Updated At - // 11 | 1707270001 | 1707270001 - // 12 | 1707271000 | 1707279999 - // 13 | 1707279999 | 1707275555 - - if assert.Len(t, prs, 3) { - assert.EqualValues(t, 12, prs[0].ID) - assert.EqualValues(t, 13, prs[1].ID) - assert.EqualValues(t, 11, prs[2].ID) + _, err := db.Exec(db.DefaultContext, "UPDATE issue SET closed_unix = 1707270001, updated_unix = 1707270001, is_closed = true WHERE id = 2") + require.NoError(t, err) + _, err = db.Exec(db.DefaultContext, "UPDATE issue SET closed_unix = 1707271000, updated_unix = 1707279999, is_closed = true WHERE id = 3") + require.NoError(t, err) + _, err = db.Exec(db.DefaultContext, "UPDATE issue SET closed_unix = 1707279999, updated_unix = 1707275555, is_closed = true WHERE id = 11") + require.NoError(t, err) + + for _, test := range tests { + t.Run(test.sortType, func(t *testing.T) { + prs, _, err := issues_model.PullRequests(db.DefaultContext, 1, &issues_model.PullRequestsOptions{ + ListOptions: db.ListOptions{ + Page: 1, + }, + State: "closed", + SortType: test.sortType, + }) + require.NoError(t, err) + + if assert.Len(t, prs, len(test.expectedIssueIdOrder)) { + for i := range test.expectedIssueIdOrder { + assert.EqualValues(t, test.expectedIssueIdOrder[i], prs[i].IssueID) + } + } + }) } } diff --git a/models/repo/release.go b/models/repo/release.go index 06cfa3734288c..663d310bc027d 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -161,11 +161,6 @@ func UpdateRelease(ctx context.Context, rel *Release) error { return err } -func UpdateReleaseNumCommits(ctx context.Context, rel *Release) error { - _, err := db.GetEngine(ctx).ID(rel.ID).Cols("num_commits").Update(rel) - return err -} - // AddReleaseAttachments adds a release attachments func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { // Check attachments @@ -423,8 +418,8 @@ func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs. return err } -// PushUpdateDeleteTags updates a number of delete tags with context -func PushUpdateDeleteTags(ctx context.Context, repo *Repository, tags []string) error { +// PushUpdateDeleteTagsContext updates a number of delete tags with context +func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error { if len(tags) == 0 { return nil } @@ -453,6 +448,58 @@ func PushUpdateDeleteTags(ctx context.Context, repo *Repository, tags []string) return nil } +// PushUpdateDeleteTag must be called for any push actions to delete tag +func PushUpdateDeleteTag(ctx context.Context, repo *Repository, tagName string) error { + rel, err := GetRelease(ctx, repo.ID, tagName) + if err != nil { + if IsErrReleaseNotExist(err) { + return nil + } + return fmt.Errorf("GetRelease: %w", err) + } + if rel.IsTag { + if _, err = db.DeleteByID[Release](ctx, rel.ID); err != nil { + return fmt.Errorf("Delete: %w", err) + } + } else { + rel.IsDraft = true + rel.NumCommits = 0 + rel.Sha1 = "" + if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil { + return fmt.Errorf("Update: %w", err) + } + } + + return nil +} + +// SaveOrUpdateTag must be called for any push actions to add tag +func SaveOrUpdateTag(ctx context.Context, repo *Repository, newRel *Release) error { + rel, err := GetRelease(ctx, repo.ID, newRel.TagName) + if err != nil && !IsErrReleaseNotExist(err) { + return fmt.Errorf("GetRelease: %w", err) + } + + if rel == nil { + rel = newRel + if _, err = db.GetEngine(ctx).Insert(rel); err != nil { + return fmt.Errorf("InsertOne: %w", err) + } + } else { + rel.Sha1 = newRel.Sha1 + rel.CreatedUnix = newRel.CreatedUnix + rel.NumCommits = newRel.NumCommits + rel.IsDraft = false + if rel.IsTag && newRel.PublisherID > 0 { + rel.PublisherID = newRel.PublisherID + } + if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil { + return fmt.Errorf("Update: %w", err) + } + } + return nil +} + // RemapExternalUser ExternalUserRemappable interface func (r *Release) RemapExternalUser(externalName string, externalID, userID int64) error { r.OriginalAuthor = externalName diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go index d14c1ae6b1f83..ca6007f6c7882 100644 --- a/models/repo/repo_list_test.go +++ b/models/repo/repo_list_test.go @@ -138,12 +138,12 @@ func getTestCases() []struct { { name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: optional.Some(false)}, - count: 35, + count: 34, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: optional.Some(false)}, - count: 40, + count: 39, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName", @@ -158,7 +158,7 @@ func getTestCases() []struct { { name: "AllPublic/PublicRepositoriesOfOrganization", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: optional.Some(false), Template: optional.Some(false)}, - count: 35, + count: 34, }, { name: "AllTemplates", diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 61d3a45d29fc1..3e38ac49b719c 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -190,7 +190,7 @@ func searchIssueByID(t *testing.T) { { // NOTE: This tests no assignees filtering and also ToSearchOptions() to ensure it handles the filter correctly opts: *ToSearchOptions("", &issues.IssuesOptions{AssigneeID: "(none)"}), - expectedIDs: []int64{25, 22, 21, 24, 23, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2}, + expectedIDs: []int64{22, 21, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2}, }, { opts: SearchOptions{ @@ -255,7 +255,7 @@ func searchIssueIsPull(t *testing.T) { SearchOptions{ IsPull: optional.Some(true), }, - []int64{25, 22, 21, 24, 23, 12, 11, 20, 19, 9, 8, 3, 2}, + []int64{22, 21, 12, 11, 20, 19, 9, 8, 3, 2}, }, } for _, test := range tests { @@ -280,7 +280,7 @@ func searchIssueIsClosed(t *testing.T) { SearchOptions{ IsClosed: optional.Some(true), }, - []int64{25, 24, 23, 5, 4}, + []int64{5, 4}, }, } for _, test := range tests { @@ -299,7 +299,7 @@ func searchIssueIsArchived(t *testing.T) { SearchOptions{ IsArchived: optional.Some(false), }, - []int64{25, 22, 21, 24, 23, 17, 16, 15, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, + []int64{22, 21, 17, 16, 15, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, }, { SearchOptions{ @@ -361,7 +361,7 @@ func searchIssueByLabelID(t *testing.T) { SearchOptions{ ExcludedLabelIDs: []int64{1}, }, - []int64{25, 22, 21, 24, 23, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3}, + []int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3}, }, } for _, test := range tests { @@ -380,7 +380,7 @@ func searchIssueByTime(t *testing.T) { SearchOptions{ UpdatedAfterUnix: optional.Some(int64(0)), }, - []int64{25, 22, 21, 24, 23, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, + []int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, }, } for _, test := range tests { @@ -399,7 +399,7 @@ func searchIssueWithOrder(t *testing.T) { SearchOptions{ SortBy: internal.SortByCreatedAsc, }, - []int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 23, 24, 21, 22, 25}, + []int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 21, 22}, }, } for _, test := range tests { @@ -452,8 +452,8 @@ func searchIssueWithPaginator(t *testing.T) { PageSize: 5, }, }, - []int64{25, 22, 21, 24, 23}, - 25, + []int64{22, 21, 17, 16, 15}, + 22, }, } for _, test := range tests { diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index 0f0892158a107..e035f7200b0bc 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -306,14 +306,14 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 5) + assert.Len(t, apiIssues, 2) query.Set("state", "all") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 20) query.Add("limit", "10") @@ -321,7 +321,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 10) query = url.Values{"assigned": {"true"}, "state": {"all"}} diff --git a/tests/integration/api_nodeinfo_test.go b/tests/integration/api_nodeinfo_test.go index aa0500b9bbd84..916c2f1723102 100644 --- a/tests/integration/api_nodeinfo_test.go +++ b/tests/integration/api_nodeinfo_test.go @@ -30,6 +30,6 @@ func TestNodeinfo(t *testing.T) { assert.True(t, nodeinfo.OpenRegistrations) assert.Equal(t, "gitea", nodeinfo.Software.Name) assert.Equal(t, 29, nodeinfo.Usage.Users.Total) - assert.Equal(t, 25, nodeinfo.Usage.LocalPosts) + assert.Equal(t, 22, nodeinfo.Usage.LocalPosts) assert.Equal(t, 3, nodeinfo.Usage.LocalComments) } diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index df8de083ca087..672c2a2c8bf9b 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -94,9 +94,9 @@ func TestAPISearchRepo(t *testing.T) { }{ { name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{ - nil: {count: 37}, - user: {count: 37}, - user2: {count: 37}, + nil: {count: 36}, + user: {count: 36}, + user2: {count: 36}, }, }, { diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index 6f60dafaada83..b403b3cf175d3 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -512,14 +512,14 @@ func TestSearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 5) + assert.Len(t, apiIssues, 2) query.Set("state", "all") link.RawQuery = query.Encode() req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 20) query.Add("limit", "5") @@ -527,7 +527,7 @@ func TestSearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Equal(t, "25", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 5) query = url.Values{"assigned": {"true"}, "state": {"all"}} From 73008cd75005d1eadb00f0f1cf3f6b356939333a Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Sun, 25 May 2025 17:55:27 +0200 Subject: [PATCH 7/9] Fix wrong checkout --- models/repo/release.go | 61 +++++------------------------------------- 1 file changed, 7 insertions(+), 54 deletions(-) diff --git a/models/repo/release.go b/models/repo/release.go index 663d310bc027d..06cfa3734288c 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -161,6 +161,11 @@ func UpdateRelease(ctx context.Context, rel *Release) error { return err } +func UpdateReleaseNumCommits(ctx context.Context, rel *Release) error { + _, err := db.GetEngine(ctx).ID(rel.ID).Cols("num_commits").Update(rel) + return err +} + // AddReleaseAttachments adds a release attachments func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { // Check attachments @@ -418,8 +423,8 @@ func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs. return err } -// PushUpdateDeleteTagsContext updates a number of delete tags with context -func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error { +// PushUpdateDeleteTags updates a number of delete tags with context +func PushUpdateDeleteTags(ctx context.Context, repo *Repository, tags []string) error { if len(tags) == 0 { return nil } @@ -448,58 +453,6 @@ func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []s return nil } -// PushUpdateDeleteTag must be called for any push actions to delete tag -func PushUpdateDeleteTag(ctx context.Context, repo *Repository, tagName string) error { - rel, err := GetRelease(ctx, repo.ID, tagName) - if err != nil { - if IsErrReleaseNotExist(err) { - return nil - } - return fmt.Errorf("GetRelease: %w", err) - } - if rel.IsTag { - if _, err = db.DeleteByID[Release](ctx, rel.ID); err != nil { - return fmt.Errorf("Delete: %w", err) - } - } else { - rel.IsDraft = true - rel.NumCommits = 0 - rel.Sha1 = "" - if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil { - return fmt.Errorf("Update: %w", err) - } - } - - return nil -} - -// SaveOrUpdateTag must be called for any push actions to add tag -func SaveOrUpdateTag(ctx context.Context, repo *Repository, newRel *Release) error { - rel, err := GetRelease(ctx, repo.ID, newRel.TagName) - if err != nil && !IsErrReleaseNotExist(err) { - return fmt.Errorf("GetRelease: %w", err) - } - - if rel == nil { - rel = newRel - if _, err = db.GetEngine(ctx).Insert(rel); err != nil { - return fmt.Errorf("InsertOne: %w", err) - } - } else { - rel.Sha1 = newRel.Sha1 - rel.CreatedUnix = newRel.CreatedUnix - rel.NumCommits = newRel.NumCommits - rel.IsDraft = false - if rel.IsTag && newRel.PublisherID > 0 { - rel.PublisherID = newRel.PublisherID - } - if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil { - return fmt.Errorf("Update: %w", err) - } - } - return nil -} - // RemapExternalUser ExternalUserRemappable interface func (r *Release) RemapExternalUser(externalName string, externalID, userID int64) error { r.OriginalAuthor = externalName From 08522dffbe897c97ff6571fa23b51e6cf6d4e228 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Sun, 25 May 2025 17:56:17 +0200 Subject: [PATCH 8/9] Run make fmt --- models/issues/pull_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 06f5b79c757db..a9aaada64941a 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -4,7 +4,6 @@ package issues_test import ( - "github.com/stretchr/testify/require" "testing" "code.gitea.io/gitea/models/db" @@ -15,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestPullRequest_LoadAttributes(t *testing.T) { From 33574a349f5a081b4b813820d95eec5f4be732bf Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Sun, 25 May 2025 18:20:26 +0200 Subject: [PATCH 9/9] Fix linter issues --- models/issues/pull_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index a9aaada64941a..53898cb42eb39 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -84,7 +84,7 @@ func TestPullRequests_Closed_RecentSortType(t *testing.T) { // 11 | 1707279999 | 1707275555 tests := []struct { sortType string - expectedIssueIdOrder []int64 + expectedIssueIDOrder []int64 }{ {"recentupdate", []int64{3, 11, 2}}, {"recentclose", []int64{11, 3, 2}}, @@ -109,9 +109,9 @@ func TestPullRequests_Closed_RecentSortType(t *testing.T) { }) require.NoError(t, err) - if assert.Len(t, prs, len(test.expectedIssueIdOrder)) { - for i := range test.expectedIssueIdOrder { - assert.EqualValues(t, test.expectedIssueIdOrder[i], prs[i].IssueID) + if assert.Len(t, prs, len(test.expectedIssueIDOrder)) { + for i := range test.expectedIssueIDOrder { + assert.Equal(t, test.expectedIssueIDOrder[i], prs[i].IssueID) } } })