From 3155355fd13fdcfb3508b937a8fbff317d1c5c1d Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 9 Oct 2023 15:37:15 +0200 Subject: [PATCH] Add News::list() and listByProject() methdos, deprecate all() method --- CHANGELOG.md | 3 + src/Redmine/Api/News.php | 53 ++++++++++++++- tests/Unit/Api/News/ListByProjectTest.php | 78 ++++++++++++++++++++++ tests/Unit/Api/News/ListTest.php | 79 +++++++++++++++++++++++ tests/Unit/Api/NewsTest.php | 27 ++++++++ 5 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 tests/Unit/Api/News/ListByProjectTest.php create mode 100644 tests/Unit/Api/News/ListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index e38189ba..c37d5499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New method `Redmine\Api\IssueRelation::listByIssueId()` to list relations from an issue. - New method `Redmine\Api\IssueStatus::list()` to list issue statuses. - New method `Redmine\Api\Membership::listByProject()` to list memberships from a project. +- New method `Redmine\Api\News::list()` to list news from all project. +- New method `Redmine\Api\News::listByProject()` to list news from a project. ### Deprecated @@ -28,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Redmine\Api\IssueRelation::all()` is deprecated, use `Redmine\Api\IssueRelation::listByIssueId()` instead - `Redmine\Api\IssueStatus::all()` is deprecated, use `Redmine\Api\IssueStatus::list()` instead - `Redmine\Api\Membership::all()` is deprecated, use `Redmine\Api\Membership::listByProject()` instead +- `Redmine\Api\News::all()` is deprecated, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead ## [v2.3.0](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.3.0) - 2023-10-09 diff --git a/src/Redmine/Api/News.php b/src/Redmine/Api/News.php index 451ffc18..03c816f5 100644 --- a/src/Redmine/Api/News.php +++ b/src/Redmine/Api/News.php @@ -2,6 +2,8 @@ namespace Redmine\Api; +use Redmine\Exception\InvalidParameterException; + /** * @see http://www.redmine.org/projects/redmine/wiki/Rest_News * @@ -11,9 +13,51 @@ class News extends AbstractApi { private $news = []; + /** + * List news for a given project. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_News#GET + * + * @param string|int $projectIdentifier project id or literal identifier + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of news found + */ + final public function listByProject($projectIdentifier, array $params = []): array + { + if (! is_int($projectIdentifier) && ! is_string($projectIdentifier)) { + throw new InvalidParameterException(sprintf( + '%s(): Argument #1 ($projectIdentifier) must be of type int or string', + __METHOD__ + )); + } + + $this->news = $this->retrieveData('/projects/'.strval($projectIdentifier).'/news.json', $params); + + return $this->news; + } + + /** + * List news for all projects. + * + * @see http://www.redmine.org/projects/redmine/wiki/Rest_News#GET + * + * @param array $params optional parameters to be passed to the api (offset, limit, ...) + * + * @return array list of news found + */ + final public function list(array $params = []): array + { + $this->news = $this->retrieveData('/news.json', $params); + + return $this->news; + } + /** * List news (if no $project is given, it will return ALL the news). * + * @deprecated since v2.4.0, use list() or listByProject() instead. + * * @see http://www.redmine.org/projects/redmine/wiki/Rest_News#GET * * @param string|int $project project id or literal identifier [optional] @@ -23,9 +67,12 @@ class News extends AbstractApi */ public function all($project = null, array $params = []) { - $path = null === $project ? '/news.json' : '/projects/'.$project.'/news.json'; - $this->news = $this->retrieveData($path, $params); + @trigger_error('`'.__METHOD__.'()` is deprecated since v2.4.0, use `'.__CLASS__.'::list()` or `'.__CLASS__.'::listByProject()` instead.', E_USER_DEPRECATED); - return $this->news; + if (null === $project) { + return $this->list($params); + } else { + return $this->listByProject(strval($project), $params); + } } } diff --git a/tests/Unit/Api/News/ListByProjectTest.php b/tests/Unit/Api/News/ListByProjectTest.php new file mode 100644 index 00000000..d2fac23c --- /dev/null +++ b/tests/Unit/Api/News/ListByProjectTest.php @@ -0,0 +1,78 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/projects/5/news.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 News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject($projectId)); + } + + /** + * @covers \Redmine\Api\News::listByProject + */ + public function testListByProjectWithParametersReturnsResponse() + { + // Test values + $projectId = 5; + $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->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 News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->listByProject($projectId, $parameters)); + } +} diff --git a/tests/Unit/Api/News/ListTest.php b/tests/Unit/Api/News/ListTest.php new file mode 100644 index 00000000..deea8e63 --- /dev/null +++ b/tests/Unit/Api/News/ListTest.php @@ -0,0 +1,79 @@ +createMock(Client::class); + $client->expects($this->once()) + ->method('requestGet') + ->with( + $this->stringStartsWith('/news.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 News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list()); + } + + /** + * @covers \Redmine\Api\News::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('/news.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 News($client); + + // Perform the tests + $this->assertSame($expectedReturn, $api->list($parameters)); + } +} diff --git a/tests/Unit/Api/NewsTest.php b/tests/Unit/Api/NewsTest.php index b60cdcef..fd868599 100644 --- a/tests/Unit/Api/NewsTest.php +++ b/tests/Unit/Api/NewsTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Redmine\Api\News; use Redmine\Client\Client; +use Redmine\Tests\Fixtures\MockClient; /** * @coversDefaultClass \Redmine\Api\News @@ -13,6 +14,32 @@ */ class NewsTest extends TestCase { + /** + * Test all(). + * + * @covers ::all + */ + public function testAllTriggersDeprecationWarning() + { + $api = new News(MockClient::create()); + + // PHPUnit 10 compatible way to test trigger_error(). + set_error_handler( + function ($errno, $errstr): bool { + $this->assertSame( + '`Redmine\Api\News::all()` is deprecated since v2.4.0, use `Redmine\Api\News::list()` or `Redmine\Api\News::listByProject()` instead.', + $errstr + ); + + restore_error_handler(); + return true; + }, + E_USER_DEPRECATED + ); + + $api->all(5); + } + /** * Test all(). *