mirror of
https://github.com/interviewstreet/go-jira.git
synced 2025-03-21 21:07:03 +02:00
feat(issues): Added support for AddWorklog and GetWorklogs
This commit is contained in:
parent
a9350ed566
commit
1ebd7e7f0d
@ -3,11 +3,11 @@ language: go
|
|||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- "1.7.x"
|
|
||||||
- "1.8.x"
|
- "1.8.x"
|
||||||
- "1.9.x"
|
- "1.9.x"
|
||||||
- "1.10.x"
|
- "1.10.x"
|
||||||
- "1.11.x"
|
- "1.11.x"
|
||||||
|
- "1.12.x"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- go get -t ./...
|
- go get -t ./...
|
||||||
|
36
Gopkg.lock
generated
36
Gopkg.lock
generated
@ -1,36 +0,0 @@
|
|||||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
|
||||||
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/fatih/structs"
|
|
||||||
packages = ["."]
|
|
||||||
revision = "a720dfa8df582c51dee1b36feabb906bde1588bd"
|
|
||||||
version = "v1.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/google/go-querystring"
|
|
||||||
packages = ["query"]
|
|
||||||
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/pkg/errors"
|
|
||||||
packages = ["."]
|
|
||||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
|
||||||
version = "v0.8.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/trivago/tgo"
|
|
||||||
packages = [
|
|
||||||
"tcontainer",
|
|
||||||
"treflect"
|
|
||||||
]
|
|
||||||
revision = "e4d1ddd28c17dd89ed26327cf69fded22060671b"
|
|
||||||
version = "v1.0.1"
|
|
||||||
|
|
||||||
[solve-meta]
|
|
||||||
analyzer-name = "dep"
|
|
||||||
analyzer-version = 1
|
|
||||||
inputs-digest = "e84ca9eea6d233e0947b0d760913db2983fd4cbf6fd0d8690c737a71affb635c"
|
|
||||||
solver-name = "gps-cdcl"
|
|
||||||
solver-version = 1
|
|
46
Gopkg.toml
46
Gopkg.toml
@ -1,46 +0,0 @@
|
|||||||
# Gopkg.toml example
|
|
||||||
#
|
|
||||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
|
||||||
# for detailed Gopkg.toml documentation.
|
|
||||||
#
|
|
||||||
# required = ["github.com/user/thing/cmd/thing"]
|
|
||||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project"
|
|
||||||
# version = "1.0.0"
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project2"
|
|
||||||
# branch = "dev"
|
|
||||||
# source = "github.com/myfork/project2"
|
|
||||||
#
|
|
||||||
# [[override]]
|
|
||||||
# name = "github.com/x/y"
|
|
||||||
# version = "2.4.0"
|
|
||||||
#
|
|
||||||
# [prune]
|
|
||||||
# non-go = false
|
|
||||||
# go-tests = true
|
|
||||||
# unused-packages = true
|
|
||||||
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/fatih/structs"
|
|
||||||
version = "1.0.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/google/go-querystring"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/pkg/errors"
|
|
||||||
version = "0.8.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/trivago/tgo"
|
|
||||||
version = "1.0.1"
|
|
||||||
|
|
||||||
[prune]
|
|
||||||
go-tests = true
|
|
||||||
unused-packages = true
|
|
19
README.md
19
README.md
@ -17,15 +17,18 @@
|
|||||||
|
|
||||||
This package is not JIRA API complete (yet), but you can call every API endpoint you want. See [Call a not implemented API endpoint](#call-a-not-implemented-api-endpoint) how to do this. For all possible API endpoints of JIRA have a look at [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/).
|
This package is not JIRA API complete (yet), but you can call every API endpoint you want. See [Call a not implemented API endpoint](#call-a-not-implemented-api-endpoint) how to do this. For all possible API endpoints of JIRA have a look at [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/).
|
||||||
|
|
||||||
## Compatible JIRA versions
|
## Requirements
|
||||||
|
|
||||||
This package was tested against JIRA v6.3.4 and v7.1.2.
|
* Go >= 1.8
|
||||||
|
* JIRA v6.3.4 & v7.1.2.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
It is go gettable
|
It is go gettable
|
||||||
|
|
||||||
$ go get github.com/andygrunwald/go-jira
|
```bash
|
||||||
|
go get github.com/andygrunwald/go-jira
|
||||||
|
```
|
||||||
|
|
||||||
For stable versions you can use one of our tags with [gopkg.in](http://labix.org/gopkg.in). E.g.
|
For stable versions you can use one of our tags with [gopkg.in](http://labix.org/gopkg.in). E.g.
|
||||||
|
|
||||||
@ -40,8 +43,10 @@ import (
|
|||||||
|
|
||||||
(optional) to run unit / example tests:
|
(optional) to run unit / example tests:
|
||||||
|
|
||||||
$ cd $GOPATH/src/github.com/andygrunwald/go-jira
|
```bash
|
||||||
$ go test -v ./...
|
cd $GOPATH/src/github.com/andygrunwald/go-jira
|
||||||
|
go test -v ./...
|
||||||
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
@ -239,9 +244,9 @@ If you are new to pull requests, checkout [Collaborating on projects using issue
|
|||||||
|
|
||||||
### Dependency management
|
### Dependency management
|
||||||
|
|
||||||
`go-jira` uses `dep` for dependency management. After cloning the repo, it's easy to make sure you have the correct dependencies by running `dep ensure`.
|
`go-jira` uses `go modules` for dependency management. After cloning the repo, it's easy to make sure you have the correct dependencies by running `go mod tidy`.
|
||||||
|
|
||||||
For adding new dependencies, updating dependencies, and other operations, the [Daily Dep](https://golang.github.io/dep/docs/daily-dep.html) is a good place to start.
|
For adding new dependencies, updating dependencies, and other operations, the [Daily workflow](https://github.com/golang/go/wiki/Modules#daily-workflow) is a good place to start.
|
||||||
|
|
||||||
### Sandbox environment for testing
|
### Sandbox environment for testing
|
||||||
|
|
||||||
|
12
go.mod
Normal file
12
go.mod
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module github.com/andygrunwald/go-jira
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/fatih/structs v1.0.0
|
||||||
|
github.com/google/go-cmp v0.3.0
|
||||||
|
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135
|
||||||
|
github.com/pkg/errors v0.8.0
|
||||||
|
github.com/trivago/tgo v1.0.1
|
||||||
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
|
||||||
|
)
|
83
issue.go
83
issue.go
@ -7,6 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
@ -295,6 +296,10 @@ type Parent struct {
|
|||||||
// Time represents the Time definition of JIRA as a time.Time of go
|
// Time represents the Time definition of JIRA as a time.Time of go
|
||||||
type Time time.Time
|
type Time time.Time
|
||||||
|
|
||||||
|
func (t Time) Equal(u Time) bool {
|
||||||
|
return time.Time(t).Equal(time.Time(u))
|
||||||
|
}
|
||||||
|
|
||||||
// Date represents the Date definition of JIRA as a time.Time of go
|
// Date represents the Date definition of JIRA as a time.Time of go
|
||||||
type Date time.Time
|
type Date time.Time
|
||||||
|
|
||||||
@ -394,17 +399,23 @@ type Worklog struct {
|
|||||||
|
|
||||||
// WorklogRecord represents one entry of a Worklog
|
// WorklogRecord represents one entry of a Worklog
|
||||||
type WorklogRecord struct {
|
type WorklogRecord struct {
|
||||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||||
Author *User `json:"author,omitempty" structs:"author,omitempty"`
|
Author *User `json:"author,omitempty" structs:"author,omitempty"`
|
||||||
UpdateAuthor *User `json:"updateAuthor,omitempty" structs:"updateAuthor,omitempty"`
|
UpdateAuthor *User `json:"updateAuthor,omitempty" structs:"updateAuthor,omitempty"`
|
||||||
Comment string `json:"comment,omitempty" structs:"comment,omitempty"`
|
Comment string `json:"comment,omitempty" structs:"comment,omitempty"`
|
||||||
Created *Time `json:"created,omitempty" structs:"created,omitempty"`
|
Created *Time `json:"created,omitempty" structs:"created,omitempty"`
|
||||||
Updated *Time `json:"updated,omitempty" structs:"updated,omitempty"`
|
Updated *Time `json:"updated,omitempty" structs:"updated,omitempty"`
|
||||||
Started *Time `json:"started,omitempty" structs:"started,omitempty"`
|
Started *Time `json:"started,omitempty" structs:"started,omitempty"`
|
||||||
TimeSpent string `json:"timeSpent,omitempty" structs:"timeSpent,omitempty"`
|
TimeSpent string `json:"timeSpent,omitempty" structs:"timeSpent,omitempty"`
|
||||||
TimeSpentSeconds int `json:"timeSpentSeconds,omitempty" structs:"timeSpentSeconds,omitempty"`
|
TimeSpentSeconds int `json:"timeSpentSeconds,omitempty" structs:"timeSpentSeconds,omitempty"`
|
||||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||||
IssueID string `json:"issueId,omitempty" structs:"issueId,omitempty"`
|
IssueID string `json:"issueId,omitempty" structs:"issueId,omitempty"`
|
||||||
|
Properties []EntityProperty `json:"properties,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EntityProperty struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value interface{} `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeTracking represents the timetracking fields of a JIRA issue.
|
// TimeTracking represents the timetracking fields of a JIRA issue.
|
||||||
@ -527,6 +538,22 @@ type GetQueryOptions struct {
|
|||||||
ProjectKeys string `url:"projectKeys,omitempty"`
|
ProjectKeys string `url:"projectKeys,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWorklogsQueryOptions specifies the optional parameters for the Get Worklogs method
|
||||||
|
type GetWorklogsQueryOptions struct {
|
||||||
|
StartAt int64 `url:"startAt,omitempty"`
|
||||||
|
MaxResults int32 `url:"maxResults,omitempty"`
|
||||||
|
Expand string `url:"expand,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddWorklogQueryOptions struct {
|
||||||
|
NotifyUsers bool `url:"notifyUsers,omitempty"`
|
||||||
|
AdjustEstimate string `url:"adjustEstimate,omitempty"`
|
||||||
|
NewEstimate string `url:"newEstimate,omitempty"`
|
||||||
|
ReduceBy string `url:"reduceBy,omitempty"`
|
||||||
|
Expand string `url:"expand,omitempty"`
|
||||||
|
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// CustomFields represents custom fields of JIRA
|
// CustomFields represents custom fields of JIRA
|
||||||
// This can heavily differ between JIRA instances
|
// This can heavily differ between JIRA instances
|
||||||
type CustomFields map[string]string
|
type CustomFields map[string]string
|
||||||
@ -626,7 +653,7 @@ func (s *IssueService) PostAttachment(issueID string, r io.Reader, attachmentNam
|
|||||||
// This method is especially important if you need to read all the worklogs, not just the first page.
|
// This method is especially important if you need to read all the worklogs, not just the first page.
|
||||||
//
|
//
|
||||||
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-getIssueWorklog
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-getIssueWorklog
|
||||||
func (s *IssueService) GetWorklogs(issueID string) (*Worklog, *Response, error) {
|
func (s *IssueService) GetWorklogs(issueID string, options ...func(*http.Request) error) (*Worklog, *Response, error) {
|
||||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/worklog", issueID)
|
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/worklog", issueID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||||
@ -634,11 +661,34 @@ func (s *IssueService) GetWorklogs(issueID string) (*Worklog, *Response, error)
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
err = option(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v := new(Worklog)
|
v := new(Worklog)
|
||||||
resp, err := s.client.Do(req, v)
|
resp, err := s.client.Do(req, v)
|
||||||
return v, resp, err
|
return v, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Applies query options to http request.
|
||||||
|
// This helper is meant to be used with all "QueryOptions" structs.
|
||||||
|
func WithQueryOptions(options interface{}) func(*http.Request) error {
|
||||||
|
q, err := query.Values(options)
|
||||||
|
if err != nil {
|
||||||
|
return func(*http.Request) error {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(r *http.Request) error {
|
||||||
|
r.URL.RawQuery = q.Encode()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create creates an issue or a sub-task from a JSON representation.
|
// Create creates an issue or a sub-task from a JSON representation.
|
||||||
// Creating a sub-task is similar to creating a regular issue, with two important differences:
|
// Creating a sub-task is similar to creating a regular issue, with two important differences:
|
||||||
// The issueType field must correspond to a sub-task issue type and you must provide a parent field in the issue create request containing the id or key of the parent issue.
|
// The issueType field must correspond to a sub-task issue type and you must provide a parent field in the issue create request containing the id or key of the parent issue.
|
||||||
@ -787,13 +837,20 @@ func (s *IssueService) DeleteComment(issueID, commentID string) error {
|
|||||||
// AddWorklogRecord adds a new worklog record to issueID.
|
// AddWorklogRecord adds a new worklog record to issueID.
|
||||||
//
|
//
|
||||||
// https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-issue-issueIdOrKey-worklog-post
|
// https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-issue-issueIdOrKey-worklog-post
|
||||||
func (s *IssueService) AddWorklogRecord(issueID string, record *WorklogRecord) (*WorklogRecord, *Response, error) {
|
func (s *IssueService) AddWorklogRecord(issueID string, record *WorklogRecord, options ...func(*http.Request) error) (*WorklogRecord, *Response, error) {
|
||||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/worklog", issueID)
|
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/worklog", issueID)
|
||||||
req, err := s.client.NewRequest("POST", apiEndpoint, record)
|
req, err := s.client.NewRequest("POST", apiEndpoint, record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
err = option(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
responseRecord := new(WorklogRecord)
|
responseRecord := new(WorklogRecord)
|
||||||
resp, err := s.client.Do(req, responseRecord)
|
resp, err := s.client.Do(req, responseRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
132
issue_test.go
132
issue_test.go
@ -3,6 +3,7 @@ package jira
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -1316,31 +1317,128 @@ func TestIssueService_Delete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTime(original time.Time) *Time {
|
||||||
|
jiraTime := Time(original)
|
||||||
|
|
||||||
|
return &jiraTime
|
||||||
|
}
|
||||||
|
|
||||||
func TestIssueService_GetWorklogs(t *testing.T) {
|
func TestIssueService_GetWorklogs(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
testMux.HandleFunc("/rest/api/2/issue/10002/worklog", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
testMethod(t, r, "GET")
|
|
||||||
testRequestURL(t, r, "/rest/api/2/issue/10002/worklog")
|
|
||||||
|
|
||||||
fmt.Fprint(w, `{"startAt": 1,"maxResults": 40,"total": 1,"worklogs": [{"id": "3","self": "http://kelpie9:8081/rest/api/2/issue/10002/worklog/3","author":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"updateAuthor":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"created":"2016-03-16T04:22:37.356+0000","updated":"2016-03-16T04:22:37.356+0000","comment":"","started":"2016-03-16T04:22:37.356+0000","timeSpent": "1h","timeSpentSeconds": 3600,"issueId":"10002"}]}`)
|
tt := []struct {
|
||||||
})
|
name string
|
||||||
|
response string
|
||||||
worklog, _, err := testClient.Issue.GetWorklogs("10002")
|
issueId string
|
||||||
if worklog == nil {
|
uri string
|
||||||
t.Error("Expected worklog. Worklog is nil")
|
worklog *Worklog
|
||||||
|
err error
|
||||||
|
option *AddWorklogQueryOptions
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "simple worklog",
|
||||||
|
response: `{"startAt": 1,"maxResults": 40,"total": 1,"worklogs": [{"id": "3","self": "http://kelpie9:8081/rest/api/2/issue/10002/worklog/3","author":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"updateAuthor":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"created":"2016-03-16T04:22:37.356+0000","updated":"2016-03-16T04:22:37.356+0000","comment":"","started":"2016-03-16T04:22:37.356+0000","timeSpent": "1h","timeSpentSeconds": 3600,"issueId":"10002"}]}`,
|
||||||
|
issueId: "10002",
|
||||||
|
uri: "/rest/api/2/issue/%s/worklog",
|
||||||
|
worklog: &Worklog{
|
||||||
|
StartAt: 1,
|
||||||
|
MaxResults: 40,
|
||||||
|
Total: 1,
|
||||||
|
Worklogs: []WorklogRecord{
|
||||||
|
{
|
||||||
|
Self: "http://kelpie9:8081/rest/api/2/issue/10002/worklog/3",
|
||||||
|
Author: &User{
|
||||||
|
Self: "http://www.example.com/jira/rest/api/2/user?username=fred",
|
||||||
|
Name: "fred",
|
||||||
|
DisplayName: "Fred F. User",
|
||||||
|
},
|
||||||
|
UpdateAuthor: &User{
|
||||||
|
Self: "http://www.example.com/jira/rest/api/2/user?username=fred",
|
||||||
|
Name: "fred",
|
||||||
|
DisplayName: "Fred F. User",
|
||||||
|
},
|
||||||
|
Created: getTime(time.Date(2016, time.March, 16, 4, 22, 37, 356000000, time.UTC)),
|
||||||
|
Started: getTime(time.Date(2016, time.March, 16, 4, 22, 37, 356000000, time.UTC)),
|
||||||
|
Updated: getTime(time.Date(2016, time.March, 16, 4, 22, 37, 356000000, time.UTC)),
|
||||||
|
TimeSpent: "1h",
|
||||||
|
TimeSpentSeconds: 3600,
|
||||||
|
ID: "3",
|
||||||
|
IssueID: "10002",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "expanded worklog",
|
||||||
|
response: `{"startAt":1,"maxResults":40,"total":1,"worklogs":[{"id":"3","self":"http://kelpie9:8081/rest/api/2/issue/10002/worklog/3","author":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"updateAuthor":{"self":"http://www.example.com/jira/rest/api/2/user?username=fred","name":"fred","displayName":"Fred F. User","active":false},"created":"2016-03-16T04:22:37.356+0000","updated":"2016-03-16T04:22:37.356+0000","comment":"","started":"2016-03-16T04:22:37.356+0000","timeSpent":"1h","timeSpentSeconds":3600,"issueId":"10002","properties":[{"key":"foo","value":{"bar":"baz"}}]}]}`,
|
||||||
|
issueId: "10002",
|
||||||
|
uri: "/rest/api/2/issue/%s/worklog?expand=properties",
|
||||||
|
worklog: &Worklog{
|
||||||
|
StartAt: 1,
|
||||||
|
MaxResults: 40,
|
||||||
|
Total: 1,
|
||||||
|
Worklogs: []WorklogRecord{
|
||||||
|
{
|
||||||
|
Self: "http://kelpie9:8081/rest/api/2/issue/10002/worklog/3",
|
||||||
|
Author: &User{
|
||||||
|
Self: "http://www.example.com/jira/rest/api/2/user?username=fred",
|
||||||
|
Name: "fred",
|
||||||
|
DisplayName: "Fred F. User",
|
||||||
|
},
|
||||||
|
UpdateAuthor: &User{
|
||||||
|
Self: "http://www.example.com/jira/rest/api/2/user?username=fred",
|
||||||
|
Name: "fred",
|
||||||
|
DisplayName: "Fred F. User",
|
||||||
|
},
|
||||||
|
Created: getTime(time.Date(2016, time.March, 16, 4, 22, 37, 356000000, time.UTC)),
|
||||||
|
Started: getTime(time.Date(2016, time.March, 16, 4, 22, 37, 356000000, time.UTC)),
|
||||||
|
Updated: getTime(time.Date(2016, time.March, 16, 4, 22, 37, 356000000, time.UTC)),
|
||||||
|
TimeSpent: "1h",
|
||||||
|
TimeSpentSeconds: 3600,
|
||||||
|
ID: "3",
|
||||||
|
IssueID: "10002",
|
||||||
|
Properties: []EntityProperty{
|
||||||
|
{
|
||||||
|
Key: "foo",
|
||||||
|
Value: map[string]interface{}{
|
||||||
|
"bar": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
option: &AddWorklogQueryOptions{Expand: "properties"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(worklog.Worklogs) != 1 {
|
for _, tc := range tt {
|
||||||
t.Error("Expected 1 worklog")
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
}
|
uri := fmt.Sprintf(tc.uri, tc.issueId)
|
||||||
|
testMux.HandleFunc(uri, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
testRequestURL(t, r, uri)
|
||||||
|
_, _ = fmt.Fprint(w, tc.response)
|
||||||
|
})
|
||||||
|
|
||||||
if worklog.Worklogs[0].Author.Name != "fred" {
|
var worklog *Worklog
|
||||||
t.Error("Expected worklog author to be fred")
|
var err error
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if tc.option != nil {
|
||||||
t.Errorf("Error given: %s", err)
|
worklog, _, err = testClient.Issue.GetWorklogs(tc.issueId, WithQueryOptions(tc.option))
|
||||||
|
} else {
|
||||||
|
worklog, _, err = testClient.Issue.GetWorklogs(tc.issueId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil && !cmp.Equal(err, tc.err) {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cmp.Equal(worklog, tc.worklog) {
|
||||||
|
t.Errorf("unexpected worklog structure: %s", cmp.Diff(worklog, tc.worklog))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user