mirror of
https://github.com/shlinkio/shlink.git
synced 2026-02-28 04:03:12 +08:00
Move logic to determine if a new key has a duplicated name to the APiKeyService
This commit is contained in:
@@ -21,7 +21,13 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
|
||||
|
||||
public function create(ApiKeyMeta $apiKeyMeta): ApiKey
|
||||
{
|
||||
// TODO If name is auto-generated, do not throw. Instead, re-generate a new key
|
||||
$apiKey = ApiKey::fromMeta($apiKeyMeta);
|
||||
if ($this->existsWithName($apiKey->name)) {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf('Another API key with name "%s" already exists', $apiKeyMeta->name),
|
||||
);
|
||||
}
|
||||
|
||||
$this->em->persist($apiKey);
|
||||
$this->em->flush();
|
||||
@@ -77,14 +83,6 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
|
||||
return $this->repo->findBy($conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function existsWithName(string $apiKeyName): bool
|
||||
{
|
||||
return $this->repo->count(['name' => $apiKeyName]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @todo This method should be transactional and to a SELECT ... FROM UPDATE when checking if the new name exists,
|
||||
@@ -120,4 +118,9 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
|
||||
{
|
||||
return $this->repo->findOneBy(['key' => ApiKey::hashKey($key)]);
|
||||
}
|
||||
|
||||
private function existsWithName(string $apiKeyName): bool
|
||||
{
|
||||
return $this->repo->count(['name' => $apiKeyName]) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,6 @@ interface ApiKeyServiceInterface
|
||||
*/
|
||||
public function listKeys(bool $enabledOnly = false): array;
|
||||
|
||||
/**
|
||||
* Check if an API key exists for provided name
|
||||
*/
|
||||
public function existsWithName(string $apiKeyName): bool;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException If an API key with oldName does not exist, or newName is in use by another one
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,6 @@ use Cake\Chronos\Chronos;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\TestWith;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
@@ -41,6 +40,9 @@ class ApiKeyServiceTest extends TestCase
|
||||
#[Test, DataProvider('provideCreationDate')]
|
||||
public function apiKeyIsProperlyCreated(Chronos|null $date, string|null $name, array $roles): void
|
||||
{
|
||||
$this->repo->expects($this->once())->method('count')->with(
|
||||
! empty($name) ? ['name' => $name] : $this->isType('array'),
|
||||
)->willReturn(0);
|
||||
$this->em->expects($this->once())->method('flush');
|
||||
$this->em->expects($this->once())->method('persist')->with($this->isInstanceOf(ApiKey::class));
|
||||
|
||||
@@ -73,6 +75,19 @@ class ApiKeyServiceTest extends TestCase
|
||||
yield 'empty name' => [null, '', []];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function exceptionIsThrownWhileCreatingIfNameIsInUse(): void
|
||||
{
|
||||
$this->repo->expects($this->once())->method('count')->with(['name' => 'the_name'])->willReturn(1);
|
||||
$this->em->expects($this->never())->method('flush');
|
||||
$this->em->expects($this->never())->method('persist');
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Another API key with name "the_name" already exists');
|
||||
|
||||
$this->service->create(ApiKeyMeta::fromParams(name: 'the_name'));
|
||||
}
|
||||
|
||||
#[Test, DataProvider('provideInvalidApiKeys')]
|
||||
public function checkReturnsFalseForInvalidApiKeys(ApiKey|null $invalidKey): void
|
||||
{
|
||||
@@ -179,17 +194,6 @@ class ApiKeyServiceTest extends TestCase
|
||||
yield 'existing api keys' => [null];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[TestWith([0, false])]
|
||||
#[TestWith([1, true])]
|
||||
#[TestWith([27, true])]
|
||||
public function existsWithNameCountsEntriesInRepository(int $count, bool $expected): void
|
||||
{
|
||||
$name = 'the_key';
|
||||
$this->repo->expects($this->once())->method('count')->with(['name' => $name])->willReturn($count);
|
||||
self::assertEquals($this->service->existsWithName($name), $expected);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function renameApiKeyThrowsExceptionIfApiKeyIsNotFound(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user