diff --git a/bin/test/run-api-tests.sh b/bin/test/run-api-tests.sh new file mode 100755 index 00000000..5086ce41 --- /dev/null +++ b/bin/test/run-api-tests.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env sh +set -e + +export APP_ENV=test + +# Try to stop server just in case it hanged in last execution +vendor/bin/zend-expressive-swoole stop + +echo 'Starting server...' +vendor/bin/zend-expressive-swoole start -d +sleep 2 + +vendor/bin/phpunit --order-by=random -c phpunit-api.xml +vendor/bin/zend-expressive-swoole stop diff --git a/build.sh b/build.sh index dd287783..99c82087 100755 --- a/build.sh +++ b/build.sh @@ -17,6 +17,7 @@ echo 'Copying project files...' rm -rf "${builtcontent}" mkdir -p "${builtcontent}" rsync -av * "${builtcontent}" \ + --exclude=bin/test \ --exclude=data/infra \ --exclude=data/travis \ --exclude=data/migrations_template.txt \ diff --git a/composer.json b/composer.json index 2e20ed83..b8ce3e66 100644 --- a/composer.json +++ b/composer.json @@ -114,7 +114,7 @@ "test:unit": "phpdbg -qrr vendor/bin/phpunit --order-by=random --coverage-php build/coverage-unit.cov", "test:unit:ci": "phpdbg -qrr vendor/bin/phpunit --order-by=random --coverage-php build/coverage-unit.cov --coverage-clover=build/clover.xml --coverage-xml=build/coverage-xml --log-junit=build/phpunit.junit.xml", "test:db": "APP_ENV=test phpdbg -qrr vendor/bin/phpunit --order-by=random -c phpunit-db.xml --coverage-php build/coverage-db.cov", - "test:api": "APP_ENV=test vendor/bin/zend-expressive-swoole start -d && echo 'Waiting 2 seconds for server to start...' && sleep 2 && APP_ENV=test phpdbg -qrr vendor/bin/phpunit --order-by=random -c phpunit-api.xml && APP_ENV=test vendor/bin/zend-expressive-swoole stop", + "test:api": "bin/test/run-api-tests.sh", "test:pretty": [ "@test", diff --git a/module/Rest/test-api/Middleware/AuthenticationTest.php b/module/Rest/test-api/Middleware/AuthenticationTest.php index 1b0d776e..1e5dea06 100644 --- a/module/Rest/test-api/Middleware/AuthenticationTest.php +++ b/module/Rest/test-api/Middleware/AuthenticationTest.php @@ -4,18 +4,55 @@ declare(strict_types=1); namespace ShlinkioApiTest\Shlink\Rest\Middleware; use GuzzleHttp\Exception\ClientException; +use Shlinkio\Shlink\Rest\Authentication\Plugin\ApiKeyHeaderPlugin; +use Shlinkio\Shlink\Rest\Authentication\RequestToHttpAuthPlugin; +use Shlinkio\Shlink\Rest\Util\RestUtils; use ShlinkioTest\Shlink\Common\ApiTest\ApiTestCase; +use function implode; +use function Shlinkio\Shlink\Common\json_decode; +use function sprintf; class AuthenticationTest extends ApiTestCase { /** * @test */ - public function unauthorizedIsReturnedIfNoAuthenticationIsSent() + public function authorizationErrorIsReturnedIfNoApiKeyIsSent() { - $this->expectException(ClientException::class); - $this->expectExceptionCode(self::STATUS_UNAUTHORIZED); + try { + $this->callApi(self::METHOD_GET, '/short-codes'); + } catch (ClientException $e) { + ['error' => $error, 'message' => $message] = json_decode((string) $e->getResponse()->getBody()); - $this->callApi(self::METHOD_GET, '/short-codes'); + $this->assertEquals(self::STATUS_UNAUTHORIZED, $e->getCode()); + $this->assertEquals(RestUtils::INVALID_AUTHORIZATION_ERROR, $error); + $this->assertEquals( + sprintf( + 'Expected one of the following authentication headers, but none were provided, ["%s"]', + implode('", "', RequestToHttpAuthPlugin::SUPPORTED_AUTH_HEADERS) + ), + $message + ); + } + } + + /** + * @test + */ + public function apiKeyErrorIsReturnedWhenProvidedApiKeyIsInvalid() + { + try { + $this->callApi(self::METHOD_GET, '/short-codes', [ + 'headers' => [ + ApiKeyHeaderPlugin::HEADER_NAME => 'invalid', + ], + ]); + } catch (ClientException $e) { + ['error' => $error, 'message' => $message] = json_decode((string) $e->getResponse()->getBody()); + + $this->assertEquals(self::STATUS_UNAUTHORIZED, $e->getCode()); + $this->assertEquals(RestUtils::INVALID_API_KEY_ERROR, $error); + $this->assertEquals('Provided API key does not exist or is invalid.', $message); + } } }