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

Fix counts on issues dashboard #2215

Merged
merged 4 commits into from
Aug 3, 2017
Merged
Show file tree
Hide file tree
Changes from all 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
57 changes: 45 additions & 12 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,7 @@ type IssuesOptions struct {
MilestoneID int64
RepoIDs []int64
Page int
PageSize int
IsClosed util.OptionalBool
IsPull util.OptionalBool
Labels string
Expand Down Expand Up @@ -1084,21 +1085,16 @@ func sortIssuesSession(sess *xorm.Session, sortType string) {
}
}

// Issues returns a list of issues by given conditions.
func Issues(opts *IssuesOptions) ([]*Issue, error) {
var sess *xorm.Session
if opts.Page >= 0 {
func (opts *IssuesOptions) setupSession(sess *xorm.Session) error {
if opts.Page >= 0 && opts.PageSize > 0 {
var start int
if opts.Page == 0 {
start = 0
} else {
start = (opts.Page - 1) * setting.UI.IssuePagingNum
start = (opts.Page - 1) * opts.PageSize
}
sess = x.Limit(setting.UI.IssuePagingNum, start)
} else {
sess = x.NewSession()
sess.Limit(opts.PageSize, start)
}
defer sess.Close()

if len(opts.IssueIDs) > 0 {
sess.In("issue.id", opts.IssueIDs)
Expand Down Expand Up @@ -1143,19 +1139,56 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
sess.And("issue.is_pull=?", false)
}

sortIssuesSession(sess, opts.SortType)

if len(opts.Labels) > 0 && opts.Labels != "0" {
labelIDs, err := base.StringsToInt64s(strings.Split(opts.Labels, ","))
if err != nil {
return nil, err
return err
}
if len(labelIDs) > 0 {
sess.
Join("INNER", "issue_label", "issue.id = issue_label.issue_id").
In("issue_label.label_id", labelIDs)
}
}
return nil
}

// CountIssuesByRepo map from repoID to number of issues matching the options
func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
sess := x.NewSession()
defer sess.Close()

if err := opts.setupSession(sess); err != nil {
return nil, err
}

countsSlice := make([]*struct {
RepoID int64
Count int64
}, 0, 10)
if err := sess.GroupBy("issue.repo_id").
Select("issue.repo_id AS repo_id, COUNT(*) AS count").
Table("issue").
Find(&countsSlice); err != nil {
return nil, err
}

countMap := make(map[int64]int64, len(countsSlice))
for _, c := range countsSlice {
countMap[c.RepoID] = c.Count
}
return countMap, nil
}

// Issues returns a list of issues by given conditions.
func Issues(opts *IssuesOptions) ([]*Issue, error) {
sess := x.NewSession()
defer sess.Close()

if err := opts.setupSession(sess); err != nil {
return nil, err
}
sortIssuesSession(sess, opts.SortType)

issues := make([]*Issue, 0, setting.UI.IssuePagingNum)
if err := sess.Find(&issues); err != nil {
Expand Down
1 change: 0 additions & 1 deletion models/issue_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ func populateIssueIndexer() error {
RepoID: repo.ID,
IsClosed: util.OptionalBoolNone,
IsPull: util.OptionalBoolNone,
Page: -1, // do not page
})
if err != nil {
return fmt.Errorf("Issues: %v", err)
Expand Down
20 changes: 1 addition & 19 deletions models/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ import (

"code.gitea.io/gitea/modules/setting"

"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
_ "github.com/mattn/go-sqlite3" // for the test engine
"github.com/stretchr/testify/assert"
"gopkg.in/testfixtures.v2"
)

// TestFixturesAreConsistent assert that test fixtures are consistent
Expand All @@ -21,23 +18,8 @@ func TestFixturesAreConsistent(t *testing.T) {
CheckConsistencyForAll(t)
}

// CreateTestEngine create an xorm engine for testing
func CreateTestEngine() error {
var err error
x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
if err != nil {
return err
}
x.SetMapper(core.GonicMapper{})
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
return err
}

return InitFixtures(&testfixtures.SQLite{}, "fixtures/")
}

func TestMain(m *testing.M) {
if err := CreateTestEngine(); err != nil {
if err := CreateTestEngine("fixtures/"); err != nil {
fmt.Printf("Error creating test engine: %v\n", err)
os.Exit(1)
}
Expand Down
5 changes: 5 additions & 0 deletions models/repo_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import (
// RepositoryList contains a list of repositories
type RepositoryList []*Repository

// RepositoryListOfMap make list from values of map
func RepositoryListOfMap(repoMap map[int64]*Repository) RepositoryList {
return RepositoryList(valuesRepository(repoMap))
}

func (repos RepositoryList) loadAttributes(e Engine) error {
if len(repos) == 0 {
return nil
Expand Down
18 changes: 18 additions & 0 deletions models/unit_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,31 @@ package models
import (
"testing"

"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
"github.com/stretchr/testify/assert"
"gopkg.in/testfixtures.v2"
)

// NonexistentID an ID that will never exist
const NonexistentID = 9223372036854775807

// CreateTestEngine create in-memory sqlite database for unit tests
// Any package that calls this must import github.com/mattn/go-sqlite3
func CreateTestEngine(fixturesDir string) error {
var err error
x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
if err != nil {
return err
}
x.SetMapper(core.GonicMapper{})
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
return err
}

return InitFixtures(&testfixtures.SQLite{}, fixturesDir)
}

// PrepareTestDatabase load test fixtures into test database
func PrepareTestDatabase() error {
return LoadFixtures()
Expand Down
150 changes: 150 additions & 0 deletions modules/test/context_tests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package test

import (
"net/http"
"net/url"
"testing"

"code.gitea.io/gitea/modules/context"

"github.com/stretchr/testify/assert"
macaron "gopkg.in/macaron.v1"
)

// MockContext mock context for unit tests
func MockContext(t *testing.T) *context.Context {
var macaronContext *macaron.Context
mac := macaron.New()
mac.Get("*/", func(ctx *macaron.Context) {
macaronContext = ctx
})
req, err := http.NewRequest("GET", "star", nil)
assert.NoError(t, err)
req.Form = url.Values{}
mac.ServeHTTP(&mockResponseWriter{}, req)
assert.NotNil(t, macaronContext)
assert.EqualValues(t, req, macaronContext.Req.Request)
macaronContext.Locale = &mockLocale{}
macaronContext.Resp = &mockResponseWriter{}
macaronContext.Render = &mockRender{ResponseWriter: macaronContext.Resp}
return &context.Context{
Context: macaronContext,
}
}

type mockLocale struct{}

func (l mockLocale) Language() string {
return "en"
}

func (l mockLocale) Tr(s string, _ ...interface{}) string {
return "test translation"
}

type mockResponseWriter struct {
status int
size int
}

func (rw *mockResponseWriter) Header() http.Header {
return map[string][]string{}
}

func (rw *mockResponseWriter) Write(b []byte) (int, error) {
rw.size += len(b)
return len(b), nil
}

func (rw *mockResponseWriter) WriteHeader(status int) {
rw.status = status
}

func (rw *mockResponseWriter) Flush() {
}

func (rw *mockResponseWriter) Status() int {
return rw.status
}

func (rw *mockResponseWriter) Written() bool {
return rw.status > 0
}

func (rw *mockResponseWriter) Size() int {
return rw.size
}

func (rw *mockResponseWriter) Before(b macaron.BeforeFunc) {
b(rw)
}

type mockRender struct {
http.ResponseWriter
}

func (tr *mockRender) SetResponseWriter(rw http.ResponseWriter) {
tr.ResponseWriter = rw
}

func (tr *mockRender) JSON(int, interface{}) {
}

func (tr *mockRender) JSONString(interface{}) (string, error) {
return "", nil
}

func (tr *mockRender) RawData(status int, _ []byte) {
tr.Status(status)
}

func (tr *mockRender) PlainText(status int, _ []byte) {
tr.Status(status)
}

func (tr *mockRender) HTML(status int, _ string, _ interface{}, _ ...macaron.HTMLOptions) {
tr.Status(status)
}

func (tr *mockRender) HTMLSet(status int, _ string, _ string, _ interface{}, _ ...macaron.HTMLOptions) {
tr.Status(status)
}

func (tr *mockRender) HTMLSetString(string, string, interface{}, ...macaron.HTMLOptions) (string, error) {
return "", nil
}

func (tr *mockRender) HTMLString(string, interface{}, ...macaron.HTMLOptions) (string, error) {
return "", nil
}

func (tr *mockRender) HTMLSetBytes(string, string, interface{}, ...macaron.HTMLOptions) ([]byte, error) {
return nil, nil
}

func (tr *mockRender) HTMLBytes(string, interface{}, ...macaron.HTMLOptions) ([]byte, error) {
return nil, nil
}

func (tr *mockRender) XML(status int, _ interface{}) {
tr.Status(status)
}

func (tr *mockRender) Error(status int, _ ...string) {
tr.Status(status)
}

func (tr *mockRender) Status(status int) {
tr.ResponseWriter.WriteHeader(status)
}

func (tr *mockRender) SetTemplatePath(string, string) {
}

func (tr *mockRender) HasTemplateSet(string) bool {
return true
}
1 change: 1 addition & 0 deletions routers/api/v1/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func ListIssues(ctx *context.APIContext) {
issues, err := models.Issues(&models.IssuesOptions{
RepoID: ctx.Repo.Repository.ID,
Page: ctx.QueryInt("page"),
PageSize: setting.UI.IssuePagingNum,
IsClosed: isClosed,
})
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions routers/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ func Issues(ctx *context.Context) {
MentionedID: mentionedID,
MilestoneID: milestoneID,
Page: pager.Current(),
PageSize: setting.UI.IssuePagingNum,
IsClosed: util.OptionalBoolOf(isShowClosed),
IsPull: util.OptionalBoolOf(isPullList),
Labels: selectLabels,
Expand Down
Loading