Skip to content

Commit dfa6b49

Browse files
authored
Merge pull request #416 from Art4/add-tracker-listnames
Add `Tracker::listNames()` method as replacement for `Tracker::listing()`
2 parents ecf0012 + 4a00fb9 commit dfa6b49

File tree

6 files changed

+296
-0
lines changed

6 files changed

+296
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- New method `Redmine\Api\Project::listNames()` for listing the ids and names of all projects.
1717
- New method `Redmine\Api\Role::listNames()` for listing the ids and names of all roles.
1818
- New method `Redmine\Api\TimeEntryActivity::listNames()` for listing the ids and names of all time entry activities.
19+
- New method `Redmine\Api\Tracker::listNames()` for listing the ids and names of all trackers.
1920

2021
### Deprecated
2122

@@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2627
- `Redmine\Api\Project::listing()` is deprecated, use `\Redmine\Api\Project::listNames()` instead.
2728
- `Redmine\Api\Role::listing()` is deprecated, use `\Redmine\Api\Role::listNames()` instead.
2829
- `Redmine\Api\TimeEntryActivity::listing()` is deprecated, use `\Redmine\Api\TimeEntryActivity::listNames()` instead.
30+
- `Redmine\Api\Tracker::listing()` is deprecated, use `\Redmine\Api\Tracker::listNames()` instead.
2931

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

