Skip to content

Commit 4034f38

Browse files
committed
feat: create IssuePriority::fromHttpClient()
1 parent 0ab0d20 commit 4034f38

File tree

5 files changed

+164
-68
lines changed

5 files changed

+164
-68
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- New method `Redmine\Api\Group::fromHttpClient()` for creating the class.
1515
- New method `Redmine\Api\Issue::fromHttpClient()` for creating the class.
1616
- New method `Redmine\Api\IssueCategory::fromHttpClient()` for creating the class.
17+
- New method `Redmine\Api\IssuePriority::fromHttpClient()` for creating the class.
1718
- Add support for PHP 8.5
1819
- Add support for Redmine 6.1.
1920

@@ -33,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3334
- Extending `Redmine\Api\Issue` is deprecated and will be set to final in future, create a wrapper class instead.
3435
- `Redmine\Api\IssueCategory::__construct()` is deprecated and will be set to private in future, use `\Redmine\Api\IssueCategory::fromHttpClient()` instead.
3536
- Extending `Redmine\Api\IssueCategory` is deprecated and will be set to final in future, create a wrapper class instead.
37+
- `Redmine\Api\IssuePriority::__construct()` is deprecated and will be set to private in future, use `\Redmine\Api\IssuePriority::fromHttpClient()` instead.
38+
- Extending `Redmine\Api\IssuePriority` is deprecated and will be set to final in future, create a wrapper class instead.
3639

3740
### Removed
3841

src/Redmine/Api/IssuePriority.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace Redmine\Api;
44

5+
use Redmine\Client\Client;
56
use Redmine\Exception;
67
use Redmine\Exception\SerializerException;
78
use Redmine\Exception\UnexpectedResponseException;
9+
use Redmine\Http\HttpClient;
810

