diff --git a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php index ebc88080..1716c19e 100644 --- a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php +++ b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php @@ -8,12 +8,14 @@ use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\Prophecy\ObjectProphecy; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Rest\Authentication; use Shlinkio\Shlink\Rest\Middleware\CrossDomainMiddleware; use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequest; use Zend\Expressive\Router\Route; use Zend\Expressive\Router\RouteResult; +use function implode; use function Zend\Stratigility\middleware; class CrossDomainMiddlewareTest extends TestCase @@ -39,6 +41,7 @@ class CrossDomainMiddlewareTest extends TestCase $this->assertSame($originalResponse, $response); $headers = $response->getHeaders(); + $this->assertArrayNotHasKey('Access-Control-Allow-Origin', $headers); $this->assertArrayNotHasKey('Access-Control-Expose-Headers', $headers); $this->assertArrayNotHasKey('Access-Control-Allow-Methods', $headers); @@ -59,8 +62,12 @@ class CrossDomainMiddlewareTest extends TestCase $this->assertNotSame($originalResponse, $response); $headers = $response->getHeaders(); - $this->assertArrayHasKey('Access-Control-Allow-Origin', $headers); - $this->assertArrayHasKey('Access-Control-Expose-Headers', $headers); + + $this->assertEquals('local', $response->getHeaderLine('Access-Control-Allow-Origin')); + $this->assertEquals(implode(', ', [ + Authentication\Plugin\ApiKeyHeaderPlugin::HEADER_NAME, + Authentication\Plugin\AuthorizationHeaderPlugin::HEADER_NAME, + ]), $response->getHeaderLine('Access-Control-Expose-Headers')); $this->assertArrayNotHasKey('Access-Control-Allow-Methods', $headers); $this->assertArrayNotHasKey('Access-Control-Max-Age', $headers); $this->assertArrayNotHasKey('Access-Control-Allow-Headers', $headers); @@ -70,18 +77,25 @@ class CrossDomainMiddlewareTest extends TestCase public function optionsRequestIncludesMoreHeaders(): void { $originalResponse = new Response(); - $request = (new ServerRequest())->withMethod('OPTIONS')->withHeader('Origin', 'local'); + $request = (new ServerRequest()) + ->withMethod('OPTIONS') + ->withHeader('Origin', 'local') + ->withHeader('Access-Control-Request-Headers', 'foo, bar, baz'); $this->handler->handle(Argument::any())->willReturn($originalResponse)->shouldBeCalledOnce(); $response = $this->middleware->process($request, $this->handler->reveal()); $this->assertNotSame($originalResponse, $response); $headers = $response->getHeaders(); - $this->assertArrayHasKey('Access-Control-Allow-Origin', $headers); - $this->assertArrayHasKey('Access-Control-Expose-Headers', $headers); + + $this->assertEquals('local', $response->getHeaderLine('Access-Control-Allow-Origin')); + $this->assertEquals(implode(', ', [ + Authentication\Plugin\ApiKeyHeaderPlugin::HEADER_NAME, + Authentication\Plugin\AuthorizationHeaderPlugin::HEADER_NAME, + ]), $response->getHeaderLine('Access-Control-Expose-Headers')); $this->assertArrayHasKey('Access-Control-Allow-Methods', $headers); - $this->assertArrayHasKey('Access-Control-Max-Age', $headers); - $this->assertArrayHasKey('Access-Control-Allow-Headers', $headers); + $this->assertEquals('1000', $response->getHeaderLine('Access-Control-Max-Age')); + $this->assertEquals('foo, bar, baz', $response->getHeaderLine('Access-Control-Allow-Headers')); } /** diff --git a/module/Rest/test/Service/ApiKeyServiceTest.php b/module/Rest/test/Service/ApiKeyServiceTest.php index d79cea41..caa50bf1 100644 --- a/module/Rest/test/Service/ApiKeyServiceTest.php +++ b/module/Rest/test/Service/ApiKeyServiceTest.php @@ -27,65 +27,49 @@ class ApiKeyServiceTest extends TestCase $this->service = new ApiKeyService($this->em->reveal()); } - /** @test */ - public function keyIsProperlyCreated() + /** + * @test + * @dataProvider provideCreationDate + */ + public function apiKeyIsProperlyCreated(?Chronos $date): void { $this->em->flush()->shouldBeCalledOnce(); $this->em->persist(Argument::type(ApiKey::class))->shouldBeCalledOnce(); - $key = $this->service->create(); - $this->assertNull($key->getExpirationDate()); - } - - /** @test */ - public function keyIsProperlyCreatedWithExpirationDate() - { - $this->em->flush()->shouldBeCalledOnce(); - $this->em->persist(Argument::type(ApiKey::class))->shouldBeCalledOnce(); - - $date = Chronos::parse('2030-01-01'); $key = $this->service->create($date); - $this->assertSame($date, $key->getExpirationDate()); + + $this->assertEquals($date, $key->getExpirationDate()); } - /** @test */ - public function checkReturnsFalseWhenKeyIsInvalid() + public function provideCreationDate(): iterable + { + yield 'no expiration date' => [null]; + yield 'expiration date' => [Chronos::parse('2030-01-01')]; + } + + /** + * @test + * @dataProvider provideInvalidApiKeys + */ + public function checkReturnsFalseForInvalidApiKeys(?ApiKey $invalidKey): void { $repo = $this->prophesize(EntityRepository::class); - $repo->findOneBy(['key' => '12345'])->willReturn(null) + $repo->findOneBy(['key' => '12345'])->willReturn($invalidKey) ->shouldBeCalledOnce(); $this->em->getRepository(ApiKey::class)->willReturn($repo->reveal()); $this->assertFalse($this->service->check('12345')); } - /** @test */ - public function checkReturnsFalseWhenKeyIsDisabled() + public function provideInvalidApiKeys(): iterable { - $key = new ApiKey(); - $key->disable(); - $repo = $this->prophesize(EntityRepository::class); - $repo->findOneBy(['key' => '12345'])->willReturn($key) - ->shouldBeCalledOnce(); - $this->em->getRepository(ApiKey::class)->willReturn($repo->reveal()); - - $this->assertFalse($this->service->check('12345')); + yield 'non-existent api key' => [null]; + yield 'disabled api key' => [(new ApiKey())->disable()]; + yield 'expired api key' => [new ApiKey(Chronos::now()->subDay())]; } /** @test */ - public function checkReturnsFalseWhenKeyIsExpired() - { - $key = new ApiKey(Chronos::now()->subDay()); - $repo = $this->prophesize(EntityRepository::class); - $repo->findOneBy(['key' => '12345'])->willReturn($key) - ->shouldBeCalledOnce(); - $this->em->getRepository(ApiKey::class)->willReturn($repo->reveal()); - - $this->assertFalse($this->service->check('12345')); - } - - /** @test */ - public function checkReturnsTrueWhenConditionsAreFavorable() + public function checkReturnsTrueWhenConditionsAreFavorable(): void { $repo = $this->prophesize(EntityRepository::class); $repo->findOneBy(['key' => '12345'])->willReturn(new ApiKey()) @@ -96,7 +80,7 @@ class ApiKeyServiceTest extends TestCase } /** @test */ - public function disableThrowsExceptionWhenNoTokenIsFound() + public function disableThrowsExceptionWhenNoApiKeyIsFound(): void { $repo = $this->prophesize(EntityRepository::class); $repo->findOneBy(['key' => '12345'])->willReturn(null) @@ -104,11 +88,12 @@ class ApiKeyServiceTest extends TestCase $this->em->getRepository(ApiKey::class)->willReturn($repo->reveal()); $this->expectException(InvalidArgumentException::class); + $this->service->disable('12345'); } /** @test */ - public function disableReturnsDisabledKeyWhenFOund() + public function disableReturnsDisabledApiKeyWhenFound(): void { $key = new ApiKey(); $repo = $this->prophesize(EntityRepository::class); @@ -125,24 +110,32 @@ class ApiKeyServiceTest extends TestCase } /** @test */ - public function listFindsAllApiKeys() + public function listFindsAllApiKeys(): void { + $expectedApiKeys = [new ApiKey(), new ApiKey(), new ApiKey()]; + $repo = $this->prophesize(EntityRepository::class); - $repo->findBy([])->willReturn([]) + $repo->findBy([])->willReturn($expectedApiKeys) ->shouldBeCalledOnce(); $this->em->getRepository(ApiKey::class)->willReturn($repo->reveal()); - $this->service->listKeys(); + $result = $this->service->listKeys(); + + $this->assertEquals($expectedApiKeys, $result); } /** @test */ - public function listEnabledFindsOnlyEnabledApiKeys() + public function listEnabledFindsOnlyEnabledApiKeys(): void { + $expectedApiKeys = [new ApiKey(), new ApiKey(), new ApiKey()]; + $repo = $this->prophesize(EntityRepository::class); - $repo->findBy(['enabled' => true])->willReturn([]) + $repo->findBy(['enabled' => true])->willReturn($expectedApiKeys) ->shouldBeCalledOnce(); $this->em->getRepository(ApiKey::class)->willReturn($repo->reveal()); - $this->service->listKeys(true); + $result = $this->service->listKeys(true); + + $this->assertEquals($expectedApiKeys, $result); } }