Skip to content

Commit

Permalink
feat: Add Search to FilterService
Browse files Browse the repository at this point in the history
  • Loading branch information
hirakiuc authored and ghostsquad committed Aug 27, 2019
1 parent ebae19d commit 38a755b
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 0 deletions.
102 changes: 102 additions & 0 deletions filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,84 @@ type GetMyFiltersQueryOptions struct {
Expand string `url:"expand,omitempty"`
}

// FiltersList reflects a list of filters
type FiltersList struct {
MaxResults int `json:"maxResults" structs:"maxResults"`
StartAt int `json:"startAt" structs:"startAt"`
Total int `json:"total" structs:"total"`
IsLast bool `json:"isLast" structs:"isLast"`
Values []FiltersListItem `json:"values" structs:"values"`
}

// FiltersListItem represents a Filter of FiltersList in Jira
type FiltersListItem 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 {
ID int `json:"id"`
User User `json:"user"`
} `json:"subscriptions"`
}

// FilterSearchOptions specifies the optional parameters for the Search method
// https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-filter-search-get
type FilterSearchOptions struct {
// String used to perform a case-insensitive partial match with name.
FilterName string `url:"filterName,omitempty"`

// User account ID used to return filters with the matching owner.accountId. This parameter cannot be used with owner.
AccountID string `url:"accountId,omitempty"`

// Group name used to returns filters that are shared with a group that matches sharePermissions.group.groupname.
GroupName string `url:"groupname,omitempty"`

// Project ID used to returns filters that are shared with a project that matches sharePermissions.project.id.
// Format: int64
ProjectID int64 `url:"projectId,omitempty"`

// Orders the results using one of these filter properties.
// - `description` Orders by filter `description`. Note that this ordering works independently of whether the expand to display the description field is in use.
// - `favourite_count` Orders by `favouritedCount`.
// - `is_favourite` Orders by `favourite`.
// - `id` Orders by filter `id`.
// - `name` Orders by filter `name`.
// - `owner` Orders by `owner.accountId`.
//
// Default: `name`
//
// Valid values: id, name, description, owner, favorite_count, is_favorite, -id, -name, -description, -owner, -favorite_count, -is_favorite
OrderBy string `url:"orderBy,omitempty"`

// The index of the first item to return in a page of results (page offset).
// Default: 0, Format: int64
StartAt int64 `url:"startAt,omitempty"`

// The maximum number of items to return per page. The maximum is 100.
// Default: 50, Format: int32
MaxResults int32 `url:"maxResults,omitempty"`

// Use expand to include additional information about filter in the response. This parameter accepts multiple values separated by a comma:
// - description Returns the description of the filter.
// - favourite Returns an indicator of whether the user has set the filter as a favorite.
// - favouritedCount Returns a count of how many users have set this filter as a favorite.
// - jql Returns the JQL query that the filter uses.
// - owner Returns the owner of the filter.
// - searchUrl Returns a URL to perform the filter's JQL query.
// - sharePermissions Returns the share permissions defined for the filter.
// - subscriptions Returns the users that are subscribed to the filter.
// - viewUrl Returns a URL to view the filter.
Expand string `url:"expand,omitempty"`
}

// GetList retrieves all filters from Jira
func (fs *FilterService) GetList() ([]*Filter, *Response, error) {

Expand Down Expand Up @@ -118,5 +196,29 @@ func (fs *FilterService) GetMyFilters(opts *GetMyFiltersQueryOptions) ([]*Filter
jerr := NewJiraError(resp, err)
return nil, resp, jerr
}
return filters, resp, nil
}

// Search will search for filter according to the search options
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-filter-search-get
func (fs *FilterService) Search(opt *FilterSearchOptions) (*FiltersList, *Response, error) {
apiEndpoint := "rest/api/3/filter/search"
url, err := addOptions(apiEndpoint, opt)
if err != nil {
return nil, nil, err
}
req, err := fs.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}

filters := new(FiltersList)
resp, err := fs.client.Do(req, filters)
if err != nil {
jerr := NewJiraError(resp, err)
return nil, resp, jerr
}

return filters, resp, err
}
24 changes: 24 additions & 0 deletions filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,27 @@ func TestFilterService_GetMyFilters(t *testing.T) {
t.Errorf("Expected Filters, got nil")
}
}

