2f3268c0b7
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>
112 lines
3.2 KiB
PHP
112 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Service\Provider;
|
|
|
|
use App\Service\Provider\GiteaProvider;
|
|
use PHPUnit\Framework\Attributes\CoversClass;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
|
|
|
#[CoversClass(GiteaProvider::class)]
|
|
final class GiteaProviderTest extends TestCase
|
|
{
|
|
private function makeProvider(
|
|
string $username = 'user',
|
|
string $token = 'token',
|
|
string $baseUrl = 'https://gitea.example.com',
|
|
?HttpClientInterface $client = null,
|
|
): GiteaProvider {
|
|
return new GiteaProvider(
|
|
$client ?? $this->createStub(HttpClientInterface::class),
|
|
$username,
|
|
$token,
|
|
$baseUrl,
|
|
$this->createStub(LoggerInterface::class),
|
|
);
|
|
}
|
|
|
|
private function stubResponse(array $data): ResponseInterface
|
|
{
|
|
$response = $this->createStub(ResponseInterface::class);
|
|
$response->method('toArray')->willReturn($data);
|
|
|
|
return $response;
|
|
}
|
|
|
|
#[Test]
|
|
public function it_returns_gitea_as_name(): void
|
|
{
|
|
$this->assertSame('gitea', $this->makeProvider()->getName());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_is_configured_when_all_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_is_not_configured_when_base_url_is_empty(): void
|
|
{
|
|
$this->assertFalse($this->makeProvider(baseUrl: '')->isConfigured());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_parses_heatmap_entries_into_contributions(): void
|
|
{
|
|
$now = time();
|
|
|
|
$client = $this->createStub(HttpClientInterface::class);
|
|
$client->method('request')->willReturn($this->stubResponse([
|
|
['timestamp' => $now, 'contributions' => 5],
|
|
]));
|
|
|
|
$result = $this->makeProvider(client: $client)->fetch();
|
|
|
|
$this->assertSame(5, $result[date('Y-m-d', $now)]);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_filters_out_entries_older_than_365_days(): void
|
|
{
|
|
$old = (new \DateTimeImmutable('-366 days'))->getTimestamp();
|
|
|
|
$client = $this->createStub(HttpClientInterface::class);
|
|
$client->method('request')->willReturn($this->stubResponse([
|
|
['timestamp' => $old, 'contributions' => 3],
|
|
]));
|
|
|
|
$result = $this->makeProvider(client: $client)->fetch();
|
|
|
|
$this->assertSame([], $result);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_returns_empty_when_response_has_no_entries(): void
|
|
{
|
|
$client = $this->createStub(HttpClientInterface::class);
|
|
$client->method('request')->willReturn($this->stubResponse([]));
|
|
|
|
$result = $this->makeProvider(client: $client)->fetch();
|
|
|
|
$this->assertSame([], $result);
|
|
}
|
|
}
|