From fab4c42b8df6cda2c703e5dfc800c674a719f6ef Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 4 Jul 2024 13:19:21 +0200 Subject: [PATCH 1/3] Add behat tests for Role::list() --- tests/Behat/Bootstrap/RoleContextTrait.php | 16 +++++++++ tests/Behat/features/role.feature | 41 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/Behat/features/role.feature diff --git a/tests/Behat/Bootstrap/RoleContextTrait.php b/tests/Behat/Bootstrap/RoleContextTrait.php index 3980a6e5..bc052323 100644 --- a/tests/Behat/Bootstrap/RoleContextTrait.php +++ b/tests/Behat/Bootstrap/RoleContextTrait.php @@ -4,6 +4,8 @@ namespace Redmine\Tests\Behat\Bootstrap; +use Redmine\Api\Role; + trait RoleContextTrait { /** @@ -28,4 +30,18 @@ public function iHaveARoleWithTheName($name) ], ); } + + /** + * @When I list all roles + */ + public function iListAllRoles() + { + /** @var Role */ + $api = $this->getNativeCurlClient()->getApi('role'); + + $this->registerClientResponse( + $api->list(), + $api->getLastResponse(), + ); + } } diff --git a/tests/Behat/features/role.feature b/tests/Behat/features/role.feature new file mode 100644 index 00000000..c4632af0 --- /dev/null +++ b/tests/Behat/features/role.feature @@ -0,0 +1,41 @@ +@role +Feature: Interacting with the REST API for roles + In order to interact with REST API for roles + As a user + I want to make sure the Redmine server replies with the correct response + + Scenario: Listing of zero roles + Given I have a "NativeCurlClient" client + When I list all roles + Then the response has the status code "200" + And the response has the content type "application/json" + And the returned data has only the following properties + """ + roles + """ + And the returned data "roles" property is an array + And the returned data "roles" property contains "0" items + + Scenario: Listing of multiple roles + Given I have a "NativeCurlClient" client + And I have a role with the name "Reporter" + And I have a role with the name "Developer" + When I list all roles + Then the response has the status code "200" + And the response has the content type "application/json" + And the returned data has only the following properties + """ + roles + """ + And the returned data "roles" property is an array + And the returned data "roles" property contains "2" items + And the returned data "roles.0" property contains "2" items + And the returned data "roles.0" property contains the following data + | property | value | + | id | 3 | + | name | Reporter | + And the returned data "roles.1" property contains "2" items + And the returned data "roles.1" property contains the following data + | property | value | + | id | 4 | + | name | Developer | From 957ab4b65e07a3387adbfb454c7b10d2f110538c Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 4 Jul 2024 13:56:56 +0200 Subject: [PATCH 2/3] Add Role::listNames() --- CHANGELOG.md | 1 + src/Redmine/Api/Role.php | 25 +++++ tests/Behat/Bootstrap/RoleContextTrait.php | 14 +++ tests/Behat/features/role.feature | 14 +++ tests/Unit/Api/Role/ListNamesTest.php | 108 +++++++++++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 tests/Unit/Api/Role/ListNamesTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index eb26d5f1..c494661e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\Group::listNames()` for listing the ids and names of all groups. - New method `Redmine\Api\IssueCategory::listNamesByProject()` for listing the ids and names of all issue categories of a project. - New method `Redmine\Api\IssueStatus::listNames()` for listing the ids and names of all issue statuses. +- New method `Redmine\Api\Role::listNames()` for listing the ids and names of all roles. ### Deprecated diff --git a/src/Redmine/Api/Role.php b/src/Redmine/Api/Role.php index b70c1e53..c474673c 100644 --- a/src/Redmine/Api/Role.php +++ b/src/Redmine/Api/Role.php @@ -19,6 +19,8 @@ class Role extends AbstractApi { private $roles = []; + private $roleNames = null; + /** * List roles. * @@ -39,6 +41,29 @@ final public function list(array $params = []): array } } + /** + * Returns an array of all roles with id/name pairs. + * + * @return array list of roles (id => name) + */ + final public function listNames(): array + { + if ($this->roleNames !== null) { + return $this->roleNames; + } + + $this->roleNames = []; + $list = $this->list(); + + if (array_key_exists('roles', $list)) { + foreach ($list['roles'] as $role) { + $this->roleNames[(int) $role['id']] = $role['name']; + } + } + + return $this->roleNames; + } + /** * List roles. * diff --git a/tests/Behat/Bootstrap/RoleContextTrait.php b/tests/Behat/Bootstrap/RoleContextTrait.php index bc052323..c320dcbf 100644 --- a/tests/Behat/Bootstrap/RoleContextTrait.php +++ b/tests/Behat/Bootstrap/RoleContextTrait.php @@ -44,4 +44,18 @@ public function iListAllRoles() $api->getLastResponse(), ); } + + /** + * @When I list all role names + */ + public function iListAllRoleNames() + { + /** @var Role */ + $api = $this->getNativeCurlClient()->getApi('role'); + + $this->registerClientResponse( + $api->listNames(), + $api->getLastResponse(), + ); + } } diff --git a/tests/Behat/features/role.feature b/tests/Behat/features/role.feature index c4632af0..533f767f 100644 --- a/tests/Behat/features/role.feature +++ b/tests/Behat/features/role.feature @@ -39,3 +39,17 @@ Feature: Interacting with the REST API for roles | property | value | | id | 4 | | name | Developer | + + Scenario: Listing of multiple role names + Given I have a "NativeCurlClient" client + And I have a role with the name "Reporter" + And I have a role with the name "Developer" + When I list all role names + Then the response has the status code "200" + And the response has the content type "application/json" + And the returned data is an array + And the returned data contains "2" items + And the returned data contains the following data + | property | value | + | 3 | Reporter | + | 4 | Developer | diff --git a/tests/Unit/Api/Role/ListNamesTest.php b/tests/Unit/Api/Role/ListNamesTest.php new file mode 100644 index 00000000..769671c3 --- /dev/null +++ b/tests/Unit/Api/Role/ListNamesTest.php @@ -0,0 +1,108 @@ +assertSame($expectedResponse, $api->listNames()); + } + + public static function getListNamesData(): array + { + return [ + 'test without roles' => [ + '/roles.json', + 201, + << [ + '/roles.json', + 201, + << "Role 3", + 8 => "Role 2", + 9 => "Role 1", + ], + ], + ]; + } + + public function testListNamesCallsHttpClientOnlyOnce() + { + $client = AssertingHttpClient::create( + $this, + [ + 'GET', + '/roles.json', + 'application/json', + '', + 200, + 'application/json', + <<assertSame([1 => 'Role 1'], $api->listNames()); + $this->assertSame([1 => 'Role 1'], $api->listNames()); + $this->assertSame([1 => 'Role 1'], $api->listNames()); + } +} From 05bc96937c251761df23cef8a786d3e8368f55df Mon Sep 17 00:00:00 2001 From: Art4 Date: Thu, 4 Jul 2024 14:59:36 +0200 Subject: [PATCH 3/3] Deprecate Role::listing() --- CHANGELOG.md | 1 + src/Redmine/Api/Role.php | 5 +++++ tests/Unit/Api/RoleTest.php | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c494661e..2504213f 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 - `Redmine\Api\Group::listing()` is deprecated, use `\Redmine\Api\Group::listNames()` instead. - `Redmine\Api\IssueCategory::listing()` is deprecated, use `\Redmine\Api\IssueCategory::listNamesByProject()` instead. - `Redmine\Api\IssueStatus::listing()` is deprecated, use `\Redmine\Api\IssueStatus::listNamesByProject()` instead. +- `Redmine\Api\Role::listing()` is deprecated, use `\Redmine\Api\Role::listNamesByProject()` instead. ## [v2.6.0](https://github.com/kbsali/php-redmine-api/compare/v2.5.0...v2.6.0) - 2024-03-25 diff --git a/src/Redmine/Api/Role.php b/src/Redmine/Api/Role.php index c474673c..57ae428f 100644 --- a/src/Redmine/Api/Role.php +++ b/src/Redmine/Api/Role.php @@ -100,12 +100,17 @@ public function all(array $params = []) /** * Returns an array of roles with name/id pairs. * + * @deprecated v2.7.0 Use listNames() instead. + * @see Role::listNames() + * * @param bool $forceUpdate to force the update of the roles var * * @return array list of roles (id => name) */ public function listing($forceUpdate = false) { + @trigger_error('`' . __METHOD__ . '()` is deprecated since v2.7.0, use `' . __CLASS__ . '::listNames()` instead.', E_USER_DEPRECATED); + if (empty($this->roles) || $forceUpdate) { $this->roles = $this->list(); } diff --git a/tests/Unit/Api/RoleTest.php b/tests/Unit/Api/RoleTest.php index 53bebefc..208b3c5d 100644 --- a/tests/Unit/Api/RoleTest.php +++ b/tests/Unit/Api/RoleTest.php @@ -214,4 +214,36 @@ public function testListingCallsGetEveryTimeWithForceUpdate() $this->assertSame($expectedReturn, $api->listing(true)); $this->assertSame($expectedReturn, $api->listing(true)); } + + /** + * Test listing(). + */ + public function testListingTriggersDeprecationWarning() + { + $client = $this->createMock(Client::class); + $client->method('requestGet') + ->willReturn(true); + $client->method('getLastResponseBody') + ->willReturn('{"roles":[{"id":1,"name":"Role 1"},{"id":5,"name":"Role 5"}]}'); + $client->method('getLastResponseContentType') + ->willReturn('application/json'); + + $api = new Role($client); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\Role::listing()` is deprecated since v2.7.0, use `Redmine\Api\Role::listNames()` instead.', + $errstr, + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED, + ); + + $api->listing(); + } }