Skip to content

Commit b118039

Browse files
authored
Merge pull request #406 from Art4/add-issuecategory-listnamesbyproject
Add `IssueCategory::listNamesByProject()` method as replacement for `IssueCategory::listing()`
2 parents be7c256 + 92da0f0 commit b118039

File tree

14 files changed

+374
-94
lines changed

14 files changed

+374
-94
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- New method `Redmine\Api\Group::listNames()` for listing the ids and names of all groups.
13+
- New method `Redmine\Api\IssueCategory::listNamesByProject()` for listing the ids and names of all issue categories of a project.
1314

1415
### Deprecated
1516

1617
- `Redmine\Api\Group::listing()` is deprecated, use `\Redmine\Api\Group::listNames()` instead.
18+
- `Redmine\Api\IssueCategory::listing()` is deprecated, use `\Redmine\Api\IssueCategory::listNamesByProject()` instead.
1719

1820
## [v2.6.0](https://github.com/kbsali/php-redmine-api/compare/v2.5.0...v2.6.0) - 2024-03-25
1921

src/Redmine/Api/IssueCategory.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class IssueCategory extends AbstractApi
2424
{
2525
private $issueCategories = [];
2626

27+
private $issueCategoriesNames = [];
28+
2729
/**
2830
* List issue categories for a given project.
2931
*
@@ -53,6 +55,41 @@ final public function listByProject($projectIdentifier, array $params = []): arr
5355
}
5456
}
5557

58+
/**
59+
* Returns an array of all issue categories by a project with id/name pairs.
60+
*
61+
* @param string|int $projectIdentifier project id or literal identifier
62+
*
63+
* @throws InvalidParameterException if $projectIdentifier is not of type int or string
64+
*
65+
* @return array<int,string> list of issue category names (id => name)
66+
*/
67+
final public function listNamesByProject($projectIdentifier): array
68+
{
69+
if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) {
70+
throw new InvalidParameterException(sprintf(
71+
'%s(): Argument #1 ($projectIdentifier) must be of type int or string',
72+
__METHOD__,
73+
));
74+
}
75+
76+
if (array_key_exists($projectIdentifier, $this->issueCategoriesNames)) {
77+
return $this->issueCategoriesNames[$projectIdentifier];
78+
}
79+
80+
$this->issueCategoriesNames[$projectIdentifier] = [];
81+
82+
$list = $this->listByProject($projectIdentifier);
83+
84+
if (array_key_exists('issue_categories', $list)) {
85+
foreach ($list['issue_categories'] as $category) {
86+
$this->issueCategoriesNames[$projectIdentifier][(int) $category['id']] = $category['name'];
87+
}
88+
}
89+
90+
return $this->issueCategoriesNames[$projectIdentifier];
91+
}
92+
5693
/**
5794
* List issue categories.
5895
*
@@ -88,13 +125,18 @@ public function all($project, array $params = [])
88125
/**
89126
* Returns an array of categories with name/id pairs.
90127
*
128+
* @deprecated v2.7.0 Use listNamesByProject() instead.
129+
* @see IssueCategory::listNamesByProject()
130+
*
91131
* @param string|int $project project id or literal identifier
92132
* @param bool $forceUpdate to force the update of the projects var
93133
*
94134
* @return array list of projects (id => project name)
95135
*/
96136
public function listing($project, $forceUpdate = false)
97137
{
138+
@trigger_error('`' . __METHOD__ . '()` is deprecated since v2.7.0, use `' . __CLASS__ . '::listNamesByProject()` instead.', E_USER_DEPRECATED);
139+
98140
if (true === $forceUpdate || empty($this->issueCategories)) {
99141
$this->issueCategories = $this->listByProject($project);
100142
}

tests/Behat/Bootstrap/IssueCategoryContextTrait.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,34 @@ public function iCreateAnIssueCategoryForProjectIdentifierAndWithTheFollowingDat
2929
);
3030
}
3131

