From 973799b4b81d142e5952d517fb41f85894cf0756 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 8 Dec 2019 22:30:37 +0100 Subject: [PATCH 1/6] squash api-stopwatch --- models/issue_stopwatch.go | 39 +++++ modules/structs/issue_stopwatch.go | 19 +++ routers/api/v1/api.go | 3 + routers/api/v1/repo/issue.go | 138 ---------------- routers/api/v1/repo/issue_stopwatch.go | 212 +++++++++++++++++++++++++ routers/api/v1/swagger/issue.go | 14 ++ templates/swagger/v1_json.tmpl | 107 ++++++++++++- 7 files changed, 393 insertions(+), 139 deletions(-) create mode 100644 modules/structs/issue_stopwatch.go create mode 100644 routers/api/v1/repo/issue_stopwatch.go diff --git a/models/issue_stopwatch.go b/models/issue_stopwatch.go index d7c3a9f73b379..b0d78a6e3cd7c 100644 --- a/models/issue_stopwatch.go +++ b/models/issue_stopwatch.go @@ -8,6 +8,7 @@ import ( "fmt" "time" + api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" ) @@ -28,6 +29,16 @@ func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, return } +// GetUserStopwatches return list of all stopwatches of a user +func GetUserStopwatches(userID int64) (sws *Stopwatches, err error) { + sws = new(Stopwatches) + err = x.Where("stopwatch.user_id = ?", userID).Find(sws) + if err != nil { + return nil, err + } + return sws, nil +} + // StopwatchExists returns true if the stopwatch exists func StopwatchExists(userID int64, issueID int64) bool { _, exists, _ := getStopwatch(x, userID, issueID) @@ -160,3 +171,31 @@ func SecToTime(duration int64) string { return hrs } + +// APIFormat convert Stopwatch type to api.StopWatch type +func (sw *Stopwatch) APIFormat() (api.StopWatch, error) { + issue, err := getIssueByID(x, sw.IssueID) + if err != nil { + return api.StopWatch{}, err + } + return api.StopWatch{ + Created: sw.CreatedUnix.AsTime(), + IssueIndex: issue.Index, + }, nil +} + +// Stopwatches is a List ful of Stopwatch +type Stopwatches []Stopwatch + +// APIFormat convert Stopwatches type to api.StopWatches type +func (sws Stopwatches) APIFormat() (api.StopWatches, error) { + result := api.StopWatches(make([]api.StopWatch, 0, len(sws))) + for _, sw := range sws { + apiSW, err := sw.APIFormat() + if err != nil { + return nil, err + } + result = append(result, apiSW) + } + return result, nil +} diff --git a/modules/structs/issue_stopwatch.go b/modules/structs/issue_stopwatch.go new file mode 100644 index 0000000000000..10510e36efbd7 --- /dev/null +++ b/modules/structs/issue_stopwatch.go @@ -0,0 +1,19 @@ +// 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 structs + +import ( + "time" +) + +// StopWatch represent a running stopwatch +type StopWatch struct { + // swagger:strfmt date-time + Created time.Time `json:"created"` + IssueIndex int64 `json:"issue_index"` +} + +// StopWatches represent a list of stopwatches +type StopWatches []StopWatch diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index cd5fc1f3eb27d..7526d3f5efe67 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -584,6 +584,8 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Get("/times", repo.ListMyTrackedTimes) + m.Get("/stopwatches", repo.GetStopwatches) + m.Get("/subscriptions", user.GetMyWatchedRepos) m.Get("/teams", org.ListUserTeams) @@ -691,6 +693,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/stopwatch", func() { m.Post("/start", reqToken(), repo.StartIssueStopwatch) m.Post("/stop", reqToken(), repo.StopIssueStopwatch) + m.Delete("/delete", reqToken(), repo.DeleteIssueStopwatch) }) m.Group("/subscriptions", func() { m.Get("", repo.GetIssueSubscribers) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 186e66cb8f8c6..6972d447a6216 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -598,141 +598,3 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) { ctx.JSON(201, api.IssueDeadline{Deadline: &deadline}) } - -// StartIssueStopwatch creates a stopwatch for the given issue. -func StartIssueStopwatch(ctx *context.APIContext) { - // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/stopwatch/start issue issueStartStopWatch - // --- - // summary: Start stopwatch on an issue. - // consumes: - // - application/json - // produces: - // - application/json - // parameters: - // - name: owner - // in: path - // description: owner of the repo - // type: string - // required: true - // - name: repo - // in: path - // description: name of the repo - // type: string - // required: true - // - name: index - // in: path - // description: index of the issue to create the stopwatch on - // type: integer - // format: int64 - // required: true - // responses: - // "201": - // "$ref": "#/responses/empty" - // "403": - // description: Not repo writer, user does not have rights to toggle stopwatch - // "404": - // description: Issue not found - // "409": - // description: Cannot start a stopwatch again if it already exists - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) - if err != nil { - if models.IsErrIssueNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetIssueByIndex", err) - } - - return - } - - if !ctx.Repo.CanWrite(models.UnitTypeIssues) { - ctx.Status(403) - return - } - - if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { - ctx.Status(403) - return - } - - if models.StopwatchExists(ctx.User.ID, issue.ID) { - ctx.Error(409, "StopwatchExists", "a stopwatch has already been started for this issue") - return - } - - if err := models.CreateOrStopIssueStopwatch(ctx.User, issue); err != nil { - ctx.Error(500, "CreateOrStopIssueStopwatch", err) - return - } - - ctx.Status(201) -} - -// StopIssueStopwatch stops a stopwatch for the given issue. -func StopIssueStopwatch(ctx *context.APIContext) { - // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/stopwatch/stop issue issueStopWatch - // --- - // summary: Stop an issue's existing stopwatch. - // consumes: - // - application/json - // produces: - // - application/json - // parameters: - // - name: owner - // in: path - // description: owner of the repo - // type: string - // required: true - // - name: repo - // in: path - // description: name of the repo - // type: string - // required: true - // - name: index - // in: path - // description: index of the issue to stop the stopwatch on - // type: integer - // format: int64 - // required: true - // responses: - // "201": - // "$ref": "#/responses/empty" - // "403": - // description: Not repo writer, user does not have rights to toggle stopwatch - // "404": - // description: Issue not found - // "409": - // description: Cannot stop a non existent stopwatch - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) - if err != nil { - if models.IsErrIssueNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetIssueByIndex", err) - } - - return - } - - if !ctx.Repo.CanWrite(models.UnitTypeIssues) { - ctx.Status(403) - return - } - - if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { - ctx.Status(403) - return - } - - if !models.StopwatchExists(ctx.User.ID, issue.ID) { - ctx.Error(409, "StopwatchExists", "cannot stop a non existent stopwatch") - return - } - - if err := models.CreateOrStopIssueStopwatch(ctx.User, issue); err != nil { - ctx.Error(500, "CreateOrStopIssueStopwatch", err) - return - } - - ctx.Status(201) -} diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go new file mode 100644 index 0000000000000..5b321b5a53eb8 --- /dev/null +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -0,0 +1,212 @@ +// 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 repo + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" +) + +// StartIssueStopwatch creates a stopwatch for the given issue. +func StartIssueStopwatch(ctx *context.APIContext) { + // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/stopwatch/start issue issueStartStopWatch + // --- + // summary: Start stopwatch on an issue. + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue to create the stopwatch on + // type: integer + // format: int64 + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "403": + // description: Not repo writer, user does not have rights to toggle stopwatch + // "404": + // description: Issue not found + // "409": + // description: Cannot start a stopwatch again if it already exists + issue, err := prepareIssueStopwatch(ctx, false) + if err != nil { + return + } + + if err := models.CreateOrStopIssueStopwatch(ctx.User, issue); err != nil { + ctx.Error(500, "CreateOrStopIssueStopwatch", err) + return + } + + ctx.Status(201) +} + +// StopIssueStopwatch stops a stopwatch for the given issue. +func StopIssueStopwatch(ctx *context.APIContext) { + // swagger:operation POST /repos/{owner}/{repo}/issues/{index}/stopwatch/stop issue issueStopStopWatch + // --- + // summary: Stop an issue's existing stopwatch. + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue to stop the stopwatch on + // type: integer + // format: int64 + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "403": + // description: Not repo writer, user does not have rights to toggle stopwatch + // "404": + // description: Issue not found + // "409": + // description: Cannot stop a non existent stopwatch + issue, err := prepareIssueStopwatch(ctx, true) + if err != nil { + return + } + + if err := models.CreateOrStopIssueStopwatch(ctx.User, issue); err != nil { + ctx.Error(500, "CreateOrStopIssueStopwatch", err) + return + } + + ctx.Status(201) +} + +// DeleteIssueStopwatch delete a specific stopwatch +func DeleteIssueStopwatch(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/stopwatch/delete issue issueDeleteStopWatch + // --- + // summary: Delete an issue's existing stopwatch. + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue to stop the stopwatch on + // type: integer + // format: int64 + // required: true + // responses: + // "202": + // "$ref": "#/responses/empty" + // "403": + // description: Not repo writer, user does not have rights to toggle stopwatch + // "404": + // description: Issue not found + // "409": + // description: Cannot stop a non existent stopwatch + issue, err := prepareIssueStopwatch(ctx, true) + if err != nil { + return + } + + if err := models.CancelStopwatch(ctx.User, issue); err != nil { + ctx.Error(500, "CancelStopwatch", err) + return + } + + ctx.Status(202) +} + +func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.Issue, error) { + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return nil, err + } + + if !ctx.Repo.CanWrite(models.UnitTypeIssues) { + ctx.Status(403) + return nil, err + } + + if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { + ctx.Status(403) + return nil, err + } + + if models.StopwatchExists(ctx.User.ID, issue.ID) == shouldExist { + ctx.Error(409, "StopwatchExists", "cannot stop a non existent stopwatch") + return nil, err + } + + return issue, nil +} + +// GetStopwatches get all stopwatches +func GetStopwatches(ctx *context.APIContext) { + // swagger:operation GET /user/stopwatches user userGetStopWatches + // --- + // summary: Get list of all existing stopwatches + // consumes: + // - application/json + // produces: + // - application/json + // responses: + // "200": + // "$ref": "#/responses/StopWatchList" + + sws, err := models.GetUserStopwatches(ctx.User.ID) + if err != nil { + ctx.Error(500, "GetUserStopwatches", err) + return + } + + apiSWs, err := sws.APIFormat() + if err != nil { + ctx.Error(500, "APIFormat", err) + return + } + + ctx.JSON(200, apiSWs) +} diff --git a/routers/api/v1/swagger/issue.go b/routers/api/v1/swagger/issue.go index a78c2982fd706..68c0a9a38d694 100644 --- a/routers/api/v1/swagger/issue.go +++ b/routers/api/v1/swagger/issue.go @@ -85,6 +85,20 @@ type swaggerIssueDeadline struct { Body api.IssueDeadline `json:"body"` } +// StopWatch +// swagger:response StopWatch +type swaggerResponseStopWatch struct { + // in:body + Body api.StopWatch `json:"body"` +} + +// StopWatchList +// swagger:response StopWatchList +type swaggerResponseStopWatchList struct { + // in:body + Body []api.StopWatch `json:"body"` +} + // EditReactionOption // swagger:response EditReactionOption type swaggerEditReactionOption struct { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 9c8db28817aba..e09b91bb40bd9 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3972,6 +3972,59 @@ } } }, + "/repos/{owner}/{repo}/issues/{index}/stopwatch/delete": { + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "Delete an issue's existing stopwatch.", + "operationId": "issueDeleteStopWatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "index of the issue to stop the stopwatch on", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "202": { + "$ref": "#/responses/empty" + }, + "403": { + "description": "Not repo writer, user does not have rights to toggle stopwatch" + }, + "404": { + "description": "Issue not found" + }, + "409": { + "description": "Cannot stop a non existent stopwatch" + } + } + } + }, "/repos/{owner}/{repo}/issues/{index}/stopwatch/start": { "post": { "consumes": [ @@ -4037,7 +4090,7 @@ "issue" ], "summary": "Stop an issue's existing stopwatch.", - "operationId": "issueStopWatch", + "operationId": "issueStopStopWatch", "parameters": [ { "type": "string", @@ -7174,6 +7227,26 @@ } } }, + "/user/stopwatches": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Get list of all existing stopwatches", + "operationId": "userGetStopWatches", + "responses": { + "200": { + "$ref": "#/responses/StopWatchList" + } + } + } + }, "/user/subscriptions": { "get": { "produces": [ @@ -10808,6 +10881,23 @@ "type": "string", "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "StopWatch": { + "description": "StopWatch represent a running stopwatch", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "issue_index": { + "type": "integer", + "format": "int64", + "x-go-name": "IssueIndex" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "Tag": { "description": "Tag represents a repository tag", "type": "object", @@ -11553,6 +11643,21 @@ } } }, + "StopWatch": { + "description": "StopWatch", + "schema": { + "$ref": "#/definitions/StopWatch" + } + }, + "StopWatchList": { + "description": "StopWatchList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/StopWatch" + } + } + }, "Tag": { "description": "Tag", "schema": { From 3d264c76455e2b727dd9d1ea3a74dbd5889c36d3 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 9 Dec 2019 15:30:44 +0100 Subject: [PATCH 2/6] fix prepair logic! + add Tests --- integrations/api_issue_stopwatch_test.go | 83 ++++++++++++++++++++++++ models/fixtures/stopwatch.yml | 4 +- routers/api/v1/repo/issue_stopwatch.go | 10 ++- templates/swagger/v1_json.tmpl | 2 +- 4 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 integrations/api_issue_stopwatch_test.go diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go new file mode 100644 index 0000000000000..f8b4fc3df26d2 --- /dev/null +++ b/integrations/api_issue_stopwatch_test.go @@ -0,0 +1,83 @@ +// 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 ( + "net/http" + "testing" + + "code.gitea.io/gitea/models" + api "code.gitea.io/gitea/modules/structs" + + "github.com/stretchr/testify/assert" +) + +func TestAPIListStopWatches(t *testing.T) { + defer prepareTestEnv(t)() + + repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) + owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + + session := loginUser(t, owner.Name) + token := getTokenForLoggedInUser(t, session) + req := NewRequestf(t, "GET", "/api/v1/user/stopwatches?token=%s", token) + resp := session.MakeRequest(t, req, http.StatusOK) + var apiWatches []*api.StopWatch + DecodeJSON(t, resp, &apiWatches) + expect := models.AssertExistsAndLoadBean(t, &models.Stopwatch{UserID: owner.ID}).(*models.Stopwatch) + expectApi, _ := expect.APIFormat() + assert.Len(t, apiWatches, 1) + + assert.EqualValues(t, expectApi.IssueIndex, apiWatches[0].IssueIndex) + assert.EqualValues(t, expectApi.Created, apiWatches[0].Created) +} + +func TestAPIStopStopWatches(t *testing.T) { + defer prepareTestEnv(t)() + + issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + _ = issue.LoadRepo() + owner := models.AssertExistsAndLoadBean(t, &models.User{ID: issue.Repo.OwnerID}).(*models.User) + user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session) + + req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/stop?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) + session.MakeRequest(t, req, http.StatusCreated) + session.MakeRequest(t, req, http.StatusConflict) +} + +func TestAPICancelStopWatches(t *testing.T) { + defer prepareTestEnv(t)() + + issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + _ = issue.LoadRepo() + owner := models.AssertExistsAndLoadBean(t, &models.User{ID: issue.Repo.OwnerID}).(*models.User) + user := models.AssertExistsAndLoadBean(t, &models.User{ID: 1}).(*models.User) + + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session) + + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/stopwatch/delete?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) + session.MakeRequest(t, req, http.StatusAccepted) + session.MakeRequest(t, req, http.StatusConflict) +} + +func TestAPIStartStopWatches(t *testing.T) { + defer prepareTestEnv(t)() + + issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) + _ = issue.LoadRepo() + owner := models.AssertExistsAndLoadBean(t, &models.User{ID: issue.Repo.OwnerID}).(*models.User) + user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session) + + req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/start?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) + session.MakeRequest(t, req, http.StatusCreated) + session.MakeRequest(t, req, http.StatusConflict) +} diff --git a/models/fixtures/stopwatch.yml b/models/fixtures/stopwatch.yml index 397a8214d4570..b7919d6fbbd6e 100644 --- a/models/fixtures/stopwatch.yml +++ b/models/fixtures/stopwatch.yml @@ -2,10 +2,10 @@ id: 1 user_id: 1 issue_id: 1 - created_unix: 1500988502 + created_unix: 1500988001 - id: 2 user_id: 2 issue_id: 2 - created_unix: 1500988502 + created_unix: 1500988002 diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 5b321b5a53eb8..8372252af50b8 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -139,7 +139,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { // "404": // description: Issue not found // "409": - // description: Cannot stop a non existent stopwatch + // description: Cannot cancel a non existent stopwatch issue, err := prepareIssueStopwatch(ctx, true) if err != nil { return @@ -175,8 +175,12 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.I return nil, err } - if models.StopwatchExists(ctx.User.ID, issue.ID) == shouldExist { - ctx.Error(409, "StopwatchExists", "cannot stop a non existent stopwatch") + if models.StopwatchExists(ctx.User.ID, issue.ID) != shouldExist { + if shouldExist { + ctx.Error(409, "StopwatchExists", "cannot stop/cancel a non existent stopwatch") + } else { + ctx.Error(409, "StopwatchExists", "cannot start a stopwatch again if it already exists") + } return nil, err } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index e09b91bb40bd9..45a7c15ceed55 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -4020,7 +4020,7 @@ "description": "Issue not found" }, "409": { - "description": "Cannot stop a non existent stopwatch" + "description": "Cannot cancel a non existent stopwatch" } } } From fcf8782b1b8e141c7305d4cfbaa3ae2183f0a179 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 9 Dec 2019 15:35:15 +0100 Subject: [PATCH 3/6] fix lint --- integrations/api_issue_stopwatch_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go index f8b4fc3df26d2..d7545190e80f7 100644 --- a/integrations/api_issue_stopwatch_test.go +++ b/integrations/api_issue_stopwatch_test.go @@ -27,11 +27,11 @@ func TestAPIListStopWatches(t *testing.T) { var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) expect := models.AssertExistsAndLoadBean(t, &models.Stopwatch{UserID: owner.ID}).(*models.Stopwatch) - expectApi, _ := expect.APIFormat() + expectAPI, _ := expect.APIFormat() assert.Len(t, apiWatches, 1) - assert.EqualValues(t, expectApi.IssueIndex, apiWatches[0].IssueIndex) - assert.EqualValues(t, expectApi.Created, apiWatches[0].Created) + assert.EqualValues(t, expectAPI.IssueIndex, apiWatches[0].IssueIndex) + assert.EqualValues(t, expectAPI.Created, apiWatches[0].Created) } func TestAPIStopStopWatches(t *testing.T) { From 1b3f76c68f33cfc1243f99cdeb34939c0d55782c Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 9 Dec 2019 16:04:55 +0100 Subject: [PATCH 4/6] more robust time compare --- integrations/api_issue_stopwatch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go index d7545190e80f7..add238cab71c9 100644 --- a/integrations/api_issue_stopwatch_test.go +++ b/integrations/api_issue_stopwatch_test.go @@ -31,7 +31,7 @@ func TestAPIListStopWatches(t *testing.T) { assert.Len(t, apiWatches, 1) assert.EqualValues(t, expectAPI.IssueIndex, apiWatches[0].IssueIndex) - assert.EqualValues(t, expectAPI.Created, apiWatches[0].Created) + assert.EqualValues(t, expectAPI.Created.Unix(), apiWatches[0].Created.Unix()) } func TestAPIStopStopWatches(t *testing.T) { From e832771cd7fcd8dbb70a2859d946916860cc3dec Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 11 Dec 2019 16:48:03 +0100 Subject: [PATCH 5/6] delete responce 202 -> 204 --- models/issue_stopwatch.go | 6 +++--- routers/api/v1/repo/issue_stopwatch.go | 4 ++-- templates/swagger/v1_json.tmpl | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/models/issue_stopwatch.go b/models/issue_stopwatch.go index b0d78a6e3cd7c..8047f122b5b4b 100644 --- a/models/issue_stopwatch.go +++ b/models/issue_stopwatch.go @@ -20,6 +20,9 @@ type Stopwatch struct { CreatedUnix timeutil.TimeStamp `xorm:"created"` } +// Stopwatches is a List ful of Stopwatch +type Stopwatches []Stopwatch + func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { sw = new(Stopwatch) exists, err = e. @@ -184,9 +187,6 @@ func (sw *Stopwatch) APIFormat() (api.StopWatch, error) { }, nil } -// Stopwatches is a List ful of Stopwatch -type Stopwatches []Stopwatch - // APIFormat convert Stopwatches type to api.StopWatches type func (sws Stopwatches) APIFormat() (api.StopWatches, error) { result := api.StopWatches(make([]api.StopWatch, 0, len(sws))) diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 8372252af50b8..48b2f6498f0f8 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -132,7 +132,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { // format: int64 // required: true // responses: - // "202": + // "204": // "$ref": "#/responses/empty" // "403": // description: Not repo writer, user does not have rights to toggle stopwatch @@ -150,7 +150,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { return } - ctx.Status(202) + ctx.Status(204) } func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.Issue, error) { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 45a7c15ceed55..7ed43b450c74c 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -4010,7 +4010,7 @@ } ], "responses": { - "202": { + "204": { "$ref": "#/responses/empty" }, "403": { From cba5578cdcf164d4d9403e2af6a1de584ffbcb8a Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 11 Dec 2019 17:39:52 +0100 Subject: [PATCH 6/6] change http responce in test too --- integrations/api_issue_stopwatch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go index add238cab71c9..e0fe00c41526b 100644 --- a/integrations/api_issue_stopwatch_test.go +++ b/integrations/api_issue_stopwatch_test.go @@ -62,7 +62,7 @@ func TestAPICancelStopWatches(t *testing.T) { token := getTokenForLoggedInUser(t, session) req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/stopwatch/delete?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) - session.MakeRequest(t, req, http.StatusAccepted) + session.MakeRequest(t, req, http.StatusNoContent) session.MakeRequest(t, req, http.StatusConflict) }