Inject ApiKeyRepository in ApiKeyService

This commit is contained in:
Alejandro Celaya 2024-11-07 09:34:42 +01:00
parent bd73362c94
commit 6f95acc202
3 changed files with 21 additions and 26 deletions

View File

@ -9,6 +9,7 @@ use Laminas\ServiceManager\Factory\InvokableFactory;
use Mezzio\ProblemDetails\ProblemDetailsResponseFactory; use Mezzio\ProblemDetails\ProblemDetailsResponseFactory;
use Mezzio\Router\Middleware\ImplicitOptionsMiddleware; use Mezzio\Router\Middleware\ImplicitOptionsMiddleware;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Common\Doctrine\EntityRepositoryFactory;
use Shlinkio\Shlink\Common\Mercure\LcobucciJwtProvider; use Shlinkio\Shlink\Common\Mercure\LcobucciJwtProvider;
use Shlinkio\Shlink\Core\Config; use Shlinkio\Shlink\Core\Config;
use Shlinkio\Shlink\Core\Domain\DomainService; use Shlinkio\Shlink\Core\Domain\DomainService;
@ -17,6 +18,7 @@ use Shlinkio\Shlink\Core\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer; use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer;
use Shlinkio\Shlink\Core\Tag\TagService; use Shlinkio\Shlink\Core\Tag\TagService;
use Shlinkio\Shlink\Core\Visit; use Shlinkio\Shlink\Core\Visit;
use Shlinkio\Shlink\Rest\ApiKey\Repository\ApiKeyRepository;
use Shlinkio\Shlink\Rest\Service\ApiKeyService; use Shlinkio\Shlink\Rest\Service\ApiKeyService;
return [ return [
@ -24,6 +26,7 @@ return [
'dependencies' => [ 'dependencies' => [
'factories' => [ 'factories' => [
ApiKeyService::class => ConfigAbstractFactory::class, ApiKeyService::class => ConfigAbstractFactory::class,
ApiKeyRepository::class => [EntityRepositoryFactory::class, Entity\ApiKey::class],
Action\HealthAction::class => ConfigAbstractFactory::class, Action\HealthAction::class => ConfigAbstractFactory::class,
Action\MercureInfoAction::class => ConfigAbstractFactory::class, Action\MercureInfoAction::class => ConfigAbstractFactory::class,
@ -62,7 +65,7 @@ return [
], ],
ConfigAbstractFactory::class => [ ConfigAbstractFactory::class => [
ApiKeyService::class => ['em'], ApiKeyService::class => ['em', ApiKeyRepository::class],
Action\HealthAction::class => ['em', Config\Options\AppOptions::class], Action\HealthAction::class => ['em', Config\Options\AppOptions::class],
Action\MercureInfoAction::class => [LcobucciJwtProvider::class, 'config.mercure'], Action\MercureInfoAction::class => [LcobucciJwtProvider::class, 'config.mercure'],

View File

@ -12,7 +12,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
readonly class ApiKeyService implements ApiKeyServiceInterface readonly class ApiKeyService implements ApiKeyServiceInterface
{ {
public function __construct(private EntityManagerInterface $em) public function __construct(private EntityManagerInterface $em, private ApiKeyRepositoryInterface $repo)
{ {
} }
@ -28,14 +28,12 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
public function createInitial(string $key): ApiKey|null public function createInitial(string $key): ApiKey|null
{ {
/** @var ApiKeyRepositoryInterface $repo */ return $this->repo->createInitialApiKey($key);
$repo = $this->em->getRepository(ApiKey::class);
return $repo->createInitialApiKey($key);
} }
public function check(string $key): ApiKeyCheckResult public function check(string $key): ApiKeyCheckResult
{ {
$apiKey = $this->getByKey($key); $apiKey = $this->findByKey($key);
return new ApiKeyCheckResult($apiKey); return new ApiKeyCheckResult($apiKey);
} }
@ -44,9 +42,7 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
*/ */
public function disableByName(string $apiKeyName): ApiKey public function disableByName(string $apiKeyName): ApiKey
{ {
return $this->disableApiKey($this->em->getRepository(ApiKey::class)->findOneBy([ return $this->disableApiKey($this->findByName($apiKeyName));
'name' => $apiKeyName,
]));
} }
/** /**
@ -54,7 +50,7 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
*/ */
public function disableByKey(string $key): ApiKey public function disableByKey(string $key): ApiKey
{ {
return $this->disableApiKey($this->getByKey($key)); return $this->disableApiKey($this->findByKey($key));
} }
private function disableApiKey(ApiKey|null $apiKey): ApiKey private function disableApiKey(ApiKey|null $apiKey): ApiKey
@ -75,13 +71,16 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
public function listKeys(bool $enabledOnly = false): array public function listKeys(bool $enabledOnly = false): array
{ {
$conditions = $enabledOnly ? ['enabled' => true] : []; $conditions = $enabledOnly ? ['enabled' => true] : [];
return $this->em->getRepository(ApiKey::class)->findBy($conditions); return $this->repo->findBy($conditions);
} }
private function getByKey(string $key): ApiKey|null private function findByKey(string $key): ApiKey|null
{ {
return $this->em->getRepository(ApiKey::class)->findOneBy([ return $this->repo->findOneBy(['key' => ApiKey::hashKey($key)]);
'key' => ApiKey::hashKey($key), }
]);
private function findByName(string $name): ApiKey|null
{
return $this->repo->findOneBy(['name' => $name]);
} }
} }

View File

@ -14,7 +14,7 @@ use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta; use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition; use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
use Shlinkio\Shlink\Rest\ApiKey\Repository\ApiKeyRepository; use Shlinkio\Shlink\Rest\ApiKey\Repository\ApiKeyRepositoryInterface;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
use Shlinkio\Shlink\Rest\Service\ApiKeyService; use Shlinkio\Shlink\Rest\Service\ApiKeyService;
@ -24,13 +24,13 @@ class ApiKeyServiceTest extends TestCase
{ {
private ApiKeyService $service; private ApiKeyService $service;
private MockObject & EntityManager $em; private MockObject & EntityManager $em;
private MockObject & ApiKeyRepository $repo; private MockObject & ApiKeyRepositoryInterface $repo;
protected function setUp(): void protected function setUp(): void
{ {
$this->em = $this->createMock(EntityManager::class); $this->em = $this->createMock(EntityManager::class);
$this->repo = $this->createMock(ApiKeyRepository::class); $this->repo = $this->createMock(ApiKeyRepositoryInterface::class);
$this->service = new ApiKeyService($this->em); $this->service = new ApiKeyService($this->em, $this->repo);
} }
/** /**
@ -77,7 +77,6 @@ class ApiKeyServiceTest extends TestCase
$this->repo->expects($this->once())->method('findOneBy')->with(['key' => ApiKey::hashKey('12345')])->willReturn( $this->repo->expects($this->once())->method('findOneBy')->with(['key' => ApiKey::hashKey('12345')])->willReturn(
$invalidKey, $invalidKey,
); );
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$result = $this->service->check('12345'); $result = $this->service->check('12345');
@ -102,7 +101,6 @@ class ApiKeyServiceTest extends TestCase
$this->repo->expects($this->once())->method('findOneBy')->with(['key' => ApiKey::hashKey('12345')])->willReturn( $this->repo->expects($this->once())->method('findOneBy')->with(['key' => ApiKey::hashKey('12345')])->willReturn(
$apiKey, $apiKey,
); );
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$result = $this->service->check('12345'); $result = $this->service->check('12345');
@ -114,7 +112,6 @@ class ApiKeyServiceTest extends TestCase
public function disableThrowsExceptionWhenNoApiKeyIsFound(string $disableMethod, array $findOneByArg): void public function disableThrowsExceptionWhenNoApiKeyIsFound(string $disableMethod, array $findOneByArg): void
{ {
$this->repo->expects($this->once())->method('findOneBy')->with($findOneByArg)->willReturn(null); $this->repo->expects($this->once())->method('findOneBy')->with($findOneByArg)->willReturn(null);
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$this->expectException(InvalidArgumentException::class); $this->expectException(InvalidArgumentException::class);
@ -126,7 +123,6 @@ class ApiKeyServiceTest extends TestCase
{ {
$key = ApiKey::create(); $key = ApiKey::create();
$this->repo->expects($this->once())->method('findOneBy')->with($findOneByArg)->willReturn($key); $this->repo->expects($this->once())->method('findOneBy')->with($findOneByArg)->willReturn($key);
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$this->em->expects($this->once())->method('flush'); $this->em->expects($this->once())->method('flush');
self::assertTrue($key->isEnabled()); self::assertTrue($key->isEnabled());
@ -147,7 +143,6 @@ class ApiKeyServiceTest extends TestCase
$expectedApiKeys = [ApiKey::create(), ApiKey::create(), ApiKey::create()]; $expectedApiKeys = [ApiKey::create(), ApiKey::create(), ApiKey::create()];
$this->repo->expects($this->once())->method('findBy')->with([])->willReturn($expectedApiKeys); $this->repo->expects($this->once())->method('findBy')->with([])->willReturn($expectedApiKeys);
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$result = $this->service->listKeys(); $result = $this->service->listKeys();
@ -160,7 +155,6 @@ class ApiKeyServiceTest extends TestCase
$expectedApiKeys = [ApiKey::create(), ApiKey::create(), ApiKey::create()]; $expectedApiKeys = [ApiKey::create(), ApiKey::create(), ApiKey::create()];
$this->repo->expects($this->once())->method('findBy')->with(['enabled' => true])->willReturn($expectedApiKeys); $this->repo->expects($this->once())->method('findBy')->with(['enabled' => true])->willReturn($expectedApiKeys);
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$result = $this->service->listKeys(enabledOnly: true); $result = $this->service->listKeys(enabledOnly: true);
@ -171,7 +165,6 @@ class ApiKeyServiceTest extends TestCase
public function createInitialDelegatesToRepository(ApiKey|null $apiKey): void public function createInitialDelegatesToRepository(ApiKey|null $apiKey): void
{ {
$this->repo->expects($this->once())->method('createInitialApiKey')->with('the_key')->willReturn($apiKey); $this->repo->expects($this->once())->method('createInitialApiKey')->with('the_key')->willReturn($apiKey);
$this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);
$result = $this->service->createInitial('the_key'); $result = $this->service->createInitial('the_key');