Skip to content

Commit

Permalink
[API] Extend times API (#9200)
Browse files Browse the repository at this point in the history
Extensively extend the times API.

close #8833; close #8513; close #8559
  • Loading branch information
6543 authored and zeripath committed Dec 27, 2019
1 parent 0bcf644 commit f2d03cd
Show file tree
Hide file tree
Showing 19 changed files with 914 additions and 192 deletions.
109 changes: 109 additions & 0 deletions integrations/api_issue_tracked_time_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2019 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 integrations

import (
"fmt"
"net/http"
"testing"
"time"

"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"

"github.com/stretchr/testify/assert"
)

func TestAPIGetTrackedTimes(t *testing.T) {
defer prepareTestEnv(t)()

user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
issue2 := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue)
assert.NoError(t, issue2.LoadRepo())

session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session)

req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token)
resp := session.MakeRequest(t, req, http.StatusOK)
var apiTimes api.TrackedTimeList
DecodeJSON(t, resp, &apiTimes)
expect, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{IssueID: issue2.ID})
assert.NoError(t, err)
assert.Len(t, apiTimes, 3)

for i, time := range expect {
assert.Equal(t, time.ID, apiTimes[i].ID)
assert.EqualValues(t, issue2.Title, apiTimes[i].Issue.Title)
assert.EqualValues(t, issue2.ID, apiTimes[i].IssueID)
assert.Equal(t, time.Created.Unix(), apiTimes[i].Created.Unix())
assert.Equal(t, time.Time, apiTimes[i].Time)
user, err := models.GetUserByID(time.UserID)
assert.NoError(t, err)
assert.Equal(t, user.Name, apiTimes[i].UserName)
}
}

func TestAPIDeleteTrackedTime(t *testing.T) {
defer prepareTestEnv(t)()

time6 := models.AssertExistsAndLoadBean(t, &models.TrackedTime{ID: 6}).(*models.TrackedTime)
issue2 := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue)
assert.NoError(t, issue2.LoadRepo())
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)

session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session)

//Deletion not allowed
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token)
session.MakeRequest(t, req, http.StatusForbidden)
/* Delete own time <-- ToDo: timout without reason
time3 := models.AssertExistsAndLoadBean(t, &models.TrackedTime{ID: 3}).(*models.TrackedTime)
req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID, token)
session.MakeRequest(t, req, http.StatusNoContent)
//Delete non existing time
session.MakeRequest(t, req, http.StatusInternalServerError) */

//Reset time of user 2 on issue 2
trackedSeconds, err := models.GetTrackedSeconds(models.FindTrackedTimesOptions{IssueID: 2, UserID: 2})
assert.NoError(t, err)
assert.Equal(t, int64(3662), trackedSeconds)

req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token)
session.MakeRequest(t, req, http.StatusNoContent)
session.MakeRequest(t, req, http.StatusNotFound)

trackedSeconds, err = models.GetTrackedSeconds(models.FindTrackedTimesOptions{IssueID: 2, UserID: 2})
assert.NoError(t, err)
assert.Equal(t, int64(0), trackedSeconds)
}

func TestAPIAddTrackedTimes(t *testing.T) {
defer prepareTestEnv(t)()

issue2 := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue)
assert.NoError(t, issue2.LoadRepo())
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
admin := models.AssertExistsAndLoadBean(t, &models.User{ID: 1}).(*models.User)

session := loginUser(t, admin.Name)
token := getTokenForLoggedInUser(t, session)

urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token)

req := NewRequestWithJSON(t, "POST", urlStr, &api.AddTimeOption{
Time: 33,
User: user2.Name,
Created: time.Unix(947688818, 0),
})
resp := session.MakeRequest(t, req, http.StatusOK)
var apiNewTime api.TrackedTime
DecodeJSON(t, resp, &apiNewTime)

assert.EqualValues(t, 33, apiNewTime.Time)
assert.EqualValues(t, user2.ID, apiNewTime.UserID)
assert.EqualValues(t, 947688818, apiNewTime.Created.Unix())
}
41 changes: 39 additions & 2 deletions models/fixtures/tracked_time.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,68 @@
issue_id: 1
time: 400
created_unix: 946684800
deleted: false

-
id: 2
user_id: 2
issue_id: 2
time: 3661
created_unix: 946684801
deleted: false

-
id: 3
user_id: 2
issue_id: 2
time: 1
created_unix: 946684802
deleted: false

-
id: 4
user_id: -1
issue_id: 4
time: 1
created_unix: 946684802
created_unix: 946684803
deleted: false

