mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-27 16:26:37 +03:00
Merge pull request #1541 from acelaya-forks/feature/initial-api-key
Feature/initial api key
This commit is contained in:
commit
a87f6c6709
88 changed files with 303 additions and 84 deletions
|
@ -30,6 +30,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
|
|||
Non-error responses are not affected.
|
||||
|
||||
* [#1513](https://github.com/shlinkio/shlink/issues/1513) Added publishing of the docker image in GHCR.
|
||||
* [#1114](https://github.com/shlinkio/shlink/issues/1114) Added support to provide an initial API key via `INITIAL_API_KEY` env var, when running Shlink with openswoole or RoadRunner.
|
||||
|
||||
Also, the installer tool now allows to generate an initial API key that can be copy-pasted (this tool is run interactively), in case you use php-fpm or you don't want to use env vars.
|
||||
|
||||
### Changed
|
||||
* [#1339](https://github.com/shlinkio/shlink/issues/1339) Added new test suite for CLI E2E tests.
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
"shlinkio/shlink-config": "dev-main#33004e6 as 2.1",
|
||||
"shlinkio/shlink-event-dispatcher": "dev-main#48c0137 as 2.6",
|
||||
"shlinkio/shlink-importer": "^4.0",
|
||||
"shlinkio/shlink-installer": "dev-develop#f1cc5c7 as 8.2",
|
||||
"shlinkio/shlink-installer": "dev-develop#a01bca9 as 8.2",
|
||||
"shlinkio/shlink-ip-geolocation": "^3.0",
|
||||
"spiral/roadrunner": "^2.11",
|
||||
"spiral/roadrunner-jobs": "^2.3",
|
||||
|
@ -92,6 +92,7 @@
|
|||
"ShlinkioCliTest\\Shlink\\CLI\\": "module/CLI/test-cli",
|
||||
"ShlinkioTest\\Shlink\\Rest\\": "module/Rest/test",
|
||||
"ShlinkioApiTest\\Shlink\\Rest\\": "module/Rest/test-api",
|
||||
"ShlinkioDbTest\\Shlink\\Rest\\": "module/Rest/test-db",
|
||||
"ShlinkioTest\\Shlink\\Core\\": "module/Core/test",
|
||||
"ShlinkioDbTest\\Shlink\\Core\\": "module/Core/test-db"
|
||||
},
|
||||
|
|
|
@ -8,8 +8,8 @@ return [
|
|||
|
||||
'debug' => false,
|
||||
|
||||
// Disabling config cache for cli, ensures it's never used for openswoole and also that console commands don't
|
||||
// generate a cache file that's then used by non-openswoole web executions
|
||||
// Disabling config cache for cli, ensures it's never used for openswoole/RoadRunner, and also that console
|
||||
// commands don't generate a cache file that's then used by php-fpm web executions
|
||||
ConfigAggregator::ENABLE_CACHE => PHP_SAPI !== 'cli',
|
||||
|
||||
];
|
||||
|
|
|
@ -82,6 +82,9 @@ return [
|
|||
InstallationCommand::GEOLITE_DOWNLOAD_DB->value => [
|
||||
'command' => 'bin/cli ' . Command\Visit\DownloadGeoLiteDbCommand::NAME,
|
||||
],
|
||||
InstallationCommand::API_KEY_GENERATE->value => [
|
||||
'command' => 'bin/cli ' . Command\Api\GenerateKeyCommand::NAME,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class DisableKeyCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $apiKeyService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->apiKeyService = $this->prophesize(ApiKeyServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new DisableKeyCommand($this->apiKeyService->reveal()));
|
||||
|
|
|
@ -23,7 +23,7 @@ class GenerateKeyCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $apiKeyService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->apiKeyService = $this->prophesize(ApiKeyServiceInterface::class);
|
||||
$roleResolver = $this->prophesize(RoleResolverInterface::class);
|
||||
|
|
|
@ -23,7 +23,7 @@ class ListKeysCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $apiKeyService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->apiKeyService = $this->prophesize(ApiKeyServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new ListKeysCommand($this->apiKeyService->reveal()));
|
||||
|
|
|
@ -33,7 +33,7 @@ class CreateDatabaseCommandTest extends TestCase
|
|||
private ObjectProphecy $schemaManager;
|
||||
private ObjectProphecy $driver;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$locker = $this->prophesize(LockFactory::class);
|
||||
$lock = $this->prophesize(LockInterface::class);
|
||||
|
|
|
@ -23,7 +23,7 @@ class MigrateDatabaseCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $processHelper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$locker = $this->prophesize(LockFactory::class);
|
||||
$lock = $this->prophesize(LockInterface::class);
|
||||
|
|
|
@ -24,7 +24,7 @@ class DomainRedirectsCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $domainService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->domainService = $this->prophesize(DomainServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new DomainRedirectsCommand($this->domainService->reveal()));
|
||||
|
|
|
@ -23,7 +23,7 @@ class ListDomainsCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $domainService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->domainService = $this->prophesize(DomainServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new ListDomainsCommand($this->domainService->reveal()));
|
||||
|
|
|
@ -30,7 +30,7 @@ class CreateShortUrlCommandTest extends TestCase
|
|||
private ObjectProphecy $urlShortener;
|
||||
private ObjectProphecy $stringifier;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlShortener = $this->prophesize(UrlShortener::class);
|
||||
$this->stringifier = $this->prophesize(ShortUrlStringifierInterface::class);
|
||||
|
|
|
@ -26,7 +26,7 @@ class DeleteShortUrlCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $service;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->service = $this->prophesize(DeleteShortUrlServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new DeleteShortUrlCommand($this->service->reveal()));
|
||||
|
|
|
@ -33,7 +33,7 @@ class GetShortUrlVisitsCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $visitsHelper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->visitsHelper = $this->prophesize(VisitsStatsHelperInterface::class);
|
||||
$command = new GetShortUrlVisitsCommand($this->visitsHelper->reveal());
|
||||
|
|
|
@ -33,7 +33,7 @@ class ListShortUrlsCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $shortUrlService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->shortUrlService = $this->prophesize(ShortUrlServiceInterface::class);
|
||||
$command = new ListShortUrlsCommand($this->shortUrlService->reveal(), new ShortUrlDataTransformer(
|
||||
|
|
|
@ -25,7 +25,7 @@ class ResolveUrlCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $urlResolver;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new ResolveUrlCommand($this->urlResolver->reveal()));
|
||||
|
|
|
@ -18,7 +18,7 @@ class DeleteTagsCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new DeleteTagsCommand($this->tagService->reveal()));
|
||||
|
|
|
@ -22,7 +22,7 @@ class ListTagsCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new ListTagsCommand($this->tagService->reveal()));
|
||||
|
|
|
@ -21,7 +21,7 @@ class RenameTagCommandTest extends TestCase
|
|||
private CommandTester $commandTester;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->commandTester = $this->testerForCommand(new RenameTagCommand($this->tagService->reveal()));
|
||||
|
|
|
@ -40,7 +40,7 @@ class LocateVisitsCommandTest extends TestCase
|
|||
private ObjectProphecy $lock;
|
||||
private ObjectProphecy $downloadDbCommand;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->visitService = $this->prophesize(VisitLocator::class);
|
||||
$this->ipResolver = $this->prophesize(IpLocationResolverInterface::class);
|
||||
|
|
|
@ -12,7 +12,7 @@ class ConfigProviderTest extends TestCase
|
|||
{
|
||||
private ConfigProvider $configProvider;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->configProvider = new ConfigProvider();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class ApplicationFactoryTest extends TestCase
|
|||
|
||||
private ApplicationFactory $factory;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->factory = new ApplicationFactory();
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class GeolocationDbUpdaterTest extends TestCase
|
|||
private TrackingOptions $trackingOptions;
|
||||
private ObjectProphecy $lock;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->dbUpdater = $this->prophesize(DbUpdaterInterface::class);
|
||||
$this->geoLiteDbReader = $this->prophesize(Reader::class);
|
||||
|
|
|
@ -21,7 +21,7 @@ class ShlinkTableTest extends TestCase
|
|||
private ShlinkTable $shlinkTable;
|
||||
private ObjectProphecy $baseTable;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->baseTable = $this->prophesize(Table::class);
|
||||
$this->shlinkTable = ShlinkTable::fromBaseTable($this->baseTable->reveal());
|
||||
|
|
|
@ -47,6 +47,7 @@ enum EnvVars: string
|
|||
case PORT = 'PORT';
|
||||
case TASK_WORKER_NUM = 'TASK_WORKER_NUM';
|
||||
case WEB_WORKER_NUM = 'WEB_WORKER_NUM';
|
||||
case INITIAL_API_KEY = 'INITIAL_API_KEY';
|
||||
case ANONYMIZE_REMOTE_ADDR = 'ANONYMIZE_REMOTE_ADDR';
|
||||
case TRACK_ORPHAN_VISITS = 'TRACK_ORPHAN_VISITS';
|
||||
case DISABLE_TRACK_PARAM = 'DISABLE_TRACK_PARAM';
|
||||
|
|
|
@ -110,7 +110,7 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito
|
|||
|
||||
return map(
|
||||
$this->getEntityManager()->createNativeQuery($nativeQb->getSQL(), $rsm)->getResult(),
|
||||
static fn (array $row) => new TagInfo($row['tag'], (int) $row['shortUrlsCount'], (int) $row['visitsCount']),
|
||||
TagInfo::fromRawData(...),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@ final class TagInfo implements JsonSerializable
|
|||
) {
|
||||
}
|
||||
|
||||
public static function fromRawData(array $data): self
|
||||
{
|
||||
return new self($data['tag'], (int) $data['shortUrlsCount'], (int) $data['visitsCount']);
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -14,6 +14,7 @@ final class TagsParams extends AbstractInfinitePaginableListParams
|
|||
private function __construct(
|
||||
public readonly ?string $searchTerm,
|
||||
public readonly Ordering $orderBy,
|
||||
/** @deprecated */
|
||||
public readonly bool $withStats,
|
||||
?int $page,
|
||||
?int $itemsPerPage,
|
||||
|
|
|
@ -25,7 +25,7 @@ class PixelActionTest extends TestCase
|
|||
private ObjectProphecy $urlResolver;
|
||||
private ObjectProphecy $requestTracker;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
|
||||
$this->requestTracker = $this->prophesize(RequestTrackerInterface::class);
|
||||
|
|
|
@ -39,7 +39,7 @@ class QrCodeActionTest extends TestCase
|
|||
private ObjectProphecy $urlResolver;
|
||||
private QrCodeOptions $options;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$router = $this->prophesize(RouterInterface::class);
|
||||
$router->generateUri(Argument::cetera())->willReturn('/foo/bar');
|
||||
|
|
|
@ -31,7 +31,7 @@ class RedirectActionTest extends TestCase
|
|||
private ObjectProphecy $requestTracker;
|
||||
private ObjectProphecy $redirectRespHelper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
|
||||
$this->requestTracker = $this->prophesize(RequestTrackerInterface::class);
|
||||
|
|
|
@ -11,7 +11,7 @@ class BasePathPrefixerTest extends TestCase
|
|||
{
|
||||
private BasePathPrefixer $prefixer;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->prefixer = new BasePathPrefixer();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class ConfigProviderTest extends TestCase
|
|||
{
|
||||
private ConfigProvider $configProvider;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->configProvider = new ConfigProvider();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class DomainServiceTest extends TestCase
|
|||
private DomainService $domainService;
|
||||
private ObjectProphecy $em;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->domainService = new DomainService($this->em->reveal(), 'default.com');
|
||||
|
|
|
@ -31,7 +31,7 @@ class NotFoundRedirectHandlerTest extends TestCase
|
|||
private ObjectProphecy $next;
|
||||
private ServerRequestInterface $req;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->redirectOptions = new NotFoundRedirectOptions();
|
||||
$this->resolver = $this->prophesize(NotFoundRedirectResolverInterface::class);
|
||||
|
|
|
@ -21,7 +21,7 @@ class NotFoundTemplateHandlerTest extends TestCase
|
|||
private NotFoundTemplateHandler $handler;
|
||||
private bool $readFileCalled;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->readFileCalled = false;
|
||||
$readFile = function (string $fileName): string {
|
||||
|
|
|
@ -18,7 +18,7 @@ class CloseDbConnectionEventListenerDelegatorTest extends TestCase
|
|||
private CloseDbConnectionEventListenerDelegator $delegator;
|
||||
private ObjectProphecy $container;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->container = $this->prophesize(ContainerInterface::class);
|
||||
$this->delegator = new CloseDbConnectionEventListenerDelegator();
|
||||
|
|
|
@ -20,7 +20,7 @@ class CloseDbConnectionEventListenerTest extends TestCase
|
|||
|
||||
private ObjectProphecy $em;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(ReopeningEntityManagerInterface::class);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class LocateVisitTest extends TestCase
|
|||
private ObjectProphecy $dbUpdater;
|
||||
private ObjectProphecy $eventDispatcher;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->ipLocationResolver = $this->prophesize(IpLocationResolverInterface::class);
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
|
|
|
@ -31,7 +31,7 @@ class NotifyVisitToMercureTest extends TestCase
|
|||
private ObjectProphecy $em;
|
||||
private ObjectProphecy $logger;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->helper = $this->prophesize(PublishingHelperInterface::class);
|
||||
$this->updatesGenerator = $this->prophesize(PublishingUpdatesGeneratorInterface::class);
|
||||
|
|
|
@ -38,7 +38,7 @@ class NotifyVisitToWebHooksTest extends TestCase
|
|||
private ObjectProphecy $em;
|
||||
private ObjectProphecy $logger;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->httpClient = $this->prophesize(ClientInterface::class);
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
|
|
|
@ -21,7 +21,7 @@ class PublishingUpdatesGeneratorTest extends TestCase
|
|||
{
|
||||
private PublishingUpdatesGenerator $generator;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->generator = new PublishingUpdatesGenerator(
|
||||
new ShortUrlDataTransformer(new ShortUrlStringifier([])),
|
||||
|
|
|
@ -31,7 +31,7 @@ class DeleteShortUrlServiceTest extends TestCase
|
|||
private ObjectProphecy $urlResolver;
|
||||
private string $shortCode;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$shortUrl = ShortUrl::createEmpty()->setVisits(new ArrayCollection(
|
||||
map(range(0, 10), fn () => Visit::forValidShortUrl(ShortUrl::createEmpty(), Visitor::emptyInstance())),
|
||||
|
|
|
@ -32,7 +32,7 @@ class ShortUrlResolverTest extends TestCase
|
|||
private ShortUrlResolver $urlResolver;
|
||||
private ObjectProphecy $em;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->urlResolver = new ShortUrlResolver($this->em->reveal());
|
||||
|
|
|
@ -34,7 +34,7 @@ class ShortUrlServiceTest extends TestCase
|
|||
private ObjectProphecy $urlResolver;
|
||||
private ObjectProphecy $titleResolutionHelper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->em->persist(Argument::any())->willReturn(null);
|
||||
|
|
|
@ -30,7 +30,7 @@ class UrlShortenerTest extends TestCase
|
|||
private ObjectProphecy $shortCodeHelper;
|
||||
private ObjectProphecy $eventDispatcher;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->titleResolutionHelper = $this->prophesize(ShortUrlTitleResolutionHelperInterface::class);
|
||||
$this->titleResolutionHelper->processTitleAndValidateUrl(Argument::cetera())->willReturnArgument();
|
||||
|
|
|
@ -22,7 +22,7 @@ class ShortUrlRepositoryAdapterTest extends TestCase
|
|||
|
||||
private ObjectProphecy $repo;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase
|
|||
private PersistenceShortUrlRelationResolver $resolver;
|
||||
private ObjectProphecy $em;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->em->getEventManager()->willReturn(new EventManager());
|
||||
|
|
|
@ -13,7 +13,7 @@ class SimpleShortUrlRelationResolverTest extends TestCase
|
|||
{
|
||||
private SimpleShortUrlRelationResolver $resolver;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->resolver = new SimpleShortUrlRelationResolver();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class ShortUrlDataTransformerTest extends TestCase
|
|||
{
|
||||
private ShortUrlDataTransformer $transformer;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->transformer = new ShortUrlDataTransformer(new ShortUrlStringifier([]));
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class TagServiceTest extends TestCase
|
|||
private ObjectProphecy $em;
|
||||
private ObjectProphecy $repo;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->repo = $this->prophesize(TagRepository::class);
|
||||
|
|
|
@ -27,7 +27,7 @@ class UrlValidatorTest extends TestCase
|
|||
private ObjectProphecy $httpClient;
|
||||
private UrlShortenerOptions $options;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->httpClient = $this->prophesize(ClientInterface::class);
|
||||
$this->options = new UrlShortenerOptions(['validate_url' => true]);
|
||||
|
|
|
@ -38,7 +38,7 @@ class VisitLocatorTest extends TestCase
|
|||
private ObjectProphecy $em;
|
||||
private ObjectProphecy $repo;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManager::class);
|
||||
$this->repo = $this->prophesize(VisitRepositoryInterface::class);
|
||||
|
|
|
@ -43,7 +43,7 @@ class VisitsStatsHelperTest extends TestCase
|
|||
private VisitsStatsHelper $helper;
|
||||
private ObjectProphecy $em;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->helper = new VisitsStatsHelper($this->em->reveal());
|
||||
|
|
|
@ -26,7 +26,7 @@ class VisitsTrackerTest extends TestCase
|
|||
private ObjectProphecy $eventDispatcher;
|
||||
private TrackingOptions $options;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManager::class);
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ use function Shlinkio\Shlink\Core\determineTableName;
|
|||
return static function (ClassMetadata $metadata, array $emConfig): void {
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable(determineTableName('api_keys', $emConfig));
|
||||
$builder->setTable(determineTableName('api_keys', $emConfig))
|
||||
->setCustomRepositoryClass(ApiKey\Repository\ApiKeyRepository::class);
|
||||
|
||||
$builder->createField('id', Types::BIGINT)
|
||||
->makePrimaryKey()
|
||||
|
|
26
module/Rest/config/initial-api-key.config.php
Normal file
26
module/Rest/config/initial-api-key.config.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest;
|
||||
|
||||
use Mezzio\Application;
|
||||
use Shlinkio\Shlink\Core\Config\EnvVars;
|
||||
|
||||
use const PHP_SAPI;
|
||||
|
||||
return [
|
||||
|
||||
// We will try to load the initial API key only for openswoole and RoadRunner.
|
||||
// For php-fpm, the check against the database would happen on every request, resulting in a very bad performance.
|
||||
'initial_api_key' => PHP_SAPI !== 'cli' ? null : EnvVars::INITIAL_API_KEY->loadFromEnv(),
|
||||
|
||||
'dependencies' => [
|
||||
'delegators' => [
|
||||
Application::class => [
|
||||
ApiKey\InitialApiKeyDelegator::class,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
];
|
31
module/Rest/src/ApiKey/InitialApiKeyDelegator.php
Normal file
31
module/Rest/src/ApiKey/InitialApiKeyDelegator.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\ApiKey;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Mezzio\Application;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Repository\ApiKeyRepositoryInterface;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class InitialApiKeyDelegator
|
||||
{
|
||||
public function __invoke(ContainerInterface $container, string $serviceName, callable $callback): Application
|
||||
{
|
||||
$initialApiKey = $container->get('config')['initial_api_key'] ?? null;
|
||||
if ($initialApiKey !== null) {
|
||||
$this->createInitialApiKey($initialApiKey, $container);
|
||||
}
|
||||
|
||||
return $callback();
|
||||
}
|
||||
|
||||
private function createInitialApiKey(string $initialApiKey, ContainerInterface $container): void
|
||||
{
|
||||
/** @var ApiKeyRepositoryInterface $repo */
|
||||
$repo = $container->get(EntityManager::class)->getRepository(ApiKey::class);
|
||||
$repo->createInitialApiKey($initialApiKey);
|
||||
}
|
||||
}
|
32
module/Rest/src/ApiKey/Repository/ApiKeyRepository.php
Normal file
32
module/Rest/src/ApiKey/Repository/ApiKeyRepository.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\ApiKey\Repository;
|
||||
|
||||
use Doctrine\DBAL\LockMode;
|
||||
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class ApiKeyRepository extends EntitySpecificationRepository implements ApiKeyRepositoryInterface
|
||||
{
|
||||
public function createInitialApiKey(string $apiKey): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
$em->wrapInTransaction(function () use ($apiKey, $em): void {
|
||||
// Ideally this would be a SELECT COUNT(...), but MsSQL and Postgres do not allow locking on aggregates
|
||||
// Because of that we check if at least one result exists
|
||||
$firstResult = $em->createQueryBuilder()->select('a.id')
|
||||
->from(ApiKey::class, 'a')
|
||||
->setMaxResults(1)
|
||||
->getQuery()
|
||||
->setLockMode(LockMode::PESSIMISTIC_WRITE)
|
||||
->getOneOrNullResult();
|
||||
|
||||
if ($firstResult === null) {
|
||||
$em->persist(ApiKey::fromKey($apiKey));
|
||||
$em->flush();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\ApiKey\Repository;
|
||||
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface;
|
||||
|
||||
interface ApiKeyRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Will create provided API key only if there's no API keys yet
|
||||
*/
|
||||
public function createInitialApiKey(string $apiKey): void;
|
||||
}
|
|
@ -23,16 +23,14 @@ class ApiKey extends AbstractEntity
|
|||
private bool $enabled;
|
||||
/** @var Collection|ApiKeyRole[] */
|
||||
private Collection $roles;
|
||||
private ?string $name;
|
||||
private ?string $name = null;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private function __construct(?string $name = null, ?Chronos $expirationDate = null)
|
||||
private function __construct(?string $key = null)
|
||||
{
|
||||
$this->key = Uuid::uuid4()->toString();
|
||||
$this->expirationDate = $expirationDate;
|
||||
$this->name = $name;
|
||||
$this->key = $key ?? Uuid::uuid4()->toString();
|
||||
$this->enabled = true;
|
||||
$this->roles = new ArrayCollection();
|
||||
}
|
||||
|
@ -44,7 +42,10 @@ class ApiKey extends AbstractEntity
|
|||
|
||||
public static function fromMeta(ApiKeyMeta $meta): self
|
||||
{
|
||||
$apiKey = new self($meta->name, $meta->expirationDate);
|
||||
$apiKey = self::create();
|
||||
$apiKey->name = $meta->name;
|
||||
$apiKey->expirationDate = $meta->expirationDate;
|
||||
|
||||
foreach ($meta->roleDefinitions as $roleDefinition) {
|
||||
$apiKey->registerRole($roleDefinition);
|
||||
}
|
||||
|
@ -52,6 +53,11 @@ class ApiKey extends AbstractEntity
|
|||
return $apiKey;
|
||||
}
|
||||
|
||||
public static function fromKey(string $key): self
|
||||
{
|
||||
return new self($key);
|
||||
}
|
||||
|
||||
public function getExpirationDate(): ?Chronos
|
||||
{
|
||||
return $this->expirationDate;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioDbTest\Shlink\Rest\ApiKey\Repository;
|
||||
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Repository\ApiKeyRepository;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
||||
|
||||
class ApiKeyRepositoryTest extends DatabaseTestCase
|
||||
{
|
||||
private ApiKeyRepository $repo;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->repo = $this->getEntityManager()->getRepository(ApiKey::class);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function initialApiKeyIsCreatedOnlyOfNoApiKeysExistYet(): void
|
||||
{
|
||||
self::assertCount(0, $this->repo->findAll());
|
||||
$this->repo->createInitialApiKey('initial_value');
|
||||
self::assertCount(1, $this->repo->findAll());
|
||||
self::assertCount(1, $this->repo->findBy(['key' => 'initial_value']));
|
||||
$this->repo->createInitialApiKey('another_one');
|
||||
self::assertCount(1, $this->repo->findAll());
|
||||
self::assertCount(0, $this->repo->findBy(['key' => 'another_one']));
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ class ListDomainsActionTest extends TestCase
|
|||
private ObjectProphecy $domainService;
|
||||
private NotFoundRedirectOptions $options;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->domainService = $this->prophesize(DomainServiceInterface::class);
|
||||
$this->options = new NotFoundRedirectOptions();
|
||||
|
|
|
@ -25,7 +25,7 @@ class HealthActionTest extends TestCase
|
|||
private HealthAction $action;
|
||||
private ObjectProphecy $conn;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->conn = $this->prophesize(Connection::class);
|
||||
$this->conn->executeQuery(Argument::cetera())->willReturn($this->prophesize(Result::class)->reveal());
|
||||
|
|
|
@ -21,7 +21,7 @@ class MercureInfoActionTest extends TestCase
|
|||
|
||||
private ObjectProphecy $provider;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->provider = $this->prophesize(JwtProviderInterface::class);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class CreateShortUrlActionTest extends TestCase
|
|||
private ObjectProphecy $urlShortener;
|
||||
private ObjectProphecy $transformer;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlShortener = $this->prophesize(UrlShortener::class);
|
||||
$this->transformer = $this->prophesize(DataTransformerInterface::class);
|
||||
|
|
|
@ -20,7 +20,7 @@ class DeleteShortUrlActionTest extends TestCase
|
|||
private DeleteShortUrlAction $action;
|
||||
private ObjectProphecy $service;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->service = $this->prophesize(DeleteShortUrlServiceInterface::class);
|
||||
$this->action = new DeleteShortUrlAction($this->service->reveal());
|
||||
|
|
|
@ -24,7 +24,7 @@ class EditShortUrlActionTest extends TestCase
|
|||
private EditShortUrlAction $action;
|
||||
private ObjectProphecy $shortUrlService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->shortUrlService = $this->prophesize(ShortUrlServiceInterface::class);
|
||||
$this->action = new EditShortUrlAction($this->shortUrlService->reveal(), new ShortUrlDataTransformer(
|
||||
|
|
|
@ -26,7 +26,7 @@ class ListShortUrlsActionTest extends TestCase
|
|||
private ListShortUrlsAction $action;
|
||||
private ObjectProphecy $service;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->service = $this->prophesize(ShortUrlService::class);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class ResolveShortUrlActionTest extends TestCase
|
|||
private ResolveShortUrlAction $action;
|
||||
private ObjectProphecy $urlResolver;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
|
||||
$this->action = new ResolveShortUrlAction($this->urlResolver->reveal(), new ShortUrlDataTransformer(
|
||||
|
|
|
@ -25,7 +25,7 @@ class SingleStepCreateShortUrlActionTest extends TestCase
|
|||
private ObjectProphecy $urlShortener;
|
||||
private ObjectProphecy $transformer;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->urlShortener = $this->prophesize(UrlShortenerInterface::class);
|
||||
$this->transformer = $this->prophesize(DataTransformerInterface::class);
|
||||
|
|
|
@ -20,7 +20,7 @@ class DeleteTagsActionTest extends TestCase
|
|||
private DeleteTagsAction $action;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->action = new DeleteTagsAction($this->tagService->reveal());
|
||||
|
|
|
@ -28,7 +28,7 @@ class ListTagsActionTest extends TestCase
|
|||
private ListTagsAction $action;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->action = new ListTagsAction($this->tagService->reveal());
|
||||
|
|
|
@ -27,7 +27,7 @@ class TagsStatsActionTest extends TestCase
|
|||
private TagsStatsAction $action;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->action = new TagsStatsAction($this->tagService->reveal());
|
||||
|
|
|
@ -24,7 +24,7 @@ class UpdateTagActionTest extends TestCase
|
|||
private UpdateTagAction $action;
|
||||
private ObjectProphecy $tagService;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tagService = $this->prophesize(TagServiceInterface::class);
|
||||
$this->action = new UpdateTagAction($this->tagService->reveal());
|
||||
|
|
|
@ -21,7 +21,7 @@ class GlobalVisitsActionTest extends TestCase
|
|||
private GlobalVisitsAction $action;
|
||||
private ObjectProphecy $helper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->helper = $this->prophesize(VisitsStatsHelperInterface::class);
|
||||
$this->action = new GlobalVisitsAction($this->helper->reveal());
|
||||
|
|
|
@ -24,7 +24,7 @@ class NonOrphanVisitsActionTest extends TestCase
|
|||
private NonOrphanVisitsAction $action;
|
||||
private ObjectProphecy $visitsHelper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->visitsHelper = $this->prophesize(VisitsStatsHelperInterface::class);
|
||||
$this->action = new NonOrphanVisitsAction($this->visitsHelper->reveal());
|
||||
|
|
|
@ -27,7 +27,7 @@ class ShortUrlVisitsActionTest extends TestCase
|
|||
private ShortUrlVisitsAction $action;
|
||||
private ObjectProphecy $visitsHelper;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->visitsHelper = $this->prophesize(VisitsStatsHelperInterface::class);
|
||||
$this->action = new ShortUrlVisitsAction($this->visitsHelper->reveal());
|
||||
|
|
61
module/Rest/test/ApiKey/InitialApiKeyDelegatorTest.php
Normal file
61
module/Rest/test/ApiKey/InitialApiKeyDelegatorTest.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Rest\ApiKey;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Mezzio\Application;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\InitialApiKeyDelegator;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Repository\ApiKeyRepositoryInterface;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class InitialApiKeyDelegatorTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
private InitialApiKeyDelegator $delegator;
|
||||
private ObjectProphecy $container;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->delegator = new InitialApiKeyDelegator();
|
||||
$this->container = $this->prophesize(ContainerInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider provideConfigs
|
||||
*/
|
||||
public function apiKeyIsInitializedWhenAppropriate(array $config, int $expectedCalls): void
|
||||
{
|
||||
$app = $this->prophesize(Application::class)->reveal();
|
||||
$apiKeyRepo = $this->prophesize(ApiKeyRepositoryInterface::class);
|
||||
$em = $this->prophesize(EntityManagerInterface::class);
|
||||
|
||||
$getConfig = $this->container->get('config')->willReturn($config);
|
||||
$getRepo = $em->getRepository(ApiKey::class)->willReturn($apiKeyRepo->reveal());
|
||||
$getEm = $this->container->get(EntityManager::class)->willReturn($em->reveal());
|
||||
|
||||
$result = ($this->delegator)($this->container->reveal(), '', fn () => $app);
|
||||
|
||||
self::assertSame($result, $app);
|
||||
$getConfig->shouldHaveBeenCalledOnce();
|
||||
$getRepo->shouldHaveBeenCalledTimes($expectedCalls);
|
||||
$getEm->shouldHaveBeenCalledTimes($expectedCalls);
|
||||
$apiKeyRepo->createInitialApiKey(Argument::any())->shouldHaveBeenCalledTimes($expectedCalls);
|
||||
}
|
||||
|
||||
public function provideConfigs(): iterable
|
||||
{
|
||||
yield [[], 0];
|
||||
yield [['initial_api_key' => null], 0];
|
||||
yield [['initial_api_key' => 'the_initial_key'], 1];
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ class ConfigProviderTest extends TestCase
|
|||
{
|
||||
private ConfigProvider $configProvider;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->configProvider = new ConfigProvider();
|
||||
}
|
||||
|
@ -22,10 +22,11 @@ class ConfigProviderTest extends TestCase
|
|||
{
|
||||
$config = ($this->configProvider)();
|
||||
|
||||
self::assertCount(4, $config);
|
||||
self::assertCount(5, $config);
|
||||
self::assertArrayHasKey('dependencies', $config);
|
||||
self::assertArrayHasKey('auth', $config);
|
||||
self::assertArrayHasKey('entity_manager', $config);
|
||||
self::assertArrayHasKey('initial_api_key', $config);
|
||||
self::assertArrayHasKey(ConfigAbstractFactory::class, $config);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class AuthenticationMiddlewareTest extends TestCase
|
|||
private ObjectProphecy $apiKeyService;
|
||||
private ObjectProphecy $handler;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->apiKeyService = $this->prophesize(ApiKeyServiceInterface::class);
|
||||
$this->middleware = new AuthenticationMiddleware(
|
||||
|
|
|
@ -23,7 +23,7 @@ class BodyParserMiddlewareTest extends TestCase
|
|||
|
||||
private BodyParserMiddleware $middleware;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->middleware = new BodyParserMiddleware();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class CrossDomainMiddlewareTest extends TestCase
|
|||
private CrossDomainMiddleware $middleware;
|
||||
private ObjectProphecy $handler;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->middleware = new CrossDomainMiddleware(['max_age' => 1000]);
|
||||
$this->handler = $this->prophesize(RequestHandlerInterface::class);
|
||||
|
|
|
@ -15,7 +15,7 @@ class EmptyResponseImplicitOptionsMiddlewareFactoryTest extends TestCase
|
|||
{
|
||||
private EmptyResponseImplicitOptionsMiddlewareFactory $factory;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->factory = new EmptyResponseImplicitOptionsMiddlewareFactory();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class CreateShortUrlContentNegotiationMiddlewareTest extends TestCase
|
|||
private CreateShortUrlContentNegotiationMiddleware $middleware;
|
||||
private ObjectProphecy $requestHandler;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->middleware = new CreateShortUrlContentNegotiationMiddleware();
|
||||
$this->requestHandler = $this->prophesize(RequestHandlerInterface::class);
|
||||
|
|
|
@ -23,7 +23,7 @@ class DefaultShortCodesLengthMiddlewareTest extends TestCase
|
|||
private DefaultShortCodesLengthMiddleware $middleware;
|
||||
private ObjectProphecy $handler;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->handler = $this->prophesize(RequestHandlerInterface::class);
|
||||
$this->middleware = new DefaultShortCodesLengthMiddleware(8);
|
||||
|
|
|
@ -22,7 +22,7 @@ class DropDefaultDomainFromRequestMiddlewareTest extends TestCase
|
|||
private DropDefaultDomainFromRequestMiddleware $middleware;
|
||||
private ObjectProphecy $next;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->next = $this->prophesize(RequestHandlerInterface::class);
|
||||
$this->middleware = new DropDefaultDomainFromRequestMiddleware('doma.in');
|
||||
|
|
|
@ -25,7 +25,7 @@ class ApiKeyServiceTest extends TestCase
|
|||
private ApiKeyService $service;
|
||||
private ObjectProphecy $em;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManager::class);
|
||||
$this->service = new ApiKeyService($this->em->reveal());
|
||||
|
|
Loading…
Reference in a new issue