diff --git a/component.go b/component.go index b76fe0cf..c4d889cf 100644 --- a/component.go +++ b/component.go @@ -1,6 +1,9 @@ package jira -import "context" +import ( + "context" + "fmt" +) // ComponentService handles components for the Jira instance / API.// // Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.1/#api/2/component @@ -42,3 +45,26 @@ func (s *ComponentService) CreateWithContext(ctx context.Context, options *Creat func (s *ComponentService) Create(options *CreateComponentOptions) (*ProjectComponent, *Response, error) { return s.CreateWithContext(context.Background(), options) } + +// GetWithContext returns a full representation of the JIRA component for the given component ID. +// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-project-components/ +func (s *ComponentService) GetWithContext(ctx context.Context, componentID string) (*ProjectComponent, *Response, error) { + apiEndpoint := fmt.Sprintf("rest/api/2/component/%s", componentID) + req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil) + if err != nil { + return nil, nil, err + } + + component := new(ProjectComponent) + resp, err := s.client.Do(req, component) + if err != nil { + return nil, resp, NewJiraError(resp, err) + } + + return component, resp, nil +} + +// Get wraps GetWithContext using the background context. +func (s *ComponentService) Get(componentID string) (*ProjectComponent, *Response, error) { + return s.GetWithContext(context.Background(), componentID) +} diff --git a/component_test.go b/component_test.go index 527cdbe6..ed1633b1 100644 --- a/component_test.go +++ b/component_test.go @@ -2,6 +2,7 @@ package jira import ( "fmt" + "io/ioutil" "net/http" "testing" ) @@ -27,3 +28,52 @@ func TestComponentService_Create_Success(t *testing.T) { t.Errorf("Error given: %s", err) } } + +func TestComponentService_Get(t *testing.T) { + setup() + defer teardown() + testAPIEdpoint := "/rest/api/2/component/42102" + + raw, err := ioutil.ReadFile("./mocks/component.json") + if err != nil { + t.Error(err.Error()) + } + testMux.HandleFunc(testAPIEdpoint, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testRequestURL(t, r, testAPIEdpoint) + fmt.Fprint(w, string(raw)) + }) + + component, _, err := testClient.Component.Get("42102") + if err != nil { + t.Errorf("Error given: %s", err) + } + if component == nil { + t.Error("Expected component. Component is nil") + return + } +} + +func TestComponentService_Get_NoComponent(t *testing.T) { + setup() + defer teardown() + testAPIEdpoint := "/rest/api/2/component/99999999" + + testMux.HandleFunc(testAPIEdpoint, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testRequestURL(t, r, testAPIEdpoint) + fmt.Fprint(w, nil) + }) + + component, resp, err := testClient.Component.Get("99999999") + if component != nil { + t.Errorf("Expected nil. Got %+v", component) + } + + if resp.Status == "404" { + t.Errorf("Expected status 404. Got %s", resp.Status) + } + if err == nil { + t.Errorf("Error given: %s", err) + } +} diff --git a/mocks/component.json b/mocks/component.json new file mode 100644 index 00000000..1d4812b9 --- /dev/null +++ b/mocks/component.json @@ -0,0 +1,50 @@ +{ + "self": "https://issues.apache.org/jira/rest/api/2/component/42102", + "id": "42102", + "name": "Some Component", + "lead": { + "self": "https://issues.apache.org/jira/rest/api/2/user?username=firstname.lastname@apache.org", + "key": "firstname.lastname", + "name": "firstname.lastname@apache.org", + "avatarUrls": { + "48x48": "https://issues.apache.org/jira/secure/useravatar?ownerId=firstname.lastname&avatarId=31851", + "24x24": "https://issues.apache.org/jira/secure/useravatar?size=small&ownerId=firstname.lastname&avatarId=31851", + "16x16": "https://issues.apache.org/jira/secure/useravatar?size=xsmall&ownerId=firstname.lastname&avatarId=31851", + "32x32": "https://issues.apache.org/jira/secure/useravatar?size=medium&ownerId=firstname.lastname&avatarId=31851" + }, + "displayName": "Firstname Lastname", + "active": true + }, + "assigneeType": "COMPONENT_LEAD", + "assignee": { + "self": "https://issues.apache.org/jira/rest/api/2/user?username=firstname.lastname@apache.org", + "key": "firstname.lastname", + "name": "firstname.lastname@apache.org", + "avatarUrls": { + "48x48": "https://issues.apache.org/jira/secure/useravatar?ownerId=firstname.lastname&avatarId=31851", + "24x24": "https://issues.apache.org/jira/secure/useravatar?size=small&ownerId=firstname.lastname&avatarId=31851", + "16x16": "https://issues.apache.org/jira/secure/useravatar?size=xsmall&ownerId=firstname.lastname&avatarId=31851", + "32x32": "https://issues.apache.org/jira/secure/useravatar?size=medium&ownerId=firstname.lastname&avatarId=31851" + }, + "displayName": "Firstname Lastname", + "active": true + }, + "realAssigneeType": "COMPONENT_LEAD", + "realAssignee": { + "self": "https://issues.apache.org/jira/rest/api/2/user?username=firstname.lastname@apache.org", + "key": "firstname.lastname", + "name": "firstname.lastname@apache.org", + "avatarUrls": { + "48x48": "https://issues.apache.org/jira/secure/useravatar?ownerId=firstname.lastname&avatarId=31851", + "24x24": "https://issues.apache.org/jira/secure/useravatar?size=small&ownerId=firstname.lastname&avatarId=31851", + "16x16": "https://issues.apache.org/jira/secure/useravatar?size=xsmall&ownerId=firstname.lastname&avatarId=31851", + "32x32": "https://issues.apache.org/jira/secure/useravatar?size=medium&ownerId=firstname.lastname&avatarId=31851" + }, + "displayName": "Firstname Lastname", + "active": true + }, + "isAssigneeTypeValid": true, + "project": "ABC", + "projectId": 12345, + "archived": false +} \ No newline at end of file