src/Redmine/Api/Tracker.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class Tracker extends AbstractApi
1717
{
1818
private $trackers = [];
1919

20+
private $trackerNames = null;
21+
2022
/**
2123
* List trackers.
2224
*
@@ -37,6 +39,29 @@ final public function list(array $params = []): array
3739
}
3840
}
3941

42+
/**
43+
* Returns an array of all trackers with id/name pairs.
44+
*
45+
* @return array<int,string> list of trackers (id => name)
46+
*/
47+
final public function listNames(): array
48+
{
49+
if ($this->trackerNames !== null) {
50+
return $this->trackerNames;
51+
}
52+
53+
$this->trackerNames = [];
54+
$list = $this->list();
55+
56+
if (array_key_exists('trackers', $list)) {
57+
foreach ($list['trackers'] as $role) {
58+
$this->trackerNames[(int) $role['id']] = $role['name'];
59+
}
60+
}
61+
62+
return $this->trackerNames;
63+
}
64+
4065
/**
4166
* List trackers.
4267
*
@@ -73,12 +98,17 @@ public function all(array $params = [])
7398
/**
7499
* Returns an array of trackers with name/id pairs.
75100
*
101+
* @deprecated v2.7.0 Use listNames() instead.
102+
* @see Tracker::listNames()
103+
*
76104
* @param bool $forceUpdate to force the update of the trackers var
77105
*
78106
* @return array list of trackers (id => name)
79107
*/
80108
public function listing($forceUpdate = false)
81109
{
110+
@trigger_error('`' . __METHOD__ . '()` is deprecated since v2.7.0, use `' . __CLASS__ . '::listNames()` instead.', E_USER_DEPRECATED);
111+
82112
if (empty($this->trackers) || $forceUpdate) {
83113
$this->trackers = $this->list();
84114
}

tests/Behat/Bootstrap/TrackerContextTrait.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Redmine\Tests\Behat\Bootstrap;
66

7+
use Redmine\Api\Tracker;
8+
79
trait TrackerContextTrait
810
{
911
/**
@@ -24,4 +26,32 @@ public function iHaveATrackerWithTheNameAndDefaultStatusId(string $trackerName,
2426
],
2527
);
2628
}
29+
30+
/**
31+
* @When I list all trackers
32+
*/
33+
public function iListAllTrackers()
34+
{
35+
/** @var Tracker */
36+
$api = $this->getNativeCurlClient()->getApi('tracker');
37+
38+
$this->registerClientResponse(
39+
$api->list(),
40+
$api->getLastResponse(),
41+
);
42+
}
43+
44+
/**
45+
* @When I list all tracker names
46+
*/
47+
public function iListAllTrackerNames()
48+
{
49+
/** @var Tracker */
50+
$api = $this->getNativeCurlClient()->getApi('tracker');
51+
52+
$this->registerClientResponse(
53+
$api->listNames(),
54+
$api->getLastResponse(),
55+
);
56+
}
2757
}

tests/Behat/features/tracker.feature

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
@tracker
2+
Feature: Interacting with the REST API for trackers
3+
In order to interact with REST API for trackers
4+
As a user
5+
I want to make sure the Redmine server replies with the correct response
6+
7+
Scenario: Listing of zero trackers
8+
Given I have a "NativeCurlClient" client
9+
When I list all trackers
10+
Then the response has the status code "200"
11+
And the response has the content type "application/json"
12+
And the returned data has only the following properties
13+
"""
14+
trackers
15+
"""
16+
And the returned data "trackers" property is an array
17+
And the returned data "trackers" property contains "0" items
18+
19+
Scenario: Listing of multiple trackers
20+
Given I have a "NativeCurlClient" client
21+
And I have an issue status with the name "New"
22+
And I have a tracker with the name "Feature" and default status id "1"
23+
And I have a tracker with the name "Defect" and default status id "1"
24+
When I list all trackers
25+
Then the response has the status code "200"
26+
And the response has the content type "application/json"
27+
And the returned data has only the following properties
28+
"""
29+
trackers
30+
"""
31+
And the returned data "trackers" property is an array
32+
And the returned data "trackers" property contains "2" items
33+
And the returned data "trackers.0" property is an array
34+
And the returned data "trackers.0" property has only the following properties with Redmine version ">= 5.0.0"
35+
"""
36+
id
37+
name
38+
default_status
39+
description
40+
enabled_standard_fields
41+
"""
42+
But the returned data "trackers.0" property has only the following properties with Redmine version "< 5.0.0"
43+
"""
44+
id
45+
name
46+
default_status
47+
description
48+
"""
49+
And the returned data "trackers.0" property contains the following data
50+
| property | value |
51+
| id | 1 |
52+
| name | Feature |
53+
| description | null |
54+
And the returned data "trackers.0.default_status" property contains the following data
55+
| property | value |
56+
| id | 1 |
57+
| name | New |
58+
And the returned data "trackers.0.enabled_standard_fields" property contains the following data with Redmine version ">= 5.1.0"
59+
| property | value |
60+
| 0 | assigned_to_id |
61+
| 1 | category_id |
62+
| 2 | fixed_version_id |
63+
| 3 | parent_issue_id |
64+
| 4 | start_date |
65+
| 5 | due_date |
66+
| 6 | estimated_hours |
67+
| 7 | done_ratio |
68+
| 8 | description |
69+
| 9 | priority_id |
70+
But the returned data "trackers.0.enabled_standard_fields" property contains the following data with Redmine version ">= 5.0.0"
71+
| property | value |
72+
| 0 | assigned_to_id |
73+
| 1 | category_id |
74+
| 2 | fixed_version_id |
75+
| 3 | parent_issue_id |
76+
| 4 | start_date |
77+
| 5 | due_date |
78+
| 6 | estimated_hours |
79+
| 7 | done_ratio |
80+
| 8 | description |
81+
82+
Scenario: Listing of multiple tracker names
83+
Given I have a "NativeCurlClient" client
84+
And I have an issue status with the name "New"
85+
And I have a tracker with the name "Feature" and default status id "1"
86+
And I have a tracker with the name "Defect" and default status id "1"
87+
When I list all tracker names
88+
Then the response has the status code "200"
89+
And the response has the content type "application/json"
90+
And the returned data contains "2" items
91+
And the returned data contains the following data
92+
| property | value |
93+
| 1 | Feature |
94+
| 2 | Defect |
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Redmine\Tests\Unit\Api\Tracker;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use PHPUnit\Framework\TestCase;
10+
use Redmine\Api\Tracker;
11+
use Redmine\Tests\Fixtures\AssertingHttpClient;
12+
13+
#[CoversClass(Tracker::class)]
14+
class ListNamesTest extends TestCase
15+
{
16+
/**
17+
* @dataProvider getListNamesData
18+
*/
19+
#[DataProvider('getListNamesData')]
20+
public function testListNamesReturnsCorrectResponse($expectedPath, $responseCode, $response, $expectedResponse)
21+
{
22+
$client = AssertingHttpClient::create(
23+
$this,
24+
[
25+
'GET',
26+
$expectedPath,
27+
'application/json',
28+
'',
29+
$responseCode,
30+
'application/json',
31+
$response,
32+
],
33+
);
34+
35+
// Create the object under test
36+
$api = new Tracker($client);
37+
38+
// Perform the tests
39+
$this->assertSame($expectedResponse, $api->listNames());
40+
}
41+
42+
public static function getListNamesData(): array
43+
{
44+
return [
45+
'test without trackers' => [
46+
'/trackers.json',
47+
201,
48+
<<<JSON
49+
{
50+
"trackers": []
51+
}
52+
JSON,
53+
[],
54+
],
55+
'test with multiple trackers' => [
56+
'/trackers.json',
57+
201,
58+
<<<JSON
59+
{
60+
"trackers": [
61+
{"id": 7, "name": "Tracker 3"},
62+
{"id": 8, "name": "Tracker 2"},
63+
{"id": 9, "name": "Tracker 1"}
64+
]
65+
}
66+
JSON,
67+
[
68+
7 => "Tracker 3",
69+
8 => "Tracker 2",
70+
9 => "Tracker 1",
71+
],
72+
],
73+
];
74+
}
75+
76+
public function testListNamesCallsHttpClientOnlyOnce()
77+
{
78+
$client = AssertingHttpClient::create(
79+
$this,
80+
[
81+
'GET',
82+
'/trackers.json',
83+
'application/json',
84+
'',
85+
200,
86+
'application/json',
87+
<<<JSON
88+
{
89+
"trackers": [
90+
{
91+
"id": 1,
92+
"name": "Tracker 1"
93+
}
94+
]
95+
}
96+
JSON,
97+
],
98+
);
99+
100+
// Create the object under test
101+
$api = new Tracker($client);
102+
103+
// Perform the tests
104+
$this->assertSame([1 => 'Tracker 1'], $api->listNames());
105+
$this->assertSame([1 => 'Tracker 1'], $api->listNames());
106+
$this->assertSame([1 => 'Tracker 1'], $api->listNames());
107+
}
108+
}

tests/Unit/Api/TrackerTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,38 @@ public function testListingCallsGetEveryTimeWithForceUpdate()
215215
$this->assertSame($expectedReturn, $api->listing(true));
216216
}
217217

218+
/**
219+
* Test listing().
220+
*/
221+
public function testListingTriggersDeprecationWarning()
222+
{
223+
$client = $this->createMock(Client::class);
224+
$client->method('requestGet')
225+
->willReturn(true);
226+
$client->method('getLastResponseBody')
227+
->willReturn('{"trackers":[{"id":1,"name":"Tracker 1"},{"id":5,"name":"Tracker 5"}]}');
228+
$client->method('getLastResponseContentType')
229+
->willReturn('application/json');
230+
231+
$api = new Tracker($client);
232+
233+
// PHPUnit 10 compatible way to test trigger_error().
234+
set_error_handler(
235+
function ($errno, $errstr): bool {
236+
$this->assertSame(
237+
'`Redmine\Api\Tracker::listing()` is deprecated since v2.7.0, use `Redmine\Api\Tracker::listNames()` instead.',
238+
$errstr,
239+
);
240+
241+
restore_error_handler();
242+
return true;
243+
},
244+
E_USER_DEPRECATED,
245+
);
246+
247+
$api->listing();
248+
}
249+
218250
/**
219251
* Test getIdByName().
220252
*/

0 commit comments

Comments
 (0)