Directly inject GitHub Repo instance as service

To prevent mocking GitHub Client's magic methods, the actual instance will now be injected
This commit is contained in:
Claudio Zizza
2024-02-06 21:01:50 +01:00
parent 4dbb5d9a05
commit 0b8cfa719a
5 changed files with 40 additions and 37 deletions

View File

@@ -33,16 +33,14 @@
<argument type="service">
<service class="Github\Client" />
</argument>
<argument type="service" id="Psr\Cache\CacheItemPoolInterface" />
<argument>%doctrine.website.github.http_token%</argument>
</service>
<service id="Github\Client">
<service id="Github\Api\Repo">
<factory service="Doctrine\Website\Github\GithubClientProvider"
method="getGithubClient"
method="repositories"
/>
<call method="addCache">
<argument type="service" id="Psr\Cache\CacheItemPoolInterface" />
</call>
</service>
<service id="Highlight\Highlighter" autowire="true" />

View File

@@ -4,25 +4,40 @@ declare(strict_types=1);
namespace Doctrine\Website\Github;
use Github\Api\Repo;
use Github\AuthMethod;
use Github\Client;
use InvalidArgumentException;
use Psr\Cache\CacheItemPoolInterface;
/** @final */
class GithubClientProvider
use function assert;
final class GithubClientProvider
{
private bool $authenticated = false;
public function __construct(
private readonly Client $githubClient,
CacheItemPoolInterface $cache,
private readonly string $githubHttpToken,
) {
if ($githubHttpToken === '') {
throw new InvalidArgumentException('You must configure a Github http token.');
}
$this->githubClient->addCache($cache);
}
public function getGithubClient(): Client
public function repositories(): Repo
{
$repositories = $this->getGithubClient()->api('repo');
assert($repositories instanceof Repo);
return $repositories;
}
private function getGithubClient(): Client
{
if ($this->authenticated === false) {
$this->githubClient->authenticate($this->githubHttpToken, '', AuthMethod::ACCESS_TOKEN);

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Doctrine\Website\Projects;
use Doctrine\Website\Github\GithubClientProvider;
use Doctrine\Website\ProcessFactory;
use Github\Api\Repo;
@@ -15,15 +14,11 @@ use function sprintf;
/** @final */
class ProjectGitSyncer
{
private readonly Repo $githubRepo;
public function __construct(
private readonly ProcessFactory $processFactory,
GithubClientProvider $githubClientProvider,
private readonly Repo $githubRepo,
private readonly string $projectsDir,
) {
// TODO Inject Repo instead of GithubClientProvider
$this->githubRepo = $githubClientProvider->getGithubClient()->repo();
}
public function isRepositoryInitialized(string $repositoryName): bool

View File

@@ -6,39 +6,47 @@ namespace Doctrine\Website\Tests\Github;
use Doctrine\Website\Github\GithubClientProvider;
use Doctrine\Website\Tests\TestCase;
use Github\Api\Repo;
use Github\AuthMethod;
use Github\Client;
use InvalidArgumentException;
use Psr\Cache\CacheItemPoolInterface;
class GithubClientProviderTest extends TestCase
{
public function testGetGithubClient(): void
public function testRepositories(): void
{
$githubRepo = $this->createMock(Repo::class);
$githubClient = $this->createMock(Client::class);
$cache = $this->createMock(CacheItemPoolInterface::class);
$githubHttpToken = '1234';
$githubClientProvider = new GithubClientProvider($githubClient, $githubHttpToken);
$githubClient->expects(self::once())
->method('authenticate')
->with($githubHttpToken, '', AuthMethod::ACCESS_TOKEN);
$githubClient->expects(self::once())
->method('addCache')
->with($cache);
$githubClient->expects(self::once())
->method('api')
->with('repo')
->willReturn($githubRepo);
$githubClientResult = $githubClientProvider->getGithubClient();
$githubClientProvider = new GithubClientProvider($githubClient, $cache, $githubHttpToken);
self::assertSame($githubClient, $githubClientResult);
$githubClientResult = $githubClientProvider->repositories();
$githubClientResult = $githubClientProvider->getGithubClient();
self::assertSame($githubClient, $githubClientResult);
self::assertSame($githubRepo, $githubClientResult);
}
public function testGetGithubClientWithMissingToken(): void
{
$githubClient = $this->createMock(Client::class);
$cache = $this->createMock(CacheItemPoolInterface::class);
$githubHttpToken = '';
$this->expectException(InvalidArgumentException::class);
new GithubClientProvider($githubClient, $githubHttpToken);
new GithubClientProvider($githubClient, $cache, $githubHttpToken);
}
}

View File

@@ -4,12 +4,10 @@ declare(strict_types=1);
namespace Doctrine\Website\Tests\Projects;
use Doctrine\Website\Github\GithubClientProvider;
use Doctrine\Website\ProcessFactory;
use Doctrine\Website\Projects\ProjectGitSyncer;
use Doctrine\Website\Tests\TestCase;
use Github\Api\Repo;
use Github\Client;
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\MockObject\MockObject;
@@ -34,21 +32,10 @@ class ProjectGitSyncerTest extends TestCase
$this->processFactory = $this->createMock(ProcessFactory::class);
$this->projectsDir = vfsStream::url('projects');
$this->githubRepo = $this->createMock(Repo::class);
$githubClientProvider = $this->createMock(GithubClientProvider::class);
$githubClient = $this->getMockBuilder(Client::class)
->disableOriginalConstructor()
->addMethods(['repo'])
->getMock();
$githubClient->method('repo')
->willReturn($this->githubRepo);
$githubClientProvider->method('getGithubClient')
->willReturn($githubClient);
$this->projectGitSyncer = new ProjectGitSyncer(
$this->processFactory,
$githubClientProvider,
$this->githubRepo,
$this->projectsDir,
);
}