From a6bdd0716081167bcfa19f659e176463f2ad64ab Mon Sep 17 00:00:00 2001 From: Marcus Olsson Date: Fri, 16 Sep 2022 10:56:38 +0200 Subject: [PATCH] Ability to set fully customizable response-handler (#59) * wip * Rewrite tests in Pest * Remove obsolete workflows, require PHP 7.4 * Fix DefaultResponseHandler namespacing * Fix for dependencies (phpunit) * Testing for response handlers * Check compatibility issue (testbench) * Update response-handler key * Update readme --- .github/workflows/test.yml | 13 +- LICENSE.md | 2 +- README.jp.md | 2 +- README.md | 23 +- composer.json | 21 +- src/Handlers/DefaultResponseHandler.php | 35 ++ src/Handlers/ResponseHandler.php | 10 + src/Http/Middleware/VeryBasicAuth.php | 37 +- src/VeryBasicAuthServiceProvider.php | 7 + src/config.stub | 3 + tests/Fixtures/CustomResponseHandler.php | 14 + tests/Pest.php | 5 + tests/TestCase.php | 27 ++ tests/VeryBasicAuthTests.php | 491 +++++++---------------- 14 files changed, 293 insertions(+), 397 deletions(-) create mode 100644 src/Handlers/DefaultResponseHandler.php create mode 100644 src/Handlers/ResponseHandler.php create mode 100644 tests/Fixtures/CustomResponseHandler.php create mode 100644 tests/Pest.php create mode 100644 tests/TestCase.php diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 154073d..122bbd8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,25 +11,14 @@ jobs: include: - php: 8.1 illuminate: ^9.0 - phpunit: ^9.0 - php: 8.1 illuminate: ^8.0 - phpunit: ^9.0 - php: 8.0 illuminate: ^8.0 - phpunit: ^9.0 - php: 8.0 illuminate: ^7.0 - phpunit: ^8.0 - php: 7.4 illuminate: ^7.0 - phpunit: ^8.0 - - php: 7.3 - illuminate: ^7.0 - phpunit: ^8.0 - - php: 7.2 - illuminate: ^6.0 - phpunit: ^8.0 name: PHP ${{ matrix.php }} - Illuminate ${{ matrix.illuminate }} @@ -46,7 +35,7 @@ jobs: run: composer self-update --2 - name: Install dependencies - run: composer require "illuminate/support:${{ matrix.illuminate }}" "phpunit/phpunit:${{ matrix.phpunit }}" --no-interaction --no-progress --no-suggest + run: composer require "illuminate/support:${{ matrix.illuminate }}" --no-interaction --no-progress --no-suggest - name: Execute tests run: composer test diff --git a/LICENSE.md b/LICENSE.md index 24a7f82..477b3eb 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # The MIT License (MIT) -Copyright (c) 2021 Marcus Olsson +Copyright (c) 2022 Marcus Olsson > Permission is hereby granted, free of charge, to any person obtaining a copy > of this software and associated documentation files (the "Software"), to deal diff --git a/README.jp.md b/README.jp.md index 8733b13..16eb34a 100644 --- a/README.jp.md +++ b/README.jp.md @@ -148,7 +148,7 @@ $ phpunit MITライセンスです。 詳しくはこちらを見てください。[License File](LICENSE.md) -© 2021 [Marcus Olsson](https://marcusolsson.me). +© 2022 [Marcus Olsson](https://marcusolsson.me). [ico-version]: https://img.shields.io/packagist/v/olssonm/l5-very-basic-auth.svg?style=flat-square [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square diff --git a/README.md b/README.md index 5e42806..f27c4cf 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,25 @@ Or ], ``` +### Response handlers + +When the authentication fails the response handler sends out an error response (see "Views and messages" for more about these options). By default the handler will be `\Olssonm\VeryBasicAuth\Handlers\DefaultResponseHandler` (see `response_handler` in `very_basic_auth.php`). You may however write your own response-logic if you so choose. The only requirement is that it implements the `\Olssonm\VeryBasicAuth\Handlers\ResponseHandler`-interface, and has an `__invoke`-method that accepts a request-object, like so: + +``` php +use Illuminate\Http\Request; +use Olssonm\VeryBasicAuth\Handlers\ResponseHandler; + +class CustomResponseHandler implements ResponseHandler +{ + public function __invoke(Request $request) + { + // Do some stuff + return response('Custom response', 401); + } +} +``` + + ### Views and messages In the `very_basic_auth.php`-configuration you have the ability to set a custom view instead of a message. @@ -116,8 +135,6 @@ In the `very_basic_auth.php`-configuration you have the ability to set a custom If you uncomment `error_view`, the middleware will try to find your specified view. You supply this value as usual (without the `.blade.php`-extention). -*If you've upgraded to 2.1 from a previous version this key and value will be missing from your published configuration and you will have to add it yourself.* - ## Usage The middleware uses the `auth.very_basic`-filter to protect routes. You can either use `Route::group()` to protect multiple routes, or chose just to protect them individually. @@ -177,7 +194,7 @@ A big thank you to the people who has contributed to this package, among others: The MIT License (MIT). Please see [License File](LICENSE.md) for more information. -© 2021 [Marcus Olsson](https://marcusolsson.me). +© 2022 [Marcus Olsson](https://marcusolsson.me). [ico-version]: https://img.shields.io/packagist/v/olssonm/l5-very-basic-auth.svg?style=flat-square [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square diff --git a/composer.json b/composer.json index 485747c..b4f19a6 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,16 @@ } ], "require": { - "illuminate/support": "^6.0|^7.0|^8.0|^9.0", - "php" : "^7.2|^8.0", + "illuminate/support": "^7.0|^8.0|^9.0", + "php" : "~7.4|^8.0", "squizlabs/php_codesniffer": "^3.5" }, "require-dev": { - "phpunit/phpunit": "^7.5|^8.0|^9.0", - "orchestra/testbench": ">=3.4.0", - "laravel/helpers": "^1.1" + "phpunit/phpunit": "^9.0", + "orchestra/testbench": ">=5.0", + "laravel/helpers": "^1.1", + "pestphp/pest": "^1.0", + "pestphp/pest-plugin-laravel": "^1.2" }, "autoload": { "psr-4": { @@ -39,7 +41,7 @@ "scripts": { "phpsniff": "vendor/bin/phpcs --standard=\"PSR12\" ./src --ignore=./src/resources/*", "phpfix": "vendor/bin/phpcbf --standard=\"PSR12\" ./src --ignore=./src/resources/*", - "test": "vendor/bin/phpunit" + "test": "vendor/bin/pest" }, "extra": { "branch-alias": { @@ -52,5 +54,10 @@ } }, "minimum-stability": "dev", - "prefer-stable": true + "prefer-stable": true, + "config": { + "allow-plugins": { + "pestphp/pest-plugin": true + } + } } diff --git a/src/Handlers/DefaultResponseHandler.php b/src/Handlers/DefaultResponseHandler.php new file mode 100644 index 0000000..dcaaba7 --- /dev/null +++ b/src/Handlers/DefaultResponseHandler.php @@ -0,0 +1,35 @@ + sprintf( + 'Basic realm="%s", charset="UTF-8"', + config('very_basic_auth.realm', 'Basic Auth') + ) + ]; + + // View + $view = config('very_basic_auth.error_view'); + + // If the request want's JSON, else view + if ($request->wantsJson()) { + return response()->json([ + 'message' => config('very_basic_auth.error_message') + ], 401, $header); + } elseif (isset($view)) { + return response()->view($view, [], 401) + ->withHeaders($header); + } + + // Return default message + return response(config('very_basic_auth.error_message'), 401, $header); + } +} diff --git a/src/Handlers/ResponseHandler.php b/src/Handlers/ResponseHandler.php new file mode 100644 index 0000000..cdc764d --- /dev/null +++ b/src/Handlers/ResponseHandler.php @@ -0,0 +1,10 @@ +responseHandler = $responseHandler; + } + /** * Handle an incoming request * @@ -26,8 +35,8 @@ public function handle(Request $request, Closure $next, $username = null, $passw // Check if middleware is in use in current environment if ($active) { - $authUsername = (empty($username)) ? config('very_basic_auth.user') : $username; - $authPassword = (empty($password)) ? config('very_basic_auth.password') : $password; + $authUsername = $username ?? config('very_basic_auth.user'); + $authPassword = $password ?? config('very_basic_auth.password'); // Check for credentials if ($request->getUser() !== $authUsername || $request->getPassword() !== $authPassword) { @@ -46,28 +55,6 @@ public function handle(Request $request, Closure $next, $username = null, $passw */ private function deniedResponse(Request $request): Response { - // Build header - $header = [ - 'WWW-Authenticate' => sprintf( - 'Basic realm="%s", charset="UTF-8"', - config('very_basic_auth.realm', 'Basic Auth') - ) - ]; - - // View - $view = config('very_basic_auth.error_view'); - - // If the request want's JSON, else view - if ($request->wantsJson()) { - return response()->json([ - 'message' => config('very_basic_auth.error_message') - ], 401, $header); - } elseif (isset($view)) { - return response()->view($view, [], 401) - ->withHeaders($header); - } - - // Return default message - return response(config('very_basic_auth.error_message'), 401, $header); + return ($this->responseHandler)($request); } } diff --git a/src/VeryBasicAuthServiceProvider.php b/src/VeryBasicAuthServiceProvider.php index 6b68589..7638463 100644 --- a/src/VeryBasicAuthServiceProvider.php +++ b/src/VeryBasicAuthServiceProvider.php @@ -4,6 +4,8 @@ use Illuminate\Support\ServiceProvider; use Illuminate\Support\Str; +use Olssonm\VeryBasicAuth\Handlers\DefaultResponseHandler; +use Olssonm\VeryBasicAuth\Handlers\ResponseHandler; class VeryBasicAuthServiceProvider extends ServiceProvider { @@ -71,6 +73,11 @@ public function register() $this->config, 'very_basic_auth' ); + + $this->app->bind( + ResponseHandler::class, + config('very_basic_auth.response_handler', DefaultResponseHandler::class) + ); } /** diff --git a/src/config.stub b/src/config.stub index 17f4f1d..de56cff 100644 --- a/src/config.stub +++ b/src/config.stub @@ -15,6 +15,9 @@ '*' ], + // Response handler for the error responses + 'response_handler' => \Olssonm\VeryBasicAuth\Handlers\DefaultResponseHandler::class, + // Message to display if the user "opts out"/clicks "cancel" 'error_message' => 'You have to supply your credentials to access this resource.', diff --git a/tests/Fixtures/CustomResponseHandler.php b/tests/Fixtures/CustomResponseHandler.php new file mode 100644 index 0000000..7169aef --- /dev/null +++ b/tests/Fixtures/CustomResponseHandler.php @@ -0,0 +1,14 @@ +in(__DIR__); diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..0ce1f51 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,27 @@ +middleware = new VeryBasicAuth; - } - - /** - * Load the package - * @return array the packages - */ - protected function getPackageProviders($app) - { - return [ - \Olssonm\VeryBasicAuth\VeryBasicAuthServiceProvider::class - ]; - } - - /** @test */ - public function test_very_basic_auth_route_filter_is_set() - { - $middlewares = $this->app->router->getMiddleware(); - $this->assertTrue(in_array('Olssonm\VeryBasicAuth\Http\Middleware\VeryBasicAuth', $middlewares)); - $this->assertTrue(array_key_exists('auth.very_basic', $middlewares)); - } - - /** @test */ - public function test_config_file_is_installed() - { - // Look for config.php - $this->assertTrue(file_exists(__DIR__ . '/../src/config.php')); - } - - /** @test */ - public function test_view_exists() - { - $view = file_get_contents(__DIR__ . '/../src/resources/views/default.blade.php'); - - if (method_exists($this, 'assertStringContainsStringIgnoringCase')) { - $this->assertStringContainsStringIgnoringCase('This is the default view for the olssonm/l5-very-basic-auth-package', $view); - } else { - $this->assertContains('This is the default view for the olssonm/l5-very-basic-auth-package', $view); - } - } - - /** @test */ - public function test_very_basic_auth_authenticate_no_credentials() - { - $request = new Request(); - $response = new JsonResponse(); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(config('very_basic_auth.error_message'), $result->getContent()); - } - - /** @test */ - public function test_very_basic_auth_authenticate_incorrect_credentials() - { - $request = new Request(); - $response = new JsonResponse(); - - $user = str_random(20); - $pass = str_random(20); - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(config('very_basic_auth.error_message'), $result->getContent()); - } - - /** @test */ - public function test_very_basic_auth_authenticate_incorrect_password() - { - $request = new Request(); - $response = new JsonResponse(); - - $user = config('very_basic_auth.user'); - $pass = str_random(20); - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(config('very_basic_auth.error_message'), $result->getContent()); - } - - /** @test */ - public function test_very_basic_auth_authenticate_incorrect_user() - { - $request = new Request(); - $response = new JsonResponse(); - - $user = str_random(20); - $pass = config('very_basic_auth.password'); - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(config('very_basic_auth.error_message'), $result->getContent()); - } - - /** @test */ - public function test_very_basic_auth_authenticate_correct_credentials() - { - $request = new Request(); - $response = new JsonResponse(); - - $user = config('very_basic_auth.user'); - $pass = config('very_basic_auth.password'); - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $this->assertEquals(200, $result->getStatusCode()); - $this->assertEquals('{}', $result->getContent()); - } - - /** @test */ - public function test_very_basic_auth_json_failed_response() - { - $request = new Request(); - $response = new JsonResponse(); - - $user = config('very_basic_auth.user'); - $pass = str_random(20); - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - $request->headers->add(['Accept' => 'application/json']); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $content = json_decode($result->getContent()); - - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(json_last_error(), JSON_ERROR_NONE); - $this->assertEquals('application/json', $result->headers->get('content-type')); - $this->assertEquals(config('very_basic_auth.error_message'), $content->message); - } - - /** @test */ - public function test_very_basic_auth_view_incorrect_credentials() - { - // Set the middleware to use a view - config()->set('very_basic_auth.error_view', 'very_basic_auth::default'); - - $request = new Request(); - $response = new JsonResponse(); - - $user = str_random(20); - $pass = str_random(20); - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - - // PHPUNIT 7.5.6+ - if (method_exists($this, 'assertStringContainsStringIgnoringCase')) { - $this->assertStringContainsStringIgnoringCase('This is the default view for the olssonm/l5-very-basic-auth-package', $result->getContent()); - } else { - $this->assertContains('This is the default view for the olssonm/l5-very-basic-auth-package', $result->getContent()); - } - } - - /* test */ - public function test_very_basic_auth_env_local() - { - // Set the environment to only be "local" - config()->set('very_basic_auth.envs', ['local']); - - $request = new Request(); - $response = new JsonResponse(); - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - // 200 becouse we should be locked out; tests occurs in the testing env. - $this->assertEquals(200, $result->getStatusCode()); - } - - /* test */ - public function test_very_basic_auth_env_testing() - { - // Set the environment to only be "testing" - config()->set('very_basic_auth.envs', ['testing']); - - $request = new Request(); - $response = new JsonResponse(); - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(config('very_basic_auth.error_message'), $result->getContent()); - } - - /* test */ - public function test_very_basic_auth_env_wildcard() - { - // Set the environment to use wildcard - config()->set('very_basic_auth.envs', ['*']); - - $request = new Request(); - $response = new JsonResponse(); - $next = function ($request) use ($response) { - return $response; - }; - - $result = $this->middleware->handle($request, $next); - - $realm = config('very_basic_auth.realm', 'Basic Auth'); - - $this->assertEquals('Basic realm="' . $realm . '", charset="UTF-8"', $result->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $result->getStatusCode()); - $this->assertEquals(config('very_basic_auth.error_message'), $result->getContent()); - } - - /* test */ - public function test_inline_credentials_success() - { - config()->set('very_basic_auth.user', 'test'); - config()->set('very_basic_auth.password', 'test'); - - // Use random user and password - $user = str_random(20); - $pass = str_random(20); - - $request = new Request(); - $response = new JsonResponse(); - $next = function ($request) use ($response) { - return $response; - }; - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $result = $this->middleware->handle($request, $next, $user, $pass); - - $this->assertEquals(200, $result->getStatusCode()); - } - - /* test */ - public function test_inline_credentials_fail() - { - config()->set('very_basic_auth.user', 'test'); - config()->set('very_basic_auth.password', 'test'); - - // Use random user and password - $user = str_random(20); - $pass = str_random(20); - - $request = new Request(); - $response = new JsonResponse(); - $next = function ($request) use ($response) { - return $response; - }; - - $request->headers->add(['PHP_AUTH_USER' => $user]); - $request->headers->add(['PHP_AUTH_PW' => $pass]); - - $result = $this->middleware->handle($request, $next, 'test', 'test'); - - $this->assertEquals(401, $result->getStatusCode()); - } - - /** Teardown */ - public static function tearDownAfterClass(): void - { - parent::tearDownAfterClass(); - unlink(__DIR__ . '/../src/config.php'); - } -} +use Olssonm\VeryBasicAuth\Tests\Fixtures\CustomResponseHandler; + +use function Pest\Laravel\get; + +beforeEach(function() { + Route::get('/', fn () => 'ok')->middleware(VeryBasicAuth::class)->name('default'); + Route::get('/test', fn () => 'ok')->middleware(VeryBasicAuth::class); + Route::get('/inline', fn () => 'ok')->middleware( + sprintf('auth.very_basic:%s,%s', config('very_basic_auth.user'), config('very_basic_auth.password')) + )->name('inline'); +}); + +test('basic auth filter is set', function () { + $this->assertTrue(in_array(VeryBasicAuth::class, $this->app->router->getMiddleware())); + $this->assertTrue(array_key_exists('auth.very_basic', $this->app->router->getMiddleware())); +}); + +test('config file is installed', function() { + $this->assertTrue(file_exists(__DIR__ . '/../src/config.php')); +}); + +test('request with no credentials fails', function() { + $response = get('/'); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals(sprintf('Basic realm="%s", charset="UTF-8"', config('very_basic_auth.realm')), $response->headers->get('WWW-Authenticate')); + $this->assertEquals(config('very_basic_auth.error_message'), $response->getContent()); +}); + +test('request with incorrect credentials fails - text/html', function () { + $response = $this->withHeaders([ + 'PHP_AUTH_USER' => str_random(20), + 'PHP_AUTH_PW' => str_random(20) + ])->get('/'); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('content-type')); + $this->assertEquals(sprintf('Basic realm="%s", charset="UTF-8"', config('very_basic_auth.realm')), $response->headers->get('WWW-Authenticate')); + $this->assertEquals(config('very_basic_auth.error_message'), $response->getContent()); +}); + +test('request with incorrect credentials fails - json', function () { + $response = $this->withHeaders([ + 'PHP_AUTH_USER' => str_random(20), + 'PHP_AUTH_PW' => str_random(20), + 'Accept' => 'application/json' + ])->get('/'); + + $content = json_decode($response->getContent()); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals('application/json', $response->headers->get('content-type')); + $this->assertEquals(json_last_error(), JSON_ERROR_NONE); + $this->assertEquals(config('very_basic_auth.error_message'), $content->message); + $this->assertEquals(sprintf('Basic realm="%s", charset="UTF-8"', config('very_basic_auth.realm')), $response->headers->get('WWW-Authenticate')); +}); + +test('request with incorrect credentials fails - view', function () { + + config()->set('very_basic_auth.error_view', 'very_basic_auth::default'); + + $response = $this->withHeaders([ + 'PHP_AUTH_USER' => str_random(20), + 'PHP_AUTH_PW' => str_random(20) + ])->get('/'); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('content-type')); + $this->assertEquals(sprintf('Basic realm="%s", charset="UTF-8"', config('very_basic_auth.realm')), $response->headers->get('WWW-Authenticate')); + $this->assertStringContainsStringIgnoringCase('This is the default view for the olssonm/l5-very-basic-auth-package', $response->getContent()); +}); + +test('request with correct credentials passes', function () { + $response = $this->withHeaders([ + 'PHP_AUTH_USER' => config('very_basic_auth.user'), + 'PHP_AUTH_PW' => config('very_basic_auth.password') + ])->get('/'); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('ok', $response->getContent()); +}); + +test('environments', function () { + config()->set('very_basic_auth.envs', ['production']); + $this->get('/')->assertStatus(200); + + config()->set('very_basic_auth.envs', ['local']); + $this->get('/')->assertStatus(200); + + config()->set('very_basic_auth.envs', ['*']); + $this->get('/')->assertStatus(401); + + config()->set('very_basic_auth.envs', ['testing']); + $this->get('/')->assertStatus(401); +}); + +test('request with incorrect inline credentials fails', function () { + $response = $this->withHeaders([ + 'PHP_AUTH_USER' => str_random(20), + 'PHP_AUTH_PW' => str_random(20) + ])->get('/inline'); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals(config('very_basic_auth.error_message'), $response->getContent()); +}); + +test('request with correct inline credentials passes', function () { + $response = $this->withHeaders([ + 'PHP_AUTH_USER' => config('very_basic_auth.user'), + 'PHP_AUTH_PW' => config('very_basic_auth.password') + ])->get('/inline'); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('ok', $response->getContent()); +}); + +test('test response handlers', function () { + // Custom response handler + app()->bind( + ResponseHandler::class, + CustomResponseHandler::class + ); + + $response = get('/test'); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals('Custom response', $response->getContent()); + + // Default response handler + app()->bind( + ResponseHandler::class, + DefaultResponseHandler::class + ); + + $response = get('/test'); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertEquals(config('very_basic_auth.error_message'), $response->getContent()); +});