From d2bd9d2d1bdbfd9443fc5514850d2bbcc152a059 Mon Sep 17 00:00:00 2001 From: Ron Rise Date: Thu, 16 Oct 2025 00:24:58 +0000 Subject: [PATCH] chore/dev-env (#6) Reviewed-on: https://gitea.siteworxpro.com/siteworxpro/Php-Template/pulls/6 Co-authored-by: Ron Rise Co-committed-by: Ron Rise --- .dockerignore | 1 + .gitignore | 1 + README.md | 2 +- config.php | 13 +++-- src/Controllers/Controller.php | 8 +++ src/Controllers/ControllerInterface.php | 8 +++ src/Server.php | 15 ++---- src/Services/Facade.php | 4 +- .../ServiceProviders/RedisServiceProvider.php | 1 + tests/Controllers/AbstractController.php | 16 ++++++ tests/Controllers/ControllerTest.php | 54 +++++++++++++++++++ tests/Controllers/IndexControllerTest.php | 25 +++++++++ tests/Facades/AbstractFacade.php | 32 +++++++++++ tests/Facades/RedisTest.php | 21 ++++++++ .../AbstractServiceProvider.php | 43 +++++++++++++++ .../LoggerServiceProviderTest.php | 15 ++++++ .../RedisServiceProviderTest.php | 15 ++++++ tests/Unit.php | 14 +++-- 18 files changed, 267 insertions(+), 21 deletions(-) create mode 100644 tests/Controllers/AbstractController.php create mode 100644 tests/Controllers/ControllerTest.php create mode 100644 tests/Controllers/IndexControllerTest.php create mode 100644 tests/Facades/AbstractFacade.php create mode 100644 tests/Facades/RedisTest.php create mode 100644 tests/ServiceProviders/AbstractServiceProvider.php create mode 100644 tests/ServiceProviders/LoggerServiceProviderTest.php create mode 100644 tests/ServiceProviders/RedisServiceProviderTest.php diff --git a/.dockerignore b/.dockerignore index 5c37160..1d86eeb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ .idea/ +.DS_Store vendor/ .phpunit.cache/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5c37160..1d86eeb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ +.DS_Store vendor/ .phpunit.cache/ \ No newline at end of file diff --git a/README.md b/README.md index 734856b..c60c60e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ You can access the api at `http://localhost:9501/` xdebug needs to be built into the container before it will work ```shell - docker exec -it template-runtime-1 bin/xdebug.sh + docker exec -it php-template-composer-runtime-1 bin/xdebug.sh ``` ### Install the dependencies diff --git a/config.php b/config.php index 38739d0..89e4c00 100644 --- a/config.php +++ b/config.php @@ -8,7 +8,7 @@ return [ * The server configuration. */ 'server' => [ - 'port' => Env::get('HTTP_PORT', 9501, 'int'), + 'port' => Env::get('HTTP_PORT', 9501, 'int'), 'dev_mode' => Env::get('DEV_MODE', false, 'bool'), ], @@ -21,9 +21,15 @@ return [ 'database' => Env::get('DB_DATABASE', 'siteworxpro'), 'username' => Env::get('DB_USERNAME', 'siteworxpro'), 'password' => Env::get('DB_PASSWORD', 'password'), + 'port' => Env::get('DB_PORT', 5432, 'int'), + 'charset' => Env::get('DB_CHARSET', 'utf8'), + 'collation' => Env::get('DB_COLLATION', 'utf8_unicode_ci'), + 'prefix' => Env::get('DB_PREFIX', ''), + 'options' => [ + // Add any additional PDO options here + ], ], - 'cors' => [ 'allowed_origins' => Env::get('CORS_ALLOWED_ORIGINS', 'localhost:3000'), 'allow_credentials' => Env::get('CORS_ALLOW_CREDENTIALS', true, 'bool'), @@ -34,5 +40,6 @@ return [ 'host' => Env::get('REDIS_HOST', 'localhost'), 'port' => Env::get('REDIS_PORT', 6379, 'int'), 'database' => Env::get('REDIS_DATABASE', 0, 'int'), + 'password' => Env::get('REDIS_PASSWORD'), ] -]; \ No newline at end of file +]; diff --git a/src/Controllers/Controller.php b/src/Controllers/Controller.php index 641f6d8..e603520 100644 --- a/src/Controllers/Controller.php +++ b/src/Controllers/Controller.php @@ -28,6 +28,14 @@ abstract class Controller implements ControllerInterface throw new NotFoundException("not found"); } + /** + * @throws NotFoundException + */ + public function put(ServerRequest $request): ResponseInterface + { + throw new NotFoundException("not found"); + } + /** * @throws NotFoundException */ diff --git a/src/Controllers/ControllerInterface.php b/src/Controllers/ControllerInterface.php index 68811fe..e3df828 100644 --- a/src/Controllers/ControllerInterface.php +++ b/src/Controllers/ControllerInterface.php @@ -25,6 +25,14 @@ interface ControllerInterface */ public function post(ServerRequest $request): ResponseInterface; + /** + * Handle the request and return a response. + * + * @param ServerRequest $request The request data. + * @return ResponseInterface The response data. + */ + public function put(ServerRequest $request): ResponseInterface; + /** * Handle the request and return a response. * diff --git a/src/Server.php b/src/Server.php index acb7d03..22a39d3 100644 --- a/src/Server.php +++ b/src/Server.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Siteworxpro\App; use Illuminate\Container\Container; +use Illuminate\Database\Capsule\Manager; use Illuminate\Support\ServiceProvider; use League\Route\Http\Exception\MethodNotAllowedException; use League\Route\Http\Exception\NotFoundException; @@ -120,18 +121,8 @@ class Server */ public function bootModelCapsule(): void { - $capsule = new \Illuminate\Database\Capsule\Manager(); - $capsule->addConnection([ - 'driver' => Config::get('db.driver'), - 'host' => Config::get('db.host'), - 'database' => Config::get('db.database'), - 'username' => Config::get('db.username'), - 'password' => Config::get('db.password'), - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - ]); - + $capsule = new Manager(); + $capsule->addConnection(Config::get('db')); $capsule->setAsGlobal(); $capsule->bootEloquent(); } diff --git a/src/Services/Facade.php b/src/Services/Facade.php index 355259a..7e8140f 100644 --- a/src/Services/Facade.php +++ b/src/Services/Facade.php @@ -278,10 +278,10 @@ class Facade /** * Set the application instance. * - * @param Container $container + * @param Container | null $container * @return void */ - public static function setFacadeContainer(Container $container): void + public static function setFacadeContainer(Container | null $container): void { static::$container = $container; } diff --git a/src/Services/ServiceProviders/RedisServiceProvider.php b/src/Services/ServiceProviders/RedisServiceProvider.php index 064d050..c22b5a5 100644 --- a/src/Services/ServiceProviders/RedisServiceProvider.php +++ b/src/Services/ServiceProviders/RedisServiceProvider.php @@ -18,6 +18,7 @@ class RedisServiceProvider extends ServiceProvider 'host' => Config::get('redis.host'), 'port' => Config::get('redis.port'), 'database' => Config::get('redis.database'), + 'password' => Config::get('redis.password'), ]); }); } diff --git a/tests/Controllers/AbstractController.php b/tests/Controllers/AbstractController.php new file mode 100644 index 0000000..084c4c4 --- /dev/null +++ b/tests/Controllers/AbstractController.php @@ -0,0 +1,16 @@ +expectException(\League\Route\Http\Exception\NotFoundException::class); + $testClass->get($this->getMockRequest()); + } + + public function testNotFoundExceptionPost() + { + $testClass = new TestClass(); + + $this->expectException(\League\Route\Http\Exception\NotFoundException::class); + $testClass->post($this->getMockRequest()); + } + + public function testNotFoundExceptionPut() + { + $testClass = new TestClass(); + + $this->expectException(\League\Route\Http\Exception\NotFoundException::class); + $testClass->put($this->getMockRequest()); + } + + public function testNotFoundExceptionDelete() + { + $testClass = new TestClass(); + + $this->expectException(\League\Route\Http\Exception\NotFoundException::class); + $testClass->delete($this->getMockRequest()); + } + + public function testNotFoundExceptionPatch() + { + $testClass = new TestClass(); + + $this->expectException(\League\Route\Http\Exception\NotFoundException::class); + $testClass->patch($this->getMockRequest()); + } +} + +class TestClass extends Controller // phpcs:ignore +{ +} diff --git a/tests/Controllers/IndexControllerTest.php b/tests/Controllers/IndexControllerTest.php new file mode 100644 index 0000000..ff28901 --- /dev/null +++ b/tests/Controllers/IndexControllerTest.php @@ -0,0 +1,25 @@ +assertTrue(true); + + $controller = new IndexController(); + + $response = $controller->get($this->getMockRequest()); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('{"status_code":200,"message":"Server is running"}', (string)$response->getBody()); + } +} diff --git a/tests/Facades/AbstractFacade.php b/tests/Facades/AbstractFacade.php new file mode 100644 index 0000000..e224979 --- /dev/null +++ b/tests/Facades/AbstractFacade.php @@ -0,0 +1,32 @@ +getFacadeClass(); + + $this->assertTrue( + method_exists($class, 'getFacadeAccessor'), + sprintf('The class %s must implement the method getFacadeAccessor.', $class) + ); + + $facade = $class::getFacadeRoot(); + + $this->assertNotNull( + $facade, + sprintf('The facade %s is not properly initialized.', $this->getConcrete()) + ); + } +} diff --git a/tests/Facades/RedisTest.php b/tests/Facades/RedisTest.php new file mode 100644 index 0000000..f087c20 --- /dev/null +++ b/tests/Facades/RedisTest.php @@ -0,0 +1,21 @@ +getProviderClass(); + + /** @var ServiceProvider $providerClass */ + $provider = new $providerClass($container); + + $this->assertInstanceOf($providerClass, $provider); + $provider->register(); + + $bindings = $provider->bindings; + foreach ($bindings as $abstract => $concrete) { + $this->assertTrue($container->bound($abstract), "The $abstract is not bound in the container."); + $this->assertNotNull($container->make($abstract), "The $abstract could not be resolved."); + + $this->assertInstanceOf( + $concrete, + $container->make($abstract), + "The $abstract is not an instance of $concrete." + ); + } + } +} diff --git a/tests/ServiceProviders/LoggerServiceProviderTest.php b/tests/ServiceProviders/LoggerServiceProviderTest.php new file mode 100644 index 0000000..beb389a --- /dev/null +++ b/tests/ServiceProviders/LoggerServiceProviderTest.php @@ -0,0 +1,15 @@ +bind(SWConfig::class, function () { + return SWConfig::load(__DIR__ . '/../config.php'); + }); } protected function tearDown(): void { Config::clearResolvedInstances(); - Facade::setFacadeApplication(null); + Facade::setFacadeContainer(null); } }