]> source.dussan.org Git - gitea.git/commitdiff
Bug fixes and unit tests for models/issue_label (#802)
authorEthan Koenig <etk39@cornell.edu>
Wed, 1 Feb 2017 01:31:35 +0000 (20:31 -0500)
committerLunny Xiao <xiaolunwen@gmail.com>
Wed, 1 Feb 2017 01:31:35 +0000 (09:31 +0800)
models/fixtures/comment.yml [new file with mode: 0644]
models/fixtures/issue.yml
models/fixtures/issue_label.yml [new file with mode: 0644]
models/fixtures/label.yml [new file with mode: 0644]
models/issue.go
models/issue_label.go
models/issue_label_test.go [new file with mode: 0644]
routers/api/v1/repo/issue_label.go

diff --git a/models/fixtures/comment.yml b/models/fixtures/comment.yml
new file mode 100644 (file)
index 0000000..e38952a
--- /dev/null
@@ -0,0 +1,7 @@
+-
+  id: 1
+  type: 7 # label
+  poster_id: 2
+  issue_id: 1
+  label_id: 1
+  content: "1"
index dbd435939ab4b4145cca71a53c94d040df667bfe..8bcadb0aae2bd82cc482d6ca857a0683c361aa2b 100644 (file)
   content: content4
   is_closed: true
   is_pull: false
+
+-
+  id: 5
+  repo_id: 1
+  index: 4
+  poster_id: 2
+  name: issue5
+  content: content5
+  is_closed: true
+  is_pull: false
diff --git a/models/fixtures/issue_label.yml b/models/fixtures/issue_label.yml
new file mode 100644 (file)
index 0000000..49d5a95
--- /dev/null
@@ -0,0 +1,14 @@
+-
+  id: 1
+  issue_id: 1
+  label_id: 1
+
+-
+  id: 2
+  issue_id: 5
+  label_id: 2
+
+-
+  id: 3
+  issue_id: 2
+  label_id: 1
diff --git a/models/fixtures/label.yml b/models/fixtures/label.yml
new file mode 100644 (file)
index 0000000..5336342
--- /dev/null
@@ -0,0 +1,15 @@
+-
+  id: 1
+  repo_id: 1
+  name: label1
+  color: '#abcdef'
+  num_issues: 2
+  num_closed_issues: 0
+
+-
+  id: 2
+  repo_id: 1
+  name: label2
+  color: '#000000'
+  num_issues: 1
+  num_closed_issues: 1
index 0102656f02cee81e32b4e44e166f95ad66ebe94f..1727da1d5014792359d4a798573b18e7e3ca946e 100644 (file)
@@ -345,7 +345,7 @@ func (issue *Issue) getLabels(e Engine) (err error) {
 }
 
 func (issue *Issue) removeLabel(e *xorm.Session, doer *User, label *Label) error {
-       return deleteIssueLabel(e, doer, issue, label)
+       return deleteIssueLabel(e, issue, label, doer)
 }
 
 // RemoveLabel removes a label from issue by given ID.
@@ -360,7 +360,7 @@ func (issue *Issue) RemoveLabel(doer *User, label *Label) error {
                return ErrLabelNotExist{}
        }
 
-       if err := DeleteIssueLabel(issue, doer, label); err != nil {
+       if err := DeleteIssueLabel(issue, label, doer); err != nil {
                return err
        }
 
index 02397f146f5d798c118b8798c7be0d76045554fd..970b3fcc4cfc1e2f9f623af6ad09fa262db4c126 100644 (file)
@@ -114,7 +114,7 @@ func getLabelInRepoByName(e Engine, repoID int64, labelName string) (*Label, err
                Name:   labelName,
                RepoID: repoID,
        }
-       has, err := x.Get(l)
+       has, err := e.Get(l)
        if err != nil {
                return nil, err
        } else if !has {
@@ -135,7 +135,7 @@ func getLabelInRepoByID(e Engine, repoID, labelID int64) (*Label, error) {
                ID:     labelID,
                RepoID: repoID,
        }
-       has, err := x.Get(l)
+       has, err := e.Get(l)
        if err != nil {
                return nil, err
        } else if !has {
@@ -355,17 +355,14 @@ func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
                Find(&issueLabels)
 }
 
-// GetIssueLabels returns all issue-label relations of given issue by ID.
-func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
-       return getIssueLabels(x, issueID)
-}
-
-func deleteIssueLabel(e *xorm.Session, doer *User, issue *Issue, label *Label) (err error) {
-       if _, err = e.Delete(&IssueLabel{
+func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label, doer *User) (err error) {
+       if count, err := e.Delete(&IssueLabel{
                IssueID: issue.ID,
                LabelID: label.ID,
        }); err != nil {
                return err
+       } else if count == 0 {
+               return nil
        }
 
        if err = issue.loadRepo(e); err != nil {
@@ -384,14 +381,14 @@ func deleteIssueLabel(e *xorm.Session, doer *User, issue *Issue, label *Label) (
 }
 
 // DeleteIssueLabel deletes issue-label relation.
-func DeleteIssueLabel(issue *Issue, doer *User, label *Label) (err error) {
+func DeleteIssueLabel(issue *Issue, label *Label, doer *User) (err error) {
        sess := x.NewSession()
        defer sessionRelease(sess)
        if err = sess.Begin(); err != nil {
                return err
        }
 
-       if err = deleteIssueLabel(sess, doer, issue, label); err != nil {
+       if err = deleteIssueLabel(sess, issue, label, doer); err != nil {
                return err
        }
 
diff --git a/models/issue_label_test.go b/models/issue_label_test.go
new file mode 100644 (file)
index 0000000..a1cdb8c
--- /dev/null
@@ -0,0 +1,244 @@
+// 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 models
+
+import (
+       "html/template"
+       "testing"
+
+       api "code.gitea.io/sdk/gitea"
+
+       "github.com/stretchr/testify/assert"
+)
+
+// TODO TestGetLabelTemplateFile
+
+func TestLabel_APIFormat(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       assert.Equal(t, api.Label{
+               ID:    label.ID,
+               Name:  label.Name,
+               Color: "abcdef",
+       }, *label.APIFormat())
+}
+
+func TestLabel_CalOpenIssues(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       label.CalOpenIssues()
+       assert.EqualValues(t, 2, label.NumOpenIssues)
+}
+
+func TestLabel_ForegroundColor(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       assert.Equal(t, template.CSS("#000"), label.ForegroundColor())
+
+       label = AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
+       assert.Equal(t, template.CSS("#fff"), label.ForegroundColor())
+}
+
+func TestNewLabels(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       labels := []*Label{
+               {RepoID: 2, Name: "labelName2", Color: "#123456"},
+               {RepoID: 3, Name: "labelName3", Color: "#234567"},
+       }
+       for _, label := range labels {
+               AssertNotExistsBean(t, label)
+       }
+       assert.NoError(t, NewLabels(labels...))
+       for _, label := range labels {
+               AssertExistsAndLoadBean(t, label)
+       }
+}
+
+func TestGetLabelByID(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label, err := GetLabelByID(1)
+       assert.NoError(t, err)
+       assert.EqualValues(t, 1, label.ID)
+
+       _, err = GetLabelByID(NonexistentID)
+       assert.True(t, IsErrLabelNotExist(err))
+}
+
+func TestGetLabelInRepoByName(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label, err := GetLabelInRepoByName(1, "label1")
+       assert.NoError(t, err)
+       assert.EqualValues(t, 1, label.ID)
+       assert.Equal(t, "label1", label.Name)
+
+       _, err = GetLabelInRepoByName(1, "")
+       assert.True(t, IsErrLabelNotExist(err))
+
+       _, err = GetLabelInRepoByName(NonexistentID, "nonexistent")
+       assert.True(t, IsErrLabelNotExist(err))
+}
+
+func TestGetLabelInRepoByID(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label, err := GetLabelInRepoByID(1, 1)
+       assert.NoError(t, err)
+       assert.EqualValues(t, 1, label.ID)
+
+       _, err = GetLabelInRepoByID(1, -1)
+       assert.True(t, IsErrLabelNotExist(err))
+
+       _, err = GetLabelInRepoByID(NonexistentID, NonexistentID)
+       assert.True(t, IsErrLabelNotExist(err))
+}
+
+func TestGetLabelsInRepoByIDs(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       labels, err := GetLabelsInRepoByIDs(1, []int64{1, 2, NonexistentID})
+       assert.NoError(t, err)
+       assert.Len(t, labels, 2)
+       assert.EqualValues(t, 1, labels[0].ID)
+       assert.EqualValues(t, 2, labels[1].ID)
+}
+
+func TestGetLabelsByRepoID(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) {
+               labels, err := GetLabelsByRepoID(repoID, sortType)
+               assert.NoError(t, err)
+               assert.Len(t, labels, len(expectedIssueIDs))
+               for i, label := range labels {
+                       assert.EqualValues(t, expectedIssueIDs[i], label.ID)
+               }
+       }
+       testSuccess(1, "leastissues", []int64{2, 1})
+       testSuccess(1, "mostissues", []int64{1, 2})
+       testSuccess(1, "reversealphabetically", []int64{2, 1})
+       testSuccess(1, "default", []int64{1, 2})
+}
+
+func TestGetLabelsByIssueID(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       labels, err := GetLabelsByIssueID(1)
+       assert.NoError(t, err)
+       assert.Len(t, labels, 1)
+       assert.EqualValues(t, 1, labels[0].ID)
+
+       labels, err = GetLabelsByIssueID(NonexistentID)
+       assert.NoError(t, err)
+       assert.Len(t, labels, 0)
+}
+
+func TestUpdateLabel(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       label.Color = "#ffff00"
+       label.Name = "newLabelName"
+       assert.NoError(t, UpdateLabel(label))
+       newLabel := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       assert.Equal(t, *label, *newLabel)
+}
+
+func TestDeleteLabel(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       assert.NoError(t, DeleteLabel(label.RepoID, label.ID))
+       AssertNotExistsBean(t, &Label{ID: label.ID, RepoID: label.RepoID})
+
+       assert.NoError(t, DeleteLabel(label.RepoID, label.ID))
+       AssertNotExistsBean(t, &Label{ID: label.ID, RepoID: label.RepoID})
+
+       assert.NoError(t, DeleteLabel(NonexistentID, NonexistentID))
+}
+
+func TestHasIssueLabel(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       assert.True(t, HasIssueLabel(1, 1))
+       assert.False(t, HasIssueLabel(1, 2))
+       assert.False(t, HasIssueLabel(NonexistentID, NonexistentID))
+}
+
+func TestNewIssueLabel(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label := AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
+       issue := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)
+       doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
+
+       // add new IssueLabel
+       prevNumIssues := label.NumIssues
+       assert.NoError(t, NewIssueLabel(issue, label, doer))
+       AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label.ID})
+       AssertExistsAndLoadBean(t, &Comment{
+               Type:     CommentTypeLabel,
+               PosterID: doer.ID,
+               IssueID:  issue.ID,
+               LabelID:  label.ID,
+               Content:  "1",
+       })
+       assert.EqualValues(t, prevNumIssues+1, label.NumIssues)
+
+       // re-add existing IssueLabel
+       assert.NoError(t, NewIssueLabel(issue, label, doer))
+}
+
+func TestNewIssueLabels(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       label1 := AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       label2 := AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
+       issue := AssertExistsAndLoadBean(t, &Issue{ID: 5}).(*Issue)
+       doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
+
+       assert.NoError(t, NewIssueLabels(issue, []*Label{label1, label2}, doer))
+       AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
+       AssertExistsAndLoadBean(t, &Comment{
+               Type:     CommentTypeLabel,
+               PosterID: doer.ID,
+               IssueID:  issue.ID,
+               LabelID:  label1.ID,
+               Content:  "1",
+       })
+       AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
+       label1 = AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
+       assert.EqualValues(t, 3, label1.NumIssues)
+       assert.EqualValues(t, 1, label1.NumClosedIssues)
+       label2 = AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
+       assert.EqualValues(t, 1, label2.NumIssues)
+       assert.EqualValues(t, 1, label2.NumClosedIssues)
+
+       // corner case: test empty slice
+       assert.NoError(t, NewIssueLabels(issue, []*Label{}, doer))
+}
+
+func TestDeleteIssueLabel(t *testing.T) {
+       assert.NoError(t, PrepareTestDatabase())
+       testSuccess := func(labelID, issueID, doerID int64) {
+               label := AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label)
+               issue := AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue)
+               doer := AssertExistsAndLoadBean(t, &User{ID: doerID}).(*User)
+
+               expectedNumIssues := label.NumIssues
+               expectedNumClosedIssues := label.NumClosedIssues
+               if BeanExists(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) {
+                       expectedNumIssues--
+                       if issue.IsClosed {
+                               expectedNumClosedIssues--
+                       }
+               }
+
+               assert.NoError(t, DeleteIssueLabel(issue, label, doer))
+               AssertNotExistsBean(t, &IssueLabel{IssueID: issueID, LabelID: labelID})
+               AssertExistsAndLoadBean(t, &Comment{
+                       Type:     CommentTypeLabel,
+                       PosterID: doerID,
+                       IssueID:  issueID,
+                       LabelID:  labelID,
+               }, `content=""`)
+               label = AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label)
+               assert.EqualValues(t, expectedNumIssues, label.NumIssues)
+               assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues)
+       }
+       testSuccess(1, 1, 2)
+       testSuccess(2, 5, 2)
+       testSuccess(1, 1, 2) // delete non-existent IssueLabel
+}
index 20de41b75807747038562a138f697c01a8b3cee6..d94d666714b973f187cd14c7fce7e44a1a0159b1 100644 (file)
@@ -98,7 +98,7 @@ func DeleteIssueLabel(ctx *context.APIContext) {
                return
        }
 
-       if err := models.DeleteIssueLabel(issue, ctx.User, label); err != nil {
+       if err := models.DeleteIssueLabel(issue, label, ctx.User); err != nil {
                ctx.Error(500, "DeleteIssueLabel", err)
                return
        }