diff --git a/filter.go b/filter.go new file mode 100644 index 0000000..1debab3 --- /dev/null +++ b/filter.go @@ -0,0 +1,77 @@ +package jira + +import "github.com/google/go-querystring/query" +import "fmt" + +// FilterService handles fields for the JIRA instance / API. +// +// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Filter +type FilterService struct { + client *Client +} + +// Filter represents a Filter in Jira +type Filter struct { + Self string `json:"self"` + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Owner User `json:"owner"` + Jql string `json:"jql"` + ViewURL string `json:"viewUrl"` + SearchURL string `json:"searchUrl"` + Favourite bool `json:"favourite"` + FavouritedCount int `json:"favouritedCount"` + SharePermissions []interface{} `json:"sharePermissions"` + Subscriptions struct { + Size int `json:"size"` + Items []interface{} `json:"items"` + MaxResults int `json:"max-results"` + StartIndex int `json:"start-index"` + EndIndex int `json:"end-index"` + } `json:"subscriptions"` +} + +// GetList retrieves all filters from Jira +func (fs *FilterService) GetList() ([]*Filter, *Response, error) { + + options := &GetQueryOptions{} + apiEndpoint := "rest/api/2/filter" + req, err := fs.client.NewRequest("GET", apiEndpoint, nil) + if err != nil { + return nil, nil, err + } + + if options != nil { + q, err := query.Values(options) + if err != nil { + return nil, nil, err + } + req.URL.RawQuery = q.Encode() + } + + filters := []*Filter{} + resp, err := fs.client.Do(req, &filters) + if err != nil { + jerr := NewJiraError(resp, err) + return nil, resp, jerr + } + return filters, resp, err +} + +// Get retrieves a single Filter from Jira +func (fs *FilterService) Get(filterID int) (*Filter, *Response, error) { + apiEndpoint := fmt.Sprintf("rest/api/2/filter/%d", filterID) + req, err := fs.client.NewRequest("GET", apiEndpoint, nil) + if err != nil { + return nil, nil, err + } + filter := new(Filter) + resp, err := fs.client.Do(req, filter) + if err != nil { + jerr := NewJiraError(resp, err) + return nil, resp, jerr + } + + return filter, resp, err +} diff --git a/filter_test.go b/filter_test.go new file mode 100644 index 0000000..6ead48f --- /dev/null +++ b/filter_test.go @@ -0,0 +1,56 @@ +package jira + +import ( + "fmt" + "io/ioutil" + "net/http" + "testing" +) + +func TestFilterService_GetList(t *testing.T) { + setup() + defer teardown() + testAPIEdpoint := "/rest/api/2/filter" + raw, err := ioutil.ReadFile("./mocks/all_filters.json") + if err != nil { + t.Error(err.Error()) + } + testMux.HandleFunc(testAPIEdpoint, func(writer http.ResponseWriter, request *http.Request) { + testMethod(t, request, "GET") + testRequestURL(t, request, testAPIEdpoint) + fmt.Fprint(writer, string(raw)) + }) + + filters, _, err := testClient.Filter.GetList() + if filters == nil { + t.Error("Expected Filters list. Filters list is nil") + } + if err != nil { + t.Errorf("Error given: %s", err) + } +} + +func TestFilterService_Get(t *testing.T) { + setup() + defer teardown() + testAPIEdpoint := "/rest/api/2/filter/10000" + raw, err := ioutil.ReadFile("./mocks/filter.json") + if err != nil { + t.Error(err.Error()) + } + testMux.HandleFunc(testAPIEdpoint, func(writer http.ResponseWriter, request *http.Request) { + testMethod(t, request, "GET") + testRequestURL(t, request, testAPIEdpoint) + fmt.Fprintf(writer, string(raw)) + }) + + filter, _, err := testClient.Filter.Get(10000) + if filter == nil { + t.Errorf("Expected Filter, got nil") + } + if err != nil { + t.Errorf("Error given: %s", err) + } + + +} diff --git a/jira.go b/jira.go index d888fe7..d8d247d 100644 --- a/jira.go +++ b/jira.go @@ -40,6 +40,7 @@ type Client struct { Component *ComponentService Resolution *ResolutionService StatusCategory *StatusCategoryService + Filter *FilterService } // NewClient returns a new JIRA API client. @@ -81,6 +82,7 @@ func NewClient(httpClient *http.Client, baseURL string) (*Client, error) { c.Component = &ComponentService{client: c} c.Resolution = &ResolutionService{client: c} c.StatusCategory = &StatusCategoryService{client: c} + c.Filter = &FilterService{client: c} return c, nil } diff --git a/mocks/all_filters.json b/mocks/all_filters.json new file mode 100644 index 0000000..50cea91 --- /dev/null +++ b/mocks/all_filters.json @@ -0,0 +1,35 @@ +[ + { + "self": "http://your-domain.atlassian.net/rest/api/2/filter/10000", + "id": "10000", + "name": "All Open Bugs", + "description": "Lists all open bugs", + "owner": { + "self": "http://your-domain.atlassian.net/rest/api/2/user?username=mia", + "key": "mia", + "accountId": "99:27935d01-92a7-4687-8272-a9b8d3b2ae2e", + "name": "mia", + "avatarUrls": { + "48x48": "http://your-domain.atlassian.net/secure/useravatar?size=large&ownerId=mia", + "24x24": "http://your-domain.atlassian.net/secure/useravatar?size=small&ownerId=mia", + "16x16": "http://your-domain.atlassian.net/secure/useravatar?size=xsmall&ownerId=mia", + "32x32": "http://your-domain.atlassian.net/secure/useravatar?size=medium&ownerId=mia" + }, + "displayName": "Mia Krystof", + "active": false + }, + "jql": "type = Bug and resolution is empty", + "viewUrl": "http://your-domain.atlassian.net/issues/?filter=10000", + "searchUrl": "http://your-domain.atlassian.net/rest/api/2/search?jql=type%20%3D%20Bug%20and%20resolutino%20is%20empty", + "favourite": true, + "favouritedCount": 0, + "sharePermissions": [], + "subscriptions": { + "size": 0, + "items": [], + "max-results": 0, + "start-index": 0, + "end-index": 0 + } + } +] diff --git a/mocks/filter.json b/mocks/filter.json new file mode 100644 index 0000000..a47141a --- /dev/null +++ b/mocks/filter.json @@ -0,0 +1,33 @@ +{ + "self": "http://your-domain.atlassian.net/rest/api/2/filter/10000", + "id": "10000", + "name": "All Open Bugs", + "description": "Lists all open bugs", + "owner": { + "self": "http://your-domain.atlassian.net/rest/api/2/user?username=mia", + "key": "mia", + "accountId": "99:27935d01-92a7-4687-8272-a9b8d3b2ae2e", + "name": "mia", + "avatarUrls": { + "48x48": "http://your-domain.atlassian.net/secure/useravatar?size=large&ownerId=mia", + "24x24": "http://your-domain.atlassian.net/secure/useravatar?size=small&ownerId=mia", + "16x16": "http://your-domain.atlassian.net/secure/useravatar?size=xsmall&ownerId=mia", + "32x32": "http://your-domain.atlassian.net/secure/useravatar?size=medium&ownerId=mia" + }, + "displayName": "Mia Krystof", + "active": false + }, + "jql": "type = Bug and resolution is empty", + "viewUrl": "http://your-domain.atlassian.net/issues/?filter=10000", + "searchUrl": "http://your-domain.atlassian.net/rest/api/2/search?jql=type%20%3D%20Bug%20and%20resolutino%20is%20empty", + "favourite": true, + "favouritedCount": 0, + "sharePermissions": [], + "subscriptions": { + "size": 0, + "items": [], + "max-results": 0, + "start-index": 0, + "end-index": 0 + } +} \ No newline at end of file