mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	As described in the title. Some points: 1. Why need those tests? Because `buildIssueOverview` is not well tested, there are several continuous bugs in the issue overview webpage. 2. Why in indexer_test.go? It's hard to put those tests in `./modules/indexer/issue/db/db_test.go` because those tests need 'real' data in db mocked by fixtures instead of random data in `./modules/indexer/issue/internal/tests`. When using 'real' data(`unittest.PrepareTestDatabase`), `InitIssueIndexer` and the package `init()` function of `indexer` are required to init indexer. 3. Why only db? The other three indexer engines are well tested by random data and it's okay to also test them with 'real' data in db mocked by fixtures. Any follow-up PR is welcome. 4. Those tests are really basic, any more complicated tests are welcome. 5. I think it's also necessary to add tests in `TestAPISearchIssues` in`api_test_issue.go` and `TestIssues` in `home_test.go`
		
			
				
	
	
		
			408 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			408 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package issues
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"path/filepath"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"code.gitea.io/gitea/models/db"
 | 
						|
	"code.gitea.io/gitea/models/unittest"
 | 
						|
	"code.gitea.io/gitea/modules/indexer/issues/internal"
 | 
						|
	"code.gitea.io/gitea/modules/setting"
 | 
						|
	"code.gitea.io/gitea/modules/util"
 | 
						|
 | 
						|
	_ "code.gitea.io/gitea/models"
 | 
						|
	_ "code.gitea.io/gitea/models/actions"
 | 
						|
	_ "code.gitea.io/gitea/models/activities"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
)
 | 
						|
 | 
						|
func TestMain(m *testing.M) {
 | 
						|
	unittest.MainTest(m, &unittest.TestOptions{
 | 
						|
		GiteaRootPath: filepath.Join("..", "..", ".."),
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestDBSearchIssues(t *testing.T) {
 | 
						|
	assert.NoError(t, unittest.PrepareTestDatabase())
 | 
						|
 | 
						|
	setting.Indexer.IssueType = "db"
 | 
						|
	InitIssueIndexer(true)
 | 
						|
 | 
						|
	t.Run("search issues with keyword", searchIssueWithKeyword)
 | 
						|
	t.Run("search issues in repo", searchIssueInRepo)
 | 
						|
	t.Run("search issues by ID", searchIssueByID)
 | 
						|
	t.Run("search issues is pr", searchIssueIsPull)
 | 
						|
	t.Run("search issues is closed", searchIssueIsClosed)
 | 
						|
	t.Run("search issues by milestone", searchIssueByMilestoneID)
 | 
						|
	t.Run("search issues by label", searchIssueByLabelID)
 | 
						|
	t.Run("search issues by time", searchIssueByTime)
 | 
						|
	t.Run("search issues with order", searchIssueWithOrder)
 | 
						|
	t.Run("search issues in project", searchIssueInProject)
 | 
						|
	t.Run("search issues with paginator", searchIssueWithPaginator)
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueWithKeyword(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				Keyword: "issue2",
 | 
						|
				RepoIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{2},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				Keyword: "first",
 | 
						|
				RepoIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				Keyword: "for",
 | 
						|
				RepoIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{11, 5, 3, 2, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				Keyword: "good",
 | 
						|
				RepoIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{1},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueInRepo(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				RepoIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{11, 5, 3, 2, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				RepoIDs: []int64{2},
 | 
						|
			},
 | 
						|
			[]int64{7, 4},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				RepoIDs: []int64{3},
 | 
						|
			},
 | 
						|
			[]int64{12, 6},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				RepoIDs: []int64{4},
 | 
						|
			},
 | 
						|
			[]int64{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				RepoIDs: []int64{5},
 | 
						|
			},
 | 
						|
			[]int64{15},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueByID(t *testing.T) {
 | 
						|
	int64Pointer := func(x int64) *int64 {
 | 
						|
		return &x
 | 
						|
	}
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				PosterID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{11, 6, 3, 2, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				AssigneeID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{6, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				MentionID: int64Pointer(4),
 | 
						|
			},
 | 
						|
			[]int64{1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				ReviewedID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				ReviewRequestedID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{12},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				SubscriberID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{11, 6, 5, 3, 2, 1},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueIsPull(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				IsPull: util.OptionalBoolFalse,
 | 
						|
			},
 | 
						|
			[]int64{17, 16, 15, 14, 13, 6, 5, 18, 10, 7, 4, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				IsPull: util.OptionalBoolTrue,
 | 
						|
			},
 | 
						|
			[]int64{12, 11, 19, 9, 8, 3, 2},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueIsClosed(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				IsClosed: util.OptionalBoolFalse,
 | 
						|
			},
 | 
						|
			[]int64{17, 16, 15, 14, 13, 12, 11, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				IsClosed: util.OptionalBoolTrue,
 | 
						|
			},
 | 
						|
			[]int64{5, 4},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueByMilestoneID(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				MilestoneIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{2},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				MilestoneIDs: []int64{3},
 | 
						|
			},
 | 
						|
			[]int64{3},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueByLabelID(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				IncludedLabelIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{2, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				IncludedLabelIDs: []int64{4},
 | 
						|
			},
 | 
						|
			[]int64{2},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				ExcludedLabelIDs: []int64{1},
 | 
						|
			},
 | 
						|
			[]int64{17, 16, 15, 14, 13, 12, 11, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueByTime(t *testing.T) {
 | 
						|
	int64Pointer := func(i int64) *int64 {
 | 
						|
		return &i
 | 
						|
	}
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				UpdatedAfterUnix: int64Pointer(0),
 | 
						|
			},
 | 
						|
			[]int64{17, 16, 15, 14, 13, 12, 11, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueWithOrder(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				SortBy: internal.SortByCreatedAsc,
 | 
						|
			},
 | 
						|
			[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 11, 12, 13, 14, 15, 16, 17},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueInProject(t *testing.T) {
 | 
						|
	int64Pointer := func(i int64) *int64 {
 | 
						|
		return &i
 | 
						|
	}
 | 
						|
	tests := []struct {
 | 
						|
		opts        SearchOptions
 | 
						|
		expectedIDs []int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				ProjectID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{5, 3, 2, 1},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				ProjectBoardID: int64Pointer(1),
 | 
						|
			},
 | 
						|
			[]int64{1},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func searchIssueWithPaginator(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		opts          SearchOptions
 | 
						|
		expectedIDs   []int64
 | 
						|
		expectedTotal int64
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SearchOptions{
 | 
						|
				Paginator: &db.ListOptions{
 | 
						|
					PageSize: 5,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			[]int64{17, 16, 15, 14, 13},
 | 
						|
			19,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, test := range tests {
 | 
						|
		issueIDs, total, err := SearchIssues(context.TODO(), &test.opts)
 | 
						|
		if !assert.NoError(t, err) {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		assert.Equal(t, test.expectedIDs, issueIDs)
 | 
						|
		assert.Equal(t, test.expectedTotal, total)
 | 
						|
	}
 | 
						|
}
 |