diff --git a/CHANGELOG.md b/CHANGELOG.md index 62fd651..c5e7c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Added optional override for the filename in `Api::createAttachment` by [@betterphp] - Allow getting issue count back from `Walker` class by [@aik099]. - Setup `.gitattributes` for better `CHANGELOG.md` merging by [@glensc]. +- Added `Api::addWorklog` and `Api::deleteWorklog` calls for more control over the work logs [@dumconstantin] and [@aik099]. ### Changed - Classes/interfaces were renamed to use namespaces by [@chobie]. @@ -71,3 +72,4 @@ This project adheres to [Semantic Versioning](https://semver.org/). [@aik099]: https://github.com/aik099 [@betterphp]: https://github.com/betterphp [@glensc]: https://github.com/glensc +[@dumconstantin]: https://github.com/dumconstantin diff --git a/src/Jira/Api.php b/src/Jira/Api.php index 8bf3cee..1426710 100644 --- a/src/Jira/Api.php +++ b/src/Jira/Api.php @@ -38,6 +38,7 @@ class Api const REQUEST_DELETE = 'DELETE'; const AUTOMAP_FIELDS = 0x01; + const DATE_TIME_FORMAT = 'Y-m-d\TG:m:s.vO'; /** * Endpoint URL. @@ -373,6 +374,33 @@ public function addComment($issue_key, $params) return $this->api(self::REQUEST_POST, sprintf('/rest/api/2/issue/%s/comment', $issue_key), $params); } + /** + * Adds a worklog for an issue. + * + * @param string $issue_key Issue key should be "YOURPROJ-22". + * @param string|integer $time_spent Either string in "2w 4d 6h 45m" format or second count as a number. + * @param array $params Params. + * + * @return array + * @since 2.0.0 + */ + public function addWorklog($issue_key, $time_spent, array $params = array()) + { + if ( is_int($time_spent) ) { + $params['timeSpentSeconds'] = $time_spent; + } + else { + $params['timeSpent'] = $time_spent; + } + + return $this->api( + self::REQUEST_POST, + sprintf('/rest/api/2/issue/%s/worklog', $issue_key), + $params, + true + ); + } + /** * Get all worklogs for an issue. * @@ -387,6 +415,26 @@ public function getWorklogs($issue_key, array $params) return $this->api(self::REQUEST_GET, sprintf('/rest/api/2/issue/%s/worklog', $issue_key), $params); } + /** + * Deletes an issue worklog. + * + * @param string $issue_key Issue key should be "YOURPROJ-22". + * @param integer $worklog_id Work Log ID. + * @param array $params Params. + * + * @return array + * @since 2.0.0 + */ + public function deleteWorklog($issue_key, $worklog_id, array $params = array()) + { + return $this->api( + self::REQUEST_DELETE, + sprintf('/rest/api/2/issue/%s/worklog/%s', $issue_key, $worklog_id), + $params, + true + ); + } + /** * Get available transitions for a ticket. * diff --git a/tests/Jira/ApiTest.php b/tests/Jira/ApiTest.php index 31c69a4..caed679 100644 --- a/tests/Jira/ApiTest.php +++ b/tests/Jira/ApiTest.php @@ -312,6 +312,86 @@ public function testGetIssueTypes() $this->assertEquals($expected, $actual); } + /** + * @param string|integer $time_spent Time spent. + * @param array $expected_rest_params Expected rest params. + * + * @return void + * @dataProvider addWorkLogWithoutCustomParamsDataProvider + */ + public function testAddWorkLogWithoutCustomParams($time_spent, array $expected_rest_params) + { + $response = '{}'; + + $this->expectClientCall( + Api::REQUEST_POST, + '/rest/api/2/issue/JRA-15/worklog', + $expected_rest_params, + $response + ); + + $actual = $this->api->addWorklog('JRA-15', $time_spent); + + $this->assertEquals(json_decode($response, true), $actual, 'The response is json-decoded.'); + } + + public static function addWorkLogWithoutCustomParamsDataProvider() + { + return array( + 'integer time spent' => array(12, array('timeSpentSeconds' => 12)), + 'string time spent' => array('12m', array('timeSpent' => '12m')), + ); + } + + public function testAddWorklogWithCustomParams() + { + $response = '{}'; + + $started = date(Api::DATE_TIME_FORMAT, 1621026000); + $this->expectClientCall( + Api::REQUEST_POST, + '/rest/api/2/issue/JRA-15/worklog', + array('timeSpent' => '12m', 'started' => $started), + $response + ); + + $actual = $this->api->addWorklog('JRA-15', '12m', array('started' => $started)); + + $this->assertEquals(json_decode($response, true), $actual, 'The response is json-decoded.'); + } + + public function testDeleteWorkLogWithoutCustomParams() + { + $response = '{}'; + + $this->expectClientCall( + Api::REQUEST_DELETE, + '/rest/api/2/issue/JRA-15/worklog/11256', + array(), + $response + ); + + $actual = $this->api->deleteWorklog('JRA-15', 11256); + + $this->assertEquals(json_decode($response, true), $actual, 'The response is json-decoded.'); + } + + public function testDeleteWorkLogWithCustomParams() + { + $response = '{}'; + + $this->expectClientCall( + Api::REQUEST_DELETE, + '/rest/api/2/issue/JRA-15/worklog/11256', + array('custom' => 'param'), + $response + ); + + $actual = $this->api->deleteWorklog('JRA-15', 11256, array('custom' => 'param')); + + $this->assertEquals(json_decode($response, true), $actual, 'The response is json-decoded.'); + } + /** * Expects a particular client call. *