diff --git a/jira.go b/jira.go index d8d247d..406e567 100644 --- a/jira.go +++ b/jira.go @@ -41,6 +41,7 @@ type Client struct { Resolution *ResolutionService StatusCategory *StatusCategoryService Filter *FilterService + Role *RoleService } // NewClient returns a new JIRA API client. @@ -83,6 +84,7 @@ func NewClient(httpClient *http.Client, baseURL string) (*Client, error) { c.Resolution = &ResolutionService{client: c} c.StatusCategory = &StatusCategoryService{client: c} c.Filter = &FilterService{client: c} + c.Role = &RoleService{client: c} return c, nil } diff --git a/mocks/all_roles.json b/mocks/all_roles.json new file mode 100644 index 0000000..0b95afa --- /dev/null +++ b/mocks/all_roles.json @@ -0,0 +1,26 @@ +[ + { + "self": "https://sample.instance.org/rest/api/3/role/10002", + "name": "Administrator", + "id": 10002, + "description": "Administrator description", + "actors": [ + { + "id": 10002, + "displayName": "jira-administrators", + "type": "atlassian-group-role-actor", + "name": "jira-administrators", + "actorGroup": { + "name": "jira-administrators", + "displayName": "jira-administrators" + } + } + ] + }, + { + "self": "https://sample.instance.org/rest/api/3/role/10222", + "name": "FooRole", + "id": 10222, + "description": "User with this role has should do fooo and bar tasks" + } + ] \ No newline at end of file diff --git a/mocks/role.json b/mocks/role.json new file mode 100644 index 0000000..057476b --- /dev/null +++ b/mocks/role.json @@ -0,0 +1,18 @@ +{ + "self": "https://sample.instance.org/rest/api/3/role/10002", + "name": "Administrator", + "id": 10002, + "description": "Administrator description", + "actors": [ + { + "id": 10002, + "displayName": "jira-administrators", + "type": "atlassian-group-role-actor", + "name": "jira-administrators", + "actorGroup": { + "name": "jira-administrators", + "displayName": "jira-administrators" + } + } + ] +} diff --git a/role.go b/role.go new file mode 100644 index 0000000..fb4200e --- /dev/null +++ b/role.go @@ -0,0 +1,69 @@ +package jira + +import ( + "fmt" +) + +// RoleService handles roles for the JIRA instance / API. +// +// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/3/role +type RoleService struct { + client *Client +} + +// Role represents a JIRA product role +type Role struct { + Self string `json:"self" structs:"self"` + Name string `json:"name" structs:"name"` + ID int `json:"id" structs:"id"` + Description string `json:"description" structs:"description"` + Actors []*Actor `json:"actors" structs:"actors"` +} + +// Actor represents a JIRA user +type Actor struct { + ID int `json:"id" structs:"id"` + DisplayName string `json:"displayName" structs:"displayName"` + Type string `json:"type" structs:"type"` + Name string `json:"name" structs:"name"` + AvatarURL string `json:"avatarUrl" structs:"avatarUrl"` + ActorUser *ActorUser `json:"actorUser" structs:"actoruser"` +} + +// ActorUser contains the account id of the actor/user +type ActorUser struct { + AccountID string `json:"accountId" structs:"accountId"` +} + +// GetList returns a list of all available project roles +func (s *RoleService) GetList() (*[]Role, *Response, error) { + apiEndpoint := "rest/api/3/role" + req, err := s.client.NewRequest("GET", apiEndpoint, nil) + if err != nil { + return nil, nil, err + } + roles := new([]Role) + resp, err := s.client.Do(req, roles) + if err != nil { + jerr := NewJiraError(resp, err) + return nil, resp, jerr + } + return roles, resp, err +} + +// Get retreives a single Role from Jira +func (s *RoleService) Get(roleID int) (*Role, *Response, error) { + apiEndpoint := fmt.Sprintf("rest/api/3/role/%d", roleID) + req, err := s.client.NewRequest("GET", apiEndpoint, nil) + if err != nil { + return nil, nil, err + } + role := new(Role) + resp, err := s.client.Do(req, role) + if err != nil { + jerr := NewJiraError(resp, err) + return nil, resp, jerr + } + + return role, resp, err +} diff --git a/role_test.go b/role_test.go new file mode 100644 index 0000000..31a1a33 --- /dev/null +++ b/role_test.go @@ -0,0 +1,56 @@ +package jira + +import ( + "fmt" + "io/ioutil" + "net/http" + "testing" +) + +func TestRoleService_GetList(t *testing.T) { + setup() + defer teardown() + testAPIEndpoint := "/rest/api/3/role" + + raw, err := ioutil.ReadFile("./mocks/all_roles.json") + if err != nil { + t.Error(err.Error()) + } + testMux.HandleFunc(testAPIEndpoint, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testRequestURL(t, r, testAPIEndpoint) + fmt.Fprintf(w, string(raw)) + }) + + roles, _, err := testClient.Role.GetList() + if roles == nil { + t.Error("Expected role list. Role list is nil") + } + if err != nil { + t.Errorf("Error given: %v", err) + } +} + +func TestRoleService_Get(t *testing.T) { + setup() + defer teardown() + testAPIEdpoint := "/rest/api/3/role/10002" + raw, err := ioutil.ReadFile("./mocks/role.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)) + }) + + role, _, err := testClient.Role.Get(10002) + if role == nil { + t.Errorf("Expected Role, got nil") + } + if err != nil { + t.Errorf("Error given: %s", err) + } + +}