Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve issue search #2387

Merged
merged 5 commits into from
Sep 16, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,8 @@ coverage.all
/integrations/gitea-integration-mysql
/integrations/gitea-integration-pgsql
/integrations/gitea-integration-sqlite
/integrations/indexers-mysql
/integrations/indexers-pgsql
/integrations/indexers-sqlite
/integrations/mysql.ini
/integrations/pgsql.ini
9 changes: 8 additions & 1 deletion integrations/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ func TestMain(m *testing.M) {
fmt.Printf("Error initializing test database: %v\n", err)
os.Exit(1)
}
os.Exit(m.Run())
exitCode := m.Run()

if err = os.RemoveAll(setting.Indexer.IssuePath); err != nil {
fmt.Printf("os.RemoveAll: %v\n", err)
os.Exit(1)
}

os.Exit(exitCode)
}

func initIntegrationTest() {
Expand Down
43 changes: 38 additions & 5 deletions integrations/issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import (
"github.com/stretchr/testify/assert"
)

func getIssuesSelection(htmlDoc *HTMLDoc) *goquery.Selection {
return htmlDoc.doc.Find(".issue.list").Find("li").Find(".title")
func getIssuesSelection(t testing.TB, htmlDoc *HTMLDoc) *goquery.Selection {
issueList := htmlDoc.doc.Find(".issue.list")
assert.EqualValues(t, 1, issueList.Length())
return issueList.Find("li").Find(".title")
}

func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *models.Issue {
Expand All @@ -31,26 +33,37 @@ func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *mo
return models.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repoID, Index: int64(index)}).(*models.Issue)
}

func assertMatch(t testing.TB, issue *models.Issue, keyword string) {
matches := strings.Contains(strings.ToLower(issue.Title), keyword) ||
strings.Contains(strings.ToLower(issue.Content), keyword)
for _, comment := range issue.Comments {
matches = matches || strings.Contains(
strings.ToLower(comment.Content),
keyword,
)
}
assert.True(t, matches)
}

func TestNoLoginViewIssues(t *testing.T) {
prepareTestEnv(t)

req := NewRequest(t, "GET", "/user2/repo1/issues")
MakeRequest(t, req, http.StatusOK)
}

func TestNoLoginViewIssuesSortByType(t *testing.T) {
func TestViewIssuesSortByType(t *testing.T) {
prepareTestEnv(t)

user := models.AssertExistsAndLoadBean(t, &models.User{ID: 1}).(*models.User)
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
repo.Owner = models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)

session := loginUser(t, user.Name)
req := NewRequest(t, "GET", repo.RelLink()+"/issues?type=created_by")
resp := session.MakeRequest(t, req, http.StatusOK)

htmlDoc := NewHTMLParser(t, resp.Body)
issuesSelection := getIssuesSelection(htmlDoc)
issuesSelection := getIssuesSelection(t, htmlDoc)
expectedNumIssues := models.GetCount(t,
&models.Issue{RepoID: repo.ID, PosterID: user.ID},
models.Cond("is_closed=?", false),
Expand All @@ -67,6 +80,26 @@ func TestNoLoginViewIssuesSortByType(t *testing.T) {
})
}

func TestViewIssuesKeyword(t *testing.T) {
prepareTestEnv(t)

repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)

const keyword = "first"
req := NewRequestf(t, "GET", "%s/issues?q=%s", repo.RelLink(), keyword)
resp := MakeRequest(t, req, http.StatusOK)

htmlDoc := NewHTMLParser(t, resp.Body)
issuesSelection := getIssuesSelection(t, htmlDoc)
assert.EqualValues(t, 1, issuesSelection.Length())
issuesSelection.Each(func(_ int, selection *goquery.Selection) {
issue := getIssue(t, repo.ID, selection)
assert.False(t, issue.IsClosed)
assert.False(t, issue.IsPull)
assertMatch(t, issue, keyword)
})
}

