From a033c13b8d11717afb43e793b810cce4f4c3011a Mon Sep 17 00:00:00 2001 From: Brandon Shipley Date: Fri, 23 Jan 2026 20:32:22 -0800 Subject: [PATCH] phpcbf and added .gitea workflows --- .gitea/workflows/ci.yaml | 48 ++-- .gitea/workflows/release.yaml | 17 ++ composer.json | 20 +- .../Migrations/20251008093507_CreateCarts.php | 200 ++++++++-------- phpcs.xml | 21 ++ phpstan.neon | 10 + src/CakeCartsPlugin.php | 84 ++++--- src/Controller/AppController.php | 3 +- src/Controller/CartItemsController.php | 219 +++++++++--------- src/Controller/CartsController.php | 41 ++-- .../Component/ShoppingCartComponent.php | 209 ++++++++--------- src/Model/Entity/Cart.php | 37 +-- src/Model/Entity/CartItem.php | 29 +-- src/Model/Enum/CartTypeId.php | 24 +- src/Model/Table/CartItemsTable.php | 116 +++++----- src/Model/Table/CartsTable.php | 95 ++++---- tests/Fixture/CartItemsFixture.php | 106 ++++----- tests/Fixture/CartsFixture.php | 130 +++++------ .../Controller/CartItemsControllerTest.php | 147 ++++++------ .../Controller/CartsControllerTest.php | 48 ++-- .../Component/ShoppingCartComponentTest.php | 33 ++- .../Model/Table/CartItemsTableTest.php | 65 +++--- tests/TestCase/Model/Table/CartsTableTest.php | 65 +++--- tests/bootstrap.php | 101 ++++---- 24 files changed, 949 insertions(+), 919 deletions(-) create mode 100644 .gitea/workflows/release.yaml create mode 100644 phpcs.xml create mode 100644 phpstan.neon diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 85f43aa..116c897 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -12,8 +12,8 @@ jobs: fail-fast: false matrix: php-version: ['8.2', '8.4'] - db-type: ['mysql'] - # db-type: ['sqlite', 'mysql', 'pgsql'] + # db-type: ['mysql'] + db-type: ['sqlite', 'mysql', 'pgsql'] prefer-lowest: [''] include: - php-version: '8.2' @@ -26,20 +26,13 @@ jobs: env: MYSQL_ALLOW_EMPTY_PASSWORD: yes MYSQL_DATABASE: cakephp -# services: -# postgres: -# image: postgres -# ports: -# - 5432:5432 -# env: -# POSTGRES_PASSWORD: postgres -# mysql8: -# image: mysql:8.0 -# env: -# MYSQL_ALLOW_EMPTY_PASSWORD: yes -# MYSQL_DATABASE: test_db -# ports: -# - 3306:3306 + # services: + # postgres: + # image: postgres + # ports: + # - 5432:5432 + # env: + # POSTGRES_PASSWORD: postgres steps: - uses: actions/checkout@v4 @@ -47,7 +40,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} - extensions: mbstring, intl, sqlite, pdo_${{ matrix.db-type }} + extensions: mbstring, intl, bcmath, sqlite, pdo_${{ matrix.db-type }} coverage: pcov - name: Get composer cache directory @@ -94,11 +87,11 @@ jobs: if: matrix.prefer-lowest == 'prefer-lowest' run: vendor/bin/validate-prefer-lowest -m -# - name: Upload coverage reports to Codecov -# if: success() && matrix.php-version == '8.2' -# uses: codecov/codecov-action@v4 -# with: -# token: ${{ secrets.CODECOV_TOKEN }} + # - name: Upload coverage reports to Codecov + # if: success() && matrix.php-version == '8.2' + # uses: codecov/codecov-action@v4 + # with: + # token: ${{ secrets.CODECOV_TOKEN }} validation: name: Coding Standard & Static Analysis @@ -108,8 +101,8 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' - extensions: mbstring, intl, sqlite + php-version: '8.2' + extensions: mbstring, intl, sqlite, bcmath coverage: none - name: Get composer cache directory @@ -133,11 +126,8 @@ jobs: composer install --no-progress --prefer-dist --optimize-autoloader fi - - name: Composer phpstan setup - run: composer stan-setup - - name: Run phpstan - run: vendor/bin/phpstan analyse --error-format=github + run: vendor/bin/phpstan analyse src --error-format=github - name: Run phpcs - run: composer cs-check \ No newline at end of file + run: composer cs-check diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..77787fb --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,17 @@ +name: Release + +on: + push: + tags: + - "v*.*.*" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Release + uses: softprops/action-gh-release@v2 + + diff --git a/composer.json b/composer.json index 7a091f8..dd4324c 100644 --- a/composer.json +++ b/composer.json @@ -8,11 +8,15 @@ "php": ">=8.2", "dereuromark/cakephp-tools": "^3.9", "muffin/trash": "^4.2", - "cakephp/cakephp": "^5.0.1" + "cakephp/cakephp": "^5.1" }, "require-dev": { "phpunit/phpunit": "^10.1", - "cakephp/migrations": "^4.0.0" + "cakephp/migrations": "^4.0.0", + "phpstan/phpstan": "^2.1", + "dereuromark/composer-prefer-lowest": "^0.1.10", + "cakedc/cakephp-phpstan": "^4.1", + "fig-r/psr2r-sniffer": "^2.7" }, "suggest": { "hi-powered-dev/cake-products": "Manage products and SKUs with a heirarhical category structure, includes attributes and variants" @@ -28,5 +32,17 @@ "Cake\\Test\\": "vendor/cakephp/cakephp/tests/", "TestApp\\": "tests/test_app/src/" } + }, + "scripts": { + "cs-check": "vendor/bin/phpcs --colors --parallel=16", + "cs-fix": "vendor/bin/phpcbf --colors --parallel=16", + "lowest": "validate-prefer-lowest", + "lowest-setup": "composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction && cp composer.json composer.backup && composer require --dev dereuromark/composer-prefer-lowest && mv composer.backup composer.json", + "stan": "phpstan analyze" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": false + } } } diff --git a/config/Migrations/20251008093507_CreateCarts.php b/config/Migrations/20251008093507_CreateCarts.php index de2aa5e..f2d1d64 100644 --- a/config/Migrations/20251008093507_CreateCarts.php +++ b/config/Migrations/20251008093507_CreateCarts.php @@ -3,112 +3,112 @@ declare(strict_types=1); use Migrations\BaseMigration; -class CreateCarts extends BaseMigration -{ - /** +class CreateCarts extends BaseMigration { + + /** * Change Method. * * More information on this method is available here: * https://book.cakephp.org/migrations/4/en/migrations.html#the-change-method * @return void */ - public function change(): void - { - $table = $this->table('carts', ['id' => false, 'primary_key' => ['id']]); - $table->addColumn('id', 'uuid', [ - 'default' => null, - 'null' => false, - ]); - $table->addColumn('cart_type_id', 'integer', [ - 'default' => null, - 'limit' => 11, - 'null' => false, - ]); - $table->addColumn('session_id', 'string', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('user_id', 'integer', [ - 'default' => null, - 'limit' => 11, - 'null' => true, - ]); - $table->addColumn('user_id_uuid', 'uuid', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('created', 'datetime', [ - 'default' => null, - 'null' => false, - ]); - $table->addColumn('modified', 'datetime', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('deleted', 'datetime', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('removed', 'datetime', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('removed_reason_id', 'integer', [ - 'default' => null, - 'limit' => 11, - 'null' => true, - ]); - $table->addColumn('num_items', 'integer', [ - 'default' => 0, - 'null' => false, - ]); - $table->create(); + public function change(): void { + $table = $this->table('carts', ['id' => false, 'primary_key' => ['id']]); + $table->addColumn('id', 'uuid', [ + 'default' => null, + 'null' => false, + ]); + $table->addColumn('cart_type_id', 'integer', [ + 'default' => null, + 'limit' => 11, + 'null' => false, + ]); + $table->addColumn('session_id', 'string', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('user_id', 'integer', [ + 'default' => null, + 'limit' => 11, + 'null' => true, + ]); + $table->addColumn('user_id_uuid', 'uuid', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('created', 'datetime', [ + 'default' => null, + 'null' => false, + ]); + $table->addColumn('modified', 'datetime', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('deleted', 'datetime', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('removed', 'datetime', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('removed_reason_id', 'integer', [ + 'default' => null, + 'limit' => 11, + 'null' => true, + ]); + $table->addColumn('num_items', 'integer', [ + 'default' => 0, + 'null' => false, + ]); + $table->create(); - $table = $this->table('cart_items', ['id' => false, 'primary_key' => ['id']]); - $table->addColumn('id', 'uuid', [ - 'default' => null, - 'null' => false, - ]); - $table->addColumn('foreign_key', 'integer', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('foreign_key_uuid', 'uuid', [ - 'default' => null, - 'null' => true, - ]); - $table->addColumn('model', 'string', [ - 'default' => null, - 'limit' => 255, - 'null' => false, - ]); - $table->addColumn('cart_id', 'uuid', [ - 'default' => null, - 'null' => false, - ]); - $table->addColumn('position', 'integer', [ - 'default' => null, - 'limit' => 11, - 'null' => true, - ]); - $table->addColumn('qty', 'integer', [ - 'default' => null, - 'limit' => 11, - 'null' => false, - ]); - $table->addColumn('price', 'decimal', [ - 'default' => null, - 'null' => true, - 'precision' => 13, - 'scale' => 5, - ]); - $table->addColumn('subtotal', 'decimal', [ - 'default' => null, - 'null' => true, - 'precision' => 13, - 'scale' => 5, - ]); + $table = $this->table('cart_items', ['id' => false, 'primary_key' => ['id']]); + $table->addColumn('id', 'uuid', [ + 'default' => null, + 'null' => false, + ]); + $table->addColumn('foreign_key', 'integer', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('foreign_key_uuid', 'uuid', [ + 'default' => null, + 'null' => true, + ]); + $table->addColumn('model', 'string', [ + 'default' => null, + 'limit' => 255, + 'null' => false, + ]); + $table->addColumn('cart_id', 'uuid', [ + 'default' => null, + 'null' => false, + ]); + $table->addColumn('position', 'integer', [ + 'default' => null, + 'limit' => 11, + 'null' => true, + ]); + $table->addColumn('qty', 'integer', [ + 'default' => null, + 'limit' => 11, + 'null' => false, + ]); + $table->addColumn('price', 'decimal', [ + 'default' => null, + 'null' => true, + 'precision' => 13, + 'scale' => 5, + ]); + $table->addColumn('subtotal', 'decimal', [ + 'default' => null, + 'null' => true, + 'precision' => 13, + 'scale' => 5, + ]); + + $table->create(); + } - $table->create(); - } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..689bfe3 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,21 @@ + + + + + src/ + config/ + tests/ + + /tests/test_files/ + /tests/test_app/ + + + + + */config/Migrations/* + + + */config/Migrations/* + + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..b251d7d --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +includes: + - vendor/cakedc/cakephp-phpstan/extension.neon + +parameters: + level: 4 + paths: + - src + bootstrapFiles: + - tests/bootstrap.php + treatPhpDocTypesAsCertain: false diff --git a/src/CakeCartsPlugin.php b/src/CakeCartsPlugin.php index 737439d..8b144af 100644 --- a/src/CakeCartsPlugin.php +++ b/src/CakeCartsPlugin.php @@ -13,9 +13,9 @@ use Cake\Routing\RouteBuilder; /** * Plugin for CakeCarts */ -class CakeCartsPlugin extends BasePlugin -{ - /** +class CakeCartsPlugin extends BasePlugin { + + /** * Load all the plugin configuration and bootstrap logic. * * The host application is provided as an argument. This allows you to load @@ -24,12 +24,11 @@ class CakeCartsPlugin extends BasePlugin * @param \Cake\Core\PluginApplicationInterface $app The host application * @return void */ - public function bootstrap(PluginApplicationInterface $app): void - { - // remove this method hook if you don't need it - } + public function bootstrap(PluginApplicationInterface $app): void { + // remove this method hook if you don't need it + } - /** + /** * Add routes for the plugin. * * If your plugin has many routes and you would like to isolate them into a separate file, @@ -38,62 +37,59 @@ class CakeCartsPlugin extends BasePlugin * @param \Cake\Routing\RouteBuilder $routes The route builder to update. * @return void */ - public function routes(RouteBuilder $routes): void - { - // remove this method hook if you don't need it - $routes->plugin( - 'CakeCarts', - ['path' => '/cake-carts'], - function (RouteBuilder $builder) { - // Add custom routes here - $builder->connect('/wishlist', ['controller' => 'CakeCarts', 'action' => 'wishlist']); + public function routes(RouteBuilder $routes): void { + // remove this method hook if you don't need it + $routes->plugin( + 'CakeCarts', + ['path' => '/cake-carts'], + function (RouteBuilder $builder) { + // Add custom routes here + $builder->connect('/wishlist', ['controller' => 'CakeCarts', 'action' => 'wishlist']); - $builder->fallbacks(); - } - ); - parent::routes($routes); - } + $builder->fallbacks(); + }, + ); + parent::routes($routes); + } - /** + /** * Add middleware for the plugin. * * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to update. * @return \Cake\Http\MiddlewareQueue */ - public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue - { - // Add your middlewares here - // remove this method hook if you don't need it + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { + // Add your middlewares here + // remove this method hook if you don't need it - return $middlewareQueue; - } + return $middlewareQueue; + } - /** + /** * Add commands for the plugin. * * @param \Cake\Console\CommandCollection $commands The command collection to update. * @return \Cake\Console\CommandCollection */ - public function console(CommandCollection $commands): CommandCollection - { - // Add your commands here - // remove this method hook if you don't need it + public function console(CommandCollection $commands): CommandCollection { + // Add your commands here + // remove this method hook if you don't need it - $commands = parent::console($commands); + $commands = parent::console($commands); - return $commands; - } + return $commands; + } - /** + /** * Register application container services. * + * @link https://book.cakephp.org/5/en/development/dependency-injection.html#dependency-injection * @param \Cake\Core\ContainerInterface $container The Container to update. * @return void - * @link https://book.cakephp.org/5/en/development/dependency-injection.html#dependency-injection */ - public function services(ContainerInterface $container): void - { - // Add your services here - // remove this method hook if you don't need it - } + public function services(ContainerInterface $container): void { + // Add your services here + // remove this method hook if you don't need it + } + } diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index a8a0743..843727f 100644 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -5,6 +5,5 @@ namespace CakeCarts\Controller; use App\Controller\AppController as BaseController; -class AppController extends BaseController -{ +class AppController extends BaseController { } diff --git a/src/Controller/CartItemsController.php b/src/Controller/CartItemsController.php index d4b0001..c77eb41 100644 --- a/src/Controller/CartItemsController.php +++ b/src/Controller/CartItemsController.php @@ -4,10 +4,7 @@ declare(strict_types=1); namespace CakeCarts\Controller; use Cake\Core\Configure; -use Cake\Datasource\Exception\RecordNotFoundException; -use Cake\Http\Client; use Cake\Log\Log; -use CakeCarts\Controller\AppController; /** * CartItems Controller @@ -15,148 +12,148 @@ use CakeCarts\Controller\AppController; * @property \CakeCarts\Model\Table\CartItemsTable $CartItems * @property \Authorization\Controller\Component\AuthorizationComponent $Authorization */ -class CartItemsController extends AppController -{ - public function initialize(): void - { - parent::initialize(); // TODO: Change the autogenerated stub +class CartItemsController extends AppController { - if (!$this->components()->has('ShoppingCart')) { - $this->loadComponent('CakeCarts.ShoppingCart', [ - // This is default config. You can modify "actions" as needed to make - // component work only for specified methods. - 'actions' => ['add'], - ]); - } + /** + * @return void + */ + public function initialize(): void { + parent::initialize(); // TODO: Change the autogenerated stub - if ($this->components()->has('Authorization')) { - $this->Authorization->skipAuthorization(); - } - } + if (!$this->components()->has('ShoppingCart')) { + $this->loadComponent('CakeCarts.ShoppingCart', [ + // This is default config. You can modify "actions" as needed to make + // component work only for specified methods. + 'actions' => ['add'], + ]); + } - /** + if ($this->components()->has('Authorization')) { + $this->Authorization->skipAuthorization(); + } + } + + /** * Add method * * @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise. */ - public function add() - { - $this->request->allowMethod(['post', 'put', 'patch']); + public function add() { + $this->request->allowMethod(['post', 'put', 'patch']); - Log::debug(print_r('$this->request->getData()', true)); - Log::debug(print_r($this->request->getData(), true)); - $cart = $this->viewBuilder()->getVar('cart'); - $postData = $this->request->getData(); - $postData['cart_id'] = $cart->id; - // get product skus with variants - $price = $this->request->getData('price'); - $qty = $this->request->getData('qty', 1); - $postData['price'] = $price; - $postData['subtotal'] = isset($price) ? bcmul("$price", "$qty", 5) : null; + Log::debug(print_r('$this->request->getData()', true)); + Log::debug(print_r($this->request->getData(), true)); + $cart = $this->viewBuilder()->getVar('cart'); + $postData = $this->request->getData(); + $postData['cart_id'] = $cart->id; + // get product skus with variants + $price = $this->request->getData('price'); + $qty = $this->request->getData('qty', 1); + $postData['price'] = $price; + $postData['subtotal'] = isset($price) ? bcmul("$price", "$qty", 5) : null; - $newCartItem = $this->CartItems->newEntity($postData, [ - 'validate' => Configure::readOrFail('CakeCarts.CartItems.requirePricing') ? 'requirePricing' : 'default', - ]); + $newCartItem = $this->CartItems->newEntity($postData, [ + 'validate' => Configure::readOrFail('CakeCarts.CartItems.requirePricing') ? 'requirePricing' : 'default', + ]); - if ($this->CartItems->save($newCartItem)) { - $this->Flash->success('Added to cart'); + if ($this->CartItems->save($newCartItem)) { + $this->Flash->success('Added to cart'); - return $this->redirect($this->referer([ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'index' - ])); - } + return $this->redirect($this->referer([ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'index', + ])); + } // Log::debug(print_r('$newCartItem->getErrors()', true)); // Log::debug(print_r($newCartItem->getErrors(), true)); - $this->Flash->error('Failed to add to cart.'); + $this->Flash->error('Failed to add to cart.'); - return $this->redirect($this->referer([ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'index' - ])); - } + return $this->redirect($this->referer([ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'index', + ])); + } - /** + /** * Edit method * * @param string|null $id Cart Item id. - * @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. + * @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise. */ - public function edit($id = null) - { - $this->request->allowMethod(['post', 'put', 'patch']); + public function edit($id = null) { + $this->request->allowMethod(['post', 'put', 'patch']); - $cartItem = $this->CartItems->find() - ->where(['CartItems.id' => $id]) - ->contain(['Carts']) - ->firstOrFail(); + $cartItem = $this->CartItems->find() + ->where(['CartItems.id' => $id]) + ->contain(['Carts']) + ->firstOrFail(); - $this->ShoppingCart->checkIfIsOwnCart($cartItem->cart); + $this->ShoppingCart->checkIfIsOwnCart($cartItem->cart); - if ($this->request->is(['patch', 'post', 'put'])) { - $postData = $this->request->getData(); - $qty = $this->request->getData('qty', 1); - $price = $this->request->getData('price', null); - $subtotal = isset($price) ? bcmul("$qty", "$price", 5) : null; - $postData['subtotal'] = $subtotal; - $cartItem = $this->CartItems->patchEntity($cartItem, $postData, [ - 'validate' => Configure::readOrFail('CakeCarts.CartItems.requirePricing') ? 'requiresPricing' : 'default', - ]); - if ($this->CartItems->save($cartItem)) { - $this->Flash->success(__('The cart item has been saved.')); + if ($this->request->is(['patch', 'post', 'put'])) { + $postData = $this->request->getData(); + $qty = $this->request->getData('qty', 1); + $price = $this->request->getData('price', null); + $subtotal = isset($price) ? bcmul("$qty", "$price", 5) : null; + $postData['subtotal'] = $subtotal; + $cartItem = $this->CartItems->patchEntity($cartItem, $postData, [ + 'validate' => Configure::readOrFail('CakeCarts.CartItems.requirePricing') ? 'requiresPricing' : 'default', + ]); + if ($this->CartItems->save($cartItem)) { + $this->Flash->success(__('The cart item has been saved.')); - return $this->redirect($this->referer([ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'index' - ])); - } - Log::debug(print_r('$cartItem->getErrors()', true)); - Log::debug(print_r($cartItem->getErrors(), true)); - $this->Flash->error(__('The cart item could not be saved. Please, try again.')); - } + return $this->redirect($this->referer([ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'index', + ])); + } + Log::debug(print_r('$cartItem->getErrors()', true)); + Log::debug(print_r($cartItem->getErrors(), true)); + $this->Flash->error(__('The cart item could not be saved. Please, try again.')); + } - return $this->redirect($this->referer([ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'index' - ])); - } + return $this->redirect($this->referer([ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'index', + ])); + } - /** + /** * Delete method * * @param string|null $id Cart Item id. - * @return \Cake\Http\Response|null Redirects to index. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. + * @return \Cake\Http\Response|null Redirects to index. */ - public function delete($id = null) - { - $this->request->allowMethod(['post', 'delete']); - $identity = $this->getRequest()->getAttribute('identity'); + public function delete($id = null) { + $this->request->allowMethod(['post', 'delete']); + $identity = $this->getRequest()->getAttribute('identity'); // $cart = $this->viewBuilder()->getVar('cart'); - $cartItem = $this->CartItems->find() - ->where(['CartItems.id' => $id]) - ->contain(['Carts']) - ->firstOrFail(); + $cartItem = $this->CartItems->find() + ->where(['CartItems.id' => $id]) + ->contain(['Carts']) + ->firstOrFail(); - $this->ShoppingCart->checkIfIsOwnCart($cartItem->cart); + $this->ShoppingCart->checkIfIsOwnCart($cartItem->cart); - unset($cartItem->cart); - if ($this->CartItems->delete($cartItem)) { - $this->Flash->success(__('The cart item has been deleted.')); - } else { - $this->Flash->error(__('The cart item could not be deleted. Please, try again.')); - } + unset($cartItem->cart); + if ($this->CartItems->delete($cartItem)) { + $this->Flash->success(__('The cart item has been deleted.')); + } else { + $this->Flash->error(__('The cart item could not be deleted. Please, try again.')); + } + + return $this->redirect($this->referer([ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'index', + ])); + } - return $this->redirect($this->referer([ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'index' - ])); - } } diff --git a/src/Controller/CartsController.php b/src/Controller/CartsController.php index 74e87d0..46f9d52 100644 --- a/src/Controller/CartsController.php +++ b/src/Controller/CartsController.php @@ -4,37 +4,36 @@ declare(strict_types=1); namespace CakeCarts\Controller; use App\Controller\AppController; -use Cake\Core\Configure; -use Cake\Event\EventInterface; -use CakeCarts\Model\Enum\CartTypeId; /** * Carts Controller * * @property \Authorization\Controller\Component\AuthorizationComponent $Authorization */ -class CartsController extends AppController -{ - public function initialize(): void - { - parent::initialize(); // TODO: Change the autogenerated stub +class CartsController extends AppController { - if (!$this->components()->has('ShoppingCart')) { - $this->loadComponent('CakeCarts.ShoppingCart', [ - // This is default config. You can modify "actions" as needed to make - // component work only for specified methods. - 'actions' => true, - ]); - } - } + /** + * @return void + */ + public function initialize(): void { + parent::initialize(); // TODO: Change the autogenerated stub - /** + if (!$this->components()->has('ShoppingCart')) { + $this->loadComponent('CakeCarts.ShoppingCart', [ + // This is default config. You can modify "actions" as needed to make + // component work only for specified methods. + 'actions' => true, + ]); + } + } + + /** * Index method * * @return \Cake\Http\Response|null|void Renders view */ - public function index() - { - // use cart from beforeFilter - } + public function index() { + // use cart from beforeFilter + } + } diff --git a/src/Controller/Component/ShoppingCartComponent.php b/src/Controller/Component/ShoppingCartComponent.php index ad6cbdc..43ae241 100644 --- a/src/Controller/Component/ShoppingCartComponent.php +++ b/src/Controller/Component/ShoppingCartComponent.php @@ -10,159 +10,156 @@ use Cake\Datasource\Exception\RecordNotFoundException; use Cake\Event\EventInterface; use Cake\ORM\Table; use Cake\ORM\TableRegistry; -use CakeCarts\Model\Entity\CartItem; use CakeCarts\Model\Enum\CartTypeId; use CakeCarts\Model\Table\CartsTable; /** * ShoppingCart component */ -class ShoppingCartComponent extends Component -{ - /** +class ShoppingCartComponent extends Component { + + /** * @var string $userIdField */ - protected string $userIdField; + protected string $userIdField; - /** - * @var CartsTable|Table $Carts + /** + * @var \CakeCarts\Model\Table\CartsTable|\Cake\ORM\Table $Carts */ - protected CartsTable|Table $Carts; + protected CartsTable|Table $Carts; + /** + * @return void + */ + public function initialize(array $config): void { + parent::initialize($config); // TODO: Change the autogenerated stub - public function initialize(array $config): void - { - parent::initialize($config); // TODO: Change the autogenerated stub + $this->userIdField = Configure::readOrFail('CakeCarts.Users.user_id') === 'uuid' ? 'user_id_uuid' : 'user_id'; + $this->Carts = TableRegistry::getTableLocator()->get(Configure::readOrFail('CakeCarts.Carts.table')); + } - $this->userIdField = Configure::readOrFail('CakeCarts.Users.user_id') === 'uuid' ? 'user_id_uuid' : 'user_id'; - $this->Carts = TableRegistry::getTableLocator()->get(Configure::readOrFail('CakeCarts.Carts.table')); - } - - /** + /** * Default configuration. * * @var array */ - protected array $_defaultConfig = []; + protected array $_defaultConfig = []; - public function beforeFilter(EventInterface $event): void - { - if (!$this->_isActionEnabled()) { - return; - } + /** + * @return void + */ + public function beforeFilter(EventInterface $event): void { + if (!$this->_isActionEnabled()) { + return; + } - $sessionId = $this->getSessionId(); - $cart = $this->findExistingCartOrCreate($sessionId); + $sessionId = $this->getSessionId(); + $cart = $this->findExistingCartOrCreate($sessionId); - $this->getController()->set(compact('cart')); - } + $this->getController()->set(compact('cart')); + } - /** + /** * @param string $cartId * * @return mixed */ - public function getCartForUserById(string $cartId) - { - $identity = $this->getController()->getRequest()->getAttribute('identity'); - $sessionId = $this->getSessionId(); + public function getCartForUserById(string $cartId) { + $identity = $this->getController()->getRequest()->getAttribute('identity'); + $sessionId = $this->getSessionId(); - $cartsQ = $this->Carts - ->find() - ->contain(['CartItems']) - ->where(['Carts.id' => $cartId]); - if ($identity) { - $cartsQ->where([$this->userIdField => $identity->getIdentifier()]); - } else { - $cartsQ->where(['session_id' => $sessionId]); - } + $cartsQ = $this->Carts + ->find() + ->contain(['CartItems']) + ->where(['Carts.id' => $cartId]); + if ($identity) { + $cartsQ->where([$this->userIdField => $identity->getIdentifier()]); + } else { + $cartsQ->where(['session_id' => $sessionId]); + } - return $cartsQ->firstOrFail(); - } + return $cartsQ->firstOrFail(); + } - public function findExistingCartOrCreate(string $sessionId, int $cartTypeId = null) - { - $identity = $this->getController()->getRequest()->getAttribute('identity'); + public function findExistingCartOrCreate(string $sessionId, int|null $cartTypeId = null) { + $identity = $this->getController()->getRequest()->getAttribute('identity'); - $cartTypeId = $cartTypeId ?? CartTypeId::Cart->value; + $cartTypeId = $cartTypeId ?? CartTypeId::Cart->value; - $cart = $this->Carts - ->findBySessionId($sessionId) - ->contain(['CartItems']) - ->where(['cart_type_id' => $cartTypeId]) - ->first(); + $cart = $this->Carts + ->findBySessionId($sessionId) + ->contain(['CartItems']) + ->where(['cart_type_id' => $cartTypeId]) + ->first(); - if (isset($cart) && isset($identity) && !isset($cart[$this->userIdField])) { - $cart = $this->Carts->patchEntity($cart, [ - $this->userIdField => $identity->getIdentifier(), - ]); + if (isset($cart) && isset($identity) && !isset($cart[$this->userIdField])) { + $cart = $this->Carts->patchEntity($cart, [ + $this->userIdField => $identity->getIdentifier(), + ]); - $cart = $this->Carts->saveOrFail($cart); - } - if (!isset($cart)) { - $cart = $this->Carts->newEntity([ - 'cart_type_id' => $cartTypeId, - 'session_id' => $sessionId, - $this->userIdField => isset($identity) ? $identity->getIdentifier() : null, - 'num_items' => 0, - 'cart_items' => [], - ]); + $cart = $this->Carts->saveOrFail($cart); + } + if (!isset($cart)) { + $cart = $this->Carts->newEntity([ + 'cart_type_id' => $cartTypeId, + 'session_id' => $sessionId, + $this->userIdField => isset($identity) ? $identity->getIdentifier() : null, + 'num_items' => 0, + 'cart_items' => [], + ]); - $cart = $this->Carts->saveOrFail($cart); - } + $cart = $this->Carts->saveOrFail($cart); + } - return $cart; - } + return $cart; + } - public function getUserIdField() - { - return $this->userIdField; - } + public function getUserIdField() { + return $this->userIdField; + } - /** + /** * @return string */ - public function getSessionId(): string - { - if (!$this->getController()->getRequest()->getSession()->started()) { - $this->getController()->getRequest()->getSession()->start(); - } + public function getSessionId(): string { + if (!$this->getController()->getRequest()->getSession()->started()) { + $this->getController()->getRequest()->getSession()->start(); + } - if (!$this->getController()->getRequest()->getSession()->check('CakeCarts.session_id')) { - $this->getController()->getRequest()->getSession()->write('CakeCarts.session_id', $this->getController()->getRequest()->getSession()->id()); - } + if (!$this->getController()->getRequest()->getSession()->check('CakeCarts.session_id')) { + $this->getController()->getRequest()->getSession()->write('CakeCarts.session_id', $this->getController()->getRequest()->getSession()->id()); + } - return $this->getController()->getRequest()->getSession()->read('CakeCarts.session_id'); - } + return $this->getController()->getRequest()->getSession()->read('CakeCarts.session_id'); + } - /** - * @param EntityInterface $cart - * @throws RecordNotFoundException + /** + * @param \Cake\Datasource\EntityInterface $cart + * @throws \Cake\Datasource\Exception\RecordNotFoundException * * @return void */ - public function checkIfIsOwnCart(EntityInterface $cart): void - { - $identity = $this->getController()->getRequest()->getAttribute('identity'); + public function checkIfIsOwnCart(EntityInterface $cart): void { + $identity = $this->getController()->getRequest()->getAttribute('identity'); - if (!isset($identity) && isset($cart->session_id) && ($cart->session_id != $this->getSessionId())) { - throw new RecordNotFoundException(); - } - if (isset($identity) && $identity->getIdentifier() != $cart->get($this->getUserIdField())) { - throw new RecordNotFoundException(); - } - } + if (!isset($identity) && isset($cart->session_id) && ($cart->session_id != $this->getSessionId())) { + throw new RecordNotFoundException(); + } + if (isset($identity) && $identity->getIdentifier() != $cart->get($this->getUserIdField())) { + throw new RecordNotFoundException(); + } + } - /** + /** * @return bool */ - protected function _isActionEnabled(): bool - { - $actions = $this->getConfig('actions'); - if (is_bool($actions)) { - return $actions; - } + protected function _isActionEnabled(): bool { + $actions = $this->getConfig('actions'); + if (is_bool($actions)) { + return $actions; + } + + return in_array($this->getController()->getRequest()->getParam('action'), (array)$actions, true); + } - return in_array($this->getController()->getRequest()->getParam('action'), (array)$actions, true); - } } diff --git a/src/Model/Entity/Cart.php b/src/Model/Entity/Cart.php index fa6ff0e..612dc55 100644 --- a/src/Model/Entity/Cart.php +++ b/src/Model/Entity/Cart.php @@ -11,7 +11,7 @@ use Cake\ORM\Entity; * @property string $id * @property int $cart_type_id * @property string|null $session_id - * @property integer|null $user_id + * @property int|null $user_id * @property string|null $user_id_uuid * @property \Cake\I18n\DateTime $created * @property \Cake\I18n\DateTime|null $modified @@ -22,9 +22,9 @@ use Cake\ORM\Entity; * * @property \CakeCarts\Model\Entity\CartItem[] $cart_items */ -class Cart extends Entity -{ - /** +class Cart extends Entity { + + /** * Fields that can be mass assigned using newEntity() or patchEntity(). * * Note that when '*' is set to true, this allows all unspecified fields to @@ -33,18 +33,19 @@ class Cart extends Entity * * @var array */ - protected array $_accessible = [ - 'cart_type_id' => true, - 'session_id' => true, - 'user_id' => true, - 'user_id_uuid' => true, - 'created' => true, - 'modified' => true, - 'deleted' => true, - 'removed' => true, - 'removed_reason_id' => true, - 'num_items' => true, - 'user' => true, - 'cart_items' => true, - ]; + protected array $_accessible = [ + 'cart_type_id' => true, + 'session_id' => true, + 'user_id' => true, + 'user_id_uuid' => true, + 'created' => true, + 'modified' => true, + 'deleted' => true, + 'removed' => true, + 'removed_reason_id' => true, + 'num_items' => true, + 'user' => true, + 'cart_items' => true, + ]; + } diff --git a/src/Model/Entity/CartItem.php b/src/Model/Entity/CartItem.php index f3de988..6425fda 100644 --- a/src/Model/Entity/CartItem.php +++ b/src/Model/Entity/CartItem.php @@ -20,9 +20,9 @@ use Cake\ORM\Entity; * * @property \CakeCarts\Model\Entity\Cart $cart */ -class CartItem extends Entity -{ - /** +class CartItem extends Entity { + + /** * Fields that can be mass assigned using newEntity() or patchEntity(). * * Note that when '*' is set to true, this allows all unspecified fields to @@ -31,15 +31,16 @@ class CartItem extends Entity * * @var array */ - protected array $_accessible = [ - 'foreign_key' => true, - 'foreign_key_uuid' => true, - 'model' => true, - 'cart_id' => true, - 'position' => true, - 'qty' => true, - 'price' => true, - 'subtotal' => true, - 'cart' => true, - ]; + protected array $_accessible = [ + 'foreign_key' => true, + 'foreign_key_uuid' => true, + 'model' => true, + 'cart_id' => true, + 'position' => true, + 'qty' => true, + 'price' => true, + 'subtotal' => true, + 'cart' => true, + ]; + } diff --git a/src/Model/Enum/CartTypeId.php b/src/Model/Enum/CartTypeId.php index c0b3a90..88119d1 100644 --- a/src/Model/Enum/CartTypeId.php +++ b/src/Model/Enum/CartTypeId.php @@ -1,4 +1,5 @@ 'Cart', - self::Wishlist => 'Wishlist', - self::CustomList => 'List' - }; - } + public function label(): string { + return match ($this) { + static::Cart => 'Cart', + static::Wishlist => 'Wishlist', + static::CustomList => 'List' + }; + } } diff --git a/src/Model/Table/CartItemsTable.php b/src/Model/Table/CartItemsTable.php index d0e9c20..c24e0ad 100644 --- a/src/Model/Table/CartItemsTable.php +++ b/src/Model/Table/CartItemsTable.php @@ -3,7 +3,6 @@ declare(strict_types=1); namespace CakeCarts\Model\Table; -use Cake\ORM\Query\SelectQuery; use Cake\ORM\RulesChecker; use Cake\ORM\Table; use Cake\Validation\Validator; @@ -27,94 +26,91 @@ use Cake\Validation\Validator; * @method iterable<\CakeCarts\Model\Entity\CartItem>|\Cake\Datasource\ResultSetInterface<\CakeCarts\Model\Entity\CartItem>|false deleteMany(iterable $entities, array $options = []) * @method iterable<\CakeCarts\Model\Entity\CartItem>|\Cake\Datasource\ResultSetInterface<\CakeCarts\Model\Entity\CartItem> deleteManyOrFail(iterable $entities, array $options = []) */ -class CartItemsTable extends Table -{ - /** +class CartItemsTable extends Table { + + /** * Initialize method * * @param array $config The configuration for the Table. * @return void */ - public function initialize(array $config): void - { - parent::initialize($config); + public function initialize(array $config): void { + parent::initialize($config); - $this->setTable('cart_items'); - $this->setDisplayField('id'); - $this->setPrimaryKey('id'); + $this->setTable('cart_items'); + $this->setDisplayField('id'); + $this->setPrimaryKey('id'); - $this->belongsTo('Carts', [ - 'foreignKey' => 'cart_id', - 'joinType' => 'INNER', - 'className' => 'CakeCarts.Carts', - ]); - } + $this->belongsTo('Carts', [ + 'foreignKey' => 'cart_id', + 'joinType' => 'INNER', + 'className' => 'CakeCarts.Carts', + ]); + } - /** + /** * Default validation rules. * * @param \Cake\Validation\Validator $validator Validator instance. * @return \Cake\Validation\Validator */ - public function validationDefault(Validator $validator): Validator - { - $validator - ->scalar('foreign_key') - ->allowEmptyString('foreign_key'); + public function validationDefault(Validator $validator): Validator { + $validator + ->scalar('foreign_key') + ->allowEmptyString('foreign_key'); - $validator - ->uuid('foreign_key_uuid') - ->allowEmptyString('foreign_key_uuid'); + $validator + ->uuid('foreign_key_uuid') + ->allowEmptyString('foreign_key_uuid'); - $validator - ->scalar('model') - ->requirePresence('model', 'create') - ->notEmptyString('model'); + $validator + ->scalar('model') + ->requirePresence('model', 'create') + ->notEmptyString('model'); - $validator - ->uuid('cart_id') - ->notEmptyString('cart_id'); + $validator + ->uuid('cart_id') + ->notEmptyString('cart_id'); - $validator - ->integer('position') - ->allowEmptyString('position'); + $validator + ->integer('position') + ->allowEmptyString('position'); - $validator - ->integer('qty') - ->requirePresence('qty', 'create') - ->notEmptyString('qty'); + $validator + ->integer('qty') + ->requirePresence('qty', 'create') + ->notEmptyString('qty'); - return $validator; - } + return $validator; + } - public function validationRequiresPricing(Validator $validator): Validator - { - $validator = $this->validationDefault($validator); + public function validationRequiresPricing(Validator $validator): Validator { + $validator = $this->validationDefault($validator); - $validator - ->decimal('price') - ->requirePresence('price', 'create') - ->allowEmptyString('price'); + $validator + ->decimal('price') + ->requirePresence('price', 'create') + ->allowEmptyString('price'); - $validator - ->decimal('subtotal') - ->requirePresence('subtotal', 'create') - ->notEmptyString('subtotal'); + $validator + ->decimal('subtotal') + ->requirePresence('subtotal', 'create') + ->notEmptyString('subtotal'); - return $validator; - } + return $validator; + } - /** + /** * Returns a rules checker object that will be used for validating * application integrity. * * @param \Cake\ORM\RulesChecker $rules The rules object to be modified. * @return \Cake\ORM\RulesChecker */ - public function buildRules(RulesChecker $rules): RulesChecker - { - $rules->add($rules->existsIn(['cart_id'], 'Carts'), ['errorField' => 'cart_id']); + public function buildRules(RulesChecker $rules): RulesChecker { + $rules->add($rules->existsIn(['cart_id'], 'Carts'), ['errorField' => 'cart_id']); + + return $rules; + } - return $rules; - } } diff --git a/src/Model/Table/CartsTable.php b/src/Model/Table/CartsTable.php index 6acdcc2..4b2ba78 100644 --- a/src/Model/Table/CartsTable.php +++ b/src/Model/Table/CartsTable.php @@ -4,8 +4,6 @@ declare(strict_types=1); namespace CakeCarts\Model\Table; use Cake\Database\Type\EnumType; -use Cake\ORM\Query\SelectQuery; -use Cake\ORM\RulesChecker; use Cake\ORM\Table; use Cake\Validation\Validator; use CakeCarts\Model\Enum\CartTypeId; @@ -32,74 +30,73 @@ use CakeCarts\Model\Enum\CartTypeId; * * @mixin \Cake\ORM\Behavior\TimestampBehavior */ -class CartsTable extends Table -{ - /** +class CartsTable extends Table { + + /** * Initialize method * * @param array $config The configuration for the Table. * @return void */ - public function initialize(array $config): void - { - parent::initialize($config); + public function initialize(array $config): void { + parent::initialize($config); - $this->setTable('carts'); - $this->setDisplayField('id'); - $this->setPrimaryKey('id'); + $this->setTable('carts'); + $this->setDisplayField('id'); + $this->setPrimaryKey('id'); - $this->addBehavior('Timestamp'); + $this->addBehavior('Timestamp'); - $this->hasMany('CartItems', [ - 'foreignKey' => 'cart_id', - 'className' => 'CakeCarts.CartItems', - ]); - $this->getSchema()->setColumnType('cart_type_id', EnumType::from(CartTypeId::class)); + $this->hasMany('CartItems', [ + 'foreignKey' => 'cart_id', + 'className' => 'CakeCarts.CartItems', + ]); + $this->getSchema()->setColumnType('cart_type_id', EnumType::from(CartTypeId::class)); - } + } - /** + /** * Default validation rules. * * @param \Cake\Validation\Validator $validator Validator instance. * @return \Cake\Validation\Validator */ - public function validationDefault(Validator $validator): Validator - { - $validator - ->integer('cart_type_id') - ->requirePresence('cart_type_id', 'create') - ->notEmptyString('cart_type_id'); + public function validationDefault(Validator $validator): Validator { + $validator + ->integer('cart_type_id') + ->requirePresence('cart_type_id', 'create') + ->notEmptyString('cart_type_id'); - $validator - ->scalar('session_id') - ->maxLength('session_id', 255) - ->allowEmptyString('session_id'); + $validator + ->scalar('session_id') + ->maxLength('session_id', 255) + ->allowEmptyString('session_id'); - $validator - ->uuid('user_id_uuid') - ->allowEmptyString('user_id_uuid'); + $validator + ->uuid('user_id_uuid') + ->allowEmptyString('user_id_uuid'); - $validator - ->integer('user_id') - ->allowEmptyString('user_id'); + $validator + ->integer('user_id') + ->allowEmptyString('user_id'); - $validator - ->dateTime('deleted') - ->allowEmptyDateTime('deleted'); + $validator + ->dateTime('deleted') + ->allowEmptyDateTime('deleted'); - $validator - ->dateTime('removed') - ->allowEmptyDateTime('removed'); + $validator + ->dateTime('removed') + ->allowEmptyDateTime('removed'); - $validator - ->integer('removed_reason_id') - ->allowEmptyString('removed_reason_id'); + $validator + ->integer('removed_reason_id') + ->allowEmptyString('removed_reason_id'); - $validator - ->integer('num_items') - ->notEmptyString('num_items'); + $validator + ->integer('num_items') + ->notEmptyString('num_items'); + + return $validator; + } - return $validator; - } } diff --git a/tests/Fixture/CartItemsFixture.php b/tests/Fixture/CartItemsFixture.php index f9c2138..8668309 100644 --- a/tests/Fixture/CartItemsFixture.php +++ b/tests/Fixture/CartItemsFixture.php @@ -8,61 +8,61 @@ use Cake\TestSuite\Fixture\TestFixture; /** * CartItemsFixture */ -class CartItemsFixture extends TestFixture -{ - /** +class CartItemsFixture extends TestFixture { + + /** * Init method * * @return void */ - public function init(): void - { - $this->records = [ - [ - 'id' => '79f66e8d-8d8d-4095-adc4-fd15234a4397', - 'foreign_key' => null, - 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', - 'model' => 'ProductSkus', - 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51ea', - 'position' => 1, - 'qty' => 1, - 'price' => 1.5, - 'subtotal' => 1.5, - ], - [ - 'id' => '74d1aa54-92a2-4039-ba10-61e1190c51eb', - 'foreign_key' => null, - 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', - 'model' => 'ProductSkus', - 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51eb', - 'position' => 1, - 'qty' => 1, - 'price' => 1.5, - 'subtotal' => 1.5, - ], - [ - 'id' => '74d1aa54-92a2-4039-bc10-61e4190c51ec', - 'foreign_key' => null, - 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', - 'model' => 'ProductSkus', - 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51ec', - 'position' => 1, - 'qty' => 1, - 'price' => 1.5, - 'subtotal' => 1.5, - ], - [ - 'id' => '79f66e8d-8d8d-4095-adc4-fd15234a4394', - 'foreign_key' => null, - 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', - 'model' => 'ProductSkus', - 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51ed', - 'position' => 1, - 'qty' => 1, - 'price' => 1.5, - 'subtotal' => 1.5, - ], - ]; - parent::init(); - } + public function init(): void { + $this->records = [ + [ + 'id' => '79f66e8d-8d8d-4095-adc4-fd15234a4397', + 'foreign_key' => null, + 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', + 'model' => 'ProductSkus', + 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51ea', + 'position' => 1, + 'qty' => 1, + 'price' => 1.5, + 'subtotal' => 1.5, + ], + [ + 'id' => '74d1aa54-92a2-4039-ba10-61e1190c51eb', + 'foreign_key' => null, + 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', + 'model' => 'ProductSkus', + 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51eb', + 'position' => 1, + 'qty' => 1, + 'price' => 1.5, + 'subtotal' => 1.5, + ], + [ + 'id' => '74d1aa54-92a2-4039-bc10-61e4190c51ec', + 'foreign_key' => null, + 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', + 'model' => 'ProductSkus', + 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51ec', + 'position' => 1, + 'qty' => 1, + 'price' => 1.5, + 'subtotal' => 1.5, + ], + [ + 'id' => '79f66e8d-8d8d-4095-adc4-fd15234a4394', + 'foreign_key' => null, + 'foreign_key_uuid' => 'e5efe749-d6b6-4f72-83c9-32b19936c70c', + 'model' => 'ProductSkus', + 'cart_id' => '74d1aa54-92a2-4039-bc10-61e1190c51ed', + 'position' => 1, + 'qty' => 1, + 'price' => 1.5, + 'subtotal' => 1.5, + ], + ]; + parent::init(); + } + } diff --git a/tests/Fixture/CartsFixture.php b/tests/Fixture/CartsFixture.php index f092a25..7d0cec7 100644 --- a/tests/Fixture/CartsFixture.php +++ b/tests/Fixture/CartsFixture.php @@ -9,73 +9,73 @@ use CakeCarts\Model\Enum\CartTypeId; /** * CartsFixture */ -class CartsFixture extends TestFixture -{ - /** +class CartsFixture extends TestFixture { + + /** * Init method * * @return void */ - public function init(): void - { - $this->records = [ - // normal cart - open - [ - 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51ea', - 'cart_type_id' => CartTypeId::Cart->value, - 'session_id' => 'session_1', - 'user_id' => null, - 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', - 'created' => '2025-10-08 09:55:15', - 'modified' => '2025-10-08 09:55:15', - 'deleted' => null, - 'removed' => null, - 'removed_reason_id' => null, - 'num_items' => 1, - ], - // normal cart - deleted - [ - 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51eb', - 'cart_type_id' => CartTypeId::Cart->value, - 'session_id' => 'session_1', - 'user_id' => null, - 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', - 'created' => '2025-10-08 09:55:15', - 'modified' => '2025-10-08 09:55:15', - 'deleted' => '2025-10-08 09:55:15', - 'removed' => null, - 'removed_reason_id' => null, - 'num_items' => 1, - ], - // wishlist cart - open - [ - 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51ec', - 'cart_type_id' => CartTypeId::Wishlist->value, - 'session_id' => 'session_2', - 'user_id' => null, - 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', - 'created' => '2025-10-08 09:55:15', - 'modified' => '2025-10-08 09:55:15', - 'deleted' => null, - 'removed' => null, - 'removed_reason_id' => null, - 'num_items' => 1, - ], - // wishlist cart - deleted - [ - 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51ed', - 'cart_type_id' => CartTypeId::Wishlist->value, - 'session_id' => 'session_2', - 'user_id' => null, - 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', - 'created' => '2025-10-08 09:55:15', - 'modified' => '2025-10-08 09:55:15', - 'deleted' => '2025-10-08 09:55:15', - 'removed' => null, - 'removed_reason_id' => null, - 'num_items' => 1, - ], - ]; - parent::init(); - } + public function init(): void { + $this->records = [ + // normal cart - open + [ + 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51ea', + 'cart_type_id' => CartTypeId::Cart->value, + 'session_id' => 'session_1', + 'user_id' => null, + 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', + 'created' => '2025-10-08 09:55:15', + 'modified' => '2025-10-08 09:55:15', + 'deleted' => null, + 'removed' => null, + 'removed_reason_id' => null, + 'num_items' => 1, + ], + // normal cart - deleted + [ + 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51eb', + 'cart_type_id' => CartTypeId::Cart->value, + 'session_id' => 'session_1', + 'user_id' => null, + 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', + 'created' => '2025-10-08 09:55:15', + 'modified' => '2025-10-08 09:55:15', + 'deleted' => '2025-10-08 09:55:15', + 'removed' => null, + 'removed_reason_id' => null, + 'num_items' => 1, + ], + // wishlist cart - open + [ + 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51ec', + 'cart_type_id' => CartTypeId::Wishlist->value, + 'session_id' => 'session_2', + 'user_id' => null, + 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', + 'created' => '2025-10-08 09:55:15', + 'modified' => '2025-10-08 09:55:15', + 'deleted' => null, + 'removed' => null, + 'removed_reason_id' => null, + 'num_items' => 1, + ], + // wishlist cart - deleted + [ + 'id' => '74d1aa54-92a2-4039-bc10-61e1190c51ed', + 'cart_type_id' => CartTypeId::Wishlist->value, + 'session_id' => 'session_2', + 'user_id' => null, + 'user_id_uuid' => '5a34a6ae-7d3f-4dcf-bac7-57335b51e697', + 'created' => '2025-10-08 09:55:15', + 'modified' => '2025-10-08 09:55:15', + 'deleted' => '2025-10-08 09:55:15', + 'removed' => null, + 'removed_reason_id' => null, + 'num_items' => 1, + ], + ]; + parent::init(); + } + } diff --git a/tests/TestCase/Controller/CartItemsControllerTest.php b/tests/TestCase/Controller/CartItemsControllerTest.php index 7c56f47..c67da99 100644 --- a/tests/TestCase/Controller/CartItemsControllerTest.php +++ b/tests/TestCase/Controller/CartItemsControllerTest.php @@ -5,118 +5,115 @@ namespace CakeCarts\Test\TestCase\Controller; use Cake\TestSuite\IntegrationTestTrait; use Cake\TestSuite\TestCase; -use CakeCarts\Controller\CartItemsController; use CakeCarts\Model\Table\CartItemsTable; -use CakeCarts\Model\Table\CartsTable; /** * CakeCarts\Controller\CartItemsController Test Case * * @link \CakeCarts\Controller\CartItemsController */ -class CartItemsControllerTest extends TestCase -{ - use IntegrationTestTrait; +class CartItemsControllerTest extends TestCase { - /** + use IntegrationTestTrait; + + /** * Test subject * * @var \CakeCarts\Model\Table\CartItemsTable */ - protected $CartItems; + protected $CartItems; - /** + /** * Fixtures * * @var array */ - protected array $fixtures = [ - 'plugin.CakeCarts.CartItems', - 'plugin.CakeCarts.Carts', - ]; + protected array $fixtures = [ + 'plugin.CakeCarts.CartItems', + 'plugin.CakeCarts.Carts', + ]; - public function setUp(): void - { - parent::setUp(); // TODO: Change the autogenerated stub + /** + * @return void + */ + public function setUp(): void { + parent::setUp(); // TODO: Change the autogenerated stub - $config = $this->getTableLocator()->exists('CartItems') ? [] : ['className' => CartItemsTable::class]; - $this->CartItems = $this->getTableLocator()->get('CartItems', $config); - } + $config = $this->getTableLocator()->exists('CartItems') ? [] : ['className' => CartItemsTable::class]; + $this->CartItems = $this->getTableLocator()->get('CartItems', $config); + } - - /** + /** * Test add method * - * @return void * @link \CakeCarts\Controller\CartItemsController::add() + * @return void */ - public function testAdd(): void - { - $url = [ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'add', - ]; - $skuId = '3a477e3e-7977-4813-81f6-f85949613979'; + public function testAdd(): void { + $url = [ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'add', + ]; + $skuId = '3a477e3e-7977-4813-81f6-f85949613979'; - $beforeCnt = $this->CartItems->find()->where(['foreign_key_uuid' => $skuId])->count(); - $postData = [ - 'foreign_key' => null, - 'foreign_key_uuid' => $skuId, - 'model' => 'ProductSkus', - 'qty' => 10, - 'price' => 0.75, - 'subtotal' => 1, - ]; - $this->post($url, $postData); - $this->assertResponseCode(302); - $afterCnt = $this->CartItems->find()->where(['foreign_key_uuid' => $skuId])->count(); - $this->assertEquals($beforeCnt + 1, $afterCnt); + $beforeCnt = $this->CartItems->find()->where(['foreign_key_uuid' => $skuId])->count(); + $postData = [ + 'foreign_key' => null, + 'foreign_key_uuid' => $skuId, + 'model' => 'ProductSkus', + 'qty' => 10, + 'price' => 0.75, + 'subtotal' => 1, + ]; + $this->post($url, $postData); + $this->assertResponseCode(302); + $afterCnt = $this->CartItems->find()->where(['foreign_key_uuid' => $skuId])->count(); + $this->assertEquals($beforeCnt + 1, $afterCnt); - $new = $this->CartItems->find()->where(['foreign_key_uuid' => $skuId, 'qty' => 10, 'model' => 'ProductSkus'])->firstOrFail(); - $this->assertEquals(7.5, $new->subtotal); - } + $new = $this->CartItems->find()->where(['foreign_key_uuid' => $skuId, 'qty' => 10, 'model' => 'ProductSkus'])->firstOrFail(); + $this->assertEquals(7.5, $new->subtotal); + } - /** + /** * Test edit method * - * @return void * @link \CakeCarts\Controller\CartItemsController::edit() + * @return void */ - public function testEdit(): void - { - $id = '79f66e8d-8d8d-4095-adc4-fd15234a4397'; - $url = [ - 'plugin' => 'CakeCarts', - 'controller' => 'CartItems', - 'action' => 'edit', - $id - ]; - $this->session(['Auth.User.id' => 1]); - $this->session(['Auth.id' => 1]); - $this->session(['CakeCarts.session_id' => 'session_1']); - $before = $this->CartItems->get($id, contain: ['Carts']); + public function testEdit(): void { + $id = '79f66e8d-8d8d-4095-adc4-fd15234a4397'; + $url = [ + 'plugin' => 'CakeCarts', + 'controller' => 'CartItems', + 'action' => 'edit', + $id, + ]; + $this->session(['Auth.User.id' => 1]); + $this->session(['Auth.id' => 1]); + $this->session(['CakeCarts.session_id' => 'session_1']); + $before = $this->CartItems->get($id, contain: ['Carts']); // dd($before); - $skuId = '3a477e3e-7977-4813-81f6-f85949613979'; + $skuId = '3a477e3e-7977-4813-81f6-f85949613979'; - $postData = [ - 'qty' => 100, - ]; - $this->post($url, $postData); - $this->assertResponseCode(302); + $postData = [ + 'qty' => 100, + ]; + $this->post($url, $postData); + $this->assertResponseCode(302); - $new = $this->CartItems->get($id); - $this->assertEquals(100, $new->qty); - } + $new = $this->CartItems->get($id); + $this->assertEquals(100, $new->qty); + } - /** + /** * Test delete method * - * @return void * @link \CakeCarts\Controller\CartItemsController::delete() + * @return void */ - public function testDelete(): void - { - $this->markTestIncomplete('Not implemented yet.'); - } + public function testDelete(): void { + $this->markTestIncomplete('Not implemented yet.'); + } + } diff --git a/tests/TestCase/Controller/CartsControllerTest.php b/tests/TestCase/Controller/CartsControllerTest.php index 844d1df..33e4d23 100644 --- a/tests/TestCase/Controller/CartsControllerTest.php +++ b/tests/TestCase/Controller/CartsControllerTest.php @@ -5,41 +5,45 @@ namespace CakeCarts\Test\TestCase\Controller; use Cake\TestSuite\IntegrationTestTrait; use Cake\TestSuite\TestCase; -use CakeCarts\Controller\CartsController; /** * CakeCarts\Controller\CartsController Test Case * * @uses \CakeCarts\Controller\CartsController */ -class CartsControllerTest extends TestCase -{ - use IntegrationTestTrait; +class CartsControllerTest extends TestCase { - /** + use IntegrationTestTrait; + + /** * Test subject * * @var \CakeCarts\Model\Table\CartItemsTable */ - protected $Carts; + protected $Carts; - public function setUp(): void - { - parent::setUp(); // TODO: Change the autogenerated stub + /** + * @return void + */ + public function setUp(): void { + parent::setUp(); // TODO: Change the autogenerated stub - $config = $this->getTableLocator()->exists('Carts') ? [] : ['className' => CartsTable::class]; - $this->Carts = $this->getTableLocator()->get('Carts', $config); - } + $config = $this->getTableLocator()->exists('Carts') ? [] : ['className' => CartsTable::class]; + $this->Carts = $this->getTableLocator()->get('Carts', $config); + } - public function testIndex(): void - { - $url = [ - 'plugin' => 'CakeCarts', - 'controller' => 'Carts', - 'action' => 'index', - ]; - $this->get($url); + /** + * @return void + */ + public function testIndex(): void { + $url = [ + 'plugin' => 'CakeCarts', + 'controller' => 'Carts', + 'action' => 'index', + ]; + $this->get($url); + + $this->assertResponseCode(200); + } - $this->assertResponseCode(200); - } } diff --git a/tests/TestCase/Controller/Component/ShoppingCartComponentTest.php b/tests/TestCase/Controller/Component/ShoppingCartComponentTest.php index bb79a8d..1d59301 100644 --- a/tests/TestCase/Controller/Component/ShoppingCartComponentTest.php +++ b/tests/TestCase/Controller/Component/ShoppingCartComponentTest.php @@ -10,36 +10,35 @@ use CakeCarts\Controller\Component\ShoppingCartComponent; /** * CakeCarts\Controller\Component\ShoppingCartComponent Test Case */ -class ShoppingCartComponentTest extends TestCase -{ - /** +class ShoppingCartComponentTest extends TestCase { + + /** * Test subject * * @var \CakeCarts\Controller\Component\ShoppingCartComponent */ - protected $ShoppingCart; + protected $ShoppingCart; - /** + /** * setUp method * * @return void */ - protected function setUp(): void - { - parent::setUp(); - $registry = new ComponentRegistry(); - $this->ShoppingCart = new ShoppingCartComponent($registry); - } + protected function setUp(): void { + parent::setUp(); + $registry = new ComponentRegistry(); + $this->ShoppingCart = new ShoppingCartComponent($registry); + } - /** + /** * tearDown method * * @return void */ - protected function tearDown(): void - { - unset($this->ShoppingCart); + protected function tearDown(): void { + unset($this->ShoppingCart); + + parent::tearDown(); + } - parent::tearDown(); - } } diff --git a/tests/TestCase/Model/Table/CartItemsTableTest.php b/tests/TestCase/Model/Table/CartItemsTableTest.php index 0872389..fde2fdf 100644 --- a/tests/TestCase/Model/Table/CartItemsTableTest.php +++ b/tests/TestCase/Model/Table/CartItemsTableTest.php @@ -9,68 +9,65 @@ use CakeCarts\Model\Table\CartItemsTable; /** * CakeCarts\Model\Table\CartItemsTable Test Case */ -class CartItemsTableTest extends TestCase -{ - /** +class CartItemsTableTest extends TestCase { + + /** * Test subject * * @var \CakeCarts\Model\Table\CartItemsTable */ - protected $CartItems; + protected $CartItems; - /** + /** * Fixtures * * @var list */ - protected array $fixtures = [ - 'plugin.CakeCarts.CartItems', - 'plugin.CakeCarts.Carts', - ]; + protected array $fixtures = [ + 'plugin.CakeCarts.CartItems', + 'plugin.CakeCarts.Carts', + ]; - /** + /** * setUp method * * @return void */ - protected function setUp(): void - { - parent::setUp(); - $config = $this->getTableLocator()->exists('CartItems') ? [] : ['className' => CartItemsTable::class]; - $this->CartItems = $this->getTableLocator()->get('CartItems', $config); - } + protected function setUp(): void { + parent::setUp(); + $config = $this->getTableLocator()->exists('CartItems') ? [] : ['className' => CartItemsTable::class]; + $this->CartItems = $this->getTableLocator()->get('CartItems', $config); + } - /** + /** * tearDown method * * @return void */ - protected function tearDown(): void - { - unset($this->CartItems); + protected function tearDown(): void { + unset($this->CartItems); - parent::tearDown(); - } + parent::tearDown(); + } - /** + /** * Test validationDefault method * - * @return void * @uses \CakeCarts\Model\Table\CartItemsTable::validationDefault() + * @return void */ - public function testValidationDefault(): void - { - $this->markTestIncomplete('Not implemented yet.'); - } + public function testValidationDefault(): void { + $this->markTestIncomplete('Not implemented yet.'); + } - /** + /** * Test buildRules method * - * @return void * @uses \CakeCarts\Model\Table\CartItemsTable::buildRules() + * @return void */ - public function testBuildRules(): void - { - $this->markTestIncomplete('Not implemented yet.'); - } + public function testBuildRules(): void { + $this->markTestIncomplete('Not implemented yet.'); + } + } diff --git a/tests/TestCase/Model/Table/CartsTableTest.php b/tests/TestCase/Model/Table/CartsTableTest.php index 0dcad8f..8f2e692 100644 --- a/tests/TestCase/Model/Table/CartsTableTest.php +++ b/tests/TestCase/Model/Table/CartsTableTest.php @@ -9,69 +9,66 @@ use CakeCarts\Model\Table\CartsTable; /** * CakeCarts\Model\Table\CartsTable Test Case */ -class CartsTableTest extends TestCase -{ - /** +class CartsTableTest extends TestCase { + + /** * Test subject * * @var \CakeCarts\Model\Table\CartsTable */ - protected $Carts; + protected $Carts; - /** + /** * Fixtures * * @var list */ - protected array $fixtures = [ - 'plugin.CakeCarts.Carts', + protected array $fixtures = [ + 'plugin.CakeCarts.Carts', // 'plugin.CakeCarts.Users', - 'plugin.CakeCarts.CartItems', - ]; + 'plugin.CakeCarts.CartItems', + ]; - /** + /** * setUp method * * @return void */ - protected function setUp(): void - { - parent::setUp(); - $config = $this->getTableLocator()->exists('Carts') ? [] : ['className' => CartsTable::class]; - $this->Carts = $this->getTableLocator()->get('Carts', $config); - } + protected function setUp(): void { + parent::setUp(); + $config = $this->getTableLocator()->exists('Carts') ? [] : ['className' => CartsTable::class]; + $this->Carts = $this->getTableLocator()->get('Carts', $config); + } - /** + /** * tearDown method * * @return void */ - protected function tearDown(): void - { - unset($this->Carts); + protected function tearDown(): void { + unset($this->Carts); - parent::tearDown(); - } + parent::tearDown(); + } - /** + /** * Test validationDefault method * - * @return void * @uses \CakeCarts\Model\Table\CartsTable::validationDefault() + * @return void */ - public function testValidationDefault(): void - { - $this->markTestIncomplete('Not implemented yet.'); - } + public function testValidationDefault(): void { + $this->markTestIncomplete('Not implemented yet.'); + } - /** + /** * Test buildRules method * - * @return void * @uses \CakeCarts\Model\Table\CartsTable::buildRules() + * @return void */ - public function testBuildRules(): void - { - $this->markTestIncomplete('Not implemented yet.'); - } + public function testBuildRules(): void { + $this->markTestIncomplete('Not implemented yet.'); + } + } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 27f464e..51d1377 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -7,20 +7,19 @@ use Cake\Core\Configure; use Cake\Core\Plugin; use Cake\Database\Connection; use Cake\Datasource\ConnectionManager; -use Cake\TestSuite\Fixture\SchemaLoader; -use CakeProducts\CakeProductsPlugin; +use CakeCarts\CakeCartsPlugin; use Migrations\TestSuite\Migrator; use TestApp\Controller\AppController; if (!defined('DS')) { - define('DS', DIRECTORY_SEPARATOR); + define('DS', DIRECTORY_SEPARATOR); } if (!defined('WINDOWS')) { - if (DS === '\\' || substr(PHP_OS, 0, 3) === 'WIN') { - define('WINDOWS', true); - } else { - define('WINDOWS', false); - } + if (DS === '\\' || substr(PHP_OS, 0, 3) === 'WIN') { + define('WINDOWS', true); + } else { + define('WINDOWS', false); + } } define('PLUGIN_ROOT', dirname(__DIR__)); @@ -45,69 +44,69 @@ require CORE_PATH . 'config/bootstrap.php'; require CAKE . 'functions.php'; Configure::write('App', [ - 'namespace' => 'TestApp', - 'encoding' => 'UTF-8', - 'paths' => [ - 'testWebroot' => PLUGIN_ROOT . DS . 'tests' . DS . 'test_app' . DS . 'webroot' . DS, - 'webroot' => PLUGIN_ROOT . DS . 'webroot' . DS, - 'templates' => [ - PLUGIN_ROOT . DS . 'tests' . DS . 'test_app' . DS . 'templates' . DS, - ], - ], + 'namespace' => 'TestApp', + 'encoding' => 'UTF-8', + 'paths' => [ + 'testWebroot' => PLUGIN_ROOT . DS . 'tests' . DS . 'test_app' . DS . 'webroot' . DS, + 'webroot' => PLUGIN_ROOT . DS . 'webroot' . DS, + 'templates' => [ + PLUGIN_ROOT . DS . 'tests' . DS . 'test_app' . DS . 'templates' . DS, + ], + ], ]); Configure::write('debug', true); Configure::write('CakeCarts', [ - 'Carts' => [ - 'table' => 'CakeCarts.Carts', - ], - 'CartItems' => [ - 'requirePricing' => false, - ], - 'Users' => [ - 'user_id' => 'uuid', // integer or uuid - ], + 'Carts' => [ + 'table' => 'CakeCarts.Carts', + ], + 'CartItems' => [ + 'requirePricing' => false, + ], + 'Users' => [ + 'user_id' => 'uuid', // integer or uuid + ], ]); $cache = [ - 'default' => [ - 'engine' => 'File', - 'path' => CACHE, - ], - '_cake_translations_' => [ - 'className' => 'File', - 'prefix' => 'crud_myapp_cake_core_', - 'path' => CACHE . 'persistent/', - 'serialize' => true, - 'duration' => '+10 seconds', - ], - '_cake_model_' => [ - 'className' => 'File', - 'prefix' => 'crud_my_app_cake_model_', - 'path' => CACHE . 'models/', - 'serialize' => 'File', - 'duration' => '+10 seconds', - ], + 'default' => [ + 'engine' => 'File', + 'path' => CACHE, + ], + '_cake_translations_' => [ + 'className' => 'File', + 'prefix' => 'crud_myapp_cake_core_', + 'path' => CACHE . 'persistent/', + 'serialize' => true, + 'duration' => '+10 seconds', + ], + '_cake_model_' => [ + 'className' => 'File', + 'prefix' => 'crud_my_app_cake_model_', + 'path' => CACHE . 'models/', + 'serialize' => 'File', + 'duration' => '+10 seconds', + ], ]; Cache::setConfig($cache); class_alias(AppController::class, 'App\Controller\AppController'); -Plugin::getCollection()->add(new \CakeCarts\CakeCartsPlugin()); +Plugin::getCollection()->add(new CakeCartsPlugin()); Chronos::setTestNow(Chronos::now()); if (!getenv('DB_URL')) { - putenv('DB_URL=sqlite:///:memory:'); + putenv('DB_URL=sqlite:///:memory:'); } ConnectionManager::setConfig('test', [ - 'className' => Connection::class, - 'url' => getenv('DB_URL') ?: null, - 'timezone' => 'UTC', - 'quoteIdentifiers' => false, - 'cacheMetadata' => true, + 'className' => Connection::class, + 'url' => getenv('DB_URL') ?: null, + 'timezone' => 'UTC', + 'quoteIdentifiers' => false, + 'cacheMetadata' => true, ]); /**