Skip to content

Commit 9938aab

Browse files
committed
feat: create Role::fromHttpClient() and use it in tests
1 parent 96a3247 commit 9938aab

File tree

6 files changed

+230
-131
lines changed

6 files changed

+230
-131
lines changed

src/Redmine/Api/Role.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
use Redmine\Http\HttpFactory;
911
use Redmine\Serializer\JsonSerializer;
1012

@@ -17,6 +19,11 @@
1719
*/
1820
class Role extends AbstractApi
1921
{
22+
final public static function fromHttpClient(HttpClient $httpClient): self
23+
{
24+
return new self($httpClient, true);
25+
}
26+
2027
/**
2128
* @var null|array<mixed>
2229
*/
@@ -27,6 +34,32 @@ class Role extends AbstractApi
2734
*/
2835
private ?array $roleNames = null;
2936

37+
/**
38+
* @deprecated v2.9.0 Use fromHttpClient() instead.
39+
* @see Role::fromHttpClient()
40+
*
41+
* @param Client|HttpClient $client
42+
*/
43+
public function __construct($client/*, bool $privatelyCalled = false*/)
44+
{
45+
$privatelyCalled = (func_num_args() > 1) ? func_get_arg(1) : false;
46+
47+
if ($privatelyCalled === true) {
48+
parent::__construct($client);
49+
50+
return;
51+
}
52+
53+
if (static::class !== self::class) {
54+
$className = (new \ReflectionClass($this))->isAnonymous() ? '' : ' in `' . static::class . '`';
55+
@trigger_error('Class `' . self::class . '` will declared as final in v3.0.0, stop extending it' . $className . '.', E_USER_DEPRECATED);
56+
} else {
57+
@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);
58+
}
59+
60+
parent::__construct($client);
61+
}
62+
3063
/**
3164
* List roles.
3265
*
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\Role;
4+
5+
use PHPUnit\Framework\Attributes\CoversClass;
6+
use PHPUnit\Framework\TestCase;
7+
use Redmine\Api\Role;
8+
use Redmine\Http\HttpClient;
9+
10+
#[CoversClass(Role::class)]
11+
class FromHttpClientTest extends TestCase
12+
{
13+
public function testReturnsCorrectObject(): void
14+
{
15+
$httpClient = $this->createStub(HttpClient::class);
16+
17+
$api = Role::fromHttpClient($httpClient);
18+
19+
$this->assertInstanceOf(Role::class, $api);
20+
}
21+
}

tests/Unit/Api/Role/ListNamesTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function testListNamesReturnsCorrectResponse(string $expectedPath, int $r
3333
);
3434

3535
// Create the object under test
36-
$api = new Role($client);
36+
$api = Role::fromHttpClient($client);
3737

3838
// Perform the tests
3939
$this->assertSame($expectedResponse, $api->listNames());
@@ -98,7 +98,7 @@ public function testListNamesCallsHttpClientOnlyOnce(): void
9898
);
9999

100100
// Create the object under test
101-
$api = new Role($client);
101+
$api = Role::fromHttpClient($client);
102102

103103
// Perform the tests
104104
$this->assertSame([1 => 'Role 1'], $api->listNames());

tests/Unit/Api/Role/ListTest.php

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use PHPUnit\Framework\Attributes\CoversClass;
66
use PHPUnit\Framework\TestCase;
77
use Redmine\Api\Role;
8-
use Redmine\Client\Client;
98
use Redmine\Exception\UnexpectedResponseException;
9+
use Redmine\Tests\Fixtures\AssertingHttpClient;
1010

1111
#[CoversClass(Role::class)]
1212
class ListTest extends TestCase
@@ -17,21 +17,21 @@ public function testListWithoutParametersReturnsResponse(): void
1717
$response = '["API Response"]';
1818
$expectedReturn = ['API Response'];
1919

20-
// Create the used mock objects
21-
$client = $this->createMock(Client::class);
22-
$client->expects($this->once())
23-
->method('requestGet')
24-
->with('/roles.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');
20+
$client = AssertingHttpClient::create(
21+
$this,
22+
[
23+
'GET',
24+
'/roles.json',
25+
'application/json',
26+
'',
27+
200,
28+
'application/json',
29+
$response,
30+
],
31+
);
3232

3333
// Create the object under test
34-
$api = new Role($client);
34+
$api = Role::fromHttpClient($client);
3535

3636
// Perform the tests
3737
$this->assertSame($expectedReturn, $api->list());
@@ -44,43 +44,45 @@ public function testListWithParametersReturnsResponse(): void
4444
$response = '["API Response"]';
4545
$expectedReturn = ['API Response'];
4646

47-
// Create the used mock objects
48-
$client = $this->createMock(Client::class);
49-
$client->expects($this->once())
50-
->method('requestGet')
51-
->with('/roles.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');
47+
$client = AssertingHttpClient::create(
48+
$this,
49+
[
50+
'GET',
51+
'/roles.json?limit=25&offset=0&0=not-used',
52+
'application/json',
53+
'',
54+
200,
55+
'application/json',
56+
$response,
57+
],
58+
);
5959

6060
// Create the object under test
61-
$api = new Role($client);
61+
$api = Role::fromHttpClient($client);
6262

6363
// Perform the tests
6464
$this->assertSame($expectedReturn, $api->list($parameters));
6565
}
6666

6767
public function testListThrowsException(): void
6868
{
69-
// Create the used mock objects
70-
$client = $this->createMock(Client::class);
71-
$client->expects($this->exactly(1))
72-
->method('requestGet')
73-
->with('/roles.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');
69+
$response = '';
70+
71+
$client = AssertingHttpClient::create(
72+
$this,
73+
[
74+
'GET',
75+
'/roles.json',
76+
'application/json',
77+
'',
78+
200,
79+
'application/json',
80+
$response,
81+
],
82+
);
8183

8284
// Create the object under test
83-
$api = new Role($client);
85+
$api = Role::fromHttpClient($client);
8486

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

tests/Unit/Api/Role/ShowTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function testShowReturnsCorrectResponse($id, string $expectedPath, string
3131
);
3232

3333
// Create the object under test
34-
$api = new Role($client);
34+
$api = Role::fromHttpClient($client);
3535

3636
// Perform the tests
3737
$this->assertSame($expectedReturn, $api->show($id));

0 commit comments

Comments
 (0)