Files
git-contribution-graph/tests/Unit/Service/Provider/GitLabProviderTest.php
T
haylan 2f3268c0b7 refactor: reorganise Service/ into Provider/ and Renderer/ sub-namespaces
Move all provider-related classes, enums, interface and trait into
App\Service\Provider; move SvgRenderer into App\Service\Renderer.
ContributionAggregator stays at the Service root as the orchestrator.
Test namespaces and use statements updated to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 00:10:09 +02:00

129 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Unit\Service\Provider;
use App\Service\Provider\GitLabProvider;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
#[CoversClass(GitLabProvider::class)]
final class GitLabProviderTest extends TestCase
{
private function makeProvider(
string $username = 'user',
string $token = 'token',
string $baseUrl = '',
?HttpClientInterface $client = null,
): GitLabProvider {
return new GitLabProvider(
$client ?? $this->createStub(HttpClientInterface::class),
$username,
$token,
$this->createStub(LoggerInterface::class),
$baseUrl,
);
}
private function stubResponse(array $data): ResponseInterface
{
$response = $this->createStub(ResponseInterface::class);
$response->method('toArray')->willReturn($data);
return $response;
}
#[Test]
public function it_returns_gitlab_as_name(): void
{
$this->assertSame('gitlab', $this->makeProvider()->getName());
}
#[Test]
public function it_is_configured_when_credentials_are_set(): void
{
$this->assertTrue($this->makeProvider()->isConfigured());
}
#[Test]
public function it_is_not_configured_when_username_is_empty(): void
{
$this->assertFalse($this->makeProvider(username: '')->isConfigured());
}
#[Test]
public function it_is_not_configured_when_token_is_empty(): void
{
$this->assertFalse($this->makeProvider(token: '')->isConfigured());
}
#[Test]
public function it_throws_not_found_exception_when_user_does_not_exist(): void
{
$client = $this->createStub(HttpClientInterface::class);
$client->method('request')->willReturn($this->stubResponse([]));
$this->expectException(NotFoundHttpException::class);
$this->makeProvider(client: $client)->fetch();
}
#[Test]
public function it_fetches_events_and_counts_them_by_date(): void
{
$client = $this->createMock(HttpClientInterface::class);
$client->method('request')->willReturnCallback(
function (string $method, string $url): ResponseInterface {
if (str_contains($url, '/events')) {
return $this->stubResponse([
['created_at' => '2024-06-10T12:00:00.000Z'],
['created_at' => '2024-06-10T14:00:00.000Z'],
['created_at' => '2024-06-11T08:00:00.000Z'],
]);
}
return $this->stubResponse([['id' => 42]]);
}
);
$result = $this->makeProvider(client: $client)->fetch();
$this->assertSame(2, $result['2024-06-10']);
$this->assertSame(1, $result['2024-06-11']);
}
#[Test]
public function it_fetches_multiple_pages_until_page_has_fewer_than_100_events(): void
{
$callCount = 0;
$client = $this->createMock(HttpClientInterface::class);
$client->method('request')->willReturnCallback(
function (string $method, string $url) use (&$callCount): ResponseInterface {
if (!str_contains($url, '/events')) {
return $this->stubResponse([['id' => 42]]);
}
$callCount++;
$data = $callCount === 1
? array_fill(0, 100, ['created_at' => '2024-06-10T12:00:00.000Z'])
: [['created_at' => '2024-06-11T08:00:00.000Z']];
return $this->stubResponse($data);
}
);
$result = $this->makeProvider(client: $client)->fetch();
$this->assertSame(2, $callCount);
$this->assertSame(100, $result['2024-06-10']);
$this->assertSame(1, $result['2024-06-11']);
}
}