From 5d7dc2d55bc6c98c4063f5b0a28d2070cffff7e5 Mon Sep 17 00:00:00 2001 From: mscherer Date: Thu, 6 Oct 2022 14:52:33 +0200 Subject: [PATCH 1/2] Consistent API return as assoc array --- src/Jira/Api.php | 58 ++-- tests/Jira/ApiTest.php | 200 +++++++++++ tests/Jira/resources/api_add_comment.json | 23 ++ tests/Jira/resources/api_get_attachment.json | 23 ++ .../resources/api_get_attachments_meta.json | 4 + tests/Jira/resources/api_get_issue.json | 322 ++++++++++++++++++ tests/Jira/resources/api_get_project.json | 52 +++ tests/Jira/resources/api_get_projects.json | 30 ++ .../api_get_role_of_project_by_id.json | 29 ++ tests/Jira/resources/api_get_roles.json | 30 ++ .../resources/api_get_roles_of_project.json | 6 + .../resources/api_get_worklog_of_issue.json | 89 +++++ 12 files changed, 837 insertions(+), 29 deletions(-) create mode 100644 tests/Jira/resources/api_add_comment.json create mode 100644 tests/Jira/resources/api_get_attachment.json create mode 100644 tests/Jira/resources/api_get_attachments_meta.json create mode 100644 tests/Jira/resources/api_get_issue.json create mode 100644 tests/Jira/resources/api_get_project.json create mode 100644 tests/Jira/resources/api_get_projects.json create mode 100644 tests/Jira/resources/api_get_role_of_project_by_id.json create mode 100644 tests/Jira/resources/api_get_roles.json create mode 100644 tests/Jira/resources/api_get_roles_of_project.json create mode 100644 tests/Jira/resources/api_get_worklog_of_issue.json diff --git a/src/Jira/Api.php b/src/Jira/Api.php index c4b6f02..7239046 100644 --- a/src/Jira/Api.php +++ b/src/Jira/Api.php @@ -187,13 +187,13 @@ protected function clearLocalCaches() { /** * Get fields definitions. * - * @return array + * @return array|null */ public function getFields() { // Fetch fields when the method is called for the first time. if ($this->fields === null) { $fields = []; - $result = $this->api(static::REQUEST_GET, '/rest/api/2/field', [], true); + $result = $this->api(static::REQUEST_GET, '/rest/api/2/field'); /* set hash key as custom field id */ foreach ($result as $field) { @@ -254,7 +254,7 @@ public function deleteIssue($issueKey, bool $deleteSubtasks = true, array $param /** * Gets attachments meta information. * - * @return array + * @return array|false */ public function getAttachmentsMetaInformation() { return $this->api(static::REQUEST_GET, '/rest/api/2/attachment/meta'); @@ -268,7 +268,7 @@ public function getAttachmentsMetaInformation() { * @return array|false */ public function getAttachment($attachment_id) { - return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/attachment/%s', $attachment_id), [], true); + return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/attachment/%s', $attachment_id)); } /** @@ -283,37 +283,37 @@ public function getProjects() { /** * Returns one project. * - * @param string $project_key Project key. + * @param string $projectKey Project ID or key. * * @return array|false */ - public function getProject($project_key) { - return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s', $project_key), [], true); + public function getProject($projectKey) { + return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s', $projectKey)); } /** * Returns all roles of a project. * - * @param string $project_key Project key. + * @param string $projectKey Project ID or key. * * @return array|false */ - public function getRoles($project_key) { - return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/role', $project_key), [], true); + public function getRoles($projectKey) { + return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/role', $projectKey)); } /** * Returns role details. * - * @param string $project_key Project key. - * @param string $role_id Role ID. + * @param string $projectKey Project key. + * @param string $roleId Role ID. * * @return array|false */ - public function getRoleDetails($project_key, $role_id) { + public function getRoleDetails($projectKey, $roleId) { return $this->api( static::REQUEST_GET, - sprintf('/rest/api/2/project/%s/role/%s', $project_key, $role_id), + sprintf('/rest/api/2/project/%s/role/%s', $projectKey, $roleId), [], true, ); @@ -322,7 +322,7 @@ public function getRoleDetails($project_key, $role_id) { /** * Returns the meta data for creating issues. * This includes the available projects, issue types - * and fields, including field types and whether or not those fields are required. + * and fields, including field types and whether those fields are required. * Projects will not be returned if the user does not have permission to create issues in that project. * Fields will only be returned if "projects.issuetypes.fields" is added as expand parameter. * @@ -472,7 +472,7 @@ public function transition($issueKey, array $params = []) { */ public function getIssueTypes() { $result = []; - $types = $this->api(static::REQUEST_GET, '/rest/api/2/issuetype', [], true); + $types = $this->api(static::REQUEST_GET, '/rest/api/2/issuetype'); foreach ($types as $type) { $result[] = new IssueType($type); @@ -489,7 +489,7 @@ public function getIssueTypes() { * @return array|false */ public function getVersions($project_key) { - return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/versions', $project_key), [], true); + return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/versions', $project_key)); } /** @@ -521,13 +521,13 @@ public function findVersionByName($project_key, $name) { /** * Get available priorities. * - * @return array + * @return array|false */ public function getPriorities() { // Fetch priorities when the method is called for the first time. if ($this->priorities === null) { $priorities = []; - $result = $this->api(static::REQUEST_GET, '/rest/api/2/priority', [], true); + $result = $this->api(static::REQUEST_GET, '/rest/api/2/priority'); /* set hash key as custom field id */ foreach ($result as $priority) { @@ -549,7 +549,7 @@ public function getStatuses() { // Fetch statuses when the method is called for the first time. if ($this->statuses === null) { $statuses = []; - $result = $this->api(static::REQUEST_GET, '/rest/api/2/status', [], true); + $result = $this->api(static::REQUEST_GET, '/rest/api/2/status'); /* set hash key as custom field id */ foreach ($result as $status) { @@ -643,7 +643,7 @@ public function createVersion($projectKey, $version, array $options = []) { * @param int $version_id Version ID. * @param array $params Key->Value list to update the version with. * - * @return false + * @return array|false */ public function updateVersion($version_id, array $params = []) { return $this->api(static::REQUEST_PUT, sprintf('/rest/api/2/version/%d', $version_id), $params); @@ -690,7 +690,7 @@ public function createAttachment($issueKey, $filename, $name = null) { static::REQUEST_POST, sprintf('/rest/api/2/issue/%s/attachments', $issueKey), $options, - false, + true, true, ); } @@ -742,7 +742,7 @@ public function api( $method, $url, $data = [], - $return_as_array = false, + $return_as_array = true, $is_file = false, $debug = false ) { @@ -884,10 +884,10 @@ public function closeIssue($issueKey) { * * @param string $project_key Project key. * - * @return array + * @return array|false */ public function getProjectComponents($project_key) { - return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/components', $project_key), [], true); + return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/components', $project_key)); } /** @@ -895,22 +895,22 @@ public function getProjectComponents($project_key) { * * @param string $project_key Project key. * - * @return array + * @return array|false */ public function getProjectIssueTypes($project_key) { - return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/statuses', $project_key), [], true); + return $this->api(static::REQUEST_GET, sprintf('/rest/api/2/project/%s/statuses', $project_key)); } /** * Returns a list of all resolutions. * - * @return array + * @return array|false */ public function getResolutions() { // Fetch resolutions when the method is called for the first time. if ($this->resolutions === null) { $resolutions = []; - $result = $this->api(static::REQUEST_GET, '/rest/api/2/resolution', [], true); + $result = $this->api(static::REQUEST_GET, '/rest/api/2/resolution'); foreach ($result as $resolution) { $resolutions[$resolution['id']] = $resolution; diff --git a/tests/Jira/ApiTest.php b/tests/Jira/ApiTest.php index 2b8772d..5710066 100644 --- a/tests/Jira/ApiTest.php +++ b/tests/Jira/ApiTest.php @@ -310,6 +310,206 @@ public function testGetPriorities() { $this->assertEquals($expected, $this->api->getPriorities(), 'Calling twice did not yield the same results'); } + /** + * @return void + */ + public function testGetIssue() { + $response = file_get_contents(__DIR__ . '/resources/api_get_issue.json'); + + $issue_key = 'POR-1'; + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/issue/' . $issue_key, + ['expand' => ''], + $response, + ); + + $actual = $this->api->getIssue($issue_key); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testEditIssue() { + $issue_key = 'POR-1'; + $params = ['update' => (object)['summary' => [(object)['set' => 'Bug in business logic']]]]; + $this->expectClientCall( + Api::REQUEST_PUT, + '/rest/api/2/issue/' . $issue_key, + $params, + false, // False is returned because there is no content (204). + ); + + $actual = $this->api->editIssue($issue_key, $params); + $this->assertEquals(false, $actual); + } + + /** + * @return void + */ + public function testGetAttachmentsMetaInformation() { + $response = file_get_contents(__DIR__ . '/resources/api_get_attachments_meta.json'); + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/attachment/meta', + [], + $response, + ); + + $actual = $this->api->getAttachmentsMetaInformation(); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testGetAttachment() { + $response = file_get_contents(__DIR__ . '/resources/api_get_attachment.json'); + $attachment_id = '18700'; + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/attachment/' . $attachment_id, + [], + $response, + ); + + $actual = $this->api->getAttachment($attachment_id); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testGetProjects() { + $response = file_get_contents(__DIR__ . '/resources/api_get_projects.json'); + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/project', + [], + $response, + ); + + $actual = $this->api->getProjects(); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testGetProject() { + $response = file_get_contents(__DIR__ . '/resources/api_get_project.json'); + $project_id = '10500'; + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/project/' . $project_id, + [], + $response, + ); + + $actual = $this->api->getProject($project_id); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testGetRoles() { + $response = file_get_contents(__DIR__ . '/resources/api_get_roles_of_project.json'); + $project_id = '10500'; + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/project/' . $project_id . '/role', + [], + $response, + ); + + $actual = $this->api->getRoles($project_id); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testGetRoleDetails() { + $response = file_get_contents(__DIR__ . '/resources/api_get_role_of_project_by_id.json'); + $project_id = '10500'; + $role_id = '10200'; + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/project/' . $project_id . '/role/' . $role_id, + [], + $response, + ); + + $actual = $this->api->getRoleDetails($project_id, $role_id); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testAddComment() { + $response = file_get_contents(__DIR__ . '/resources/api_add_comment.json'); + $issue_key = 'POR-1'; + + // Testing the case where the description is provided directly instead of params + $description = 'testdesc'; + + $this->expectClientCall( + Api::REQUEST_POST, + '/rest/api/2/issue/' . $issue_key . '/comment', + ['body' => $description], + $response, + ); + + $actual = $this->api->addComment($issue_key, $description); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testGetWorklog() { + $response = file_get_contents(__DIR__ . '/resources/api_get_roles_of_project.json'); + $issue_key = 'POR-1'; + + $this->expectClientCall( + Api::REQUEST_GET, + '/rest/api/2/issue/' . $issue_key . '/worklog', + [], + $response, + ); + + $actual = $this->api->getWorklogs($issue_key); + + $expected = json_decode($response, true); + $this->assertEquals($expected, $actual); + } + /** * Expects a particular client call. * diff --git a/tests/Jira/resources/api_add_comment.json b/tests/Jira/resources/api_add_comment.json new file mode 100644 index 0000000..538540e --- /dev/null +++ b/tests/Jira/resources/api_add_comment.json @@ -0,0 +1,23 @@ +{ + "self": "http://www.example.com/jira/rest/api/2/issue/10010/comment/10000", + "id": "10000", + "author": { + "self": "http://www.example.com/jira/rest/api/2/user?username=fred", + "name": "fred", + "displayName": "Fred F. User", + "active": false + }, + "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eget venenatis elit. Duis eu justo eget augue iaculis fermentum. Sed semper quam laoreet nisi egestas at posuere augue semper.", + "updateAuthor": { + "self": "http://www.example.com/jira/rest/api/2/user?username=fred", + "name": "fred", + "displayName": "Fred F. User", + "active": false + }, + "created": "2016-08-17T12:37:37.987+0000", + "updated": "2016-08-17T12:37:37.987+0000", + "visibility": { + "type": "role", + "value": "Administrators" + } +} diff --git a/tests/Jira/resources/api_get_attachment.json b/tests/Jira/resources/api_get_attachment.json new file mode 100644 index 0000000..1fa9302 --- /dev/null +++ b/tests/Jira/resources/api_get_attachment.json @@ -0,0 +1,23 @@ +{ + "self": "https://test.atlassian.net/rest/api/2/attachment/18700", + "filename": "2016-04-04 10.02.45.jpg", + "author": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost.pastoor", + "key": "joost.pastoor", + "name": "joost.pastoor", + "avatarUrls": { + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost.pastoor&avatarId=10502", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost.pastoor&avatarId=10502", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost.pastoor&avatarId=10502", + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost.pastoor&avatarId=10502" + }, + "displayName": "Ernst van Rijn", + "active": true + }, + "created": "2016-04-04T10:04:07.537+0200", + "size": 4097662, + "mimeType": "image/jpeg", + "properties": {}, + "content": "https://test.atlassian.net/secure/attachment/18700/2016-04-04+10.02.45.jpg", + "thumbnail": "https://test.atlassian.net/secure/thumbnail/18700/_thumb_18700.png" +} diff --git a/tests/Jira/resources/api_get_attachments_meta.json b/tests/Jira/resources/api_get_attachments_meta.json new file mode 100644 index 0000000..ae3f08c --- /dev/null +++ b/tests/Jira/resources/api_get_attachments_meta.json @@ -0,0 +1,4 @@ +{ + "enabled": true, + "uploadLimit": 10485760 +} diff --git a/tests/Jira/resources/api_get_issue.json b/tests/Jira/resources/api_get_issue.json new file mode 100644 index 0000000..45b14b7 --- /dev/null +++ b/tests/Jira/resources/api_get_issue.json @@ -0,0 +1,322 @@ +{ + "expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations", + "id": "10100", + "self": "https://test.atlassian.net/rest/api/2/issue/10100", + "key": "POR-1", + "fields": { + "issuetype": { + "self": "https://test.atlassian.net/rest/api/2/issuetype/4", + "id": "4", + "description": "An improvement or enhancement to an existing feature or task.", + "iconUrl": "https://test.atlassian.net/secure/viewavatar?size=xsmall&avatarId=11110&avatarType=issuetype", + "name": "Improvement", + "subtask": false, + "avatarId": 11110 + }, + "timespent": 316800, + "project": { + "self": "https://test.atlassian.net/rest/api/2/project/10100", + "id": "10100", + "key": "POR", + "name": "Portal", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/projectavatar?pid=10100&avatarId=10401", + "24x24": "https://test.atlassian.net/secure/projectavatar?size=small&pid=10100&avatarId=10401", + "16x16": "https://test.atlassian.net/secure/projectavatar?size=xsmall&pid=10100&avatarId=10401", + "32x32": "https://test.atlassian.net/secure/projectavatar?size=medium&pid=10100&avatarId=10401" + } + }, + "fixVersions": [], + "aggregatetimespent": 316800, + "resolution": { + "self": "https://test.atlassian.net/rest/api/2/resolution/1", + "id": "1", + "description": "A fix for this issue is checked into the tree and tested.", + "name": "Fixed" + }, + "customfield_10500": null, + "customfield_10501": [], + "customfield_10502": null, + "resolutiondate": "2013-05-13T15:53:48.236+0200", + "workratio": 1100, + "lastViewed": null, + "watches": { + "self": "https://test.atlassian.net/rest/api/2/issue/POR-1/watchers", + "watchCount": 1, + "isWatching": true + }, + "created": "2013-05-13T08:57:21.520+0200", + "customfield_10020": null, + "customfield_10021": "Not started", + "priority": { + "self": "https://test.atlassian.net/rest/api/2/priority/3", + "iconUrl": "https://test.atlassian.net/images/icons/priorities/major.svg", + "name": "Major", + "id": "3" + }, + "customfield_10024": null, + "customfield_10300": null, + "labels": [ + "esee-wp5.4" + ], + "customfield_10016": null, + "customfield_10017": null, + "customfield_10018": null, + "customfield_10019": null, + "timeestimate": 0, + "aggregatetimeoriginalestimate": 28800, + "versions": [], + "issuelinks": [ + { + "id": "10000", + "self": "https://test.atlassian.net/rest/api/2/issueLink/10000", + "type": { + "id": "10003", + "name": "Relates", + "inward": "relates to", + "outward": "relates to", + "self": "https://test.atlassian.net/rest/api/2/issueLinkType/10003" + }, + "outwardIssue": { + "id": "10101", + "key": "POR-2", + "self": "https://test.atlassian.net/rest/api/2/issue/10101", + "fields": { + "summary": "Speedup Precalced Props with Gearman", + "status": { + "self": "https://test.atlassian.net/rest/api/2/status/6", + "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", + "iconUrl": "https://test.atlassian.net/images/icons/statuses/closed.png", + "name": "Closed", + "id": "6", + "statusCategory": { + "self": "https://test.atlassian.net/rest/api/2/statuscategory/3", + "id": 3, + "key": "done", + "colorName": "green", + "name": "Done" + } + }, + "priority": { + "self": "https://test.atlassian.net/rest/api/2/priority/3", + "iconUrl": "https://test.atlassian.net/images/icons/priorities/major.svg", + "name": "Major", + "id": "3" + }, + "issuetype": { + "self": "https://test.atlassian.net/rest/api/2/issuetype/4", + "id": "4", + "description": "An improvement or enhancement to an existing feature or task.", + "iconUrl": "https://test.atlassian.net/secure/viewavatar?size=xsmall&avatarId=11110&avatarType=issuetype", + "name": "Improvement", + "subtask": false, + "avatarId": 11110 + } + } + } + } + ], + "assignee": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "updated": "2016-08-03T16:57:31.232+0200", + "status": { + "self": "https://test.atlassian.net/rest/api/2/status/5", + "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", + "iconUrl": "https://test.atlassian.net/images/icons/statuses/resolved.png", + "name": "Resolved", + "id": "5", + "statusCategory": { + "self": "https://test.atlassian.net/rest/api/2/statuscategory/3", + "id": 3, + "key": "done", + "colorName": "green", + "name": "Done" + } + }, + "components": [], + "timeoriginalestimate": 28800, + "description": "- Both hourly reports and passings", + "customfield_10012": null, + "customfield_10013": null, + "customfield_10014": null, + "timetracking": { + "originalEstimate": "1d", + "remainingEstimate": "0m", + "timeSpent": "2w 1d", + "originalEstimateSeconds": 28800, + "remainingEstimateSeconds": 0, + "timeSpentSeconds": 316800 + }, + "customfield_10015": null, + "customfield_10401": null, + "customfield_10006": "22", + "customfield_10600": "com.atlassian.servicedesk.plugins.approvals.internal.customfield.ApprovalsCFValue@1956b56", + "customfield_10007": null, + "customfield_10008": null, + "attachment": [], + "aggregatetimeestimate": 0, + "summary": "Convert TrainMeasurement passings to Precalculated Property", + "creator": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "subtasks": [], + "reporter": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "customfield_10000": "3_*:*_1_*:*_0_*|*_1_*:*_1_*:*_307391", + "aggregateprogress": { + "progress": 316800, + "total": 316800, + "percent": 100 + }, + "customfield_10001": null, + "customfield_10200": "0|10004g:", + "customfield_10002": null, + "customfield_10003": null, + "customfield_10400": null, + "environment": null, + "duedate": null, + "progress": { + "progress": 316800, + "total": 316800, + "percent": 100 + }, + "comment": { + "comments": [], + "maxResults": 0, + "total": 0, + "startAt": 0 + }, + "votes": { + "self": "https://test.atlassian.net/rest/api/2/issue/POR-1/votes", + "votes": 0, + "hasVoted": false + }, + "worklog": { + "startAt": 0, + "maxResults": 20, + "total": 2, + "worklogs": [ + { + "self": "https://test.atlassian.net/rest/api/2/issue/10100/worklog/10001", + "author": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "updateAuthor": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "comment": "", + "created": "2013-05-13T15:53:48.236+0200", + "updated": "2013-05-13T15:53:48.236+0200", + "started": "2013-05-13T15:53:00.000+0200", + "timeSpent": "1d", + "timeSpentSeconds": 28800, + "id": "10001", + "issueId": "10100" + }, + { + "self": "https://test.atlassian.net/rest/api/2/issue/10100/worklog/31214", + "author": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "updateAuthor": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "comment": "", + "created": "2016-08-03T16:57:15.840+0200", + "updated": "2016-08-03T16:57:15.840+0200", + "started": "2013-05-01T16:56:00.000+0200", + "timeSpent": "2w", + "timeSpentSeconds": 288000, + "id": "31214", + "issueId": "10100" + } + ] + } + } +} diff --git a/tests/Jira/resources/api_get_project.json b/tests/Jira/resources/api_get_project.json new file mode 100644 index 0000000..d0b4a8e --- /dev/null +++ b/tests/Jira/resources/api_get_project.json @@ -0,0 +1,52 @@ +{ + "expand": "description,lead,url,projectKeys", + "self": "https://test.atlassian.net/rest/api/2/project/10500", + "id": "10500", + "key": "ONEDS", + "description": "", + "lead": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost.pastoor", + "key": "joost.pastoor", + "name": "joost.pastoor", + "avatarUrls": { + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost.pastoor&avatarId=10607", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost.pastoor&avatarId=10607", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost.pastoor&avatarId=10607", + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost.pastoor&avatarId=10607" + }, + "displayName": "Joost Pastoor", + "active": true + }, + "components": [], + "issueTypes": [ + { + "self": "https://test.atlassian.net/rest/api/2/issuetype/1", + "id": "1", + "description": "A problem which impairs or prevents the functions of the product.", + "iconUrl": "https://test.atlassian.net/secure/viewavatar?size=xsmall&avatarId=11103&avatarType=issuetype", + "name": "Bug", + "subtask": false, + "avatarId": 11103 + } + ], + "assigneeType": "UNASSIGNED", + "versions": [], + "name": "1D Sound", + "roles": { + "atlassian-addons-project-access": "https://test.atlassian.net/rest/api/2/project/10500/role/10200", + "Service Desk Team": "https://test.atlassian.net/rest/api/2/project/10500/role/10301", + "Developers": "https://test.atlassian.net/rest/api/2/project/10500/role/10001", + "Service Desk Customers": "https://test.atlassian.net/rest/api/2/project/10500/role/10300", + "Service Desk Collaborators": "https://test.atlassian.net/rest/api/2/project/10500/role/10302", + "Administrators": "https://test.atlassian.net/rest/api/2/project/10500/role/10002", + "Users": "https://test.atlassian.net/rest/api/2/project/10500/role/10000", + "Tempo Project Managers": "https://test.atlassian.net/rest/api/2/project/10500/role/10100" + }, + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/projectavatar?pid=10500&avatarId=10011", + "24x24": "https://test.atlassian.net/secure/projectavatar?size=small&pid=10500&avatarId=10011", + "16x16": "https://test.atlassian.net/secure/projectavatar?size=xsmall&pid=10500&avatarId=10011", + "32x32": "https://test.atlassian.net/secure/projectavatar?size=medium&pid=10500&avatarId=10011" + }, + "projectTypeKey": "software" +} diff --git a/tests/Jira/resources/api_get_projects.json b/tests/Jira/resources/api_get_projects.json new file mode 100644 index 0000000..694d819 --- /dev/null +++ b/tests/Jira/resources/api_get_projects.json @@ -0,0 +1,30 @@ +[ + { + "expand": "description,lead,url,projectKeys", + "self": "https://test.atlassian.net/rest/api/2/project/10500", + "id": "10500", + "key": "ONEDS", + "name": "1D Sound", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/projectavatar?pid=10500&avatarId=10011", + "24x24": "https://test.atlassian.net/secure/projectavatar?size=small&pid=10500&avatarId=10011", + "16x16": "https://test.atlassian.net/secure/projectavatar?size=xsmall&pid=10500&avatarId=10011", + "32x32": "https://test.atlassian.net/secure/projectavatar?size=medium&pid=10500&avatarId=10011" + }, + "projectTypeKey": "software" + }, + { + "expand": "description,lead,url,projectKeys", + "self": "https://test.atlassian.net/rest/api/2/project/10201", + "id": "10201", + "key": "SNDDIR", + "name": "3D Sound", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/projectavatar?pid=10201&avatarId=10605", + "24x24": "https://test.atlassian.net/secure/projectavatar?size=small&pid=10201&avatarId=10605", + "16x16": "https://test.atlassian.net/secure/projectavatar?size=xsmall&pid=10201&avatarId=10605", + "32x32": "https://test.atlassian.net/secure/projectavatar?size=medium&pid=10201&avatarId=10605" + }, + "projectTypeKey": "software" + } +] diff --git a/tests/Jira/resources/api_get_role_of_project_by_id.json b/tests/Jira/resources/api_get_role_of_project_by_id.json new file mode 100644 index 0000000..c361c8d --- /dev/null +++ b/tests/Jira/resources/api_get_role_of_project_by_id.json @@ -0,0 +1,29 @@ +{ + "self": "https://test.atlassian.net/rest/api/2/project/10500/role/10200", + "name": "atlassian-addons-project-access", + "id": 10200, + "description": "A project role that represents Connect add-ons declaring a scope that requires more than read issue permissions", + "actors": [ + { + "id": 15301, + "displayName": "Epic Sum Up - Free", + "type": "atlassian-user-role-actor", + "name": "addon_aptis.plugins.epicSumUpFree", + "avatarUrl": "https://test.atlassian.net/secure/useravatar?size=xsmall&avatarId=10122" + }, + { + "id": 11701, + "displayName": "Gantt Cloud", + "type": "atlassian-user-role-actor", + "name": "addon_eu.wisoft.gantt-ondemand", + "avatarUrl": "https://test.atlassian.net/secure/useravatar?size=xsmall&avatarId=10122" + }, + { + "id": 14601, + "displayName": "Zendesk for JIRA", + "type": "atlassian-user-role-actor", + "name": "addon_zendesk_for_jira", + "avatarUrl": "https://test.atlassian.net/secure/useravatar?size=xsmall&avatarId=10122" + } + ] +} diff --git a/tests/Jira/resources/api_get_roles.json b/tests/Jira/resources/api_get_roles.json new file mode 100644 index 0000000..be92101 --- /dev/null +++ b/tests/Jira/resources/api_get_roles.json @@ -0,0 +1,30 @@ +[ + { + "self": "https://test.atlassian.net/rest/api/2/role/10002", + "name": "Administrators", + "id": 10002, + "description": "A project role that represents administrators in a project", + "actors": [ + { + "id": 10002, + "displayName": "administrators", + "type": "atlassian-group-role-actor", + "name": "administrators" + } + ] + }, + { + "self": "https://test.atlassian.net/rest/api/2/role/10000", + "name": "Users", + "id": 10000, + "description": "A project role that represents users in a project", + "actors": [ + { + "id": 10000, + "displayName": "users", + "type": "atlassian-group-role-actor", + "name": "users" + } + ] + } +] diff --git a/tests/Jira/resources/api_get_roles_of_project.json b/tests/Jira/resources/api_get_roles_of_project.json new file mode 100644 index 0000000..7c0d9e4 --- /dev/null +++ b/tests/Jira/resources/api_get_roles_of_project.json @@ -0,0 +1,6 @@ +{ + "Service Desk Team": "https://test.atlassian.net/rest/api/2/project/10500/role/10301", + "Developers": "https://test.atlassian.net/rest/api/2/project/10500/role/10001", + "Administrators": "https://test.atlassian.net/rest/api/2/project/10500/role/10002", + "Users": "https://test.atlassian.net/rest/api/2/project/10500/role/10000" +} diff --git a/tests/Jira/resources/api_get_worklog_of_issue.json b/tests/Jira/resources/api_get_worklog_of_issue.json new file mode 100644 index 0000000..88c6fa5 --- /dev/null +++ b/tests/Jira/resources/api_get_worklog_of_issue.json @@ -0,0 +1,89 @@ +{ + "startAt": 0, + "maxResults": 2, + "total": 2, + "worklogs": [ + { + "self": "https://test.atlassian.net/rest/api/2/issue/10100/worklog/10001", + "author": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "updateAuthor": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "comment": "", + "created": "2013-05-13T15:53:48.236+0200", + "updated": "2013-05-13T15:53:48.236+0200", + "started": "2013-05-13T15:53:00.000+0200", + "timeSpent": "1d", + "timeSpentSeconds": 28800, + "id": "10001", + "issueId": "10100" + }, + { + "self": "https://test.atlassian.net/rest/api/2/issue/10100/worklog/31214", + "author": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "updateAuthor": { + "self": "https://test.atlassian.net/rest/api/2/user?username=joost", + "name": "joost", + "key": "joost", + "emailAddress": "joost.pastoor@test.com", + "avatarUrls": { + "48x48": "https://test.atlassian.net/secure/useravatar?ownerId=joost&avatarId=10500", + "24x24": "https://test.atlassian.net/secure/useravatar?size=small&ownerId=joost&avatarId=10500", + "16x16": "https://test.atlassian.net/secure/useravatar?size=xsmall&ownerId=joost&avatarId=10500", + "32x32": "https://test.atlassian.net/secure/useravatar?size=medium&ownerId=joost&avatarId=10500" + }, + "displayName": "Joost Pastoor", + "active": true, + "timeZone": "Europe/Berlin" + }, + "comment": "", + "created": "2016-08-03T16:57:15.840+0200", + "updated": "2016-08-03T16:57:15.840+0200", + "started": "2013-05-01T16:56:00.000+0200", + "timeSpent": "2w", + "timeSpentSeconds": 288000, + "id": "31214", + "issueId": "10100" + } + ] +} From bd46f73a5a9cfc90b127203fa78f20270eb3439c Mon Sep 17 00:00:00 2001 From: mscherer Date: Thu, 6 Oct 2022 14:55:53 +0200 Subject: [PATCH 2/2] Consistent API return as assoc array --- tests/Jira/ApiTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Jira/ApiTest.php b/tests/Jira/ApiTest.php index 5710066..6eb216a 100644 --- a/tests/Jira/ApiTest.php +++ b/tests/Jira/ApiTest.php @@ -3,7 +3,6 @@ namespace Tests\chobie\Jira; use chobie\Jira\Api; -use chobie\Jira\Api\Result; use PHPUnit\Framework\TestCase; /** @@ -99,7 +98,7 @@ public function testSearch() { file_get_contents(__DIR__ . '/resources/api_field.json'), ); - $this->assertEquals(new Result($response_decoded), $this->api->search('test', 0, 2, 'description')); + $this->assertEquals($response_decoded, $this->api->search('test', 0, 2, 'description')); } /**