func TestFilterService_Search(t *testing.T) {
setup()
defer teardown()
testAPIEndpoint := "/rest/api/3/filter/search"
raw, err := ioutil.ReadFile("./mocks/search_filters.json")
if err != nil {
t.Error(err.Error())
}
testMux.HandleFunc(testAPIEndpoint, func(writer http.ResponseWriter, request *http.Request) {
testMethod(t, request, "GET")
testRequestURL(t, request, testAPIEndpoint)
fmt.Fprint(writer, string(raw))
})

opt := FilterSearchOptions{}
filters, _, err := testClient.Filter.Search(&opt)
if err != nil {
t.Errorf("Error given: %s", err)
}
if filters == nil {
t.Errorf("Expected Filters, got nil")
}
}
120 changes: 120 additions & 0 deletions mocks/search_filters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"self": "b",
"maxResults": 100,
"startAt": 0,
"total": 2,
"isLast": true,
"values": [
{
"self": "http://test.jira.org/rest/api/3/filter/10000",
"id": "10000",
"name": "All Open Bugs",
"description": "Lists all open bugs",
"owner": {
"self": "http://test.jira.org/rest/api/3/user?accountId=99:27935d01-92a7-4687-8272-a9b8d3b2ae2e",
"key": "",
"accountId": "99:27935d01-92a7-4687-8272-a9b8d3b2ae2e",
"name": "",
"avatarUrls": {
"48x48": "http://test.jira.org/secure/useravatar?size=large&ownerId=mia",
"24x24": "http://test.jira.org/secure/useravatar?size=small&ownerId=mia",
"16x16": "http://test.jira.org/secure/useravatar?size=xsmall&ownerId=mia",
"32x32": "http://test.jira.org/secure/useravatar?size=medium&ownerId=mia"
},
"displayName": "Mia Krystof",
"active": false
},
"jql": "type = Bug and resolution is empty",
"viewUrl": "http://test.jira.org/issues/?filter=10000",
"searchUrl": "http://test.jira.org/rest/api/3/search?jql=type%20%3D%20Bug%20and%20resolutino%20is%20empty",
"favourite": true,
"favouritedCount": 0,
"sharePermissions": [],
"subscriptions": []
},
{
"self": "http://test.jira.org/rest/api/3/filter/10010",
"id": "10010",
"name": "My issues",
"description": "Issues assigned to me",
"owner": {
"self": "http://test.jira.org/rest/api/3/user?accountId=99:27935d01-92a7-4687-8272-a9b8d3b2ae2e",
"key": "",
"accountId": "99:27935d01-92a7-4687-8272-a9b8d3b2ae2e",
"name": "",
"avatarUrls": {
"48x48": "http://test.jira.org/secure/useravatar?size=large&ownerId=mia",
"24x24": "http://test.jira.org/secure/useravatar?size=small&ownerId=mia",
"16x16": "http://test.jira.org/secure/useravatar?size=xsmall&ownerId=mia",
"32x32": "http://test.jira.org/secure/useravatar?size=medium&ownerId=mia"
},
"displayName": "Mia Krystof",
"active": false
},
"jql": "assignee = currentUser() and resolution is empty",
"viewUrl": "http://test.jira.org/issues/?filter=10010",
"searchUrl": "http://test.jira.org/rest/api/3/search?jql=assignee+in+%28currentUser%28%29%29+and+resolution+is+empty",
"favourite": true,
"favouritedCount": 0,
"sharePermissions": [
{
"id": 10000,
"type": "global"
},
{
"id": 10010,
"type": "project",
"project": {
"self": "http://test.jira.org/rest/api/3/project/EX",
"id": "10000",
"key": "EX",
"name": "Example",
"avatarUrls": {
"48x48": "http://test.jira.org/secure/projectavatar?size=large&pid=10000",
"24x24": "http://test.jira.org/secure/projectavatar?size=small&pid=10000",
"16x16": "http://test.jira.org/secure/projectavatar?size=xsmall&pid=10000",
"32x32": "http://test.jira.org/secure/projectavatar?size=medium&pid=10000"
},
"projectCategory": {
"self": "http://test.jira.org/rest/api/3/projectCategory/10000",
"id": "10000",
"name": "FIRST",
"description": "First Project Category"
},
"simplified": false,
"style": "classic"
}
}
],
"subscriptions": [
{
"id": 1,
"user": {
"self": "http://test.jira.org/rest/api/3/user?accountId=99:27935d01-92a7-4687-8272-a9b8d3b2ae2e",
"key": "",
"accountId": "99:27935d01-92a7-4687-8272-a9b8d3b2ae2e",
"name": "",
"emailAddress": "[email protected]",
"avatarUrls": {
"48x48": "http://test.jira.org/secure/useravatar?size=large&ownerId=mia",
"24x24": "http://test.jira.org/secure/useravatar?size=small&ownerId=mia",
"16x16": "http://test.jira.org/secure/useravatar?size=xsmall&ownerId=mia",
"32x32": "http://test.jira.org/secure/useravatar?size=medium&ownerId=mia"
},
"displayName": "Mia Krystof",
"active": true,
"timeZone": "Australia/Sydney",
"groups": {
"size": 3,
"items": []
},
"applicationRoles": {
"size": 1,
"items": []
}
}
}
]
}
]
}

0 comments on commit 38a755b

Please sign in to comment.