911
/**
1012
* Listing issue priorities.
@@ -15,6 +17,37 @@
1517
*/
1618
class IssuePriority extends AbstractApi
1719
{
20+
final public static function fromHttpClient(HttpClient $httpClient): self
21+
{
22+
return new self($httpClient, true);
23+
}
24+
25+
/**
26+
* @deprecated v2.9.0 Use fromHttpClient() instead.
27+
* @see IssuePriority::fromHttpClient()
28+
*
29+
* @param Client|HttpClient $client
30+
*/
31+
public function __construct($client/*, bool $privatelyCalled = false*/)
32+
{
33+
$privatelyCalled = (func_num_args() > 1) ? func_get_arg(1) : false;
34+
35+
if ($privatelyCalled === true) {
36+
parent::__construct($client);
37+
38+
return;
39+
}
40+
41+
if (static::class !== self::class) {
42+
$className = (new \ReflectionClass($this))->isAnonymous() ? '' : ' in `' . static::class . '`';
43+
@trigger_error('Class `' . self::class . '` will declared as final in v3.0.0, stop extending it' . $className . '.', E_USER_DEPRECATED);
44+
} else {
45+
@trigger_error('Method `' . __METHOD__ . '()` is deprecated since v2.9.0 and will declared as private in v3.0.0, use `' . self::class . '::fromHttpClient()` instead.', E_USER_DEPRECATED);
46+
}
47+
48+
parent::__construct($client);
49+
}
50+
1851
/**
1952
* List issue priorities.
2053
*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Redmine\Tests\Unit\Api\IssuePriority;
4+
5+
use PHPUnit\Framework\Attributes\CoversClass;
6+
use PHPUnit\Framework\TestCase;
7+
use Redmine\Api\IssuePriority;
8+
use Redmine\Http\HttpClient;
9+
10+
#[CoversClass(IssuePriority::class)]
11+
class FromHttpClientTest extends TestCase
12+
{
13+
public function testReturnsCorrectObject(): void
14+
{
15+
$httpClient = $this->createStub(HttpClient::class);
16+
17+
$api = IssuePriority::fromHttpClient($httpClient);
18+
19+
$this->assertInstanceOf(IssuePriority::class, $api);
20+
}
21+
}

tests/Unit/Api/IssuePriority/ListTest.php

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Redmine\Api\IssuePriority;
88
use Redmine\Client\Client;
99
use Redmine\Exception\UnexpectedResponseException;
10+
use Redmine\Tests\Fixtures\AssertingHttpClient;
1011

1112
#[CoversClass(IssuePriority::class)]
1213
class ListTest extends TestCase
@@ -17,21 +18,21 @@ public function testListWithoutParametersReturnsResponse(): void
1718
$response = '["API Response"]';
1819
$expectedReturn = ['API Response'];
1920

20-
// Create the used mock objects
21-
$client = $this->createMock(Client::class);
22-
$client->expects($this->once())
23-
->method('requestGet')
24-
->with('/enumerations/issue_priorities.json')
25-
->willReturn(true);
26-
$client->expects($this->exactly(1))
27-
->method('getLastResponseBody')
28-
->willReturn($response);
29-
$client->expects($this->exactly(1))
30-
->method('getLastResponseContentType')
31-
->willReturn('application/json');
21+
$client = AssertingHttpClient::create(
22+
$this,
23+
[
24+
'GET',
25+
'/enumerations/issue_priorities.json',
26+
'application/json',
27+
'',
28+
200,
29+
'application/json',
30+
$response,
31+
],
32+
);
3233

3334
// Create the object under test
34-
$api = new IssuePriority($client);
35+
$api = IssuePriority::fromHttpClient($client);
3536

3637
// Perform the tests
3738
$this->assertSame($expectedReturn, $api->list());
@@ -44,43 +45,43 @@ public function testListWithParametersReturnsResponse(): void
4445
$response = '["API Response"]';
4546
$expectedReturn = ['API Response'];
4647

47-
// Create the used mock objects
48-
$client = $this->createMock(Client::class);
49-
$client->expects($this->once())
50-
->method('requestGet')
51-
->with('/enumerations/issue_priorities.json?limit=25&offset=0&0=not-used')
52-
->willReturn(true);
53-
$client->expects($this->exactly(1))
54-
->method('getLastResponseBody')
55-
->willReturn($response);
56-
$client->expects($this->exactly(1))
57-
->method('getLastResponseContentType')
58-
->willReturn('application/json');
48+
$client = AssertingHttpClient::create(
49+
$this,
50+
[
51+
'GET',
52+
'/enumerations/issue_priorities.json?limit=25&offset=0&0=not-used',
53+
'application/json',
54+
'',
55+
200,
56+
'application/json',
57+
$response,
58+
],
59+
);
5960

6061
// Create the object under test
61-
$api = new IssuePriority($client);
62+
$api = IssuePriority::fromHttpClient($client);
6263

6364
// Perform the tests
6465
$this->assertSame($expectedReturn, $api->list($allParameters));
6566
}
6667

6768
public function testListThrowsException(): void
6869
{
69-
// Create the used mock objects
70-
$client = $this->createMock(Client::class);
71-
$client->expects($this->exactly(1))
72-
->method('requestGet')
73-
->with('/enumerations/issue_priorities.json')
74-
->willReturn(true);
75-
$client->expects($this->exactly(1))
76-
->method('getLastResponseBody')
77-
->willReturn('');
78-
$client->expects($this->exactly(1))
79-
->method('getLastResponseContentType')
80-
->willReturn('application/json');
70+
$client = AssertingHttpClient::create(
71+
$this,
72+
[
73+
'GET',
74+
'/enumerations/issue_priorities.json',
75+
'application/json',
76+
'',
77+
200,
78+
'application/json',
79+
'',
80+
],
81+
);
8182

8283
// Create the object under test
83-
$api = new IssuePriority($client);
84+
$api = IssuePriority::fromHttpClient($client);
8485

8586
$this->expectException(UnexpectedResponseException::class);
8687
$this->expectExceptionMessage('The Redmine server replied with an unexpected response.');

tests/Unit/Api/IssuePriorityTest.php

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use PHPUnit\Framework\TestCase;
88
use Redmine\Api\IssuePriority;
99
use Redmine\Client\Client;
10+
use Redmine\Http\HttpClient;
11+
use Redmine\Tests\Fixtures\AssertingHttpClient;
1012
use Redmine\Tests\Fixtures\MockClient;
1113

1214
/**
@@ -15,12 +17,50 @@
1517
#[CoversClass(IssuePriority::class)]
1618
class IssuePriorityTest extends TestCase
1719
{
20+
public function testExtendingTheClassTriggersDeprecationWarning(): void
21+
{
22+
// PHPUnit 10 compatible way to test trigger_error().
23+
set_error_handler(
24+
function ($errno, $errstr): bool {
25+
$this->assertSame(
26+
'Class `Redmine\Api\IssuePriority` will declared as final in v3.0.0, stop extending it.',
27+
$errstr,
28+
);
29+
30+
restore_error_handler();
31+
return true;
32+
},
33+
E_USER_DEPRECATED,
34+
);
35+
36+
new class ($this->createStub(HttpClient::class)) extends IssuePriority {};
37+
}
38+
39+
public function testConstructorTriggersDeprecationWarning(): void
40+
{
41+
// PHPUnit 10 compatible way to test trigger_error().
42+
set_error_handler(
43+
function ($errno, $errstr): bool {
44+
$this->assertSame(
45+
'Method `Redmine\Api\IssuePriority::__construct()` is deprecated since v2.9.0 and will declared as private in v3.0.0, use `Redmine\Api\IssuePriority::fromHttpClient()` instead.',
46+
$errstr,
47+
);
48+
49+
restore_error_handler();
50+
return true;
51+
},
52+
E_USER_DEPRECATED,
53+
);
54+
55+
new IssuePriority($this->createStub(HttpClient::class));
56+
}
57+
1858
/**
1959
* Test all().
2060
*/
2161
public function testAllTriggersDeprecationWarning(): void
2262
{
23-
$api = new IssuePriority(MockClient::create());
63+
$api = IssuePriority::fromHttpClient($this->createStub(HttpClient::class));
2464

2565
// PHPUnit 10 compatible way to test trigger_error().
2666
set_error_handler(
@@ -47,21 +87,21 @@ function ($errno, $errstr): bool {
4787
#[DataProvider('getAllData')]
4888
public function testAllReturnsClientGetResponse(string $response, string $responseType, $expectedResponse): void
4989
{
50-
// Create the used mock objects
51-
$client = $this->createMock(Client::class);
52-
$client->expects($this->exactly(1))
53-
->method('requestGet')
54-
->with('/enumerations/issue_priorities.json')
55-
->willReturn(true);
56-
$client->expects($this->atLeast(1))
57-
->method('getLastResponseBody')
58-
->willReturn($response);
59-
$client->expects($this->exactly(1))
60-
->method('getLastResponseContentType')
61-
->willReturn($responseType);
90+
$client = AssertingHttpClient::create(
91+
$this,
92+
[
93+
'GET',
94+
'/enumerations/issue_priorities.json',
95+
'application/json',
96+
'',
97+
200,
98+
$responseType,
99+
$response,
100+
],
101+
);
62102

63103
// Create the object under test
64-
$api = new IssuePriority($client);
104+
$api = IssuePriority::fromHttpClient($client);
65105

66106
// Perform the tests
67107
$this->assertSame($expectedResponse, $api->all());
@@ -86,23 +126,21 @@ public function testAllReturnsClientGetResponseWithParameters(): void
86126
$response = '["API Response"]';
87127
$expectedReturn = ['API Response'];
88128

89-
// Create the used mock objects
90-
$client = $this->createMock(Client::class);
91-
$client->expects($this->once())
92-
->method('requestGet')
93-
->with(
94-
$this->stringContains('not-used'),
95-
)
96-
->willReturn(true);
97-
$client->expects($this->exactly(1))
98-
->method('getLastResponseBody')
99-
->willReturn($response);
100-
$client->expects($this->exactly(1))
101-
->method('getLastResponseContentType')
102-
->willReturn('application/json');
129+
$client = AssertingHttpClient::create(
130+
$this,
131+
[
132+
'GET',
133+
'/enumerations/issue_priorities.json?limit=25&offset=0&0=not-used',
134+
'application/json',
135+
'',
136+
200,
137+
'application/json',
138+
$response,
139+
],
140+
);
103141

104142
// Create the object under test
105-
$api = new IssuePriority($client);
143+
$api = IssuePriority::fromHttpClient($client);
106144

107145
// Perform the tests
108146
$this->assertSame($expectedReturn, $api->all($allParameters));

0 commit comments

Comments
 (0)