This commit is contained in:
@@ -13,10 +13,10 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/indexer/issues/internal"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"gitea.dev/models/db"
|
||||
"gitea.dev/modules/indexer/issues/internal"
|
||||
"gitea.dev/modules/optional"
|
||||
"gitea.dev/modules/timeutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -116,6 +116,16 @@ var cases = []*testIndexerCase{
|
||||
assert.Equal(t, len(data), int(result.Total))
|
||||
},
|
||||
},
|
||||
{
|
||||
// Exercises the single-doc Index/Delete fast path in backends that have one (e.g. Elasticsearch).
|
||||
Name: "single-doc index",
|
||||
ExtraData: []*internal.IndexerData{
|
||||
{ID: 999, Title: "solo-issue-marker"},
|
||||
},
|
||||
SearchOptions: &internal.SearchOptions{Keyword: "solo-issue-marker"},
|
||||
ExpectedIDs: []int64{999},
|
||||
ExpectedTotal: 1,
|
||||
},
|
||||
{
|
||||
Name: "Keyword",
|
||||
ExtraData: []*internal.IndexerData{
|
||||
@@ -301,75 +311,41 @@ var cases = []*testIndexerCase{
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ProjectID",
|
||||
Name: "ProjectIDs",
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
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)
|
||||
for _, v := range result.Hits {
|
||||
assert.Equal(t, int64(1), data[v.ID].ProjectID)
|
||||
assert.Contains(t, data[v.ID].ProjectIDs, int64(1))
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.ProjectID == 1
|
||||
return slices.Contains(v.ProjectIDs, int64(1))
|
||||
}), result.Total)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "no ProjectID",
|
||||
Name: "no ProjectIDs (empty array)",
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: 5,
|
||||
PageSize: 50,
|
||||
},
|
||||
ProjectID: optional.Some(int64(0)),
|
||||
NoProjectOnly: true,
|
||||
},
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Len(t, result.Hits, 5)
|
||||
// Verify only issues with no projects are returned
|
||||
for _, v := range result.Hits {
|
||||
assert.Equal(t, int64(0), data[v.ID].ProjectID)
|
||||
assert.Empty(t, data[v.ID].ProjectIDs, "Issue %d should have no projects", v.ID)
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.ProjectID == 0
|
||||
}), result.Total)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ProjectColumnID",
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: 5,
|
||||
},
|
||||
ProjectColumnID: optional.Some(int64(1)),
|
||||
},
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Len(t, result.Hits, 5)
|
||||
for _, v := range result.Hits {
|
||||
assert.Equal(t, int64(1), data[v.ID].ProjectColumnID)
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.ProjectColumnID == 1
|
||||
}), result.Total)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "no ProjectColumnID",
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: 5,
|
||||
},
|
||||
ProjectColumnID: optional.Some(int64(0)),
|
||||
},
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Len(t, result.Hits, 5)
|
||||
for _, v := range result.Hits {
|
||||
assert.Equal(t, int64(0), data[v.ID].ProjectColumnID)
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.ProjectColumnID == 0
|
||||
}), result.Total)
|
||||
// Verify we got ALL issues with no projects
|
||||
expectedCount := countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return len(v.ProjectIDs) == 0
|
||||
})
|
||||
assert.Equal(t, expectedCount, result.Total, "Should return all %d issues with no project", expectedCount)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -401,10 +377,10 @@ var cases = []*testIndexerCase{
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Len(t, result.Hits, 5)
|
||||
for _, v := range result.Hits {
|
||||
assert.Equal(t, int64(1), data[v.ID].AssigneeID)
|
||||
assert.True(t, slices.Contains(data[v.ID].AssigneeIDs, int64(1)))
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.AssigneeID == 1
|
||||
return slices.Contains(v.AssigneeIDs, int64(1))
|
||||
}), result.Total)
|
||||
},
|
||||
},
|
||||
@@ -419,10 +395,10 @@ var cases = []*testIndexerCase{
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Len(t, result.Hits, 5)
|
||||
for _, v := range result.Hits {
|
||||
assert.Equal(t, int64(0), data[v.ID].AssigneeID)
|
||||
assert.True(t, data[v.ID].NoAssignee)
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.AssigneeID == 0
|
||||
return v.NoAssignee
|
||||
}), result.Total)
|
||||
},
|
||||
},
|
||||
@@ -654,10 +630,10 @@ var cases = []*testIndexerCase{
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Len(t, result.Hits, 180)
|
||||
for _, v := range result.Hits {
|
||||
assert.GreaterOrEqual(t, data[v.ID].AssigneeID, int64(1))
|
||||
assert.False(t, data[v.ID].NoAssignee)
|
||||
}
|
||||
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
|
||||
return v.AssigneeID >= 1
|
||||
return !v.NoAssignee
|
||||
}), result.Total)
|
||||
},
|
||||
},
|
||||
@@ -706,6 +682,22 @@ func generateDefaultIndexerData() []*internal.IndexerData {
|
||||
for i := range subscriberIDs {
|
||||
subscriberIDs[i] = int64(i) + 1 // SubscriberID should not be 0
|
||||
}
|
||||
projectIDs := make([]int64, id%5)
|
||||
for i := range projectIDs {
|
||||
projectIDs[i] = int64(i) + 1 // projectID should not be 0
|
||||
}
|
||||
var assigneeIDs []int64
|
||||
if issueIndex%10 != 0 {
|
||||
assigneeID := issueIndex % 10
|
||||
assigneeIDs = []int64{assigneeID}
|
||||
if issueIndex%3 == 0 {
|
||||
nextAssigneeID := assigneeID + 1
|
||||
if nextAssigneeID == 10 {
|
||||
nextAssigneeID = 1
|
||||
}
|
||||
assigneeIDs = append(assigneeIDs, nextAssigneeID)
|
||||
}
|
||||
}
|
||||
|
||||
data = append(data, &internal.IndexerData{
|
||||
ID: id,
|
||||
@@ -719,10 +711,11 @@ func generateDefaultIndexerData() []*internal.IndexerData {
|
||||
LabelIDs: labelIDs,
|
||||
NoLabel: len(labelIDs) == 0,
|
||||
MilestoneID: issueIndex % 4,
|
||||
ProjectID: issueIndex % 5,
|
||||
ProjectColumnID: issueIndex % 6,
|
||||
ProjectIDs: projectIDs,
|
||||
NoProject: len(projectIDs) == 0,
|
||||
PosterID: id%10 + 1, // PosterID should not be 0
|
||||
AssigneeID: issueIndex % 10,
|
||||
AssigneeIDs: assigneeIDs,
|
||||
NoAssignee: len(assigneeIDs) == 0,
|
||||
MentionIDs: mentionIDs,
|
||||
ReviewedIDs: reviewedIDs,
|
||||
ReviewRequestedIDs: reviewRequestedIDs,
|
||||
|
||||
Reference in New Issue
Block a user