From 58a0546409095b1e41b99a4f274d1046b0a8df3e Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 28 Sep 2023 15:28:00 +0200 Subject: [PATCH 01/27] Add CustomFields::list(), deprecate all() --- CHANGELOG.md | 2 + src/Redmine/Api/CustomField.php | 22 +++- tests/Unit/Api/CustomField/ListTest.php | 162 ++++++++++++++++++++++++ tests/Unit/Api/CustomFieldTest.php | 125 ------------------ 4 files changed, 184 insertions(+), 127 deletions(-) create mode 100644 tests/Unit/Api/CustomField/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 72fbf8a0..3e38a612 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Allow `Psr\Http\Message\RequestFactoryInterface` as Argument #2 ($requestFactory) in `Redmine\Client\Psr18Client::__construct()` +- New method `Redmine\Api\CustomField::list()` to list custom fields. - Added support for PHP 8.2 ### Deprecated - Providing Argument #2 ($requestFactory) in `Redmine\Client\Psr18Client::__construct()` as type `Psr\Http\Message\ServerRequestFactoryInterface` is deprecated, provide as type `Psr\Http\Message\RequestFactoryInterface` instead - `Redmine\Api\AbstractApi::attachCustomFieldXML()` is deprecated +- `Redmine\Api\CustomField::all()` is deprecated, use `Redmine\Api\CustomField::list()` instead - `Redmine\Api\Project::prepareParamsXml()` is deprecated ## [v2.2.0](https://github.com/kbsali/php-redmine-api/compare/v2.1.1...v2.2.0) - 2022-03-01 diff --git a/src/Redmine/Api/CustomField.php b/src/Redmine/Api/CustomField.php index 523a3726..7c3b7995 100644 --- a/src/Redmine/Api/CustomField.php +++ b/src/Redmine/Api/CustomField.php @@ -22,13 +22,31 @@ class CustomField extends AbstractApi * * @return array list of custom fields found */ - public function all(array $params = []) + public function list(array $params = []): array { $this->customFields = $this->retrieveData('/custom_fields.json', $params); return $this->customFields; } + /** + * List custom fields. + * + * @deprecated sind v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_CustomFields#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of custom fields found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of custom fields with name/id pairs. * @@ -40,7 +58,7 @@ public function all(array $params = []) public function listing($forceUpdate = false, array $params = []) { if (empty($this->customFields) || $forceUpdate) { - $this->all($params); + $this->list($params); } $ret = []; foreach ($this->customFields['custom_fields'] as $e) { diff --git a/tests/Unit/Api/CustomField/ListTest.php b/tests/Unit/Api/CustomField/ListTest.php new file mode 100644 index 00000000..4a2e0274 --- /dev/null +++ b/tests/Unit/Api/CustomField/ListTest.php @@ -0,0 +1,162 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/custom_fields.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $this->assertSame($expectedResponse, $api->list()); + } + + /** + * @covers \Redmine\Api\CustomField::list + * @covers \Redmine\Api\CustomField::get + * @covers \Redmine\Api\CustomField::retrieveAll + * @covers \Redmine\Api\CustomField::isNotNull + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $allParameters = ['not-used']; + $response = '["API Response"]'; + $expectedResponse = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringContains('not-used') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $this->assertSame($expectedResponse, $api->list($allParameters)); + } + + /** + * @covers \Redmine\Api\CustomField::list + * @covers \Redmine\Api\CustomField::get + * @covers \Redmine\Api\CustomField::retrieveAll + * @covers \Redmine\Api\CustomField::isNotNull + */ + public function testListWithHighLimitParametersReturnsResponse() + { + // Test values + $response = '{"limit":"100","items":[]}'; + $allParameters = ['limit' => 250]; + $expectedResponse = [ + 'limit' => ['100', '100', '100'], // TODO: Check response created by array_merge_recursive() + 'items' => [], + ]; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->exactly(3)) + ->method('requestGet') + ->with( + $this->stringStartsWith('/custom_fields.json') + ) + ->willReturn(true); + $client->expects($this->exactly(3)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(3)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $this->assertSame($expectedResponse, $api->list($allParameters)); + } + + /** + * Test list(). + * + * @covers \Redmine\Api\CustomField::list + * @covers \Redmine\Api\CustomField::get + * @covers \Redmine\Api\CustomField::retrieveAll + * @covers \Redmine\Api\CustomField::isNotNull + */ + public function testListCallsEndpointUntilOffsetIsHigherThanTotalCount() + { + // Test values + $response = '{"limit":"100","offset":"10","total_count":"5","items":[]}'; + $allParameters = ['limit' => 250]; + $returnDataSet = [ + 'limit' => '100', + 'offset' => '10', + 'total_count' => '5', + 'items' => [], + ]; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/custom_fields.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $this->assertSame($returnDataSet, $api->list($allParameters)); + } +} diff --git a/tests/Unit/Api/CustomFieldTest.php b/tests/Unit/Api/CustomFieldTest.php index a3481100..29869937 100644 --- a/tests/Unit/Api/CustomFieldTest.php +++ b/tests/Unit/Api/CustomFieldTest.php @@ -50,131 +50,6 @@ public function testAllReturnsClientGetResponse() $this->assertSame($expectedResponse, $api->all()); } - /** - * Test all(). - * - * @covers ::all - * @covers ::get - * @covers ::retrieveAll - * @covers ::isNotNull - * @test - */ - public function testAllReturnsClientGetResponseWithParameters() - { - // Test values - $allParameters = ['not-used']; - $response = '["API Response"]'; - $expectedResponse = ['API Response']; - - // Create the used mock objects - $client = $this->createMock(Client::class); - $client->expects($this->once()) - ->method('requestGet') - ->with( - $this->stringContains('not-used') - ) - ->willReturn(true); - $client->expects($this->exactly(1)) - ->method('getLastResponseBody') - ->willReturn($response); - $client->expects($this->exactly(1)) - ->method('getLastResponseContentType') - ->willReturn('application/json'); - - // Create the object under test - $api = new CustomField($client); - - // Perform the tests - $this->assertSame($expectedResponse, $api->all($allParameters)); - } - - /** - * Test all(). - * - * @covers ::all - * @covers ::get - * @covers ::retrieveAll - * @covers ::isNotNull - * @test - */ - public function testAllReturnsClientGetResponseWithHighLimit() - { - // Test values - $response = '{"limit":"100","items":[]}'; - $allParameters = ['limit' => 250]; - $expectedResponse = [ - 'limit' => ['100', '100', '100'], // TODO: Check response created by array_merge_recursive() - 'items' => [], - ]; - - // Create the used mock objects - $client = $this->createMock(Client::class); - $client->expects($this->exactly(3)) - ->method('requestGet') - ->with( - $this->stringStartsWith('/custom_fields.json') - ) - ->willReturn(true); - $client->expects($this->exactly(3)) - ->method('getLastResponseBody') - ->willReturn($response); - $client->expects($this->exactly(3)) - ->method('getLastResponseContentType') - ->willReturn('application/json'); - - // Create the object under test - $api = new CustomField($client); - - // Perform the tests - $this->assertSame($expectedResponse, $api->all($allParameters)); - } - - /** - * Test all(). - * - * @covers ::all - * @covers ::get - * @covers ::retrieveAll - * @covers ::isNotNull - * @test - */ - public function testAllCallsEndpointUntilOffsetIsHigherThanTotalCount() - { - // Test values - $response = '{"limit":"100","offset":"10","total_count":"5","items":[]}'; - $allParameters = ['limit' => 250]; - $returnDataSet = [ - 'limit' => '100', - 'offset' => '10', - 'total_count' => '5', - 'items' => [], - ]; - - // Create the used mock objects - $client = $this->createMock(Client::class); - $client->expects($this->once()) - ->method('requestGet') - ->with( - $this->stringStartsWith('/custom_fields.json') - ) - ->willReturn(true); - $client->expects($this->exactly(1)) - ->method('getLastResponseBody') - ->willReturn($response); - $client->expects($this->exactly(1)) - ->method('getLastResponseContentType') - ->willReturn('application/json'); - - // Create the object under test - $api = new CustomField($client); - - // Perform the tests - $retrievedDataSet = $api->all($allParameters); - $this->assertTrue(is_array($retrievedDataSet)); - $this->assertArrayHasKey('limit', $retrievedDataSet); - $this->assertArrayHasKey('items', $retrievedDataSet); - } - /** * Test listing(). * From 34ef6e403be0972e0bafbfefee93f62ec5df6122 Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 28 Sep 2023 16:11:30 +0200 Subject: [PATCH 02/27] Add Group::list(), deprecate all() --- CHANGELOG.md | 2 + src/Redmine/Api/Group.php | 20 ++++- tests/Unit/Api/CustomFieldTest.php | 125 +++++++++++++++++++++++++++++ tests/Unit/Api/Group/ListTest.php | 80 ++++++++++++++++++ 4 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Api/Group/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e38a612..98892cde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow `Psr\Http\Message\RequestFactoryInterface` as Argument #2 ($requestFactory) in `Redmine\Client\Psr18Client::__construct()` - New method `Redmine\Api\CustomField::list()` to list custom fields. +- New method `Redmine\Api\Group::list()` to list groups. - Added support for PHP 8.2 ### Deprecated @@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Providing Argument #2 ($requestFactory) in `Redmine\Client\Psr18Client::__construct()` as type `Psr\Http\Message\ServerRequestFactoryInterface` is deprecated, provide as type `Psr\Http\Message\RequestFactoryInterface` instead - `Redmine\Api\AbstractApi::attachCustomFieldXML()` is deprecated - `Redmine\Api\CustomField::all()` is deprecated, use `Redmine\Api\CustomField::list()` instead +- `Redmine\Api\Group::all()` is deprecated, use `Redmine\Api\Group::list()` instead - `Redmine\Api\Project::prepareParamsXml()` is deprecated ## [v2.2.0](https://github.com/kbsali/php-redmine-api/compare/v2.1.1...v2.2.0) - 2022-03-01 diff --git a/src/Redmine/Api/Group.php b/src/Redmine/Api/Group.php index 0cf3439a..79a2e597 100644 --- a/src/Redmine/Api/Group.php +++ b/src/Redmine/Api/Group.php @@ -27,13 +27,31 @@ class Group extends AbstractApi * * @return array list of groups found */ - public function all(array $params = []) + public function list(array $params = []): array { $this->groups = $this->retrieveData('/groups.json', $params); return $this->groups; } + /** + * List groups. + * + * @deprecated sind v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Groups#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of groups found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of groups with name/id pairs. * diff --git a/tests/Unit/Api/CustomFieldTest.php b/tests/Unit/Api/CustomFieldTest.php index 29869937..a3481100 100644 --- a/tests/Unit/Api/CustomFieldTest.php +++ b/tests/Unit/Api/CustomFieldTest.php @@ -50,6 +50,131 @@ public function testAllReturnsClientGetResponse() $this->assertSame($expectedResponse, $api->all()); } + /** + * Test all(). + * + * @covers ::all + * @covers ::get + * @covers ::retrieveAll + * @covers ::isNotNull + * @test + */ + public function testAllReturnsClientGetResponseWithParameters() + { + // Test values + $allParameters = ['not-used']; + $response = '["API Response"]'; + $expectedResponse = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringContains('not-used') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $this->assertSame($expectedResponse, $api->all($allParameters)); + } + + /** + * Test all(). + * + * @covers ::all + * @covers ::get + * @covers ::retrieveAll + * @covers ::isNotNull + * @test + */ + public function testAllReturnsClientGetResponseWithHighLimit() + { + // Test values + $response = '{"limit":"100","items":[]}'; + $allParameters = ['limit' => 250]; + $expectedResponse = [ + 'limit' => ['100', '100', '100'], // TODO: Check response created by array_merge_recursive() + 'items' => [], + ]; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->exactly(3)) + ->method('requestGet') + ->with( + $this->stringStartsWith('/custom_fields.json') + ) + ->willReturn(true); + $client->expects($this->exactly(3)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(3)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $this->assertSame($expectedResponse, $api->all($allParameters)); + } + + /** + * Test all(). + * + * @covers ::all + * @covers ::get + * @covers ::retrieveAll + * @covers ::isNotNull + * @test + */ + public function testAllCallsEndpointUntilOffsetIsHigherThanTotalCount() + { + // Test values + $response = '{"limit":"100","offset":"10","total_count":"5","items":[]}'; + $allParameters = ['limit' => 250]; + $returnDataSet = [ + 'limit' => '100', + 'offset' => '10', + 'total_count' => '5', + 'items' => [], + ]; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/custom_fields.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new CustomField($client); + + // Perform the tests + $retrievedDataSet = $api->all($allParameters); + $this->assertTrue(is_array($retrievedDataSet)); + $this->assertArrayHasKey('limit', $retrievedDataSet); + $this->assertArrayHasKey('items', $retrievedDataSet); + } + /** * Test listing(). * diff --git a/tests/Unit/Api/Group/ListTest.php b/tests/Unit/Api/Group/ListTest.php new file mode 100644 index 00000000..a002aadb --- /dev/null +++ b/tests/Unit/Api/Group/ListTest.php @@ -0,0 +1,80 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/groups.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Group($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\Group::all + */ + public function testListeWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/groups.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Group($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} From 909aec00797b6344aa3dc73d7386d4907f754538 Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 28 Sep 2023 16:29:21 +0200 Subject: [PATCH 03/27] test deprecation warnings --- src/Redmine/Api/Group.php | 2 +- tests/Unit/Api/CustomFieldTest.php | 27 +++++++++++++++++++++++++++ tests/Unit/Api/GroupTest.php | 27 +++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/Redmine/Api/Group.php b/src/Redmine/Api/Group.php index 79a2e597..99577d83 100644 --- a/src/Redmine/Api/Group.php +++ b/src/Redmine/Api/Group.php @@ -62,7 +62,7 @@ public function all(array $params = []) public function listing($forceUpdate = false) { if (empty($this->groups) || $forceUpdate) { - $this->all(); + $this->list(); } $ret = []; foreach ($this->groups['groups'] as $e) { diff --git a/tests/Unit/Api/CustomFieldTest.php b/tests/Unit/Api/CustomFieldTest.php index a3481100..399c390a 100644 --- a/tests/Unit/Api/CustomFieldTest.php +++ b/tests/Unit/Api/CustomFieldTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\CustomField; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\CustomField @@ -13,6 +14,32 @@ */ class CustomFieldTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new CustomField(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\CustomField::all()` is deprecated since v2.4.0, use `Redmine\Api\CustomField::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * diff --git a/tests/Unit/Api/GroupTest.php b/tests/Unit/Api/GroupTest.php index b84011d6..f8773a59 100644 --- a/tests/Unit/Api/GroupTest.php +++ b/tests/Unit/Api/GroupTest.php @@ -6,6 +6,7 @@ use Redmine\Api\Group; use Redmine\Client\Client; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Group @@ -14,6 +15,32 @@ */ class GroupTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Group(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Group::all()` is deprecated since v2.4.0, use `Redmine\Api\Group::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From c72e9a4abf3be0ecde71d2f22fa49d532ec32472 Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 28 Sep 2023 16:52:48 +0200 Subject: [PATCH 04/27] Add Issue::list(), deprecate all() --- src/Redmine/Api/CustomField.php | 2 +- src/Redmine/Api/Group.php | 2 +- src/Redmine/Api/Issue.php | 30 +++++++++++- tests/Unit/Api/Group/ListTest.php | 1 - tests/Unit/Api/Issue/ListTest.php | 79 +++++++++++++++++++++++++++++++ tests/Unit/Api/IssueTest.php | 27 +++++++++++ 6 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 tests/Unit/Api/Issue/ListTest.php diff --git a/src/Redmine/Api/CustomField.php b/src/Redmine/Api/CustomField.php index 7c3b7995..ecc0a446 100644 --- a/src/Redmine/Api/CustomField.php +++ b/src/Redmine/Api/CustomField.php @@ -32,7 +32,7 @@ public function list(array $params = []): array /** * List custom fields. * - * @deprecated sind v2.4.0, use list() instead. + * @deprecated since v2.4.0, use list() instead. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_CustomFields#GET * diff --git a/src/Redmine/Api/Group.php b/src/Redmine/Api/Group.php index 99577d83..8414d829 100644 --- a/src/Redmine/Api/Group.php +++ b/src/Redmine/Api/Group.php @@ -37,7 +37,7 @@ public function list(array $params = []): array /** * List groups. * - * @deprecated sind v2.4.0, use list() instead. + * @deprecated since v2.4.0, use list() instead. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_Groups#GET * diff --git a/src/Redmine/Api/Issue.php b/src/Redmine/Api/Issue.php index 05035d8c..ae3a22ee 100644 --- a/src/Redmine/Api/Issue.php +++ b/src/Redmine/Api/Issue.php @@ -40,11 +40,39 @@ class Issue extends AbstractApi * * @return array list of issues found */ - public function all(array $params = []) + public function list(array $params = []): array { return $this->retrieveData('/issues.json', $params); } + /** + * List issues. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Issues + * available $params : + * - offset: skip this number of issues in response (optional) + * - limit: number of issues per page (optional) + * - sort: column to sort with. Append :desc to invert the order. + * - project_id: get issues from the project with the given id, where id is either project id or project identifier + * - tracker_id: get issues from the tracker with the given id + * - status_id: get issues with the given status id only. Possible values: open, closed, * to get open and closed issues, status id + * - assigned_to_id: get issues which are assigned to the given user id + * - cf_x: get issues with the given value for custom field with an ID of x. (Custom field must have 'used as a filter' checked.) + * - query_id : id of the previously saved query + * + * @param array $params the additional parameters (cf available $params above) + * + * @return array list of issues found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Get extended information about an issue gitven its id. * diff --git a/tests/Unit/Api/Group/ListTest.php b/tests/Unit/Api/Group/ListTest.php index a002aadb..a03f1f5e 100644 --- a/tests/Unit/Api/Group/ListTest.php +++ b/tests/Unit/Api/Group/ListTest.php @@ -5,7 +5,6 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\Group; use Redmine\Client\Client; -use Redmine\Exception\MissingParameterException; /** * Tests for Group::list() diff --git a/tests/Unit/Api/Issue/ListTest.php b/tests/Unit/Api/Issue/ListTest.php new file mode 100644 index 00000000..18508e80 --- /dev/null +++ b/tests/Unit/Api/Issue/ListTest.php @@ -0,0 +1,79 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/issues.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Issue($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\Issue::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/issues.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Issue($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/IssueTest.php b/tests/Unit/Api/IssueTest.php index 362d816e..12bd75db 100644 --- a/tests/Unit/Api/IssueTest.php +++ b/tests/Unit/Api/IssueTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\Issue; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Issue @@ -36,6 +37,32 @@ public function testPriorityConstants($expected, $value) $this->assertSame($expected, $value); } + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Issue(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Issue::all()` is deprecated since v2.4.0, use `Redmine\Api\Issue::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From 046d779f612eda22e2db04911a5b6719666efe14 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 09:57:42 +0200 Subject: [PATCH 05/27] Add IssueCategory::list(), deprecate all() --- CHANGELOG.md | 4 + src/Redmine/Api/IssueCategory.php | 33 ++++++- tests/Unit/Api/IssueCategory/ListTest.php | 111 ++++++++++++++++++++++ tests/Unit/Api/IssueCategoryTest.php | 27 ++++++ 4 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/IssueCategory/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 8df6e842..82563bbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\CustomField::list()` to list custom fields. - New method `Redmine\Api\Group::list()` to list groups. +- New method `Redmine\Api\Issue::list()` to list issues. +- New method `Redmine\Api\IssueCategory::list()` to list issue categories. ### Deprecated - `Redmine\Api\CustomField::all()` is deprecated, use `Redmine\Api\CustomField::list()` instead - `Redmine\Api\Group::all()` is deprecated, use `Redmine\Api\Group::list()` instead +- `Redmine\Api\Issue::all()` is deprecated, use `Redmine\Api\Issue::list()` instead +- `Redmine\Api\IssueCategory::all()` is deprecated, use `Redmine\Api\IssueCategory::list()` instead ### Added diff --git a/src/Redmine/Api/IssueCategory.php b/src/Redmine/Api/IssueCategory.php index cd375c3c..b7fc07c6 100644 --- a/src/Redmine/Api/IssueCategory.php +++ b/src/Redmine/Api/IssueCategory.php @@ -2,6 +2,7 @@ namespace Redmine\Api; +use Redmine\Exception\InvalidParameterException; use Redmine\Exception\MissingParameterException; use Redmine\Serializer\PathSerializer; use Redmine\Serializer\XmlSerializer; @@ -22,6 +23,34 @@ class IssueCategory extends AbstractApi * * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#GET * + * @param string|int $projectIdentifier project id or literal identifier + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @throws InvalidParameterException if $projectIdentifier is not of type int or string + * + * @return array list of issue categories found + */ + public function list($projectIdentifier, array $params = []): array + { + if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { + throw new InvalidParameterException(sprintf( + '%s(): Argument #1 ($projectIdentifier) must be of type int or string', + __METHOD__ + )); + } + + $this->issueCategories = $this->retrieveData('/projects/'.strval($projectIdentifier).'/issue_categories.json', $params); + + return $this->issueCategories; + } + + /** + * List issue categories. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#GET + * * @param string|int $project project id or literal identifier * @param array $params optional parameters to be passed to the api (offset, limit, ...) * @@ -29,9 +58,9 @@ class IssueCategory extends AbstractApi */ public function all($project, array $params = []) { - $this->issueCategories = $this->retrieveData('/projects/'.$project.'/issue_categories.json', $params); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); - return $this->issueCategories; + return $this->list(strval($project), $params); } /** diff --git a/tests/Unit/Api/IssueCategory/ListTest.php b/tests/Unit/Api/IssueCategory/ListTest.php new file mode 100644 index 00000000..fae49397 --- /dev/null +++ b/tests/Unit/Api/IssueCategory/ListTest.php @@ -0,0 +1,111 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/projects/5/issue_categories.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssueCategory($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($projectId)); + } + + /** + * @covers \Redmine\Api\IssueCategory::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $projectId = 'project-slug'; + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/projects/project-slug/issue_categories.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssueCategory($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($projectId, $parameters)); + } + + /** + * @covers \Redmine\Api\IssueCategory::list + * + * @dataProvider getInvalidProjectIdentifiers + */ + public function testListWithWrongProjectIdentifierThrowsException($projectIdentifier) + { + $api = new IssueCategory(MockClient::create()); + + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('Redmine\Api\IssueCategory::list(): Argument #1 ($projectIdentifier) must be of type int or string'); + + $api->list($projectIdentifier); + } + + public static function getInvalidProjectIdentifiers(): array + { + return [ + 'null' => [null], + 'true' => [true], + 'false' => [false], + 'float' => [0.0], + 'array' => [[]], + 'object' => [new stdClass()], + ]; + } +} diff --git a/tests/Unit/Api/IssueCategoryTest.php b/tests/Unit/Api/IssueCategoryTest.php index e1763a31..5780e21c 100644 --- a/tests/Unit/Api/IssueCategoryTest.php +++ b/tests/Unit/Api/IssueCategoryTest.php @@ -6,6 +6,7 @@ use Redmine\Api\IssueCategory; use Redmine\Client\Client; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\IssueCategory @@ -14,6 +15,32 @@ */ class IssueCategoryTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new IssueCategory(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\IssueCategory::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueCategory::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). * From 00bff3dfb6f56760c96b2e8457f67d6436b67ab5 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 11:16:42 +0200 Subject: [PATCH 06/27] Add IssuePriority::list(), deprecate all() --- .phpstan.neon | 2 + src/Redmine/Api/IssueCategory.php | 2 +- src/Redmine/Api/IssuePriority.php | 20 +++++- tests/Unit/Api/IssuePriority/ListTest.php | 76 +++++++++++++++++++++++ tests/Unit/Api/IssuePriorityTest.php | 27 ++++++++ 5 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/IssuePriority/ListTest.php diff --git a/.phpstan.neon b/.phpstan.neon index 97e931b9..ab597c23 100644 --- a/.phpstan.neon +++ b/.phpstan.neon @@ -7,3 +7,5 @@ parameters: scanDirectories: - vendor + + treatPhpDocTypesAsCertain: false diff --git a/src/Redmine/Api/IssueCategory.php b/src/Redmine/Api/IssueCategory.php index b7fc07c6..62543161 100644 --- a/src/Redmine/Api/IssueCategory.php +++ b/src/Redmine/Api/IssueCategory.php @@ -74,7 +74,7 @@ public function all($project, array $params = []) public function listing($project, $forceUpdate = false) { if (true === $forceUpdate || empty($this->issueCategories)) { - $this->all($project); + $this->list($project); } $ret = []; foreach ($this->issueCategories['issue_categories'] as $e) { diff --git a/src/Redmine/Api/IssuePriority.php b/src/Redmine/Api/IssuePriority.php index 6d6b7e46..deba02e7 100644 --- a/src/Redmine/Api/IssuePriority.php +++ b/src/Redmine/Api/IssuePriority.php @@ -22,10 +22,28 @@ class IssuePriority extends AbstractApi * * @return array list of issue priorities found */ - public function all(array $params = []) + public function list(array $params = []): array { $this->issuePriorities = $this->retrieveData('/enumerations/issue_priorities.json', $params); return $this->issuePriorities; } + + /** + * List issue priorities. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Enumerations#enumerationsissue_prioritiesformat + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of issue priorities found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } } diff --git a/tests/Unit/Api/IssuePriority/ListTest.php b/tests/Unit/Api/IssuePriority/ListTest.php new file mode 100644 index 00000000..07212b78 --- /dev/null +++ b/tests/Unit/Api/IssuePriority/ListTest.php @@ -0,0 +1,76 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/enumerations/issue_priorities.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssuePriority($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\IssuePriority::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $allParameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringContains('not-used') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssuePriority($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($allParameters)); + } +} diff --git a/tests/Unit/Api/IssuePriorityTest.php b/tests/Unit/Api/IssuePriorityTest.php index 6f947a77..699e7e21 100644 --- a/tests/Unit/Api/IssuePriorityTest.php +++ b/tests/Unit/Api/IssuePriorityTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\IssuePriority; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\IssuePriority @@ -13,6 +14,32 @@ */ class IssuePriorityTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new IssuePriority(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\IssuePriority::all()` is deprecated since v2.4.0, use `Redmine\Api\IssuePriority::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From 6abb8b9ea84e2783e08fe3442bb89f3463a4af0c Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 12:47:47 +0200 Subject: [PATCH 07/27] Add IssueRelation::list(), deprecate all() --- CHANGELOG.md | 4 + src/Redmine/Api/IssueRelation.php | 23 +++++- .../Psr18ClientRequestGenerationTest.php | 30 +++---- tests/Unit/Api/IssueRelation/ListTest.php | 79 +++++++++++++++++++ tests/Unit/Api/IssueRelationTest.php | 27 +++++++ 5 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 tests/Unit/Api/IssueRelation/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fd4bfa0..7293650e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Group::list()` to list groups. - New method `Redmine\Api\Issue::list()` to list issues. - New method `Redmine\Api\IssueCategory::list()` to list issue categories. +- New method `Redmine\Api\IssuePriority::list()` to list issue priorities. +- New method `Redmine\Api\IssueRelation::list()` to list issue relations. ### Deprecated @@ -22,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Group::all()` is deprecated, use `Redmine\Api\Group::list()` instead - `Redmine\Api\Issue::all()` is deprecated, use `Redmine\Api\Issue::list()` instead - `Redmine\Api\IssueCategory::all()` is deprecated, use `Redmine\Api\IssueCategory::list()` instead +- `Redmine\Api\IssuePriority::all()` is deprecated, use `Redmine\Api\IssuePriority::list()` instead +- `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::list()` instead ### Added diff --git a/src/Redmine/Api/IssueRelation.php b/src/Redmine/Api/IssueRelation.php index 31b319a5..bc16410d 100644 --- a/src/Redmine/Api/IssueRelation.php +++ b/src/Redmine/Api/IssueRelation.php @@ -25,13 +25,32 @@ class IssueRelation extends AbstractApi * * @return array list of relations found */ - public function all($issueId, array $params = []) + public function list(int $issueId, array $params = []): array { - $this->relations = $this->retrieveData('/issues/'.urlencode($issueId).'/relations.json', $params); + $this->relations = $this->retrieveData('/issues/'.strval($issueId).'/relations.json', $params); return $this->relations; } + /** + * List relations of the given $issueId. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations#GET + * + * @param int $issueId the issue id + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of relations found + */ + public function all($issueId, array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($issueId, $params); + } + /** * Get extended information about the given relation $id. * diff --git a/tests/Integration/Psr18ClientRequestGenerationTest.php b/tests/Integration/Psr18ClientRequestGenerationTest.php index 43729042..0d891f89 100644 --- a/tests/Integration/Psr18ClientRequestGenerationTest.php +++ b/tests/Integration/Psr18ClientRequestGenerationTest.php @@ -100,8 +100,7 @@ public function createStreamFromResource($resource): StreamInterface public static function createdGetRequestsData(): array { return [ - [ - // Test username/password in auth header + 'Test username/password in auth header' => [ 'http://test.local', 'username', 'password', null, 'requestGet', '/path', null, 'GET http://test.local/path HTTP/1.1'.\PHP_EOL. @@ -109,8 +108,7 @@ public static function createdGetRequestsData(): array 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ='.\PHP_EOL. \PHP_EOL, ], - [ - // Test access token in X-Redmine-API-Key header + 'Test access token in X-Redmine-API-Key header' => [ 'http://test.local', 'access_token', null, null, 'requestGet', '/path', null, 'GET http://test.local/path HTTP/1.1'.\PHP_EOL. @@ -118,8 +116,7 @@ public static function createdGetRequestsData(): array 'X-Redmine-API-Key: access_token'.\PHP_EOL. \PHP_EOL, ], - [ - // Test user impersonate in X-Redmine-Switch-User header + 'Test user impersonate in X-Redmine-Switch-User header' => [ 'http://test.local', 'access_token', null, 'Robin', 'requestGet', '/path', null, 'GET http://test.local/path HTTP/1.1'.\PHP_EOL. @@ -128,8 +125,7 @@ public static function createdGetRequestsData(): array 'X-Redmine-Switch-User: Robin'.\PHP_EOL. \PHP_EOL, ], - [ - // Test POST + 'Test POST' => [ 'http://test.local', 'access_token', null, null, 'requestPost', '/path.json', '{"foo":"bar"}', 'POST http://test.local/path.json HTTP/1.1'.\PHP_EOL. @@ -139,8 +135,7 @@ public static function createdGetRequestsData(): array \PHP_EOL. '{"foo":"bar"}', ], - [ - // Test fileupload with file content + 'Test fileupload with file content' => [ // @see https://www.redmine.org/projects/redmine/wiki/Rest_api#Attaching-files 'http://test.local', 'access_token', null, null, 'requestPost', '/uploads.json?filename=textfile.md', 'The content of the file', @@ -151,8 +146,7 @@ public static function createdGetRequestsData(): array \PHP_EOL. 'The content of the file', ], - [ - // Test fileupload with file path + 'Test fileupload with file path' => [ // @see https://www.redmine.org/projects/redmine/wiki/Rest_api#Attaching-files 'http://test.local', 'access_token', null, null, 'requestPost', '/uploads.json?filename=textfile.md', realpath(__DIR__.'/../Fixtures/testfile_01.txt'), @@ -164,8 +158,7 @@ public static function createdGetRequestsData(): array 'This is a test file.'."\n". 'It will be needed for testing file uploads.'."\n", ], - [ - // Test fileupload with file path to image + 'Test fileupload with file path to image' => [ // @see https://www.redmine.org/projects/redmine/wiki/Rest_api#Attaching-files 'http://test.local', 'access_token', null, null, 'requestPost', '/uploads.json?filename=1x1.png', realpath(__DIR__.'/../Fixtures/FF4D00-1.png'), @@ -176,8 +169,7 @@ public static function createdGetRequestsData(): array \PHP_EOL. base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=='), ], - [ - // Test PUT + 'Test PUT' => [ 'http://test.local', 'access_token', null, null, 'requestPut', '/path.json', '{"foo":"bar"}', 'PUT http://test.local/path.json HTTP/1.1'.\PHP_EOL. @@ -187,8 +179,7 @@ public static function createdGetRequestsData(): array \PHP_EOL. '{"foo":"bar"}', ], - [ - // Test DELETE + 'Test DELETE' => [ 'http://test.local', 'access_token', null, null, 'requestDelete', '/path.json', '{"foo":"bar"}', 'DELETE http://test.local/path.json HTTP/1.1'.\PHP_EOL. @@ -197,8 +188,7 @@ public static function createdGetRequestsData(): array 'Content-Type: application/json'.\PHP_EOL. \PHP_EOL, ], - [ - // Test body will be ignored on DELETE + 'Test body will be ignored on DELETE' => [ 'http://test.local', 'access_token', null, null, 'requestDelete', '/path.json', '{"foo":"bar"}', 'DELETE http://test.local/path.json HTTP/1.1'.\PHP_EOL. diff --git a/tests/Unit/Api/IssueRelation/ListTest.php b/tests/Unit/Api/IssueRelation/ListTest.php new file mode 100644 index 00000000..d06694ea --- /dev/null +++ b/tests/Unit/Api/IssueRelation/ListTest.php @@ -0,0 +1,79 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/issues/5/relations.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssueRelation($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list(5)); + } + + /** + * @covers \Redmine\Api\IssuePriority::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/issues/5/relations.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssueRelation($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list(5, $parameters)); + } +} diff --git a/tests/Unit/Api/IssueRelationTest.php b/tests/Unit/Api/IssueRelationTest.php index a79e3816..9b975d0b 100644 --- a/tests/Unit/Api/IssueRelationTest.php +++ b/tests/Unit/Api/IssueRelationTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\IssueRelation; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\IssueRelation @@ -13,6 +14,32 @@ */ class IssueRelationTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new IssueRelation(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\IssueRelation::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueRelation::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). * From 4e5cc6705beeada21c61db10081a22c493612d55 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 12:49:12 +0200 Subject: [PATCH 08/27] Set new list() methods as final --- src/Redmine/Api/CustomField.php | 2 +- src/Redmine/Api/Group.php | 2 +- src/Redmine/Api/Issue.php | 2 +- src/Redmine/Api/IssueCategory.php | 2 +- src/Redmine/Api/IssuePriority.php | 2 +- src/Redmine/Api/IssueRelation.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Redmine/Api/CustomField.php b/src/Redmine/Api/CustomField.php index ecc0a446..8aa3d8ed 100644 --- a/src/Redmine/Api/CustomField.php +++ b/src/Redmine/Api/CustomField.php @@ -22,7 +22,7 @@ class CustomField extends AbstractApi * * @return array list of custom fields found */ - public function list(array $params = []): array + final public function list(array $params = []): array { $this->customFields = $this->retrieveData('/custom_fields.json', $params); diff --git a/src/Redmine/Api/Group.php b/src/Redmine/Api/Group.php index 8414d829..a361acae 100644 --- a/src/Redmine/Api/Group.php +++ b/src/Redmine/Api/Group.php @@ -27,7 +27,7 @@ class Group extends AbstractApi * * @return array list of groups found */ - public function list(array $params = []): array + final public function list(array $params = []): array { $this->groups = $this->retrieveData('/groups.json', $params); diff --git a/src/Redmine/Api/Issue.php b/src/Redmine/Api/Issue.php index ae3a22ee..e896885c 100644 --- a/src/Redmine/Api/Issue.php +++ b/src/Redmine/Api/Issue.php @@ -40,7 +40,7 @@ class Issue extends AbstractApi * * @return array list of issues found */ - public function list(array $params = []): array + final public function list(array $params = []): array { return $this->retrieveData('/issues.json', $params); } diff --git a/src/Redmine/Api/IssueCategory.php b/src/Redmine/Api/IssueCategory.php index 62543161..222737ec 100644 --- a/src/Redmine/Api/IssueCategory.php +++ b/src/Redmine/Api/IssueCategory.php @@ -30,7 +30,7 @@ class IssueCategory extends AbstractApi * * @return array list of issue categories found */ - public function list($projectIdentifier, array $params = []): array + final public function list($projectIdentifier, array $params = []): array { if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { throw new InvalidParameterException(sprintf( diff --git a/src/Redmine/Api/IssuePriority.php b/src/Redmine/Api/IssuePriority.php index deba02e7..70b07157 100644 --- a/src/Redmine/Api/IssuePriority.php +++ b/src/Redmine/Api/IssuePriority.php @@ -22,7 +22,7 @@ class IssuePriority extends AbstractApi * * @return array list of issue priorities found */ - public function list(array $params = []): array + final public function list(array $params = []): array { $this->issuePriorities = $this->retrieveData('/enumerations/issue_priorities.json', $params); diff --git a/src/Redmine/Api/IssueRelation.php b/src/Redmine/Api/IssueRelation.php index bc16410d..f398850a 100644 --- a/src/Redmine/Api/IssueRelation.php +++ b/src/Redmine/Api/IssueRelation.php @@ -25,7 +25,7 @@ class IssueRelation extends AbstractApi * * @return array list of relations found */ - public function list(int $issueId, array $params = []): array + final public function list(int $issueId, array $params = []): array { $this->relations = $this->retrieveData('/issues/'.strval($issueId).'/relations.json', $params); From bf61171f985f8546b68e8518de04f71921dec66c Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 13:10:05 +0200 Subject: [PATCH 09/27] Add IssueStatus::list() method, deprecate all() method --- CHANGELOG.md | 6 +- src/Redmine/Api/IssueStatus.php | 22 ++++++- tests/Unit/Api/IssueStatus/ListTest.php | 79 +++++++++++++++++++++++++ tests/Unit/Api/IssueStatusTest.php | 27 +++++++++ 4 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 tests/Unit/Api/IssueStatus/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 7293650e..868333c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/kbsali/php-redmine-api/compare/v2.3.0...v2.x) -## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 - ### Added - New method `Redmine\Api\CustomField::list()` to list custom fields. @@ -17,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\IssueCategory::list()` to list issue categories. - New method `Redmine\Api\IssuePriority::list()` to list issue priorities. - New method `Redmine\Api\IssueRelation::list()` to list issue relations. +- New method `Redmine\Api\IssueStatus::list()` to list issue statuses. ### Deprecated @@ -26,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\IssueCategory::all()` is deprecated, use `Redmine\Api\IssueCategory::list()` instead - `Redmine\Api\IssuePriority::all()` is deprecated, use `Redmine\Api\IssuePriority::list()` instead - `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::list()` instead +- `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead + +## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 ### Added diff --git a/src/Redmine/Api/IssueStatus.php b/src/Redmine/Api/IssueStatus.php index 6c6f776a..bcb68eea 100644 --- a/src/Redmine/Api/IssueStatus.php +++ b/src/Redmine/Api/IssueStatus.php @@ -22,13 +22,31 @@ class IssueStatus extends AbstractApi * * @return array list of issue statuses found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->issueStatuses = $this->retrieveData('/issue_statuses.json', $params); return $this->issueStatuses; } + /** + * List issue statuses. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueStatuses#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of issue statuses found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of issue statuses with name/id pairs. * @@ -39,7 +57,7 @@ public function all(array $params = []) public function listing($forceUpdate = false) { if (empty($this->issueStatuses) || $forceUpdate) { - $this->all(); + $this->list(); } $ret = []; foreach ($this->issueStatuses['issue_statuses'] as $e) { diff --git a/tests/Unit/Api/IssueStatus/ListTest.php b/tests/Unit/Api/IssueStatus/ListTest.php new file mode 100644 index 00000000..1dc874da --- /dev/null +++ b/tests/Unit/Api/IssueStatus/ListTest.php @@ -0,0 +1,79 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/issue_statuses.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssueStatus($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\IssueStatus::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/issue_statuses.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new IssueStatus($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/IssueStatusTest.php b/tests/Unit/Api/IssueStatusTest.php index ac812ac0..4e795b1e 100644 --- a/tests/Unit/Api/IssueStatusTest.php +++ b/tests/Unit/Api/IssueStatusTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\IssueStatus; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\IssueStatus @@ -13,6 +14,32 @@ */ class IssueStatusTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new IssueStatus(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\IssueStatus::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueStatus::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From 011064020d83c41071f7c9b19ab99be2dd325082 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 13:42:12 +0200 Subject: [PATCH 10/27] Add Membership::list() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/Membership.php | 35 +++++++- tests/Unit/Api/Membership/ListTest.php | 109 +++++++++++++++++++++++++ tests/Unit/Api/MembershipTest.php | 27 ++++++ 4 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 tests/Unit/Api/Membership/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 868333c9..626ac67b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\IssuePriority::list()` to list issue priorities. - New method `Redmine\Api\IssueRelation::list()` to list issue relations. - New method `Redmine\Api\IssueStatus::list()` to list issue statuses. +- New method `Redmine\Api\Membership::list()` to list memberships. ### Deprecated @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\IssuePriority::all()` is deprecated, use `Redmine\Api\IssuePriority::list()` instead - `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::list()` instead - `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead +- `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Membership.php b/src/Redmine/Api/Membership.php index 4715f57f..4b234604 100644 --- a/src/Redmine/Api/Membership.php +++ b/src/Redmine/Api/Membership.php @@ -2,6 +2,7 @@ namespace Redmine\Api; +use Redmine\Exception\InvalidParameterException; use Redmine\Exception\MissingParameterException; use Redmine\Serializer\XmlSerializer; @@ -21,6 +22,34 @@ class Membership extends AbstractApi * * @see http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET * + * @param string|int $projectIdentifier project id or literal identifier + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @throws InvalidParameterException if $projectIdentifier is not of type int or string + * + * @return array list of memberships found + */ + final public function list($projectIdentifier, array $params = []) + { + if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { + throw new InvalidParameterException(sprintf( + '%s(): Argument #1 ($projectIdentifier) must be of type int or string', + __METHOD__ + )); + } + + $this->memberships = $this->retrieveData('/projects/'.strval($projectIdentifier).'/memberships.json', $params); + + return $this->memberships; + } + + /** + * List memberships for a given $project. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET + * * @param string|int $project project id or literal identifier * @param array $params optional parameters to be passed to the api (offset, limit, ...) * @@ -28,9 +57,9 @@ class Membership extends AbstractApi */ public function all($project, array $params = []) { - $this->memberships = $this->retrieveData('/projects/'.$project.'/memberships.json', $params); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); - return $this->memberships; + return $this->list(strval($project), $params); } /** @@ -119,7 +148,7 @@ public function remove($id) */ public function removeMember($projectId, $userId, array $params = []) { - $memberships = $this->all($projectId, $params); + $memberships = $this->list($projectId, $params); if (!isset($memberships['memberships']) || !is_array($memberships['memberships'])) { return false; } diff --git a/tests/Unit/Api/Membership/ListTest.php b/tests/Unit/Api/Membership/ListTest.php new file mode 100644 index 00000000..d405dd60 --- /dev/null +++ b/tests/Unit/Api/Membership/ListTest.php @@ -0,0 +1,109 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/projects/5/memberships.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Membership($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list(5)); + } + + /** + * @covers \Redmine\Api\Membership::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/projects/project-slug/memberships.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Membership($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list('project-slug', $parameters)); + } + + /** + * @covers \Redmine\Api\Membership::list + * + * @dataProvider getInvalidProjectIdentifiers + */ + public function testListWithWrongProjectIdentifierThrowsException($projectIdentifier) + { + $api = new Membership(MockClient::create()); + + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('Redmine\Api\Membership::list(): Argument #1 ($projectIdentifier) must be of type int or string'); + + $api->list($projectIdentifier); + } + + public static function getInvalidProjectIdentifiers(): array + { + return [ + 'null' => [null], + 'true' => [true], + 'false' => [false], + 'float' => [0.0], + 'array' => [[]], + 'object' => [new stdClass()], + ]; + } +} diff --git a/tests/Unit/Api/MembershipTest.php b/tests/Unit/Api/MembershipTest.php index 2ac800c1..7b5e6651 100644 --- a/tests/Unit/Api/MembershipTest.php +++ b/tests/Unit/Api/MembershipTest.php @@ -7,6 +7,7 @@ use Redmine\Api\Membership; use Redmine\Client\Client; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Membership @@ -15,6 +16,32 @@ */ class MembershipTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Membership(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Membership::all()` is deprecated since v2.4.0, use `Redmine\Api\Membership::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). * From 8358b48470f2a5e4a44dbbc8b0f1e57a9eab82c2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 14:38:30 +0200 Subject: [PATCH 11/27] rename list() methods if parameter is required --- CHANGELOG.md | 12 ++++++------ src/Redmine/Api/IssueCategory.php | 12 ++++++------ src/Redmine/Api/IssueRelation.php | 10 +++++----- src/Redmine/Api/Membership.php | 12 ++++++------ 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 626ac67b..e38189ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,22 +12,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\CustomField::list()` to list custom fields. - New method `Redmine\Api\Group::list()` to list groups. - New method `Redmine\Api\Issue::list()` to list issues. -- New method `Redmine\Api\IssueCategory::list()` to list issue categories. +- New method `Redmine\Api\IssueCategory::listByProject()` to list issue categories from a project. - New method `Redmine\Api\IssuePriority::list()` to list issue priorities. -- New method `Redmine\Api\IssueRelation::list()` to list issue relations. +- New method `Redmine\Api\IssueRelation::listByIssueId()` to list relations from an issue. - New method `Redmine\Api\IssueStatus::list()` to list issue statuses. -- New method `Redmine\Api\Membership::list()` to list memberships. +- New method `Redmine\Api\Membership::listByProject()` to list memberships from a project. ### Deprecated - `Redmine\Api\CustomField::all()` is deprecated, use `Redmine\Api\CustomField::list()` instead - `Redmine\Api\Group::all()` is deprecated, use `Redmine\Api\Group::list()` instead - `Redmine\Api\Issue::all()` is deprecated, use `Redmine\Api\Issue::list()` instead -- `Redmine\Api\IssueCategory::all()` is deprecated, use `Redmine\Api\IssueCategory::list()` instead +- `Redmine\Api\IssueCategory::all()` is deprecated, use `Redmine\Api\IssueCategory::listByProject()` instead - `Redmine\Api\IssuePriority::all()` is deprecated, use `Redmine\Api\IssuePriority::list()` instead -- `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::list()` instead +- `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::listByIssueId()` instead - `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead -- `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::list()` instead +- `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::listByProject()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/IssueCategory.php b/src/Redmine/Api/IssueCategory.php index 222737ec..46ef4afc 100644 --- a/src/Redmine/Api/IssueCategory.php +++ b/src/Redmine/Api/IssueCategory.php @@ -19,7 +19,7 @@ class IssueCategory extends AbstractApi private $issueCategories = []; /** - * List issue categories. + * List issue categories for a given project. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#GET * @@ -30,7 +30,7 @@ class IssueCategory extends AbstractApi * * @return array list of issue categories found */ - final public function list($projectIdentifier, array $params = []): array + final public function listByProject($projectIdentifier, array $params = []): array { if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { throw new InvalidParameterException(sprintf( @@ -47,7 +47,7 @@ final public function list($projectIdentifier, array $params = []): array /** * List issue categories. * - * @deprecated since v2.4.0, use list() instead. + * @deprecated since v2.4.0, use listByProject() instead. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#GET * @@ -58,9 +58,9 @@ final public function list($projectIdentifier, array $params = []): array */ public function all($project, array $params = []) { - @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::listByProject()` instead.', E_USER_DEPRECATED); - return $this->list(strval($project), $params); + return $this->listByProject(strval($project), $params); } /** @@ -74,7 +74,7 @@ public function all($project, array $params = []) public function listing($project, $forceUpdate = false) { if (true === $forceUpdate || empty($this->issueCategories)) { - $this->list($project); + $this->listByProject($project); } $ret = []; foreach ($this->issueCategories['issue_categories'] as $e) { diff --git a/src/Redmine/Api/IssueRelation.php b/src/Redmine/Api/IssueRelation.php index f398850a..158c5c08 100644 --- a/src/Redmine/Api/IssueRelation.php +++ b/src/Redmine/Api/IssueRelation.php @@ -25,7 +25,7 @@ class IssueRelation extends AbstractApi * * @return array list of relations found */ - final public function list(int $issueId, array $params = []): array + final public function listByIssueId(int $issueId, array $params = []): array { $this->relations = $this->retrieveData('/issues/'.strval($issueId).'/relations.json', $params); @@ -33,9 +33,9 @@ final public function list(int $issueId, array $params = []): array } /** - * List relations of the given $issueId. + * List relations of the given issue. * - * @deprecated since v2.4.0, use list() instead. + * @deprecated since v2.4.0, use listByIssueId() instead. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations#GET * @@ -46,9 +46,9 @@ final public function list(int $issueId, array $params = []): array */ public function all($issueId, array $params = []) { - @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::listByIssueId()` instead.', E_USER_DEPRECATED); - return $this->list($issueId, $params); + return $this->listByIssueId($issueId, $params); } /** diff --git a/src/Redmine/Api/Membership.php b/src/Redmine/Api/Membership.php index 4b234604..c46f77bf 100644 --- a/src/Redmine/Api/Membership.php +++ b/src/Redmine/Api/Membership.php @@ -18,7 +18,7 @@ class Membership extends AbstractApi private $memberships = []; /** - * List memberships for a given $project. + * List memberships for a given project. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET * @@ -29,7 +29,7 @@ class Membership extends AbstractApi * * @return array list of memberships found */ - final public function list($projectIdentifier, array $params = []) + final public function listByProject($projectIdentifier, array $params = []): array { if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { throw new InvalidParameterException(sprintf( @@ -46,7 +46,7 @@ final public function list($projectIdentifier, array $params = []) /** * List memberships for a given $project. * - * @deprecated since v2.4.0, use list() instead. + * @deprecated since v2.4.0, use listByProject() instead. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET * @@ -57,9 +57,9 @@ final public function list($projectIdentifier, array $params = []) */ public function all($project, array $params = []) { - @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::listByProject()` instead.', E_USER_DEPRECATED); - return $this->list(strval($project), $params); + return $this->listByProject(strval($project), $params); } /** @@ -148,7 +148,7 @@ public function remove($id) */ public function removeMember($projectId, $userId, array $params = []) { - $memberships = $this->list($projectId, $params); + $memberships = $this->listByProject($projectId, $params); if (!isset($memberships['memberships']) || !is_array($memberships['memberships'])) { return false; } From a31c99de32d0a1840ccd071602ccc4a957302543 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 14:55:34 +0200 Subject: [PATCH 12/27] fix tests --- .../{ListTest.php => ListByProjectTest.php} | 24 +++++++++---------- tests/Unit/Api/IssueCategoryTest.php | 2 +- .../{ListTest.php => ListByIssueIdTest.php} | 16 ++++++------- tests/Unit/Api/IssueRelationTest.php | 2 +- .../{ListTest.php => ListByProjectTest.php} | 24 +++++++++---------- tests/Unit/Api/MembershipTest.php | 2 +- 6 files changed, 35 insertions(+), 35 deletions(-) rename tests/Unit/Api/IssueCategory/{ListTest.php => ListByProjectTest.php} (77%) rename tests/Unit/Api/IssueRelation/{ListTest.php => ListByIssueIdTest.php} (79%) rename tests/Unit/Api/Membership/{ListTest.php => ListByProjectTest.php} (77%) diff --git a/tests/Unit/Api/IssueCategory/ListTest.php b/tests/Unit/Api/IssueCategory/ListByProjectTest.php similarity index 77% rename from tests/Unit/Api/IssueCategory/ListTest.php rename to tests/Unit/Api/IssueCategory/ListByProjectTest.php index fae49397..d91d962a 100644 --- a/tests/Unit/Api/IssueCategory/ListTest.php +++ b/tests/Unit/Api/IssueCategory/ListByProjectTest.php @@ -10,14 +10,14 @@ use stdClass; /** - * Tests for IssueCategory::list() + * Tests for IssueCategory::listByProject() */ -class ListTest extends TestCase +class ListByProjectTest extends TestCase { /** - * @covers \Redmine\Api\IssueCategory::list + * @covers \Redmine\Api\IssueCategory::listByProject */ - public function testListWithoutParametersReturnsResponse() + public function testListByProjectWithoutParametersReturnsResponse() { // Test values $projectId = 5; @@ -43,13 +43,13 @@ public function testListWithoutParametersReturnsResponse() $api = new IssueCategory($client); // Perform the tests - $this->assertSame($expectedReturn, $api->list($projectId)); + $this->assertSame($expectedReturn, $api->listByProject($projectId)); } /** - * @covers \Redmine\Api\IssueCategory::list + * @covers \Redmine\Api\IssueCategory::listByProject */ - public function testListWithParametersReturnsResponse() + public function testListByProjectWithParametersReturnsResponse() { // Test values $projectId = 'project-slug'; @@ -79,22 +79,22 @@ public function testListWithParametersReturnsResponse() $api = new IssueCategory($client); // Perform the tests - $this->assertSame($expectedReturn, $api->list($projectId, $parameters)); + $this->assertSame($expectedReturn, $api->listByProject($projectId, $parameters)); } /** - * @covers \Redmine\Api\IssueCategory::list + * @covers \Redmine\Api\IssueCategory::listByProject * * @dataProvider getInvalidProjectIdentifiers */ - public function testListWithWrongProjectIdentifierThrowsException($projectIdentifier) + public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) { $api = new IssueCategory(MockClient::create()); $this->expectException(InvalidParameterException::class); - $this->expectExceptionMessage('Redmine\Api\IssueCategory::list(): Argument #1 ($projectIdentifier) must be of type int or string'); + $this->expectExceptionMessage('Redmine\Api\IssueCategory::listByProject(): Argument #1 ($projectIdentifier) must be of type int or string'); - $api->list($projectIdentifier); + $api->listByProject($projectIdentifier); } public static function getInvalidProjectIdentifiers(): array diff --git a/tests/Unit/Api/IssueCategoryTest.php b/tests/Unit/Api/IssueCategoryTest.php index 5780e21c..affdd957 100644 --- a/tests/Unit/Api/IssueCategoryTest.php +++ b/tests/Unit/Api/IssueCategoryTest.php @@ -28,7 +28,7 @@ public function testAllTriggersDeprecationWarning() set_error_handler( function ($errno, $errstr): bool { $this->assertSame( - '`Redmine\Api\IssueCategory::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueCategory::list()` instead.', + '`Redmine\Api\IssueCategory::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueCategory::listByProject()` instead.', $errstr ); diff --git a/tests/Unit/Api/IssueRelation/ListTest.php b/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php similarity index 79% rename from tests/Unit/Api/IssueRelation/ListTest.php rename to tests/Unit/Api/IssueRelation/ListByIssueIdTest.php index d06694ea..9ba3ce19 100644 --- a/tests/Unit/Api/IssueRelation/ListTest.php +++ b/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php @@ -7,14 +7,14 @@ use Redmine\Client\Client; /** - * Tests for IssueRelation::list() + * Tests for IssueRelation::listByIssueId() */ -class ListTest extends TestCase +class ListByIssueIdTest extends TestCase { /** - * @covers \Redmine\Api\IssueRelation::list + * @covers \Redmine\Api\IssueRelation::listByIssueId */ - public function testListWithoutParametersReturnsResponse() + public function testListByIssueIdWithoutParametersReturnsResponse() { // Test values $response = '["API Response"]'; @@ -39,13 +39,13 @@ public function testListWithoutParametersReturnsResponse() $api = new IssueRelation($client); // Perform the tests - $this->assertSame($expectedReturn, $api->list(5)); + $this->assertSame($expectedReturn, $api->listByIssueId(5)); } /** - * @covers \Redmine\Api\IssuePriority::list + * @covers \Redmine\Api\IssueRelation::listByIssueId */ - public function testListWithParametersReturnsResponse() + public function testListByIssueIdWithParametersReturnsResponse() { // Test values $parameters = ['not-used']; @@ -74,6 +74,6 @@ public function testListWithParametersReturnsResponse() $api = new IssueRelation($client); // Perform the tests - $this->assertSame($expectedReturn, $api->list(5, $parameters)); + $this->assertSame($expectedReturn, $api->listByIssueId(5, $parameters)); } } diff --git a/tests/Unit/Api/IssueRelationTest.php b/tests/Unit/Api/IssueRelationTest.php index 9b975d0b..f2236b79 100644 --- a/tests/Unit/Api/IssueRelationTest.php +++ b/tests/Unit/Api/IssueRelationTest.php @@ -27,7 +27,7 @@ public function testAllTriggersDeprecationWarning() set_error_handler( function ($errno, $errstr): bool { $this->assertSame( - '`Redmine\Api\IssueRelation::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueRelation::list()` instead.', + '`Redmine\Api\IssueRelation::all()` is deprecated since v2.4.0, use `Redmine\Api\IssueRelation::listByIssueId()` instead.', $errstr ); diff --git a/tests/Unit/Api/Membership/ListTest.php b/tests/Unit/Api/Membership/ListByProjectTest.php similarity index 77% rename from tests/Unit/Api/Membership/ListTest.php rename to tests/Unit/Api/Membership/ListByProjectTest.php index d405dd60..1d0df356 100644 --- a/tests/Unit/Api/Membership/ListTest.php +++ b/tests/Unit/Api/Membership/ListByProjectTest.php @@ -10,14 +10,14 @@ use stdClass; /** - * Tests for Membership::list() + * Tests for Membership::listByProject() */ -class ListTest extends TestCase +class ListByProjectTest extends TestCase { /** - * @covers \Redmine\Api\Membership::list + * @covers \Redmine\Api\Membership::listByProject */ - public function testListWithoutParametersReturnsResponse() + public function testListByProjectWithoutParametersReturnsResponse() { // Test values $response = '["API Response"]'; @@ -42,13 +42,13 @@ public function testListWithoutParametersReturnsResponse() $api = new Membership($client); // Perform the tests - $this->assertSame($expectedReturn, $api->list(5)); + $this->assertSame($expectedReturn, $api->listByProject(5)); } /** - * @covers \Redmine\Api\Membership::list + * @covers \Redmine\Api\Membership::listByProject */ - public function testListWithParametersReturnsResponse() + public function testListByProjectWithParametersReturnsResponse() { // Test values $parameters = ['not-used']; @@ -77,22 +77,22 @@ public function testListWithParametersReturnsResponse() $api = new Membership($client); // Perform the tests - $this->assertSame($expectedReturn, $api->list('project-slug', $parameters)); + $this->assertSame($expectedReturn, $api->listByProject('project-slug', $parameters)); } /** - * @covers \Redmine\Api\Membership::list + * @covers \Redmine\Api\Membership::listByProject * * @dataProvider getInvalidProjectIdentifiers */ - public function testListWithWrongProjectIdentifierThrowsException($projectIdentifier) + public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) { $api = new Membership(MockClient::create()); $this->expectException(InvalidParameterException::class); - $this->expectExceptionMessage('Redmine\Api\Membership::list(): Argument #1 ($projectIdentifier) must be of type int or string'); + $this->expectExceptionMessage('Redmine\Api\Membership::listByProject(): Argument #1 ($projectIdentifier) must be of type int or string'); - $api->list($projectIdentifier); + $api->listByProject($projectIdentifier); } public static function getInvalidProjectIdentifiers(): array diff --git a/tests/Unit/Api/MembershipTest.php b/tests/Unit/Api/MembershipTest.php index 7b5e6651..a27035a2 100644 --- a/tests/Unit/Api/MembershipTest.php +++ b/tests/Unit/Api/MembershipTest.php @@ -29,7 +29,7 @@ public function testAllTriggersDeprecationWarning() set_error_handler( function ($errno, $errstr): bool { $this->assertSame( - '`Redmine\Api\Membership::all()` is deprecated since v2.4.0, use `Redmine\Api\Membership::list()` instead.', + '`Redmine\Api\Membership::all()` is deprecated since v2.4.0, use `Redmine\Api\Membership::listByProject()` instead.', $errstr ); From 3155355fd13fdcfb3508b937a8fbff317d1c5c1d Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 15:37:15 +0200 Subject: [PATCH 13/27] Add News::list() and listByProject() methdos, deprecate all() method --- CHANGELOG.md | 3 + src/Redmine/Api/News.php | 53 ++++++++++++++- tests/Unit/Api/News/ListByProjectTest.php | 78 ++++++++++++++++++++++ tests/Unit/Api/News/ListTest.php | 79 +++++++++++++++++++++++ tests/Unit/Api/NewsTest.php | 27 ++++++++ 5 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 tests/Unit/Api/News/ListByProjectTest.php create mode 100644 tests/Unit/Api/News/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index e38189ba..c37d5499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\IssueRelation::listByIssueId()` to list relations from an issue. - New method `Redmine\Api\IssueStatus::list()` to list issue statuses. - New method `Redmine\Api\Membership::listByProject()` to list memberships from a project. +- New method `Redmine\Api\News::list()` to list news from all project. +- New method `Redmine\Api\News::listByProject()` to list news from a project. ### Deprecated @@ -28,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::listByIssueId()` instead - `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead - `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::listByProject()` instead +- `Redmine\Api\News::all()` is deprecated, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/News.php b/src/Redmine/Api/News.php index 451ffc18..03c816f5 100644 --- a/src/Redmine/Api/News.php +++ b/src/Redmine/Api/News.php @@ -2,6 +2,8 @@ namespace Redmine\Api; +use Redmine\Exception\InvalidParameterException; + /** * @see http://www.redmine.org/projects/redmine/wiki/Rest_News * @@ -11,9 +13,51 @@ class News extends AbstractApi { private $news = []; + /** + * List news for a given project. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_News#GET + * + * @param string|int $projectIdentifier project id or literal identifier + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of news found + */ + final public function listByProject($projectIdentifier, array $params = []): array + { + if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { + throw new InvalidParameterException(sprintf( + '%s(): Argument #1 ($projectIdentifier) must be of type int or string', + __METHOD__ + )); + } + + $this->news = $this->retrieveData('/projects/'.strval($projectIdentifier).'/news.json', $params); + + return $this->news; + } + + /** + * List news for all projects. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_News#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of news found + */ + final public function list(array $params = []): array + { + $this->news = $this->retrieveData('/news.json', $params); + + return $this->news; + } + /** * List news (if no $project is given, it will return ALL the news). * + * @deprecated since v2.4.0, use list() or listByProject() instead. + * * @see http://www.redmine.org/projects/redmine/wiki/Rest_News#GET * * @param string|int $project project id or literal identifier [optional] @@ -23,9 +67,12 @@ class News extends AbstractApi */ public function all($project = null, array $params = []) { - $path = null === $project ? '/news.json' : '/projects/'.$project.'/news.json'; - $this->news = $this->retrieveData($path, $params); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` or `'.__CLASS__.'::listByProject()` instead.', E_USER_DEPRECATED); - return $this->news; + if (null === $project) { + return $this->list($params); + } else { + return $this->listByProject(strval($project), $params); + } } } diff --git a/tests/Unit/Api/News/ListByProjectTest.php b/tests/Unit/Api/News/ListByProjectTest.php new file mode 100644 index 00000000..d2fac23c --- /dev/null +++ b/tests/Unit/Api/News/ListByProjectTest.php @@ -0,0 +1,78 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/projects/5/news.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject($projectId)); + } + + /** + * @covers \Redmine\Api\News::listByProject + */ + public function testListByProjectWithParametersReturnsResponse() + { + // Test values + $projectId = 5; + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringContains('not-used') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject($projectId, $parameters)); + } +} diff --git a/tests/Unit/Api/News/ListTest.php b/tests/Unit/Api/News/ListTest.php new file mode 100644 index 00000000..deea8e63 --- /dev/null +++ b/tests/Unit/Api/News/ListTest.php @@ -0,0 +1,79 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/news.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\News::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/news.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/NewsTest.php b/tests/Unit/Api/NewsTest.php index b60cdcef..fd868599 100644 --- a/tests/Unit/Api/NewsTest.php +++ b/tests/Unit/Api/NewsTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\News; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\News @@ -13,6 +14,32 @@ */ class NewsTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new News(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\News::all()` is deprecated since v2.4.0, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). * From 0ef7eb509b7bff891448a6d96a423206bc3e7599 Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 15:44:59 +0200 Subject: [PATCH 14/27] Add tests for exceptions --- tests/Unit/Api/News/ListByProjectTest.php | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/Unit/Api/News/ListByProjectTest.php b/tests/Unit/Api/News/ListByProjectTest.php index d2fac23c..5bed6415 100644 --- a/tests/Unit/Api/News/ListByProjectTest.php +++ b/tests/Unit/Api/News/ListByProjectTest.php @@ -5,6 +5,8 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\News; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; +use stdClass; /** * Tests for News::listByProject() @@ -75,4 +77,31 @@ public function testListByProjectWithParametersReturnsResponse() // Perform the tests $this->assertSame($expectedReturn, $api->listByProject($projectId, $parameters)); } + + /** + * @covers \Redmine\Api\News::listByProject + * + * @dataProvider getInvalidProjectIdentifiers + */ + public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) + { + $api = new News(MockClient::create()); + + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('Redmine\Api\News::listByProject(): Argument #1 ($projectIdentifier) must be of type int or string'); + + $api->listByProject($projectIdentifier); + } + + public static function getInvalidProjectIdentifiers(): array + { + return [ + 'null' => [null], + 'true' => [true], + 'false' => [false], + 'float' => [0.0], + 'array' => [[]], + 'object' => [new stdClass()], + ]; + } } From 6b36dd3ca46e7fa86e6a98d7179af32f7983b3d8 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 09:13:06 +0200 Subject: [PATCH 15/27] Add Project::list() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/Project.php | 22 ++++++- tests/Unit/Api/News/ListByProjectTest.php | 1 + tests/Unit/Api/Project/ListTest.php | 77 +++++++++++++++++++++++ tests/Unit/Api/ProjectTest.php | 27 ++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/Project/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c37d5499..4041e9b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Membership::listByProject()` to list memberships from a project. - New method `Redmine\Api\News::list()` to list news from all project. - New method `Redmine\Api\News::listByProject()` to list news from a project. +- New method `Redmine\Api\Project::list()` to list projects. ### Deprecated @@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead - `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::listByProject()` instead - `Redmine\Api\News::all()` is deprecated, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead +- `Redmine\Api\Project::all()` is deprecated, use `Redmine\Api\Project::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Project.php b/src/Redmine/Api/Project.php index e01000df..4e4b5655 100755 --- a/src/Redmine/Api/Project.php +++ b/src/Redmine/Api/Project.php @@ -26,13 +26,31 @@ class Project extends AbstractApi * * @return array list of projects found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->projects = $this->retrieveData('/projects.json', $params); return $this->projects; } + /** + * List projects. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Projects + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of projects found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of projects with name/id pairs (or id/name if $reserse is false). * @@ -45,7 +63,7 @@ public function all(array $params = []) public function listing($forceUpdate = false, $reverse = true, array $params = []) { if (true === $forceUpdate || empty($this->projects)) { - $this->all($params); + $this->list($params); } $ret = []; foreach ($this->projects['projects'] as $e) { diff --git a/tests/Unit/Api/News/ListByProjectTest.php b/tests/Unit/Api/News/ListByProjectTest.php index 5bed6415..6bcf167d 100644 --- a/tests/Unit/Api/News/ListByProjectTest.php +++ b/tests/Unit/Api/News/ListByProjectTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\News; use Redmine\Client\Client; +use Redmine\Exception\InvalidParameterException; use Redmine\Tests\Fixtures\MockClient; use stdClass; diff --git a/tests/Unit/Api/Project/ListTest.php b/tests/Unit/Api/Project/ListTest.php new file mode 100644 index 00000000..43f7cb30 --- /dev/null +++ b/tests/Unit/Api/Project/ListTest.php @@ -0,0 +1,77 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/projects.json') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Project($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\News::list + */ + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/projects.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Project($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/ProjectTest.php b/tests/Unit/Api/ProjectTest.php index 0180c80d..f780fc37 100644 --- a/tests/Unit/Api/ProjectTest.php +++ b/tests/Unit/Api/ProjectTest.php @@ -6,6 +6,7 @@ use Redmine\Api\Project; use Redmine\Client\Client; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; use ReflectionMethod; use SimpleXMLElement; @@ -16,6 +17,32 @@ */ class ProjectTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Project(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Project::all()` is deprecated since v2.4.0, use `Redmine\Api\Project::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From 34db28dfd76798167f2119331e72112f8be14302 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 09:23:18 +0200 Subject: [PATCH 16/27] simplify covers tags --- tests/Unit/Api/CustomField/ListTest.php | 28 +------------------ tests/Unit/Api/Group/ListTest.php | 8 +----- tests/Unit/Api/Issue/ListTest.php | 8 +----- .../Api/IssueCategory/ListByProjectTest.php | 10 +------ tests/Unit/Api/IssuePriority/ListTest.php | 8 +----- .../Api/IssueRelation/ListByIssueIdTest.php | 8 +----- tests/Unit/Api/IssueStatus/ListTest.php | 8 +----- .../Unit/Api/Membership/ListByProjectTest.php | 10 +------ tests/Unit/Api/News/ListByProjectTest.php | 10 +------ tests/Unit/Api/News/ListTest.php | 8 +----- tests/Unit/Api/Project/ListTest.php | 8 +----- 11 files changed, 11 insertions(+), 103 deletions(-) diff --git a/tests/Unit/Api/CustomField/ListTest.php b/tests/Unit/Api/CustomField/ListTest.php index 4a2e0274..e36108dd 100644 --- a/tests/Unit/Api/CustomField/ListTest.php +++ b/tests/Unit/Api/CustomField/ListTest.php @@ -7,16 +7,10 @@ use Redmine\Client\Client; /** - * Tests for CustomField::list() + * @covers \Redmine\Api\CustomField::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\CustomField::list - * @covers \Redmine\Api\CustomField::get - * @covers \Redmine\Api\CustomField::retrieveAll - * @covers \Redmine\Api\CustomField::isNotNull - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -45,12 +39,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedResponse, $api->list()); } - /** - * @covers \Redmine\Api\CustomField::list - * @covers \Redmine\Api\CustomField::get - * @covers \Redmine\Api\CustomField::retrieveAll - * @covers \Redmine\Api\CustomField::isNotNull - */ public function testListWithParametersReturnsResponse() { // Test values @@ -80,12 +68,6 @@ public function testListWithParametersReturnsResponse() $this->assertSame($expectedResponse, $api->list($allParameters)); } - /** - * @covers \Redmine\Api\CustomField::list - * @covers \Redmine\Api\CustomField::get - * @covers \Redmine\Api\CustomField::retrieveAll - * @covers \Redmine\Api\CustomField::isNotNull - */ public function testListWithHighLimitParametersReturnsResponse() { // Test values @@ -118,14 +100,6 @@ public function testListWithHighLimitParametersReturnsResponse() $this->assertSame($expectedResponse, $api->list($allParameters)); } - /** - * Test list(). - * - * @covers \Redmine\Api\CustomField::list - * @covers \Redmine\Api\CustomField::get - * @covers \Redmine\Api\CustomField::retrieveAll - * @covers \Redmine\Api\CustomField::isNotNull - */ public function testListCallsEndpointUntilOffsetIsHigherThanTotalCount() { // Test values diff --git a/tests/Unit/Api/Group/ListTest.php b/tests/Unit/Api/Group/ListTest.php index a03f1f5e..e0defcc9 100644 --- a/tests/Unit/Api/Group/ListTest.php +++ b/tests/Unit/Api/Group/ListTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for Group::list() + * @covers \Redmine\Api\Group::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\Group::list - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -42,9 +39,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->list()); } - /** - * @covers \Redmine\Api\Group::all - */ public function testListeWithParametersReturnsResponse() { // Test values diff --git a/tests/Unit/Api/Issue/ListTest.php b/tests/Unit/Api/Issue/ListTest.php index 18508e80..bf35e7be 100644 --- a/tests/Unit/Api/Issue/ListTest.php +++ b/tests/Unit/Api/Issue/ListTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for Issue::list() + * @covers \Redmine\Api\Issue::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\Issue::list - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -42,9 +39,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->list()); } - /** - * @covers \Redmine\Api\Issue::list - */ public function testListWithParametersReturnsResponse() { // Test values diff --git a/tests/Unit/Api/IssueCategory/ListByProjectTest.php b/tests/Unit/Api/IssueCategory/ListByProjectTest.php index d91d962a..b31d48ec 100644 --- a/tests/Unit/Api/IssueCategory/ListByProjectTest.php +++ b/tests/Unit/Api/IssueCategory/ListByProjectTest.php @@ -10,13 +10,10 @@ use stdClass; /** - * Tests for IssueCategory::listByProject() + * @covers \Redmine\Api\IssueCategory::listByProject */ class ListByProjectTest extends TestCase { - /** - * @covers \Redmine\Api\IssueCategory::listByProject - */ public function testListByProjectWithoutParametersReturnsResponse() { // Test values @@ -46,9 +43,6 @@ public function testListByProjectWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->listByProject($projectId)); } - /** - * @covers \Redmine\Api\IssueCategory::listByProject - */ public function testListByProjectWithParametersReturnsResponse() { // Test values @@ -83,8 +77,6 @@ public function testListByProjectWithParametersReturnsResponse() } /** - * @covers \Redmine\Api\IssueCategory::listByProject - * * @dataProvider getInvalidProjectIdentifiers */ public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) diff --git a/tests/Unit/Api/IssuePriority/ListTest.php b/tests/Unit/Api/IssuePriority/ListTest.php index 07212b78..7e6832bf 100644 --- a/tests/Unit/Api/IssuePriority/ListTest.php +++ b/tests/Unit/Api/IssuePriority/ListTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for IssuePriority::list() + * @covers \Redmine\Api\IssuePriority::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\IssuePriority::list - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -42,9 +39,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->list()); } - /** - * @covers \Redmine\Api\IssuePriority::list - */ public function testListWithParametersReturnsResponse() { // Test values diff --git a/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php b/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php index 9ba3ce19..e107af1b 100644 --- a/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php +++ b/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for IssueRelation::listByIssueId() + * @covers \Redmine\Api\IssueRelation::listByIssueId */ class ListByIssueIdTest extends TestCase { - /** - * @covers \Redmine\Api\IssueRelation::listByIssueId - */ public function testListByIssueIdWithoutParametersReturnsResponse() { // Test values @@ -42,9 +39,6 @@ public function testListByIssueIdWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->listByIssueId(5)); } - /** - * @covers \Redmine\Api\IssueRelation::listByIssueId - */ public function testListByIssueIdWithParametersReturnsResponse() { // Test values diff --git a/tests/Unit/Api/IssueStatus/ListTest.php b/tests/Unit/Api/IssueStatus/ListTest.php index 1dc874da..06284400 100644 --- a/tests/Unit/Api/IssueStatus/ListTest.php +++ b/tests/Unit/Api/IssueStatus/ListTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for IssueStatus::list() + * @covers \Redmine\Api\IssueStatus::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\IssueStatus::list - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -42,9 +39,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->list()); } - /** - * @covers \Redmine\Api\IssueStatus::list - */ public function testListWithParametersReturnsResponse() { // Test values diff --git a/tests/Unit/Api/Membership/ListByProjectTest.php b/tests/Unit/Api/Membership/ListByProjectTest.php index 1d0df356..1f3e268e 100644 --- a/tests/Unit/Api/Membership/ListByProjectTest.php +++ b/tests/Unit/Api/Membership/ListByProjectTest.php @@ -10,13 +10,10 @@ use stdClass; /** - * Tests for Membership::listByProject() + * @covers \Redmine\Api\Membership::listByProject */ class ListByProjectTest extends TestCase { - /** - * @covers \Redmine\Api\Membership::listByProject - */ public function testListByProjectWithoutParametersReturnsResponse() { // Test values @@ -45,9 +42,6 @@ public function testListByProjectWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->listByProject(5)); } - /** - * @covers \Redmine\Api\Membership::listByProject - */ public function testListByProjectWithParametersReturnsResponse() { // Test values @@ -81,8 +75,6 @@ public function testListByProjectWithParametersReturnsResponse() } /** - * @covers \Redmine\Api\Membership::listByProject - * * @dataProvider getInvalidProjectIdentifiers */ public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) diff --git a/tests/Unit/Api/News/ListByProjectTest.php b/tests/Unit/Api/News/ListByProjectTest.php index 6bcf167d..fcede07c 100644 --- a/tests/Unit/Api/News/ListByProjectTest.php +++ b/tests/Unit/Api/News/ListByProjectTest.php @@ -10,13 +10,10 @@ use stdClass; /** - * Tests for News::listByProject() + * @covers \Redmine\Api\News::listByProject */ class ListByProjectTest extends TestCase { - /** - * @covers \Redmine\Api\News::listByProject - */ public function testListByProjectWithoutParametersReturnsResponse() { // Test values @@ -46,9 +43,6 @@ public function testListByProjectWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->listByProject($projectId)); } - /** - * @covers \Redmine\Api\News::listByProject - */ public function testListByProjectWithParametersReturnsResponse() { // Test values @@ -80,8 +74,6 @@ public function testListByProjectWithParametersReturnsResponse() } /** - * @covers \Redmine\Api\News::listByProject - * * @dataProvider getInvalidProjectIdentifiers */ public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) diff --git a/tests/Unit/Api/News/ListTest.php b/tests/Unit/Api/News/ListTest.php index deea8e63..776d3c35 100644 --- a/tests/Unit/Api/News/ListTest.php +++ b/tests/Unit/Api/News/ListTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for News::list() + * @covers \Redmine\Api\News::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\News::list - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -42,9 +39,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->list()); } - /** - * @covers \Redmine\Api\News::list - */ public function testListWithParametersReturnsResponse() { // Test values diff --git a/tests/Unit/Api/Project/ListTest.php b/tests/Unit/Api/Project/ListTest.php index 43f7cb30..3f25b3c8 100644 --- a/tests/Unit/Api/Project/ListTest.php +++ b/tests/Unit/Api/Project/ListTest.php @@ -7,13 +7,10 @@ use Redmine\Client\Client; /** - * Tests for News::list() + * @covers \Redmine\Api\Project::list */ class ListTest extends TestCase { - /** - * @covers \Redmine\Api\News::list - */ public function testListWithoutParametersReturnsResponse() { // Test values @@ -40,9 +37,6 @@ public function testListWithoutParametersReturnsResponse() $this->assertSame($expectedReturn, $api->list()); } - /** - * @covers \Redmine\Api\News::list - */ public function testListWithParametersReturnsResponse() { // Test values From 0fb1493075b8af780127115c1108709cbfa9b90c Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 10:04:36 +0200 Subject: [PATCH 17/27] Add Query::list() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/Query.php | 20 ++++++++- tests/Unit/Api/Query/ListTest.php | 73 +++++++++++++++++++++++++++++++ tests/Unit/Api/QueryTest.php | 27 ++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Api/Query/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 4041e9b2..0c80c16d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\News::list()` to list news from all project. - New method `Redmine\Api\News::listByProject()` to list news from a project. - New method `Redmine\Api\Project::list()` to list projects. +- New method `Redmine\Api\Query::list()` to list projects. ### Deprecated @@ -33,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::listByProject()` instead - `Redmine\Api\News::all()` is deprecated, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead - `Redmine\Api\Project::all()` is deprecated, use `Redmine\Api\Project::list()` instead +- `Redmine\Api\Query::all()` is deprecated, use `Redmine\Api\Query::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Query.php b/src/Redmine/Api/Query.php index 3bcb2e21..04c4a9d3 100644 --- a/src/Redmine/Api/Query.php +++ b/src/Redmine/Api/Query.php @@ -22,10 +22,28 @@ class Query extends AbstractApi * * @return array list of queries found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->query = $this->retrieveData('/queries.json', $params); return $this->query; } + + /** + * Returns the list of all custom queries visible by the user (public and private queries) for all projects. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Queries#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of queries found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } } diff --git a/tests/Unit/Api/Query/ListTest.php b/tests/Unit/Api/Query/ListTest.php new file mode 100644 index 00000000..bbc69cbc --- /dev/null +++ b/tests/Unit/Api/Query/ListTest.php @@ -0,0 +1,73 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/queries.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Query($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->any()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/queries.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Query($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/QueryTest.php b/tests/Unit/Api/QueryTest.php index d11c2ae7..659079f3 100644 --- a/tests/Unit/Api/QueryTest.php +++ b/tests/Unit/Api/QueryTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\Query; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Query @@ -13,6 +14,32 @@ */ class QueryTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Query(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Query::all()` is deprecated since v2.4.0, use `Redmine\Api\Query::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From a6e096654b59251a37572bbf9b9f87ba03e00e0a Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 10:15:39 +0200 Subject: [PATCH 18/27] Add Role::list() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/Role.php | 22 +++++++++- tests/Unit/Api/Role/ListTest.php | 73 ++++++++++++++++++++++++++++++++ tests/Unit/Api/RoleTest.php | 27 ++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/Role/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c80c16d..053a5e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\News::listByProject()` to list news from a project. - New method `Redmine\Api\Project::list()` to list projects. - New method `Redmine\Api\Query::list()` to list projects. +- New method `Redmine\Api\Role::list()` to list roles. ### Deprecated @@ -35,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\News::all()` is deprecated, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead - `Redmine\Api\Project::all()` is deprecated, use `Redmine\Api\Project::list()` instead - `Redmine\Api\Query::all()` is deprecated, use `Redmine\Api\Query::list()` instead +- `Redmine\Api\Role::all()` is deprecated, use `Redmine\Api\Role::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Role.php b/src/Redmine/Api/Role.php index 0250a9cf..63de7996 100644 --- a/src/Redmine/Api/Role.php +++ b/src/Redmine/Api/Role.php @@ -22,13 +22,31 @@ class Role extends AbstractApi * * @return array list of roles found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->roles = $this->retrieveData('/roles.json', $params); return $this->roles; } + /** + * List roles. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Roles#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of roles found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of roles with name/id pairs. * @@ -39,7 +57,7 @@ public function all(array $params = []) public function listing($forceUpdate = false) { if (empty($this->roles) || $forceUpdate) { - $this->all(); + $this->list(); } $ret = []; foreach ($this->roles['roles'] as $e) { diff --git a/tests/Unit/Api/Role/ListTest.php b/tests/Unit/Api/Role/ListTest.php new file mode 100644 index 00000000..edd5effc --- /dev/null +++ b/tests/Unit/Api/Role/ListTest.php @@ -0,0 +1,73 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/roles.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Role($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/roles.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Role($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/RoleTest.php b/tests/Unit/Api/RoleTest.php index 9d4ed9c0..61558ef7 100644 --- a/tests/Unit/Api/RoleTest.php +++ b/tests/Unit/Api/RoleTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\Role; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Role @@ -13,6 +14,32 @@ */ class RoleTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Role(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Role::all()` is deprecated since v2.4.0, use `Redmine\Api\Role::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From e0d21053557a7a19631e30ae6d7d21ec99e7c3b6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 10:29:07 +0200 Subject: [PATCH 19/27] Add method Search::listByQuery(), deprecate search() method --- CHANGELOG.md | 2 + src/Redmine/Api/Search.php | 23 +++++- tests/Unit/Api/Search/ListByQueryTest.php | 67 +++++++++++++++++ tests/Unit/Api/Search/SearchTest.php | 88 +++++++++++++++++++++++ 4 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/Search/ListByQueryTest.php create mode 100644 tests/Unit/Api/Search/SearchTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 053a5e90..435cfddc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Project::list()` to list projects. - New method `Redmine\Api\Query::list()` to list projects. - New method `Redmine\Api\Role::list()` to list roles. +- New method `Redmine\Api\Search::listByQuery()` to list search results by query. ### Deprecated @@ -37,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Project::all()` is deprecated, use `Redmine\Api\Project::list()` instead - `Redmine\Api\Query::all()` is deprecated, use `Redmine\Api\Query::list()` instead - `Redmine\Api\Role::all()` is deprecated, use `Redmine\Api\Role::list()` instead +- `Redmine\Api\Search::search()` is deprecated, use `Redmine\Api\Search::listByQuery()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Search.php b/src/Redmine/Api/Search.php index f8326b50..e2cd5b26 100644 --- a/src/Redmine/Api/Search.php +++ b/src/Redmine/Api/Search.php @@ -10,7 +10,7 @@ class Search extends AbstractApi private $results = []; /** - * Search. + * list search results by Query. * * @see http://www.redmine.org/projects/redmine/wiki/Rest_Search * @@ -19,11 +19,30 @@ class Search extends AbstractApi * * @return array list of results (projects, issues) */ - public function search($query, array $params = []) + final public function listByQuery(string $query, array $params = []): array { $params['q'] = $query; $this->results = $this->retrieveData('/search.json', $params); return $this->results; } + + /** + * Search. + * + * @deprecated since v2.4.0, use listByQuery() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Search + * + * @param string $query string to search + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of results (projects, issues) + */ + public function search($query, array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::listByQuery()` instead.', E_USER_DEPRECATED); + + return $this->listByQuery($query, $params); + } } diff --git a/tests/Unit/Api/Search/ListByQueryTest.php b/tests/Unit/Api/Search/ListByQueryTest.php new file mode 100644 index 00000000..e4d4740c --- /dev/null +++ b/tests/Unit/Api/Search/ListByQueryTest.php @@ -0,0 +1,67 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/search.json?limit=25&offset=0&q=query') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Search($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByQuery('query')); + } + + public function testListByQueryWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->any()) + ->method('requestGet') + ->with('/search.json?limit=25&offset=0&0=not-used&q=query') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Search($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByQuery('query', $parameters)); + } +} diff --git a/tests/Unit/Api/Search/SearchTest.php b/tests/Unit/Api/Search/SearchTest.php new file mode 100644 index 00000000..b604d290 --- /dev/null +++ b/tests/Unit/Api/Search/SearchTest.php @@ -0,0 +1,88 @@ +assertSame( + '`Redmine\Api\Search::search()` is deprecated since v2.4.0, use `Redmine\Api\Search::listByQuery()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->search('query'); + } + + public function testSearchReturnsClientGetResponse() + { + // Test values + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/search.json?limit=25&offset=0&q=query') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Search($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->search('query')); + } + + public function testSearchReturnsClientGetResponseWithParameters() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->any()) + ->method('requestGet') + ->with('/search.json?limit=25&offset=0&0=not-used&q=query') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Search($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->search('query', $parameters)); + } +} From 71464f1e65a16f51fcaba8bb11340f6f21519802 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 11:43:41 +0200 Subject: [PATCH 20/27] Add method TimeEntry::list(), deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/TimeEntry.php | 20 ++++++- tests/Unit/Api/TimeEntry/ListTest.php | 77 +++++++++++++++++++++++++++ tests/Unit/Api/TimeEntryTest.php | 27 ++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Api/TimeEntry/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 435cfddc..5e8f8661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Query::list()` to list projects. - New method `Redmine\Api\Role::list()` to list roles. - New method `Redmine\Api\Search::listByQuery()` to list search results by query. +- New method `Redmine\Api\TimeEntry::list()` to list time entries. ### Deprecated @@ -39,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Query::all()` is deprecated, use `Redmine\Api\Query::list()` instead - `Redmine\Api\Role::all()` is deprecated, use `Redmine\Api\Role::list()` instead - `Redmine\Api\Search::search()` is deprecated, use `Redmine\Api\Search::listByQuery()` instead +- `Redmine\Api\TimeEntry::all()` is deprecated, use `Redmine\Api\TimeEntry::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/TimeEntry.php b/src/Redmine/Api/TimeEntry.php index 343633eb..2bf71752 100644 --- a/src/Redmine/Api/TimeEntry.php +++ b/src/Redmine/Api/TimeEntry.php @@ -25,13 +25,31 @@ class TimeEntry extends AbstractApi * * @return array list of time entries found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->timeEntries = $this->retrieveData('/time_entries.json', $params); return $this->timeEntries; } + /** + * List time entries. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of time entries found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Get extended information about a time entry (including memberships + groups). * diff --git a/tests/Unit/Api/TimeEntry/ListTest.php b/tests/Unit/Api/TimeEntry/ListTest.php new file mode 100644 index 00000000..64010a9e --- /dev/null +++ b/tests/Unit/Api/TimeEntry/ListTest.php @@ -0,0 +1,77 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/time_entries.json') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new TimeEntry($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = [ + 'project_id' => 5, + 'user_id' => 10, + 'limit' => 2, + ]; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/time_entries.json?'), + $this->stringContains('project_id=5'), + $this->stringContains('user_id=10'), + $this->stringContains('limit=2') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new TimeEntry($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/TimeEntryTest.php b/tests/Unit/Api/TimeEntryTest.php index 652da294..5f407da4 100644 --- a/tests/Unit/Api/TimeEntryTest.php +++ b/tests/Unit/Api/TimeEntryTest.php @@ -6,6 +6,7 @@ use Redmine\Api\TimeEntry; use Redmine\Client\Client; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\TimeEntry @@ -14,6 +15,32 @@ */ class TimeEntryTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new TimeEntry(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\TimeEntry::all()` is deprecated since v2.4.0, use `Redmine\Api\TimeEntry::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From b9e1165c648483a086b284922649a0ae6fc04b86 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 12:49:12 +0200 Subject: [PATCH 21/27] Add TimeEntryActivity::list() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/TimeEntryActivity.php | 20 ++++- tests/Unit/Api/TimeEntryActivity/ListTest.php | 73 +++++++++++++++++++ tests/Unit/Api/TimeEntryActivityTest.php | 27 +++++++ 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/TimeEntryActivity/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e8f8661..0c18cc82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Role::list()` to list roles. - New method `Redmine\Api\Search::listByQuery()` to list search results by query. - New method `Redmine\Api\TimeEntry::list()` to list time entries. +- New method `Redmine\Api\TimeEntryActivity::list()` to list time entries. ### Deprecated @@ -41,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Role::all()` is deprecated, use `Redmine\Api\Role::list()` instead - `Redmine\Api\Search::search()` is deprecated, use `Redmine\Api\Search::listByQuery()` instead - `Redmine\Api\TimeEntry::all()` is deprecated, use `Redmine\Api\TimeEntry::list()` instead +- `Redmine\Api\TimeEntryActivity::all()` is deprecated, use `Redmine\Api\TimeEntryActivity::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/TimeEntryActivity.php b/src/Redmine/Api/TimeEntryActivity.php index a0a10f77..c3e5bcd9 100644 --- a/src/Redmine/Api/TimeEntryActivity.php +++ b/src/Redmine/Api/TimeEntryActivity.php @@ -20,13 +20,29 @@ class TimeEntryActivity extends AbstractApi * * @return array list of time entry activities found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->timeEntryActivities = $this->retrieveData('/enumerations/time_entry_activities.json', $params); return $this->timeEntryActivities; } + /** + * List time entry activities. + * + * @deprecated since v2.4.0, use list() instead. + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of time entry activities found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of time entry activities with name/id pairs. * @@ -37,7 +53,7 @@ public function all(array $params = []) public function listing($forceUpdate = false) { if (empty($this->timeEntryActivities) || $forceUpdate) { - $this->all(); + $this->list(); } $ret = []; foreach ($this->timeEntryActivities['time_entry_activities'] as $e) { diff --git a/tests/Unit/Api/TimeEntryActivity/ListTest.php b/tests/Unit/Api/TimeEntryActivity/ListTest.php new file mode 100644 index 00000000..cb39d780 --- /dev/null +++ b/tests/Unit/Api/TimeEntryActivity/ListTest.php @@ -0,0 +1,73 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/enumerations/time_entry_activities.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new TimeEntryActivity($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/enumerations/time_entry_activities.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new TimeEntryActivity($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/TimeEntryActivityTest.php b/tests/Unit/Api/TimeEntryActivityTest.php index 50ec89eb..da1a5ce6 100644 --- a/tests/Unit/Api/TimeEntryActivityTest.php +++ b/tests/Unit/Api/TimeEntryActivityTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\TimeEntryActivity; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\TimeEntryActivity @@ -13,6 +14,32 @@ */ class TimeEntryActivityTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new TimeEntryActivity(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\TimeEntryActivity::all()` is deprecated since v2.4.0, use `Redmine\Api\TimeEntryActivity::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From 590c415e19c424bdc1b091bcf180cd5e91c9c21c Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 13:11:26 +0200 Subject: [PATCH 22/27] Add Tracker::list() method, deprecate all() method --- CHANGELOG.md | 4 +- src/Redmine/Api/Tracker.php | 22 ++++++++- tests/Unit/Api/Tracker/ListTest.php | 73 +++++++++++++++++++++++++++++ tests/Unit/Api/TrackerTest.php | 27 +++++++++++ 4 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 tests/Unit/Api/Tracker/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c18cc82..6db298dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Role::list()` to list roles. - New method `Redmine\Api\Search::listByQuery()` to list search results by query. - New method `Redmine\Api\TimeEntry::list()` to list time entries. -- New method `Redmine\Api\TimeEntryActivity::list()` to list time entries. +- New method `Redmine\Api\TimeEntryActivity::list()` to list time entry activities. +- New method `Redmine\Api\Tracker::list()` to list trackers. ### Deprecated @@ -43,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Search::search()` is deprecated, use `Redmine\Api\Search::listByQuery()` instead - `Redmine\Api\TimeEntry::all()` is deprecated, use `Redmine\Api\TimeEntry::list()` instead - `Redmine\Api\TimeEntryActivity::all()` is deprecated, use `Redmine\Api\TimeEntryActivity::list()` instead +- `Redmine\Api\Tracker::all()` is deprecated, use `Redmine\Api\Tracker::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Tracker.php b/src/Redmine/Api/Tracker.php index 7c3a6365..95c66811 100644 --- a/src/Redmine/Api/Tracker.php +++ b/src/Redmine/Api/Tracker.php @@ -22,13 +22,31 @@ class Tracker extends AbstractApi * * @return array list of trackers found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->trackers = $this->retrieveData('/trackers.json', $params); return $this->trackers; } + /** + * List trackers. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Trackers#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of trackers found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of trackers with name/id pairs. * @@ -39,7 +57,7 @@ public function all(array $params = []) public function listing($forceUpdate = false) { if (empty($this->trackers) || $forceUpdate) { - $this->all(); + $this->list(); } $ret = []; foreach ($this->trackers['trackers'] as $e) { diff --git a/tests/Unit/Api/Tracker/ListTest.php b/tests/Unit/Api/Tracker/ListTest.php new file mode 100644 index 00000000..5e09a8cd --- /dev/null +++ b/tests/Unit/Api/Tracker/ListTest.php @@ -0,0 +1,73 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/trackers.json') + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Tracker($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = ['not-used']; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->logicalAnd( + $this->stringStartsWith('/trackers.json'), + $this->stringContains('not-used') + ) + ) + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Tracker($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/TrackerTest.php b/tests/Unit/Api/TrackerTest.php index 7cb018f5..041aa14b 100644 --- a/tests/Unit/Api/TrackerTest.php +++ b/tests/Unit/Api/TrackerTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\Tracker; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Tracker @@ -13,6 +14,32 @@ */ class TrackerTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Tracker(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Tracker::all()` is deprecated since v2.4.0, use `Redmine\Api\Tracker::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From 97786ea3000d1e34b4cc1f1546221b76abc620f4 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 13:32:30 +0200 Subject: [PATCH 23/27] test for correct requested url --- tests/Unit/Api/CustomField/ListTest.php | 8 ++------ tests/Unit/Api/Group/ListTest.php | 11 ++--------- tests/Unit/Api/Issue/ListTest.php | 11 ++--------- tests/Unit/Api/IssueCategory/ListByProjectTest.php | 11 ++--------- tests/Unit/Api/IssuePriority/ListTest.php | 8 ++------ tests/Unit/Api/IssueRelation/ListByIssueIdTest.php | 11 ++--------- tests/Unit/Api/IssueStatus/ListTest.php | 11 ++--------- tests/Unit/Api/Membership/ListByProjectTest.php | 11 ++--------- tests/Unit/Api/News/ListByProjectTest.php | 8 ++------ tests/Unit/Api/News/ListTest.php | 11 ++--------- tests/Unit/Api/Project/ListTest.php | 7 +------ tests/Unit/Api/Query/ListTest.php | 11 ++--------- tests/Unit/Api/Role/ListTest.php | 11 ++--------- tests/Unit/Api/TimeEntry/ListTest.php | 9 +-------- tests/Unit/Api/TimeEntryActivity/ListTest.php | 11 ++--------- tests/Unit/Api/Tracker/ListTest.php | 11 ++--------- 16 files changed, 30 insertions(+), 131 deletions(-) diff --git a/tests/Unit/Api/CustomField/ListTest.php b/tests/Unit/Api/CustomField/ListTest.php index e36108dd..bf67684a 100644 --- a/tests/Unit/Api/CustomField/ListTest.php +++ b/tests/Unit/Api/CustomField/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/custom_fields.json') - ) + ->with('/custom_fields.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,9 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringContains('not-used') - ) + ->with('/custom_fields.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Group/ListTest.php b/tests/Unit/Api/Group/ListTest.php index e0defcc9..5e8cfdaa 100644 --- a/tests/Unit/Api/Group/ListTest.php +++ b/tests/Unit/Api/Group/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/groups.json') - ) + ->with('/groups.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListeWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/groups.json'), - $this->stringContains('not-used') - ) - ) + ->with('/groups.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Issue/ListTest.php b/tests/Unit/Api/Issue/ListTest.php index bf35e7be..94c23cbe 100644 --- a/tests/Unit/Api/Issue/ListTest.php +++ b/tests/Unit/Api/Issue/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/issues.json') - ) + ->with('/issues.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/issues.json'), - $this->stringContains('not-used') - ) - ) + ->with('/issues.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/IssueCategory/ListByProjectTest.php b/tests/Unit/Api/IssueCategory/ListByProjectTest.php index b31d48ec..563a392b 100644 --- a/tests/Unit/Api/IssueCategory/ListByProjectTest.php +++ b/tests/Unit/Api/IssueCategory/ListByProjectTest.php @@ -25,9 +25,7 @@ public function testListByProjectWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/projects/5/issue_categories.json') - ) + ->with('/projects/5/issue_categories.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -55,12 +53,7 @@ public function testListByProjectWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/projects/project-slug/issue_categories.json'), - $this->stringContains('not-used') - ) - ) + ->with('/projects/project-slug/issue_categories.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/IssuePriority/ListTest.php b/tests/Unit/Api/IssuePriority/ListTest.php index 7e6832bf..855f9074 100644 --- a/tests/Unit/Api/IssuePriority/ListTest.php +++ b/tests/Unit/Api/IssuePriority/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/enumerations/issue_priorities.json') - ) + ->with('/enumerations/issue_priorities.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,9 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringContains('not-used') - ) + ->with('/enumerations/issue_priorities.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php b/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php index e107af1b..c05c4866 100644 --- a/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php +++ b/tests/Unit/Api/IssueRelation/ListByIssueIdTest.php @@ -21,9 +21,7 @@ public function testListByIssueIdWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/issues/5/relations.json') - ) + ->with('/issues/5/relations.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListByIssueIdWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/issues/5/relations.json'), - $this->stringContains('not-used') - ) - ) + ->with('/issues/5/relations.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/IssueStatus/ListTest.php b/tests/Unit/Api/IssueStatus/ListTest.php index 06284400..801d2b3c 100644 --- a/tests/Unit/Api/IssueStatus/ListTest.php +++ b/tests/Unit/Api/IssueStatus/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/issue_statuses.json') - ) + ->with('/issue_statuses.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/issue_statuses.json'), - $this->stringContains('not-used') - ) - ) + ->with('/issue_statuses.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Membership/ListByProjectTest.php b/tests/Unit/Api/Membership/ListByProjectTest.php index 1f3e268e..55b4b49a 100644 --- a/tests/Unit/Api/Membership/ListByProjectTest.php +++ b/tests/Unit/Api/Membership/ListByProjectTest.php @@ -24,9 +24,7 @@ public function testListByProjectWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/projects/5/memberships.json') - ) + ->with('/projects/5/memberships.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -53,12 +51,7 @@ public function testListByProjectWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/projects/project-slug/memberships.json'), - $this->stringContains('not-used') - ) - ) + ->with('/projects/project-slug/memberships.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/News/ListByProjectTest.php b/tests/Unit/Api/News/ListByProjectTest.php index fcede07c..1b42ce5c 100644 --- a/tests/Unit/Api/News/ListByProjectTest.php +++ b/tests/Unit/Api/News/ListByProjectTest.php @@ -25,9 +25,7 @@ public function testListByProjectWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/projects/5/news.json') - ) + ->with('/projects/5/news.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -55,9 +53,7 @@ public function testListByProjectWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringContains('not-used') - ) + ->with('/projects/5/news.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/News/ListTest.php b/tests/Unit/Api/News/ListTest.php index 776d3c35..80e2ef38 100644 --- a/tests/Unit/Api/News/ListTest.php +++ b/tests/Unit/Api/News/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/news.json') - ) + ->with('/news.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/news.json'), - $this->stringContains('not-used') - ) - ) + ->with('/news.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Project/ListTest.php b/tests/Unit/Api/Project/ListTest.php index 3f25b3c8..ede326d0 100644 --- a/tests/Unit/Api/Project/ListTest.php +++ b/tests/Unit/Api/Project/ListTest.php @@ -48,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/projects.json'), - $this->stringContains('not-used') - ) - ) + ->with('/projects.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Query/ListTest.php b/tests/Unit/Api/Query/ListTest.php index bbc69cbc..01e46773 100644 --- a/tests/Unit/Api/Query/ListTest.php +++ b/tests/Unit/Api/Query/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/queries.json') - ) + ->with('/queries.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->any()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/queries.json'), - $this->stringContains('not-used') - ) - ) + ->with('/queries.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Role/ListTest.php b/tests/Unit/Api/Role/ListTest.php index edd5effc..d274a1b2 100644 --- a/tests/Unit/Api/Role/ListTest.php +++ b/tests/Unit/Api/Role/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/roles.json') - ) + ->with('/roles.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/roles.json'), - $this->stringContains('not-used') - ) - ) + ->with('/roles.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/TimeEntry/ListTest.php b/tests/Unit/Api/TimeEntry/ListTest.php index 64010a9e..126dcca4 100644 --- a/tests/Unit/Api/TimeEntry/ListTest.php +++ b/tests/Unit/Api/TimeEntry/ListTest.php @@ -52,14 +52,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/time_entries.json?'), - $this->stringContains('project_id=5'), - $this->stringContains('user_id=10'), - $this->stringContains('limit=2') - ) - ) + ->with('/time_entries.json?limit=2&offset=0&project_id=5&user_id=10') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/TimeEntryActivity/ListTest.php b/tests/Unit/Api/TimeEntryActivity/ListTest.php index cb39d780..d296ca0c 100644 --- a/tests/Unit/Api/TimeEntryActivity/ListTest.php +++ b/tests/Unit/Api/TimeEntryActivity/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/enumerations/time_entry_activities.json') - ) + ->with('/enumerations/time_entry_activities.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/enumerations/time_entry_activities.json'), - $this->stringContains('not-used') - ) - ) + ->with('/enumerations/time_entry_activities.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') diff --git a/tests/Unit/Api/Tracker/ListTest.php b/tests/Unit/Api/Tracker/ListTest.php index 5e09a8cd..66ed63ed 100644 --- a/tests/Unit/Api/Tracker/ListTest.php +++ b/tests/Unit/Api/Tracker/ListTest.php @@ -21,9 +21,7 @@ public function testListWithoutParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->stringStartsWith('/trackers.json') - ) + ->with('/trackers.json') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') @@ -50,12 +48,7 @@ public function testListWithParametersReturnsResponse() $client = $this->createMock(Client::class); $client->expects($this->once()) ->method('requestGet') - ->with( - $this->logicalAnd( - $this->stringStartsWith('/trackers.json'), - $this->stringContains('not-used') - ) - ) + ->with('/trackers.json?limit=25&offset=0&0=not-used') ->willReturn(true); $client->expects($this->exactly(1)) ->method('getLastResponseBody') From 1bcaf883a9b7efd87cc231ec3714496ecf6ca84c Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 16:12:08 +0200 Subject: [PATCH 24/27] Add User::list() method, deprecated all() method --- CHANGELOG.md | 2 + src/Redmine/Api/User.php | 20 ++++++++- tests/Unit/Api/User/ListTest.php | 69 ++++++++++++++++++++++++++++++++ tests/Unit/Api/UserTest.php | 27 +++++++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Api/User/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6db298dd..86e952c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\TimeEntry::list()` to list time entries. - New method `Redmine\Api\TimeEntryActivity::list()` to list time entry activities. - New method `Redmine\Api\Tracker::list()` to list trackers. +- New method `Redmine\Api\User::list()` to list users. ### Deprecated @@ -45,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\TimeEntry::all()` is deprecated, use `Redmine\Api\TimeEntry::list()` instead - `Redmine\Api\TimeEntryActivity::all()` is deprecated, use `Redmine\Api\TimeEntryActivity::list()` instead - `Redmine\Api\Tracker::all()` is deprecated, use `Redmine\Api\Tracker::list()` instead +- `Redmine\Api\User::all()` is deprecated, use `Redmine\Api\User::list()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/User.php b/src/Redmine/Api/User.php index 05c4fc09..7b0151f2 100644 --- a/src/Redmine/Api/User.php +++ b/src/Redmine/Api/User.php @@ -26,13 +26,31 @@ class User extends AbstractApi * * @return array list of users found */ - public function all(array $params = []) + final public function list(array $params = []): array { $this->users = $this->retrieveData('/users.json', $params); return $this->users; } + /** + * List users. + * + * @deprecated since v2.4.0, use list() instead. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Users#GET + * + * @param array $params to allow offset/limit (and more) to be passed + * + * @return array list of users found + */ + public function all(array $params = []) + { + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED); + + return $this->list($params); + } + /** * Returns an array of users with login/id pairs. * diff --git a/tests/Unit/Api/User/ListTest.php b/tests/Unit/Api/User/ListTest.php new file mode 100644 index 00000000..82c554a2 --- /dev/null +++ b/tests/Unit/Api/User/ListTest.php @@ -0,0 +1,69 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/users.json') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new User($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + public function testListWithParametersReturnsResponse() + { + // Test values + $parameters = [ + 'offset' => 10, + 'limit' => 2, + ]; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/users.json?limit=2&offset=10') + ->willReturn(true); + $client->expects($this->exactly(1)) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new User($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/UserTest.php b/tests/Unit/Api/UserTest.php index e3746fcc..9d1d7087 100644 --- a/tests/Unit/Api/UserTest.php +++ b/tests/Unit/Api/UserTest.php @@ -6,6 +6,7 @@ use Redmine\Api\User; use Redmine\Client\Client; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\User @@ -88,6 +89,32 @@ public function testGetIdByUsernameMakesGetRequest() $this->assertSame(5, $api->getIdByUsername('User 5')); } + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new User(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\User::all()` is deprecated since v2.4.0, use `Redmine\Api\User::list()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(); + } + /** * Test all(). * From e361cc1148cd59a4bbe0c7bc08fadcc44127fdfb Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 10 Oct 2023 16:26:38 +0200 Subject: [PATCH 25/27] Add Version::listByProject() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/Version.php | 30 +++++- tests/Unit/Api/Version/ListByProjectTest.php | 97 ++++++++++++++++++++ tests/Unit/Api/VersionTest.php | 27 ++++++ 4 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Api/Version/ListByProjectTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 86e952c2..e42f4f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\TimeEntryActivity::list()` to list time entry activities. - New method `Redmine\Api\Tracker::list()` to list trackers. - New method `Redmine\Api\User::list()` to list users. +- New method `Redmine\Api\Version::listByProject()` to list versions from a project. ### Deprecated @@ -47,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\TimeEntryActivity::all()` is deprecated, use `Redmine\Api\TimeEntryActivity::list()` instead - `Redmine\Api\Tracker::all()` is deprecated, use `Redmine\Api\Tracker::list()` instead - `Redmine\Api\User::all()` is deprecated, use `Redmine\Api\User::list()` instead +- `Redmine\Api\Version::all()` is deprecated, use `Redmine\Api\Version::listByProject()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Version.php b/src/Redmine/Api/Version.php index fda33443..d618c5fb 100644 --- a/src/Redmine/Api/Version.php +++ b/src/Redmine/Api/Version.php @@ -17,9 +17,35 @@ class Version extends AbstractApi { private $versions = []; + /** + * List versions of a project. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_Versions#GET + * + * @param string|int $projectIdentifier project id or literal identifier + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of versions found + */ + final public function listByProject($projectIdentifier, array $params = []): array + { + if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { + throw new InvalidParameterException(sprintf( + '%s(): Argument #1 ($projectIdentifier) must be of type int or string', + __METHOD__ + )); + } + + $this->versions = $this->retrieveData('/projects/'.$projectIdentifier.'/versions.json', $params); + + return $this->versions; + } + /** * List versions. * + * @deprecated since v2.4.0, use listByProject() instead. + * * @see http://www.redmine.org/projects/redmine/wiki/Rest_Versions#GET * * @param string|int $project project id or literal identifier @@ -29,9 +55,9 @@ class Version extends AbstractApi */ public function all($project, array $params = []) { - $this->versions = $this->retrieveData('/projects/'.$project.'/versions.json', $params); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::listByProject()` instead.', E_USER_DEPRECATED); - return $this->versions; + return $this->listByProject(strval($project), $params); } /** diff --git a/tests/Unit/Api/Version/ListByProjectTest.php b/tests/Unit/Api/Version/ListByProjectTest.php new file mode 100644 index 00000000..55d5e063 --- /dev/null +++ b/tests/Unit/Api/Version/ListByProjectTest.php @@ -0,0 +1,97 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/projects/5/versions.json') + ->willReturn(true); + $client->expects($this->once()) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Version($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject(5)); + } + + public function testListByProjectWithParametersReturnsResponse() + { + // Test values + $parameters = [ + 'offset' => 10, + 'limit' => 2, + ]; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->any()) + ->method('requestGet') + ->with('/projects/project-slug/versions.json?limit=2&offset=10') + ->willReturn(true); + $client->expects($this->once()) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Version($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject('project-slug', $parameters)); + } + + /** + * @dataProvider getInvalidProjectIdentifiers + */ + public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) + { + $api = new Version(MockClient::create()); + + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('Redmine\Api\Version::listByProject(): Argument #1 ($projectIdentifier) must be of type int or string'); + + $api->listByProject($projectIdentifier); + } + + public static function getInvalidProjectIdentifiers(): array + { + return [ + 'null' => [null], + 'true' => [true], + 'false' => [false], + 'float' => [0.0], + 'array' => [[]], + 'object' => [new stdClass()], + ]; + } +} diff --git a/tests/Unit/Api/VersionTest.php b/tests/Unit/Api/VersionTest.php index 668d8d38..9efc32a8 100644 --- a/tests/Unit/Api/VersionTest.php +++ b/tests/Unit/Api/VersionTest.php @@ -7,6 +7,7 @@ use Redmine\Client\Client; use Redmine\Exception\InvalidParameterException; use Redmine\Exception\MissingParameterException; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Version @@ -15,6 +16,32 @@ */ class VersionTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Version(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Version::all()` is deprecated since v2.4.0, use `Redmine\Api\Version::listByProject()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). * From 62e54a3003a92cf58653932cd1de02b7fc9762da Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 11 Oct 2023 08:50:38 +0200 Subject: [PATCH 26/27] Add Wiki::listByProject() method, deprecate all() method --- CHANGELOG.md | 2 + src/Redmine/Api/Version.php | 2 +- src/Redmine/Api/Wiki.php | 31 +++++++- tests/Unit/Api/Wiki/ListByProjectTest.php | 97 +++++++++++++++++++++++ tests/Unit/Api/WikiTest.php | 27 +++++++ 5 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 tests/Unit/Api/Wiki/ListByProjectTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index e42f4f8a..a5d1e1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Tracker::list()` to list trackers. - New method `Redmine\Api\User::list()` to list users. - New method `Redmine\Api\Version::listByProject()` to list versions from a project. +- New method `Redmine\Api\Wiki::listByProject()` to list wiki pages from a project. ### Deprecated @@ -49,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\Tracker::all()` is deprecated, use `Redmine\Api\Tracker::list()` instead - `Redmine\Api\User::all()` is deprecated, use `Redmine\Api\User::list()` instead - `Redmine\Api\Version::all()` is deprecated, use `Redmine\Api\Version::listByProject()` instead +- `Redmine\Api\Wiki::all()` is deprecated, use `Redmine\Api\Wiki::listByProject()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/Version.php b/src/Redmine/Api/Version.php index d618c5fb..3bd463ac 100644 --- a/src/Redmine/Api/Version.php +++ b/src/Redmine/Api/Version.php @@ -36,7 +36,7 @@ final public function listByProject($projectIdentifier, array $params = []): arr )); } - $this->versions = $this->retrieveData('/projects/'.$projectIdentifier.'/versions.json', $params); + $this->versions = $this->retrieveData('/projects/'.strval($projectIdentifier).'/versions.json', $params); return $this->versions; } diff --git a/src/Redmine/Api/Wiki.php b/src/Redmine/Api/Wiki.php index cc459c3f..549fd9a3 100644 --- a/src/Redmine/Api/Wiki.php +++ b/src/Redmine/Api/Wiki.php @@ -2,6 +2,7 @@ namespace Redmine\Api; +use Redmine\Exception\InvalidParameterException; use Redmine\Serializer\PathSerializer; use Redmine\Serializer\XmlSerializer; @@ -16,9 +17,35 @@ class Wiki extends AbstractApi { private $wikiPages = []; + /** + * List wiki pages of a given project. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Getting-the-pages-list-of-a-wiki + * + * @param int|string $projectIdentifier project id or slug + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of wiki pages found for the given project + */ + final public function listByProject($projectIdentifier, array $params = []): array + { + if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { + throw new InvalidParameterException(sprintf( + '%s(): Argument #1 ($projectIdentifier) must be of type int or string', + __METHOD__ + )); + } + + $this->wikiPages = $this->retrieveData('/projects/'.strval($projectIdentifier).'/wiki/index.json', $params); + + return $this->wikiPages; + } + /** * List wiki pages of given $project. * + * @deprecated since v2.4.0, use listByProject() instead. + * * @see http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Getting-the-pages-list-of-a-wiki * * @param int|string $project project name @@ -28,9 +55,9 @@ class Wiki extends AbstractApi */ public function all($project, array $params = []) { - $this->wikiPages = $this->retrieveData('/projects/'.$project.'/wiki/index.json', $params); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::listByProject()` instead.', E_USER_DEPRECATED); - return $this->wikiPages; + return $this->listByProject(strval($project), $params); } /** diff --git a/tests/Unit/Api/Wiki/ListByProjectTest.php b/tests/Unit/Api/Wiki/ListByProjectTest.php new file mode 100644 index 00000000..b08d6c2e --- /dev/null +++ b/tests/Unit/Api/Wiki/ListByProjectTest.php @@ -0,0 +1,97 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with('/projects/5/wiki/index.json') + ->willReturn(true); + $client->expects($this->once()) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Wiki($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject(5)); + } + + public function testListByProjectWithParametersReturnsResponse() + { + // Test values + $parameters = [ + 'offset' => 10, + 'limit' => 2, + ]; + $response = '["API Response"]'; + $expectedReturn = ['API Response']; + + // Create the used mock objects + $client = $this->createMock(Client::class); + $client->expects($this->any()) + ->method('requestGet') + ->with('/projects/project-slug/wiki/index.json?limit=2&offset=10') + ->willReturn(true); + $client->expects($this->once()) + ->method('getLastResponseBody') + ->willReturn($response); + $client->expects($this->exactly(1)) + ->method('getLastResponseContentType') + ->willReturn('application/json'); + + // Create the object under test + $api = new Wiki($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject('project-slug', $parameters)); + } + + /** + * @dataProvider getInvalidProjectIdentifiers + */ + public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier) + { + $api = new Wiki(MockClient::create()); + + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('Redmine\Api\Wiki::listByProject(): Argument #1 ($projectIdentifier) must be of type int or string'); + + $api->listByProject($projectIdentifier); + } + + public static function getInvalidProjectIdentifiers(): array + { + return [ + 'null' => [null], + 'true' => [true], + 'false' => [false], + 'float' => [0.0], + 'array' => [[]], + 'object' => [new stdClass()], + ]; + } +} diff --git a/tests/Unit/Api/WikiTest.php b/tests/Unit/Api/WikiTest.php index a2fee2ed..6e10894b 100644 --- a/tests/Unit/Api/WikiTest.php +++ b/tests/Unit/Api/WikiTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\Wiki; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\Wiki @@ -13,6 +14,32 @@ */ class WikiTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new Wiki(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Wiki::all()` is deprecated since v2.4.0, use `Redmine\Api\Wiki::listByProject()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). * From 151d20e2d9e3ca288578baf8ac5699ee025e784c Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 11 Oct 2023 09:08:56 +0200 Subject: [PATCH 27/27] Update docs --- README.md | 4 +-- docs/usage.md | 58 ++++++++++++++++++------------------- src/Redmine/Api/User.php | 2 +- src/Redmine/Api/Version.php | 2 +- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index f0ac412d..0f018223 100644 --- a/README.md +++ b/README.md @@ -310,7 +310,7 @@ You can now use the `getApi()` method to create and get a specific Redmine API. ```php getApi('user')->all(); +$client->getApi('user')->list(); $client->getApi('user')->listing(); $client->getApi('issue')->create([ @@ -319,7 +319,7 @@ $client->getApi('issue')->create([ 'description' => 'a long description blablabla', 'assigned_to_id' => 123, // or 'assigned_to' => 'user1' OR 'groupXX' ]); -$client->getApi('issue')->all([ +$client->getApi('issue')->list([ 'limit' => 1000 ]); ``` diff --git a/docs/usage.md b/docs/usage.md index bce2a34f..f0c5ac4a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -226,19 +226,19 @@ To check for failed requests you can afterwards check the status code via `$clie ```php // ---------------------------- // Trackers -$client->getApi('tracker')->all(); +$client->getApi('tracker')->list(); $client->getApi('tracker')->listing(); // ---------------------------- // Issue statuses -$client->getApi('issue_status')->all(); +$client->getApi('issue_status')->list(); $client->getApi('issue_status')->listing(); $client->getApi('issue_status')->getIdByName('New'); // ---------------------------- // Project -$client->getApi('project')->all(); -$client->getApi('project')->all([ +$client->getApi('project')->list(); +$client->getApi('project')->list([ 'limit' => 10, ]); $client->getApi('project')->listing(); @@ -257,7 +257,7 @@ $client->getApi('project')->remove($projectId); // ---------------------------- // Users -$client->getApi('user')->all(); +$client->getApi('user')->list(); $client->getApi('user')->listing(); $client->getApi('user')->getCurrentUser([ 'include' => [ @@ -290,15 +290,15 @@ $client->getApi('user')->create([ // ---------------------------- // Issues $client->getApi('issue')->show($issueId); -$client->getApi('issue')->all([ +$client->getApi('issue')->list([ 'limit' => 100, ]); -$client->getApi('issue')->all(['category_id' => $categoryId]); -$client->getApi('issue')->all(['tracker_id' => $trackerId]); -$client->getApi('issue')->all(['status_id' => 'closed']); -$client->getApi('issue')->all(['assigned_to_id' => $userId]); -$client->getApi('issue')->all(['project_id' => 'test']); -$client->getApi('issue')->all([ +$client->getApi('issue')->list(['category_id' => $categoryId]); +$client->getApi('issue')->list(['tracker_id' => $trackerId]); +$client->getApi('issue')->list(['status_id' => 'closed']); +$client->getApi('issue')->list(['assigned_to_id' => $userId]); +$client->getApi('issue')->list(['project_id' => 'test']); +$client->getApi('issue')->list([ 'offset' => 100, 'limit' => 100, 'sort' => 'id', @@ -375,7 +375,7 @@ $client->getApi('issue')->create([ // ---------------------------- // Issue categories -$client->getApi('issue_category')->all('project1'); +$client->getApi('issue_category')->listByProject('project1'); $client->getApi('issue_category')->listing($projectId); $client->getApi('issue_category')->show($categoryId); $client->getApi('issue_category')->getIdByName($projectId, 'Administration'); @@ -392,7 +392,7 @@ $client->getApi('issue_category')->remove($categoryId, [ // ---------------------------- // Versions -$client->getApi('version')->all('test'); +$client->getApi('version')->listByProject('test'); $client->getApi('version')->listing('test'); $client->getApi('version')->show($versionId); $client->getApi('version')->getIdByName('test', 'v2'); @@ -413,24 +413,24 @@ file_put_contents('example.png', $file_content); // ---------------------------- // News -$client->getApi('news')->all('test'); -$client->getApi('news')->all(); +$client->getApi('news')->list(); +$client->getApi('news')->listByProject('test'); // ---------------------------- // Roles -$client->getApi('role')->all(); +$client->getApi('role')->list(); $client->getApi('role')->show(1); $client->getApi('role')->listing(); // ---------------------------- // Queries -$client->getApi('query')->all(); +$client->getApi('query')->list(); // ---------------------------- // Time entries -$client->getApi('time_entry')->all(); +$client->getApi('time_entry')->list(); $client->getApi('time_entry')->show($timeEntryId); -$client->getApi('time_entry')->all([ +$client->getApi('time_entry')->list([ 'issue_id' => 1234, 'project_id' => 1234, 'spent_on' => '2015-04-13', @@ -470,17 +470,17 @@ $client->getApi('time_entry')->remove($timeEntryId); // ---------------------------- // Time entry activities -$client->getApi('time_entry_activity')->all(); +$client->getApi('time_entry_activity')->list(); // ---------------------------- // Issue relations -$client->getApi('issue_relation')->all($issueId); +$client->getApi('issue_relation')->listByIssueId($issueId); $client->getApi('issue_relation')->show($issueRelationId); $client->getApi('issue_relation')->remove($issueRelationId); // ---------------------------- // Group (of members) -$client->getApi('group')->all(); +$client->getApi('group')->list(); $client->getApi('group')->listing(); $client->getApi('group')->show($groupId, ['include' => 'users,memberships']); $client->getApi('group')->remove($groupId); @@ -493,7 +493,7 @@ $client->getApi('group')->create([ // ---------------------------- // Project memberships -$client->getApi('membership')->all($projectId); +$client->getApi('membership')->listByProject($projectId); $client->getApi('membership')->create($projectId, [ 'user_id' => null, 'role_ids' => [], @@ -502,11 +502,11 @@ $client->getApi('membership')->remove($membershipId); // ---------------------------- // Issue priorities -$client->getApi('issue_priority')->all(); +$client->getApi('issue_priority')->list(); // ---------------------------- // Wiki -$client->getApi('wiki')->all('testProject'); +$client->getApi('wiki')->listByProject('testProject'); $client->getApi('wiki')->show('testProject', 'about'); $client->getApi('wiki')->show('testProject', 'about', $version); $client->getApi('wiki')->create('testProject', 'about', [ @@ -523,19 +523,19 @@ $client->getApi('wiki')->remove('testProject', 'about'); // ---------------------------- // Issues' stats (see https://github.com/kbsali/php-redmine-api/issues/44) -$issues['all'] = $client->getApi('issue')->all([ +$issues['all'] = $client->getApi('issue')->list([ 'limit' => 1, 'tracker_id' => 1, 'status_id' => '*', ])['total_count']; -$issues['opened'] = $client->getApi('issue')->all([ +$issues['opened'] = $client->getApi('issue')->list([ 'limit' => 1, 'tracker_id' => 1, 'status_id' => 'open', ])['total_count']; -$issues['closed'] = $client->getApi('issue')->all([ +$issues['closed'] = $client->getApi('issue')->list([ 'limit' => 1, 'tracker_id' => 1, 'status_id' => 'closed', diff --git a/src/Redmine/Api/User.php b/src/Redmine/Api/User.php index 7b0151f2..33e6cdeb 100644 --- a/src/Redmine/Api/User.php +++ b/src/Redmine/Api/User.php @@ -62,7 +62,7 @@ public function all(array $params = []) public function listing($forceUpdate = false, array $params = []) { if (empty($this->users) || $forceUpdate) { - $this->all($params); + $this->list($params); } $ret = []; if (is_array($this->users) && isset($this->users['users'])) { diff --git a/src/Redmine/Api/Version.php b/src/Redmine/Api/Version.php index 3bd463ac..1cd2620f 100644 --- a/src/Redmine/Api/Version.php +++ b/src/Redmine/Api/Version.php @@ -73,7 +73,7 @@ public function all($project, array $params = []) public function listing($project, $forceUpdate = false, $reverse = true, array $params = []) { if (true === $forceUpdate || empty($this->versions)) { - $this->all($project, $params); + $this->listByProject($project, $params); } $ret = []; foreach ($this->versions['versions'] as $e) {