func TestNoLoginViewIssue(t *testing.T) {
prepareTestEnv(t)

Expand Down
3 changes: 3 additions & 0 deletions integrations/mysql.ini.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ PASSWD = {{TEST_MYSQL_PASSWORD}}
SSL_MODE = disable
PATH = data/gitea.db

[indexer]
ISSUE_INDEXER_PATH = integrations/indexers-mysql/issues.bleve

[repository]
ROOT = integrations/gitea-integration-mysql/gitea-repositories

Expand Down
3 changes: 3 additions & 0 deletions integrations/pgsql.ini.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ PASSWD = {{TEST_PGSQL_PASSWORD}}
SSL_MODE = disable
PATH = data/gitea.db

[indexer]
ISSUE_INDEXER_PATH = integrations/indexers-pgsql/issues.bleve

[repository]
ROOT = integrations/gitea-integration-pgsql/gitea-repositories

Expand Down
3 changes: 3 additions & 0 deletions integrations/sqlite.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ RUN_MODE = prod
DB_TYPE = sqlite3
PATH = :memory:

[indexer]
ISSUE_INDEXER_PATH = integrations/indexers-sqlite/issues.bleve

[repository]
ROOT = integrations/gitea-integration-sqlite/gitea-repositories

Expand Down
10 changes: 5 additions & 5 deletions models/fixtures/issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
poster_id: 1
assignee_id: 1
name: issue1
content: content1
content: content for the first issue
is_closed: false
is_pull: false
num_comments: 2
Expand All @@ -18,7 +18,7 @@
index: 2
poster_id: 1
name: issue2
content: content2
content: content for the second issue
milestone_id: 1
is_closed: false
is_pull: true
Expand All @@ -32,7 +32,7 @@
index: 3
poster_id: 1
name: issue3
content: content4
content: content for the third issue
is_closed: false
is_pull: true
created_unix: 946684820
Expand All @@ -44,7 +44,7 @@
index: 1
poster_id: 2
name: issue4
content: content4
content: content for the fourth issue
is_closed: true
is_pull: false

Expand All @@ -54,7 +54,7 @@
index: 4
poster_id: 2
name: issue5
content: content5
content: content for the fifth issue
is_closed: true
is_pull: false
-
Expand Down
29 changes: 17 additions & 12 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ func (issue *Issue) loadPullRequest(e Engine) (err error) {
return nil
}

func (issue *Issue) loadComments(e Engine) (err error) {
if issue.Comments != nil {
return nil
}
issue.Comments, err = findComments(e, FindCommentsOptions{
IssueID: issue.ID,
Type: CommentTypeUnknown,
})
return err
}

func (issue *Issue) loadAttributes(e Engine) (err error) {
if err = issue.loadRepo(e); err != nil {
return
Expand Down Expand Up @@ -191,14 +202,8 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
}
}

if issue.Comments == nil {
issue.Comments, err = findComments(e, FindCommentsOptions{
IssueID: issue.ID,
Type: CommentTypeUnknown,
})
if err != nil {
return fmt.Errorf("getCommentsByIssueID [%d]: %v", issue.ID, err)
}
if err = issue.loadComments(e); err != nil {
return
}

return nil
Expand Down Expand Up @@ -577,7 +582,7 @@ func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
if _, err := e.Id(issue.ID).Cols(cols...).Update(issue); err != nil {
return err
}
UpdateIssueIndexer(issue)
UpdateIssueIndexer(issue.ID)
return nil
}

Expand Down Expand Up @@ -907,8 +912,6 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
return err
}

UpdateIssueIndexer(opts.Issue)

if len(opts.Attachments) > 0 {
attachments, err := getAttachmentsByUUIDs(e, opts.Attachments)
if err != nil {
Expand Down Expand Up @@ -947,6 +950,8 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
return fmt.Errorf("Commit: %v", err)
}

UpdateIssueIndexer(issue.ID)

if err = NotifyWatchers(&Action{
ActUserID: issue.Poster.ID,
ActUser: issue.Poster,
Expand Down Expand Up @@ -1448,7 +1453,7 @@ func updateIssue(e Engine, issue *Issue) error {
if err != nil {
return err
}
UpdateIssueIndexer(issue)
UpdateIssueIndexer(issue.ID)
return nil
}

Expand Down
24 changes: 20 additions & 4 deletions models/issue_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,14 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
return nil, err
}

return comment, sess.Commit()
if err = sess.Commit(); err != nil {
return nil, err
}

if opts.Type == CommentTypeComment {
UpdateIssueIndexer(opts.Issue.ID)
}
return comment, nil
}

// CreateIssueComment creates a plain issue comment.
Expand Down Expand Up @@ -645,8 +652,12 @@ func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {

// UpdateComment updates information of comment.
func UpdateComment(c *Comment) error {
_, err := x.Id(c.ID).AllCols().Update(c)
return err
if _, err := x.Id(c.ID).AllCols().Update(c); err != nil {
return err
} else if c.Type == CommentTypeComment {
UpdateIssueIndexer(c.IssueID)
}
return nil
}

// DeleteComment deletes the comment
Expand All @@ -672,5 +683,10 @@ func DeleteComment(comment *Comment) error {
return err
}

return sess.Commit()
if err := sess.Commit(); err != nil {
return err
} else if comment.Type == CommentTypeComment {
UpdateIssueIndexer(comment.IssueID)
}
return nil
}
Loading