diff --git a/module/Rest/config/dependencies.config.php b/module/Rest/config/dependencies.config.php index e9fcbfa5..2434c88b 100644 --- a/module/Rest/config/dependencies.config.php +++ b/module/Rest/config/dependencies.config.php @@ -21,7 +21,7 @@ return [ ApiKeyService::class => ConfigAbstractFactory::class, Action\HealthAction::class => ConfigAbstractFactory::class, - Action\MercureAction::class => ConfigAbstractFactory::class, + Action\MercureInfoAction::class => ConfigAbstractFactory::class, Action\ShortUrl\CreateShortUrlAction::class => ConfigAbstractFactory::class, Action\ShortUrl\SingleStepCreateShortUrlAction::class => ConfigAbstractFactory::class, Action\ShortUrl\EditShortUrlAction::class => ConfigAbstractFactory::class, @@ -48,7 +48,7 @@ return [ ApiKeyService::class => ['em'], Action\HealthAction::class => [Connection::class, AppOptions::class, 'Logger_Shlink'], - Action\MercureAction::class => [LcobucciJwtProvider::class, 'config.mercure', 'Logger_Shlink'], + Action\MercureInfoAction::class => [LcobucciJwtProvider::class, 'config.mercure', 'Logger_Shlink'], Action\ShortUrl\CreateShortUrlAction::class => [ Service\UrlShortener::class, 'config.url_shortener.domain', diff --git a/module/Rest/config/routes.config.php b/module/Rest/config/routes.config.php index afb44249..3ced8357 100644 --- a/module/Rest/config/routes.config.php +++ b/module/Rest/config/routes.config.php @@ -34,7 +34,7 @@ return [ Action\Tag\CreateTagsAction::getRouteDef(), Action\Tag\UpdateTagAction::getRouteDef(), - Action\MercureAction::getRouteDef(), + Action\MercureInfoAction::getRouteDef(), ], ]; diff --git a/module/Rest/src/Action/MercureAction.php b/module/Rest/src/Action/MercureInfoAction.php similarity index 96% rename from module/Rest/src/Action/MercureAction.php rename to module/Rest/src/Action/MercureInfoAction.php index 7c33fa31..906a0b45 100644 --- a/module/Rest/src/Action/MercureAction.php +++ b/module/Rest/src/Action/MercureInfoAction.php @@ -13,7 +13,7 @@ use Shlinkio\Shlink\Common\Mercure\JwtProviderInterface; use Shlinkio\Shlink\Rest\Exception\MercureException; use Throwable; -class MercureAction extends AbstractRestAction +class MercureInfoAction extends AbstractRestAction { protected const ROUTE_PATH = '/mercure-info'; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; diff --git a/module/Rest/test/Action/MercureInfoActionTest.php b/module/Rest/test/Action/MercureInfoActionTest.php new file mode 100644 index 00000000..f9489c99 --- /dev/null +++ b/module/Rest/test/Action/MercureInfoActionTest.php @@ -0,0 +1,107 @@ +provider = $this->prophesize(JwtProviderInterface::class); + } + + /** + * @test + * @dataProvider provideNoHostConfigs + */ + public function throwsExceptionWhenConfigDoesNotHavePublicHost(array $mercureConfig): void + { + $buildToken = $this->provider->buildSubscriptionToken(Argument::any())->willReturn('abc.123'); + + $action = new MercureInfoAction($this->provider->reveal(), $mercureConfig); + + $this->expectException(MercureException::class); + $buildToken->shouldNotBeCalled(); + + $action->handle(ServerRequestFactory::fromGlobals()); + } + + public function provideNoHostConfigs(): iterable + { + yield 'host not defined' => [[]]; + yield 'host is null' => [['public_hub_url' => null]]; + } + + /** + * @test + * @dataProvider provideValidConfigs + */ + public function throwsExceptionWhenBuildingTokenFails(array $mercureConfig): void + { + $buildToken = $this->provider->buildSubscriptionToken(Argument::any())->willThrow( + new RuntimeException('Error'), + ); + + $action = new MercureInfoAction($this->provider->reveal(), $mercureConfig); + + $this->expectException(MercureException::class); + $buildToken->shouldBeCalledOnce(); + + $action->handle(ServerRequestFactory::fromGlobals()); + } + + public function provideValidConfigs(): iterable + { + yield 'days not defined' => [['public_hub_url' => 'http://foobar.com']]; + yield 'days defined' => [['public_hub_url' => 'http://foobar.com', 'jwt_days_duration' => 20]]; + } + + /** + * @test + * @dataProvider provideDays + */ + public function returnsExpectedInfoWhenEverythingIsOk(?int $days): void + { + $buildToken = $this->provider->buildSubscriptionToken(Argument::any())->willReturn('abc.123'); + + $action = new MercureInfoAction($this->provider->reveal(), [ + 'public_hub_url' => 'http://foobar.com', + 'jwt_days_duration' => $days, + ]); + + /** @var JsonResponse $resp */ + $resp = $action->handle(ServerRequestFactory::fromGlobals()); + $payload = $resp->getPayload(); + + $this->assertArrayHasKey('mercureHubUrl', $payload); + $this->assertEquals('http://foobar.com', $payload['mercureHubUrl']); + $this->assertArrayHasKey('token', $payload); + $this->assertArrayHasKey('jwtExpiration', $payload); + $this->assertEquals( + Chronos::now()->addDays($days ?? 3)->startOfDay(), + Chronos::parse($payload['jwtExpiration'])->startOfDay(), + ); + $buildToken->shouldHaveBeenCalledOnce(); + } + + public function provideDays(): iterable + { + yield 'days not defined' => [null]; + yield 'days defined' => [10]; + } +}