Skip to content

Commit

Permalink
Let Project::listNames() handle pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
Art4 committed Jul 4, 2024
1 parent 352a8dc commit 4e0dec6
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 8 deletions.
23 changes: 18 additions & 5 deletions src/Redmine/Api/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,26 @@ final public function listNames(): array

$this->projectNames = [];

$list = $this->list();
$limit = 100;
$offset = 0;

if (array_key_exists('projects', $list)) {
foreach ($list['projects'] as $issueStatus) {
$this->projectNames[(int) $issueStatus['id']] = (string) $issueStatus['name'];
do {
$list = $this->list([
'limit' => $limit,
'offset' => $offset,
]);

$listCount = 0;
$offset += $limit;

if (array_key_exists('projects', $list)) {
$listCount = count($list['projects']);

foreach ($list['projects'] as $issueStatus) {
$this->projectNames[(int) $issueStatus['id']] = (string) $issueStatus['name'];
}
}
}
} while ($listCount === $limit);

return $this->projectNames;
}
Expand Down
12 changes: 12 additions & 0 deletions tests/Behat/Bootstrap/ProjectContextTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ public function iCreateAProjectWithTheFollowingData(TableNode $table)
);
}

/**
* @Given I create :count projects
*/
public function iCreateProjects(int $count)
{
while ($count > 0) {
$this->iCreateAProjectWithNameAndIdentifier('Test Project ' . $count, 'test-project-' . $count);

$count--;
}
}

/**
* @When I list all projects
*/
Expand Down
8 changes: 8 additions & 0 deletions tests/Behat/features/projects.feature
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ Feature: Interacting with the REST API for projects
| 1 | Test Project B |
| 2 | Test Project A |

Scenario: Listing of multiple project names
Given I have a "NativeCurlClient" client
And I create "108" projects
When I list all project names
Then the response has the status code "200"
And the response has the content type "application/json"
And the returned data contains "108" items

Scenario: Updating a project
Given I have a "NativeCurlClient" client
And I create a project with name "Test Project" and identifier "test-project"
Expand Down
65 changes: 62 additions & 3 deletions tests/Unit/Api/Project/ListNamesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static function getListNamesData(): array
{
return [
'test without projects' => [
'/projects.json',
'/projects.json?limit=100&offset=0',
201,
<<<JSON
{
Expand All @@ -53,7 +53,7 @@ public static function getListNamesData(): array
[],
],
'test with multiple projects' => [
'/projects.json',
'/projects.json?limit=100&offset=0',
201,
<<<JSON
{
Expand All @@ -73,13 +73,72 @@ public static function getListNamesData(): array
];
}

public function testListNamesWithALotOfProjectsHandlesPagination()
{
$assertData = [];
$projectsRequest1 = [];
$projectsRequest2 = [];
$projectsRequest3 = [];

for ($i = 1; $i <= 100; $i++) {
$name = 'Project ' . $i;

$assertData[$i] = $name;
$projectsRequest1[] = ['id' => $i, 'name' => $name];
}

for ($i = 101; $i <= 200; $i++) {
$name = 'Project ' . $i;

$assertData[$i] = $name;
$projectsRequest2[] = ['id' => $i, 'name' => $name];
}

$client = AssertingHttpClient::create(
$this,
[
'GET',
'/projects.json?limit=100&offset=0',
'application/json',
'',
200,
'application/json',
json_encode(['projects' => $projectsRequest1]),
],
[
'GET',
'/projects.json?limit=100&offset=100',
'application/json',
'',
200,
'application/json',
json_encode(['projects' => $projectsRequest2]),
],
[
'GET',
'/projects.json?limit=100&offset=200',
'application/json',
'',
200,
'application/json',
json_encode(['projects' => $projectsRequest3]),
],
);

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

// Perform the tests
$this->assertSame($assertData, $api->listNames());
}

public function testListNamesCallsHttpClientOnlyOnce()
{
$client = AssertingHttpClient::create(
$this,
[
'GET',
'/projects.json',
'/projects.json?limit=100&offset=0',
'application/json',
'',
200,
Expand Down

0 comments on commit 4e0dec6

Please sign in to comment.