-
id: 5
user_id: 2
issue_id: 5
time: 1
created_unix: 946684802
created_unix: 946684804
deleted: false

-
id: 6
user_id: 1
issue_id: 2
time: 20
created_unix: 946684812
deleted: false

-
id: 7
user_id: 2
issue_id: 4
time: 3
created_unix: 946684813
deleted: false

-
id: 8
user_id: 1
issue_id: 4
time: 71
created_unix: 947688814
deleted: false

-
id: 9
user_id: 2
issue_id: 2
time: 100000
created_unix: 947688815
deleted: true
4 changes: 3 additions & 1 deletion models/issue_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ const (
CommentTypeUnlock
// Change pull request's target branch
CommentTypeChangeTargetBranch
// Delete time manual for time tracking
CommentTypeDeleteTimeManual
)

// CommentTag defines comment tag type
Expand All @@ -100,7 +102,7 @@ const (
// Comment represents a comment in commit and issue page.
type Comment struct {
ID int64 `xorm:"pk autoincr"`
Type CommentType `xorm:"index"`
Type CommentType `xorm:"INDEX"`
PosterID int64 `xorm:"INDEX"`
Poster *User `xorm:"-"`
OriginalAuthor string
Expand Down
1 change: 1 addition & 0 deletions models/issue_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ func (issues IssueList) loadTotalTrackedTimes(e Engine) (err error) {

// select issue_id, sum(time) from tracked_time where issue_id in (<issue ids in current page>) group by issue_id
rows, err := e.Table("tracked_time").
Where("deleted = ?", false).
Select("issue_id, sum(time) as time").
In("issue_id", ids[:limit]).
GroupBy("issue_id").
Expand Down
2 changes: 1 addition & 1 deletion models/issue_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestIssueList_LoadAttributes(t *testing.T) {
if issue.ID == int64(1) {
assert.Equal(t, int64(400), issue.TotalTrackedTime)
} else if issue.ID == int64(2) {
assert.Equal(t, int64(3662), issue.TotalTrackedTime)
assert.Equal(t, int64(3682), issue.TotalTrackedTime)
}
}
}
4 changes: 3 additions & 1 deletion models/issue_milestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"

"xorm.io/builder"
"xorm.io/xorm"
)

Expand Down Expand Up @@ -153,6 +153,7 @@ func (milestones MilestoneList) loadTotalTrackedTimes(e Engine) error {
rows, err := e.Table("issue").
Join("INNER", "milestone", "issue.milestone_id = milestone.id").
Join("LEFT", "tracked_time", "tracked_time.issue_id = issue.id").
Where("tracked_time.deleted = ?", false).
Select("milestone_id, sum(time) as time").
In("milestone_id", milestones.getMilestoneIDs()).
GroupBy("milestone_id").
Expand Down Expand Up @@ -187,6 +188,7 @@ func (m *Milestone) loadTotalTrackedTime(e Engine) error {
has, err := e.Table("issue").
Join("INNER", "milestone", "issue.milestone_id = milestone.id").
Join("LEFT", "tracked_time", "tracked_time.issue_id = issue.id").
Where("tracked_time.deleted = ?", false).
Select("milestone_id, sum(time) as time").
Where("milestone_id = ?", m.ID).
GroupBy("milestone_id").
Expand Down
4 changes: 2 additions & 2 deletions models/issue_milestone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) {

assert.NoError(t, miles.LoadTotalTrackedTimes())

assert.Equal(t, miles[0].TotalTrackedTime, int64(3662))
assert.Equal(t, int64(3682), miles[0].TotalTrackedTime)
}

func TestCountMilestonesByRepoIDs(t *testing.T) {
Expand Down Expand Up @@ -361,7 +361,7 @@ func TestLoadTotalTrackedTime(t *testing.T) {

assert.NoError(t, milestone.LoadTotalTrackedTime())

assert.Equal(t, milestone.TotalTrackedTime, int64(3662))
assert.Equal(t, int64(3682), milestone.TotalTrackedTime)
}

func TestGetMilestonesStats(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion models/issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func TestIssue_loadTotalTimes(t *testing.T) {
ms, err := GetIssueByID(2)
assert.NoError(t, err)
assert.NoError(t, ms.loadTotalTimes(x))
assert.Equal(t, int64(3662), ms.TotalTrackedTime)
assert.Equal(t, int64(3682), ms.TotalTrackedTime)
}

func TestIssue_SearchIssueIDsByKeyword(t *testing.T) {
Expand Down

0 comments on commit f2d03cd

Please sign in to comment.