From a82a39d3226454ce855c46c2805b110867cca695 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Wed, 7 May 2025 12:25:12 +0800 Subject: [PATCH] Try fixing your unit tests --- models/issues/issue_project.go | 4 ++-- models/issues/issue_search.go | 18 ++++++++++++------ modules/indexer/issues/bleve/bleve.go | 9 +++++++-- modules/indexer/issues/db/options.go | 5 ++++- modules/indexer/issues/dboptions.go | 6 ++---- .../issues/elasticsearch/elasticsearch.go | 4 ++-- modules/indexer/issues/internal/model.go | 2 +- modules/indexer/issues/internal/tests/tests.go | 4 ++-- .../indexer/issues/meilisearch/meilisearch.go | 4 ++-- routers/web/repo/issue_list.go | 18 +++++++++--------- services/projects/issue.go | 10 +++++----- 11 files changed, 48 insertions(+), 36 deletions(-) diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index ced2f9c087..71b589d066 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -62,7 +62,7 @@ func LoadProjectIssueColumnMap(ctx context.Context, projectID, defaultColumnID i func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *IssuesOptions) (IssueList, error) { issueList, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) { o.ProjectColumnID = b.ID - o.ProjectID = b.ProjectID + o.ProjectIDs = []int64{b.ProjectID} o.SortType = "project-column-sorting" })) if err != nil { @@ -72,7 +72,7 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *Is if b.Default { issues, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) { o.ProjectColumnID = db.NoConditionID - o.ProjectID = b.ProjectID + o.ProjectIDs = []int64{b.ProjectID} o.SortType = "project-column-sorting" })) if err != nil { diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index f9e1fbeb14..0c17971e07 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -36,7 +36,7 @@ type IssuesOptions struct { //nolint ReviewedID int64 SubscriberID int64 MilestoneIDs []int64 - ProjectID int64 + ProjectIDs []int64 ProjectColumnID int64 IsClosed optional.Option[bool] IsPull optional.Option[bool] @@ -196,11 +196,17 @@ func applyMilestoneCondition(sess *xorm.Session, opts *IssuesOptions) { } func applyProjectCondition(sess *xorm.Session, opts *IssuesOptions) { - if opts.ProjectID > 0 { // specific project - sess.Join("INNER", "project_issue", "issue.id = project_issue.issue_id"). - And("project_issue.project_id=?", opts.ProjectID) - } else if opts.ProjectID == db.NoConditionID { // show those that are in no project - sess.And(builder.NotIn("issue.id", builder.Select("issue_id").From("project_issue").And(builder.Neq{"project_id": 0}))) + if len(opts.ProjectIDs) > 0 { // specific project + var includedProjectIDs []int64 + for _, projectID := range opts.ProjectIDs { + if projectID > 0 { + includedProjectIDs = append(includedProjectIDs, projectID) + } + } + if len(includedProjectIDs) > 0 { + sess.Join("INNER", "project_issue", "issue.id = project_issue.issue_id"). + In("project_issue.project_id", includedProjectIDs) + } } // opts.ProjectID == 0 means all projects, // do not need to apply any condition diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 39d96cab98..f7dd6ea03d 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -241,9 +241,14 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( queries = append(queries, bleve.NewDisjunctionQuery(milestoneQueries...)) } - if options.ProjectID.Has() { - queries = append(queries, inner_bleve.NumericEqualityQuery(options.ProjectID.Value(), "project_id")) + if len(options.ProjectIDs) > 0 { + var projectQueries []query.Query + for _, projectID := range options.ProjectIDs { + projectQueries = append(projectQueries, inner_bleve.NumericEqualityQuery(projectID, "project_id")) + } + queries = append(queries, bleve.NewDisjunctionQuery(projectQueries...)) } + if options.ProjectColumnID.Has() { queries = append(queries, inner_bleve.NumericEqualityQuery(options.ProjectColumnID.Value(), "project_board_id")) } diff --git a/modules/indexer/issues/db/options.go b/modules/indexer/issues/db/options.go index 380a25dc23..e5359ad105 100644 --- a/modules/indexer/issues/db/options.go +++ b/modules/indexer/issues/db/options.go @@ -65,7 +65,6 @@ func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_m ReviewRequestedID: convertID(options.ReviewRequestedID), ReviewedID: convertID(options.ReviewedID), SubscriberID: convertID(options.SubscriberID), - ProjectID: convertID(options.ProjectID), ProjectColumnID: convertID(options.ProjectColumnID), IsClosed: options.IsClosed, IsPull: options.IsPull, @@ -88,6 +87,10 @@ func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_m opts.MilestoneIDs = options.MilestoneIDs } + if len(options.ProjectIDs) > 0 { + opts.ProjectIDs = options.ProjectIDs + } + if options.NoLabelOnly { opts.LabelIDs = []int64{0} // Be careful, it's zero, not db.NoConditionID } else { diff --git a/modules/indexer/issues/dboptions.go b/modules/indexer/issues/dboptions.go index f17724664d..ccc8c95ae7 100644 --- a/modules/indexer/issues/dboptions.go +++ b/modules/indexer/issues/dboptions.go @@ -46,10 +46,8 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp searchOpt.MilestoneIDs = opts.MilestoneIDs } - if opts.ProjectID > 0 { - searchOpt.ProjectID = optional.Some(opts.ProjectID) - } else if opts.ProjectID == db.NoConditionID { // FIXME: this is inconsistent from other places - searchOpt.ProjectID = optional.Some[int64](0) // Those issues with no project(projectid==0) + if len(opts.ProjectIDs) > 0 { + searchOpt.ProjectIDs = opts.ProjectIDs } searchOpt.AssigneeID = opts.AssigneeID diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 9d627466ef..1bcbd67c1d 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -204,8 +204,8 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( query.Must(elastic.NewTermsQuery("milestone_id", toAnySlice(options.MilestoneIDs)...)) } - if options.ProjectID.Has() { - query.Must(elastic.NewTermQuery("project_id", options.ProjectID.Value())) + if len(options.ProjectIDs) > 0 { + query.Must(elastic.NewTermsQuery("project_id", toAnySlice(options.ProjectIDs)...)) } if options.ProjectColumnID.Has() { query.Must(elastic.NewTermQuery("project_board_id", options.ProjectColumnID.Value())) diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go index e0ef52a437..8a251dd2ab 100644 --- a/modules/indexer/issues/internal/model.go +++ b/modules/indexer/issues/internal/model.go @@ -94,7 +94,7 @@ type SearchOptions struct { MilestoneIDs []int64 // milestones the issues have - ProjectID optional.Option[int64] // project the issues belong to + ProjectIDs []int64 // project the issues belong to ProjectColumnID optional.Option[int64] // project column the issues belong to PosterID string // poster of the issues, "(none)" or "(any)" or a user ID diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go index dc082eacd4..5e628d1fe4 100644 --- a/modules/indexer/issues/internal/tests/tests.go +++ b/modules/indexer/issues/internal/tests/tests.go @@ -307,7 +307,7 @@ var cases = []*testIndexerCase{ Paginator: &db.ListOptions{ PageSize: 5, }, - ProjectID: optional.Some(int64(1)), + ProjectIDs: []int64{1}, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) @@ -325,7 +325,7 @@ var cases = []*testIndexerCase{ Paginator: &db.ListOptions{ PageSize: 5, }, - ProjectID: optional.Some(int64(0)), + ProjectIDs: []int64{0}, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index 759a98473f..c1edcfbe38 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -180,8 +180,8 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( query.And(inner_meilisearch.NewFilterIn("milestone_id", options.MilestoneIDs...)) } - if options.ProjectID.Has() { - query.And(inner_meilisearch.NewFilterEq("project_id", options.ProjectID.Value())) + if len(options.ProjectIDs) > 0 { + query.And(inner_meilisearch.NewFilterIn("project_id", options.ProjectIDs...)) } if options.ProjectColumnID.Has() { query.And(inner_meilisearch.NewFilterEq("project_board_id", options.ProjectColumnID.Value())) diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go index 35107bc585..6c0b6e7374 100644 --- a/routers/web/repo/issue_list.go +++ b/routers/web/repo/issue_list.go @@ -189,7 +189,7 @@ func SearchIssues(ctx *context.Context) { IsClosed: isClosed, IncludedAnyLabelIDs: includedAnyLabels, MilestoneIDs: includedMilestones, - ProjectID: projectID, + ProjectIDs: projectID, SortBy: issue_indexer.SortByCreatedDesc, } @@ -345,12 +345,12 @@ func SearchRepoIssuesJSON(ctx *context.Context) { Page: ctx.FormInt("page"), PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), }, - Keyword: keyword, - RepoIDs: []int64{ctx.Repo.Repository.ID}, - IsPull: isPull, - IsClosed: isClosed, - ProjectID: projectID, - SortBy: issue_indexer.SortByCreatedDesc, + Keyword: keyword, + RepoIDs: []int64{ctx.Repo.Repository.ID}, + IsPull: isPull, + IsClosed: isClosed, + ProjectIDs: projectID, + SortBy: issue_indexer.SortByCreatedDesc, } if since != 0 { searchOpt.UpdatedAfterUnix = optional.Some(since) @@ -542,7 +542,7 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID, projectID int6 RepoIDs: []int64{repo.ID}, LabelIDs: preparedLabelFilter.SelectedLabelIDs, MilestoneIDs: mileIDs, - ProjectID: projectID, + ProjectIDs: []int64{projectID}, AssigneeID: assigneeID, MentionedID: mentionedID, PosterID: posterUserID, @@ -629,7 +629,7 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID, projectID int6 ReviewRequestedID: reviewRequestedID, ReviewedID: reviewedID, MilestoneIDs: mileIDs, - ProjectID: projectID, + ProjectIDs: []int64{projectID}, IsClosed: isShowClosed, IsPull: isPullOption, LabelIDs: preparedLabelFilter.SelectedLabelIDs, diff --git a/services/projects/issue.go b/services/projects/issue.go index 80562480af..10bb1c5c07 100644 --- a/services/projects/issue.go +++ b/services/projects/issue.go @@ -89,7 +89,7 @@ func MoveIssuesOnProjectColumn(ctx context.Context, doer *user_model.User, colum // LoadIssuesFromProject load issues assigned to each project column inside the given project func LoadIssuesFromProject(ctx context.Context, project *project_model.Project, opts *issues_model.IssuesOptions) (map[int64]issues_model.IssueList, error) { issueList, err := issues_model.Issues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) { - o.ProjectID = project.ID + o.ProjectIDs = []int64{project.ID} o.SortType = "project-column-sorting" })) if err != nil { @@ -180,10 +180,10 @@ func LoadIssueNumbersForProject(ctx context.Context, project *project_model.Proj // for user or org projects, we need to check access permissions opts := issues_model.IssuesOptions{ - ProjectID: project.ID, - Doer: doer, - AllPublic: doer == nil, - Owner: project.Owner, + ProjectIDs: []int64{project.ID}, + Doer: doer, + AllPublic: doer == nil, + Owner: project.Owner, } var err error