32+
/**
33+
* @When I list all issue categories for project identifier :identifier
34+
*/
35+
public function iListAllIssueCategoriesForProjectIdentifier($identifier)
36+
{
37+
/** @var IssueCategory */
38+
$api = $this->getNativeCurlClient()->getApi('issue_category');
39+
40+
$this->registerClientResponse(
41+
$api->listByProject($identifier),
42+
$api->getLastResponse(),
43+
);
44+
}
45+
46+
/**
47+
* @When I list all issue category names for project identifier :identifier
48+
*/
49+
public function iListAllIssueCategoryNamesForProjectIdentifier($identifier)
50+
{
51+
/** @var IssueCategory */
52+
$api = $this->getNativeCurlClient()->getApi('issue_category');
53+
54+
$this->registerClientResponse(
55+
$api->listNamesByProject($identifier),
56+
$api->getLastResponse(),
57+
);
58+
}
59+
3260
/**
3361
* @When I update the issue category with id :id and the following data
3462
*/

tests/Behat/features/groups.feature

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,23 @@ Feature: Interacting with the REST API for groups
5757

5858
Scenario: Listing names of all groups
5959
Given I have a "NativeCurlClient" client
60-
And I create a group with name "Test Group 1"
61-
And I create a group with name "Test Group 2"
62-
And I create a group with name "Test Group 3"
63-
And I create a group with name "Test Group 4"
64-
And I create a group with name "Test Group 5"
60+
And I create a group with name "Test Group D"
61+
And I create a group with name "Test Group E"
62+
And I create a group with name "Test Group C"
63+
And I create a group with name "Test Group B"
64+
And I create a group with name "Test Group A"
6565
When I list the names of all groups
6666
Then the response has the status code "200"
6767
And the response has the content type "application/json"
6868
And the returned data is an array
6969
And the returned data contains "5" items
7070
And the returned data contains the following data
7171
| property | value |
72-
| 4 | Test Group 1 |
73-
| 5 | Test Group 2 |
74-
| 6 | Test Group 3 |
75-
| 7 | Test Group 4 |
76-
| 8 | Test Group 5 |
72+
| 4 | Test Group D |
73+
| 5 | Test Group E |
74+
| 6 | Test Group C |
75+
| 7 | Test Group B |
76+
| 8 | Test Group A |
7777

7878
Scenario: Showing a specific group
7979
Given I have a "NativeCurlClient" client

tests/Behat/features/issue_category.feature

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,92 @@ Feature: Interacting with the REST API for issue categories
8282
| id | 1 |
8383
| name | Redmine Admin |
8484

85+
Scenario: Listing of zero issue categories
86+
Given I have a "NativeCurlClient" client
87+
And I create a project with name "Test Project" and identifier "test-project"
88+
When I list all issue categories for project identifier "test-project"
89+
Then the response has the status code "200"
90+
And the response has the content type "application/json"
91+
And the returned data has only the following properties
92+
"""
93+
issue_categories
94+
total_count
95+
"""
96+
And the returned data contains the following data
97+
| property | value |
98+
| issue_categories | [] |
99+
| total_count | 0 |
100+
101+
Scenario: Listing of multiple issue categories
102+
Given I have a "NativeCurlClient" client
103+
And I create a project with name "Test Project" and identifier "test-project"
104+
And I create an issue category for project identifier "test-project" and with the following data
105+
| property | value |
106+
| name | Category name B |
107+
And I create an issue category for project identifier "test-project" and with the following data
108+
| property | value |
109+
| name | Category name A |
110+
When I list all issue categories for project identifier "test-project"
111+
Then the response has the status code "200"
112+
And the response has the content type "application/json"
113+
And the returned data has only the following properties
114+
"""
115+
issue_categories
116+
total_count
117+
"""
118+
And the returned data contains the following data
119+
| property | value |
120+
| total_count | 2 |
121+
And the returned data "issue_categories" property is an array
122+
And the returned data "issue_categories" property contains "2" items
123+
And the returned data "issue_categories.0" property is an array
124+
And the returned data "issue_categories.0" property has only the following properties
125+
"""
126+
id
127+
project
128+
name
129+
"""
130+
And the returned data "issue_categories.0" property contains the following data
131+
| property | value |
132+
| id | 2 |
133+
| name | Category name A |
134+
And the returned data "issue_categories.0.project" property contains the following data
135+
| property | value |
136+
| id | 1 |
137+
| name | Test Project |
138+
And the returned data "issue_categories.1" property is an array
139+
And the returned data "issue_categories.1" property has only the following properties
140+
"""
141+
id
142+
project
143+
name
144+
"""
145+
And the returned data "issue_categories.1" property contains the following data
146+
| property | value |
147+
| id | 1 |
148+
| name | Category name B |
149+
And the returned data "issue_categories.1.project" property contains the following data
150+
| property | value |
151+
| id | 1 |
152+
| name | Test Project |
153+
154+
Scenario: Listing of multiple issue category names
155+
Given I have a "NativeCurlClient" client
156+
And I create a project with name "Test Project" and identifier "test-project"
157+
And I create an issue category for project identifier "test-project" and with the following data
158+
| property | value |
159+
| name | Category name B |
160+
And I create an issue category for project identifier "test-project" and with the following data
161+
| property | value |
162+
| name | Category name A |
163+
When I list all issue category names for project identifier "test-project"
164+
Then the response has the status code "200"
165+
And the response has the content type "application/json"
166+
And the returned data contains the following data
167+
| property | value |
168+
| 1 | Category name B |
169+
| 2 | Category name A |
170+
85171
Scenario: Updating an issue category with all data
86172
Given I have a "NativeCurlClient" client
87173
And I create a project with name "Test Project" and identifier "test-project"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Redmine\Tests\Fixtures;
6+
7+
use stdClass;
8+
9+
final class TestDataProvider
10+
{
11+
public static function getInvalidProjectIdentifiers(): array
12+
{
13+
return [
14+
'null' => [null],
15+
'true' => [true],
16+
'false' => [false],
17+
'float' => [0.0],
18+
'array' => [[]],
19+
'object' => [new stdClass()],
20+
];
21+
}
22+
}

