Skip to content

Commit

Permalink
Add Membership::list() method, deprecate all() method
Browse files Browse the repository at this point in the history
  • Loading branch information
Art4 committed Oct 9, 2023
1 parent bf61171 commit 0110640
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- New method `Redmine\Api\IssuePriority::list()` to list issue priorities.
- New method `Redmine\Api\IssueRelation::list()` to list issue relations.
- New method `Redmine\Api\IssueStatus::list()` to list issue statuses.
- New method `Redmine\Api\Membership::list()` to list memberships.

### Deprecated

Expand All @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Redmine\Api\IssuePriority::all()` is deprecated, use `Redmine\Api\IssuePriority::list()` instead
- `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::list()` instead
- `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead
- `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::list()` instead

## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09

Expand Down
35 changes: 32 additions & 3 deletions src/Redmine/Api/Membership.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Redmine\Api;

use Redmine\Exception\InvalidParameterException;
use Redmine\Exception\MissingParameterException;
use Redmine\Serializer\XmlSerializer;

Expand All @@ -21,16 +22,44 @@ class Membership extends AbstractApi
*
* @see http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET
*
* @param string|int $projectIdentifier project id or literal identifier
* @param array $params optional parameters to be passed to the api (offset, limit, ...)
*
* @throws InvalidParameterException if $projectIdentifier is not of type int or string
*
* @return array list of memberships found
*/
final public function list($projectIdentifier, array $params = [])
{
if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) {
throw new InvalidParameterException(sprintf(
'%s(): Argument #1 ($projectIdentifier) must be of type int or string',
__METHOD__
));
}

$this->memberships = $this->retrieveData('/projects/'.strval($projectIdentifier).'/memberships.json', $params);

return $this->memberships;
}

/**
* List memberships for a given $project.
*
* @deprecated since v2.4.0, use list() instead.
*
* @see http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET
*
* @param string|int $project project id or literal identifier
* @param array $params optional parameters to be passed to the api (offset, limit, ...)
*
* @return array list of memberships found
*/
public function all($project, array $params = [])
{
$this->memberships = $this->retrieveData('/projects/'.$project.'/memberships.json', $params);
@trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` instead.', E_USER_DEPRECATED);

return $this->memberships;
return $this->list(strval($project), $params);
}

/**
Expand Down Expand Up @@ -119,7 +148,7 @@ public function remove($id)
*/
public function removeMember($projectId, $userId, array $params = [])
{
$memberships = $this->all($projectId, $params);
$memberships = $this->list($projectId, $params);
if (!isset($memberships['memberships']) || !is_array($memberships['memberships'])) {
return false;
}
Expand Down
109 changes: 109 additions & 0 deletions tests/Unit/Api/Membership/ListTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace Redmine\Tests\Unit\Api\Membership;

use PHPUnit\Framework\TestCase;
use Redmine\Api\Membership;
use Redmine\Client\Client;
use Redmine\Exception\InvalidParameterException;
use Redmine\Tests\Fixtures\MockClient;
use stdClass;

/**
* Tests for Membership::list()
*/
class ListTest extends TestCase
{
/**
* @covers \Redmine\Api\Membership::list
*/
public function testListWithoutParametersReturnsResponse()
{
// Test values
$response = '["API Response"]';
$expectedReturn = ['API Response'];

// Create the used mock objects
$client = $this->createMock(Client::class);
$client->expects($this->once())
->method('requestGet')
->with(
$this->stringStartsWith('/projects/5/memberships.json')
)
->willReturn(true);
$client->expects($this->exactly(1))
->method('getLastResponseBody')
->willReturn($response);
$client->expects($this->exactly(1))
->method('getLastResponseContentType')
->willReturn('application/json');

// Create the object under test
$api = new Membership($client);

// Perform the tests
$this->assertSame($expectedReturn, $api->list(5));
}

/**
* @covers \Redmine\Api\Membership::list
*/
public function testListWithParametersReturnsResponse()
{
// Test values
$parameters = ['not-used'];
$response = '["API Response"]';
$expectedReturn = ['API Response'];

// Create the used mock objects
$client = $this->createMock(Client::class);
$client->expects($this->once())
->method('requestGet')
->with(
$this->logicalAnd(
$this->stringStartsWith('/projects/project-slug/memberships.json'),
$this->stringContains('not-used')
)
)
->willReturn(true);
$client->expects($this->exactly(1))
->method('getLastResponseBody')
->willReturn($response);
$client->expects($this->exactly(1))
->method('getLastResponseContentType')
->willReturn('application/json');

// Create the object under test
$api = new Membership($client);

// Perform the tests
$this->assertSame($expectedReturn, $api->list('project-slug', $parameters));
}

/**
* @covers \Redmine\Api\Membership::list
*
* @dataProvider getInvalidProjectIdentifiers
*/
public function testListWithWrongProjectIdentifierThrowsException($projectIdentifier)
{
$api = new Membership(MockClient::create());

$this->expectException(InvalidParameterException::class);
$this->expectExceptionMessage('Redmine\Api\Membership::list(): Argument #1 ($projectIdentifier) must be of type int or string');

$api->list($projectIdentifier);
}

public static function getInvalidProjectIdentifiers(): array
{
return [
'null' => [null],
'true' => [true],
'false' => [false],
'float' => [0.0],
'array' => [[]],
'object' => [new stdClass()],
];
}
}
27 changes: 27 additions & 0 deletions tests/Unit/Api/MembershipTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Redmine\Api\Membership;
use Redmine\Client\Client;
use Redmine\Exception\MissingParameterException;
use Redmine\Tests\Fixtures\MockClient;

/**
* @coversDefaultClass \Redmine\Api\Membership
Expand All @@ -15,6 +16,32 @@
*/
class MembershipTest extends TestCase
{
/**
* Test all().
*
* @covers ::all
*/
public function testAllTriggersDeprecationWarning()
{
$api = new Membership(MockClient::create());

// PHPUnit 10 compatible way to test trigger_error().
set_error_handler(
function ($errno, $errstr): bool {
$this->assertSame(
'`Redmine\Api\Membership::all()` is deprecated since v2.4.0, use `Redmine\Api\Membership::list()` instead.',
$errstr
);

restore_error_handler();
return true;
},
E_USER_DEPRECATED
);

$api->all(5);
}

/**
* Test all().
*
Expand Down

0 comments on commit 0110640

Please sign in to comment.