Skip to content

Commit 214ecfc

Browse files
committed
Improve tests for Membership::create() and update()
1 parent 82821ed commit 214ecfc

File tree

11 files changed

+274
-115
lines changed

11 files changed

+274
-115
lines changed

docs/usage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,8 @@ $client->getApi('group')->update($groupId, [
518518
// Project memberships
519519
$client->getApi('membership')->listByProject($projectId);
520520
$client->getApi('membership')->create($projectId, [
521-
'user_id' => null,
522-
'role_ids' => [],
521+
'user_id' => 1,
522+
'role_ids' => [5],
523523
]);
524524
$client->getApi('membership')->remove($membershipId);
525525

src/Redmine/Api/Membership.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public function update($id, array $params = [])
144144
$params = $this->sanitizeParams($defaults, $params);
145145

146146
if (!isset($params['role_ids'])) {
147-
throw new MissingParameterException('Missing mandatory parameters');
147+
throw new MissingParameterException('Theses parameters are mandatory: `role_ids`');
148148
}
149149

150150
return $this->put(

tests/Behat/Bootstrap/FeatureContext.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ final class FeatureContext extends TestCase implements Context
2929
use IssuePriorityContextTrait;
3030
use IssueRelationContextTrait;
3131
use IssueStatusContextTrait;
32+
use MembershipContextTrait;
3233
use ProjectContextTrait;
34+
use RoleContextTrait;
3335
use TimeEntryActivityContextTrait;
3436
use TimeEntryContextTrait;
3537
use TrackerContextTrait;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Redmine\Tests\Behat\Bootstrap;
6+
7+
use Behat\Gherkin\Node\TableNode;
8+
use Redmine\Api\Membership;
9+
10+
trait MembershipContextTrait
11+
{
12+
/**
13+
* @When I create a membership to project with identifier :identifier and the following data
14+
*/
15+
public function iCreateAMembershipToProjectWithIdentifierAndTheFollowingData($identifier, TableNode $table)
16+
{
17+
$data = [];
18+
19+
foreach ($table as $row) {
20+
$data[$row['property']] = $row['value'];
21+
}
22+
23+
if (array_key_exists('role_ids', $data)) {
24+
$data['role_ids'] = json_decode($data['role_ids'], true);
25+
}
26+
27+
/** @var Membership */
28+
$api = $this->getNativeCurlClient()->getApi('membership');
29+
30+
$this->registerClientResponse(
31+
$api->create($identifier, $data),
32+
$api->getLastResponse()
33+
);
34+
}
35+
36+
/**
37+
* @When I update the membership with id :id and the following data
38+
*/
39+
public function iUpdateTheMembershipWithIdAndTheFollowingData($id, TableNode $table)
40+
{
41+
$data = [];
42+
43+
foreach ($table as $row) {
44+
$data[$row['property']] = $row['value'];
45+
}
46+
47+
if (array_key_exists('role_ids', $data)) {
48+
$data['role_ids'] = json_decode($data['role_ids'], true);
49+
}
50+
51+
/** @var Membership */
52+
$api = $this->getNativeCurlClient()->getApi('membership');
53+
54+
$this->registerClientResponse(
55+
$api->update($id, $data),
56+
$api->getLastResponse()
57+
);
58+
}
59+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Redmine\Tests\Behat\Bootstrap;
6+
7+
trait RoleContextTrait
8+
{
9+
/**
10+
* @Given I have a role with the name :name
11+
*/
12+
public function iHaveARoleWithTheName($name)
13+
{
14+
// support for creating issue status via REST API is missing
15+
$this->redmine->excecuteDatabaseQuery(
16+
'INSERT INTO roles(name, position, assignable, builtin, issues_visibility, users_visibility, time_entries_visibility, all_roles_managed, settings) VALUES(:name, :position, :assignable, :builtin, :issues_visibility, :users_visibility, :time_entries_visibility, :all_roles_managed, :settings);',
17+
[],
18+
[
19+
':name' => $name,
20+
':position' => 1,
21+
':assignable' => 0,
22+
':builtin' => 0,
23+
':issues_visibility' => 'default',
24+
':users_visibility' => 'all',
25+
':time_entries_visibility' => 'all',
26+
':all_roles_managed' => 1,
27+
':settings' => '',
28+
],
29+
);
30+
}
31+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Feature: Interacting with the REST API for memberships
2+
In order to interact with REST API for memberships
3+
As a user
4+
I want to make sure the Redmine server replies with the correct response
5+
6+
@membership
7+
Scenario: Creating a membership
8+
Given I have a "NativeCurlClient" client
9+
And I have a role with the name "Developer"
10+
And I create a project with name "Test Project" and identifier "test-project"
11+
When I create a membership to project with identifier "test-project" and the following data
12+
| property | value |
13+
| user_id | 1 |
14+
| role_ids | [3] |
15+
Then the response has the status code "201"
16+
And the response has the content type "application/xml"
17+
And the returned data is an instance of "SimpleXMLElement"
18+
19+
@membership
20+
Scenario: Updating a membership
21+
Given I have a "NativeCurlClient" client
22+
And I have a role with the name "Developer"
23+
And I create a project with name "Test Project" and identifier "test-project"
24+
And I create a membership to project with identifier "test-project" and the following data
25+
| property | value |
26+
| user_id | 1 |
27+
| role_ids | [3] |
28+
When I update the membership with id "1" and the following data
29+
| property | value |
30+
| user_id | 1 |
31+
| role_ids | [3] |
32+
Then the response has the status code "204"
33+
And the response has an empty content type
34+
And the response has the content ""
35+
And the returned data is exactly ""

tests/Integration/MembershipXmlTest.php

Lines changed: 0 additions & 34 deletions
This file was deleted.

tests/Integration/UrlTest.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,6 @@ public function testMembership()
157157
/** @var \Redmine\Api\Membership */
158158
$api = MockClient::create()->getApi('membership');
159159

160-
$res = $api->update(1, [
161-
'user_id' => 1,
162-
'role_ids' => [1],
163-
]);
164-
$res = json_decode($res, true);
165-
166-
$this->assertEquals('/memberships/1.xml', $res['path']);
167-
$this->assertEquals('PUT', $res['method']);
168-
169160
$res = $api->all('testProject');
170161

171162
$this->assertEquals('/projects/testProject/memberships.json', $res['path']);

tests/Unit/Api/Membership/CreateTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ public function testCreateReturnsCorrectResponse($identifier, $parameters, $expe
4545
public static function getCreateData(): array
4646
{
4747
return [
48-
'test with on role_id' => [
48+
'test with one role_id' => [
4949
5,
50-
['user_id' => 4, 'role_ids' => 2],
50+
['user_id' => 4, 'role_ids' => [2]],
5151
'/projects/5/memberships.xml',
52-
'<?xml version="1.0" encoding="UTF-8"?><membership><user_id>4</user_id><role_ids>2</role_ids></membership>',
52+
'<?xml version="1.0" encoding="UTF-8"?><membership><user_id>4</user_id><role_ids type="array"><role_id>2</role_id></role_ids></membership>',
5353
201,
5454
'<?xml version="1.0" encoding="UTF-8"?><membership></membership>',
5555
],
@@ -134,7 +134,7 @@ public static function incompleteCreateParameterProvider(): array
134134
],
135135
'missing `user_id` parameter' => [
136136
[
137-
'role_ids' => 2,
137+
'role_ids' => [2],
138138
],
139139
],
140140
'missing `role_ids` parameter' => [
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
3+
namespace Redmine\Tests\Unit\Api\Membership;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Redmine\Api\Membership;
7+
use Redmine\Exception\MissingParameterException;
8+
use Redmine\Http\HttpClient;
9+
use Redmine\Tests\Fixtures\AssertingHttpClient;
10+
use SimpleXMLElement;
11+
12+
/**
13+
* @covers \Redmine\Api\Membership::update
14+
*/
15+
class UpdateTest extends TestCase
16+
{
17+
/**
18+
* @dataProvider getUpdateData
19+
*/
20+
public function testUpdateReturnsCorrectResponse($id, $parameters, $expectedPath, $expectedBody, $responseCode, $response)
21+
{
22+
$client = AssertingHttpClient::create(
23+
$this,
24+
[
25+
'PUT',
26+
$expectedPath,
27+
'application/xml',
28+
$expectedBody,
29+
$responseCode,
30+
'',
31+
$response
32+
]
33+
);
34+
35+
// Create the object under test
36+
$api = new Membership($client);
37+
38+
// Perform the tests
39+
$this->assertSame('', $api->update($id, $parameters));
40+
}
41+
42+
public static function getUpdateData(): array
43+
{
44+
return [
45+
'test with one role_id' => [
46+
5,
47+
['user_id' => 4, 'role_ids' => [2]],
48+
'/memberships/5.xml',
49+
'<?xml version="1.0" encoding="UTF-8"?><membership><role_ids type="array"><role_id>2</role_id></role_ids><user_id>4</user_id>
50+
</membership>',
51+
204,
52+
'',
53+
],
54+
'test with multiple role_ids' => [
55+
5,
56+
['user_id' => 4, 'role_ids' => [5, 6]],
57+
'/memberships/5.xml',
58+
'<?xml version="1.0" encoding="UTF-8"?><membership><role_ids type="array"><role_id>5</role_id><role_id>6</role_id></role_ids><user_id>4</user_id></membership>',
59+
204,
60+
'',
61+
],
62+
];
63+
}
64+
65+
public function testUpdateReturnsEmptyString()
66+
{
67+
$client = AssertingHttpClient::create(
68+
$this,
69+
[
70+
'PUT',
71+
'/memberships/5.xml',
72+
'application/xml',
73+
'<?xml version="1.0" encoding="UTF-8"?><membership><role_ids>2</role_ids><user_id>4</user_id></membership>',
74+
500,
75+
'',
76+
''
77+
]
78+
);
79+
80+
// Create the object under test
81+
$api = new Membership($client);
82+
83+
// Perform the tests
84+
$return = $api->update(5, ['user_id' => 4, 'role_ids' => 2]);
85+
86+
$this->assertSame('', $return);
87+
}
88+
89+
public function testUpdateThrowsExceptionWithEmptyParameters()
90+
{
91+
// Create the used mock objects
92+
$client = $this->createMock(HttpClient::class);
93+
94+
// Create the object under test
95+
$api = new Membership($client);
96+
97+
$this->expectException(MissingParameterException::class);
98+
$this->expectExceptionMessage('Theses parameters are mandatory: `role_ids`');
99+
100+
// Perform the tests
101+
$api->update(5);
102+
}
103+
104+
/**
105+
* @dataProvider incompleteUpdateParameterProvider
106+
*/
107+
public function testUpdateThrowsExceptionIfMandatoyParametersAreMissing($parameters)
108+
{
109+
// Create the used mock objects
110+
$client = $this->createMock(HttpClient::class);
111+
112+
// Create the object under test
113+
$api = new Membership($client);
114+
115+
$this->expectException(MissingParameterException::class);
116+
$this->expectExceptionMessage('Theses parameters are mandatory: `role_ids`');
117+
118+
// Perform the tests
119+
$api->update(5, $parameters);
120+
}
121+
122+
/**
123+
* Provider for incomplete create parameters.
124+
*
125+
* @return array[]
126+
*/
127+
public static function incompleteUpdateParameterProvider(): array
128+
{
129+
return [
130+
'missing all mandatory parameters' => [
131+
[],
132+
],
133+
'missing `role_ids` parameter' => [
134+
[
135+
'user_id' => 4,
136+
],
137+
],
138+
];
139+
}
140+
}

0 commit comments

Comments
 (0)