tests/Unit/Api/Group/ListNamesTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,16 @@ public static function getListNamesData(): array
5858
<<<JSON
5959
{
6060
"groups": [
61-
{"id": 9, "name": "Group 1"},
61+
{"id": 7, "name": "Group 3"},
6262
{"id": 8, "name": "Group 2"},
63-
{"id": 7, "name": "Group 3"}
63+
{"id": 9, "name": "Group 1"}
6464
]
6565
}
6666
JSON,
6767
[
68-
9 => "Group 1",
69-
8 => "Group 2",
7068
7 => "Group 3",
69+
8 => "Group 2",
70+
9 => "Group 1",
7171
],
7272
],
7373
];

tests/Unit/Api/IssueCategory/ListByProjectTest.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
namespace Redmine\Tests\Unit\Api\IssueCategory;
44

55
use PHPUnit\Framework\Attributes\CoversClass;
6-
use PHPUnit\Framework\Attributes\DataProvider;
6+
use PHPUnit\Framework\Attributes\DataProviderExternal;
77
use PHPUnit\Framework\TestCase;
88
use Redmine\Api\IssueCategory;
99
use Redmine\Client\Client;
1010
use Redmine\Exception\InvalidParameterException;
1111
use Redmine\Exception\UnexpectedResponseException;
1212
use Redmine\Tests\Fixtures\MockClient;
13-
use stdClass;
13+
use Redmine\Tests\Fixtures\TestDataProvider;
1414

1515
#[CoversClass(IssueCategory::class)]
1616
class ListByProjectTest extends TestCase
@@ -71,9 +71,9 @@ public function testListByProjectWithParametersReturnsResponse()
7171
}
7272

7373
/**
74-
* @dataProvider getInvalidProjectIdentifiers
74+
* @dataProvider Redmine\Tests\Fixtures\TestDataProvider::getInvalidProjectIdentifiers
7575
*/
76-
#[DataProvider('getInvalidProjectIdentifiers')]
76+
#[DataProviderExternal(TestDataProvider::class, 'getInvalidProjectIdentifiers')]
7777
public function testListByProjectWithWrongProjectIdentifierThrowsException($projectIdentifier)
7878
{
7979
$api = new IssueCategory(MockClient::create());
@@ -84,18 +84,6 @@ public function testListByProjectWithWrongProjectIdentifierThrowsException($proj
8484
$api->listByProject($projectIdentifier);
8585
}
8686

87-
public static function getInvalidProjectIdentifiers(): array
88-
{
89-
return [
90-
'null' => [null],
91-
'true' => [true],
92-
'false' => [false],
93-
'float' => [0.0],
94-
'array' => [[]],
95-
'object' => [new stdClass()],
96-
];
97-
}
98-
9987
public function testListByProjectThrowsException()
10088
{
10189
// Create the used mock objects

0 commit comments

Comments
 (0)