From 81f07875390f54a57a7d03567a5fee556757b656 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:59:48 +0400 Subject: [PATCH 01/10] Upgrade framework to v3.0, update namespaces, add type hinting, and cleanup dependencies --- composer.json | 6 +-- helpers/functions.php | 11 ++-- .../create_table_comments_1698145440.php | 2 +- migrations/create_table_posts_1669639752.php | 2 +- migrations/create_table_users_1669639740.php | 2 +- shared/Commands/CommandValidationTrait.php | 6 +-- shared/Commands/CommentCreateCommand.php | 18 +++---- shared/Commands/CommentDeleteCommand.php | 23 ++++----- shared/Commands/DemoCommand.php | 38 +++++++------- shared/Commands/PostCreateCommand.php | 23 ++++----- shared/Commands/PostDeleteCommand.php | 18 +++---- shared/Commands/PostShowCommand.php | 19 +++---- shared/Commands/PostUpdateCommand.php | 25 ++++------ shared/Commands/UserCreateCommand.php | 23 +++++---- shared/Commands/UserDeleteCommand.php | 32 +++++------- shared/Commands/UserShowCommand.php | 19 +++---- shared/Models/Comment.php | 18 +++---- shared/Models/Post.php | 18 +++---- shared/Models/User.php | 15 +++--- shared/Services/AuthService.php | 20 ++++---- shared/Services/CommentService.php | 7 ++- shared/Services/PostService.php | 28 +++++------ shared/Transformers/CommentTransformer.php | 4 +- shared/Transformers/PostTransformer.php | 4 +- tests/Feature/AppTestCase.php | 17 +++---- .../modules/Api/AuthControllerTest.php | 10 ++-- .../modules/Api/CommentControllerTest.php | 4 +- tests/Helpers/functions.php | 14 ++++-- .../Unit/shared/Services/AuthServiceTest.php | 2 +- .../Unit/shared/Services/PostServiceTest.php | 26 +++++----- tests/_root/helpers/functions.php | 47 ++---------------- tests/_root/logs/app.log | 0 tests/_root/tmp/php8fe1.tmp | Bin 9113 -> 4 bytes 33 files changed, 216 insertions(+), 285 deletions(-) delete mode 100644 tests/_root/logs/app.log diff --git a/composer.json b/composer.json index 9c885228..df054187 100644 --- a/composer.json +++ b/composer.json @@ -5,14 +5,10 @@ "license": "MIT", "type": "project", "require": { - "quantum/framework": "^2.9.9", + "quantum/framework": "dev-master", "fakerphp/faker": "^1.15", "bluemmb/faker-picsum-photos-provider": "^2.0", "ottaviano/faker-gravatar": "^0.3.0", - "doctrine/annotations": "^2.0", - "voku/html-min": "^4.5", - "league/commonmark": "^1.6", - "ezyang/htmlpurifier": "^4.18", "symfony/process": "^5.4" }, "require-dev": { diff --git a/helpers/functions.php b/helpers/functions.php index b820f1f9..96b06de5 100644 --- a/helpers/functions.php +++ b/helpers/functions.php @@ -12,16 +12,15 @@ * @since 2.9.9 */ -use Quantum\Libraries\HttpClient\Exceptions\HttpClientException; -use Quantum\Libraries\Storage\Factories\FileSystemFactory; +use Quantum\HttpClient\Exceptions\HttpClientException; +use Quantum\Storage\Factories\FileSystemFactory; use Quantum\Config\Exceptions\ConfigException; -use Quantum\Libraries\HttpClient\HttpClient; use Quantum\App\Exceptions\BaseException; use Quantum\Di\Exceptions\DiException; -use Quantum\Http\Request; +use Quantum\HttpClient\HttpClient; /** - * Gets the url with selected language + * Gets the url with the selected language * @param string $lang * @return string */ @@ -132,7 +131,7 @@ function nav_ref_encode(?string $query): string /** * Decodes a URL-safe base64 reference back to query string. * - * @param string $ref + * @param string|null $ref * @return string */ function nav_ref_decode(?string $ref): string diff --git a/migrations/create_table_comments_1698145440.php b/migrations/create_table_comments_1698145440.php index a7b99510..94525cf5 100644 --- a/migrations/create_table_comments_1698145440.php +++ b/migrations/create_table_comments_1698145440.php @@ -1,6 +1,6 @@ * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; -use Quantum\Libraries\Validation\Validator; +use Quantum\Validation\Validator; /** * Trait CommandValidationTrait @@ -26,7 +26,7 @@ trait CommandValidationTrait /** * @var Validator */ - protected $validator; + protected Validator $validator; /** * Initiates the validator diff --git a/shared/Commands/CommentCreateCommand.php b/shared/Commands/CommentCreateCommand.php index 5ef470c1..eb4dc1a9 100644 --- a/shared/Commands/CommentCreateCommand.php +++ b/shared/Commands/CommentCreateCommand.php @@ -9,17 +9,17 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; use Quantum\Service\Exceptions\ServiceException; use Quantum\App\Exceptions\BaseException; -use Quantum\Libraries\Validation\Rule; use Quantum\Di\Exceptions\DiException; use Shared\Services\CommentService; use Quantum\Console\QtCommand; +use Quantum\Validation\Rule; use ReflectionException; /** @@ -33,27 +33,27 @@ class CommentCreateCommand extends QtCommand /** * Command name - * @var string + * @var string|null */ - protected $name = 'comment:create'; + protected ?string $name = 'comment:create'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Allows to create a comment record'; + protected ?string $description = 'Allows to create a comment record'; /** * Command help text - * @var string + * @var string|null */ - protected $help = 'Use the following format to create a comment record:' . PHP_EOL . 'php qt comment:create `Post UUID` `User UUID` `Content`'; + protected ?string $help = 'Use the following format to create a comment record:' . PHP_EOL . 'php qt comment:create `Post UUID` `User UUID` `Content`'; /** * Command arguments * @var array[] */ - protected $args = [ + protected array $args = [ ['post_uuid', 'required', 'The post uuid the comment belongs to'], ['user_uuid', 'required', 'The user uuid who writes the comment'], ['content', 'required', 'Comment text'], diff --git a/shared/Commands/CommentDeleteCommand.php b/shared/Commands/CommentDeleteCommand.php index 59e82585..c4cf86f6 100644 --- a/shared/Commands/CommentDeleteCommand.php +++ b/shared/Commands/CommentDeleteCommand.php @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; @@ -29,21 +29,21 @@ class CommentDeleteCommand extends QtCommand { /** * Command name - * @var string + * @var string|null */ - protected $name = 'comment:delete'; + protected ?string $name = 'comment:delete'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Deletes a comment by UUID or clears the entire comments table with confirmation'; + protected ?string $description = 'Deletes a comment by UUID or clears the entire comments table with confirmation'; /** * Command help text - * @var string + * @var string|null */ - protected $help = << * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; -use Quantum\Libraries\HttpClient\Exceptions\HttpClientException; use Symfony\Component\Console\Exception\ExceptionInterface; -use Quantum\Libraries\Storage\Factories\FileSystemFactory; +use Quantum\HttpClient\Exceptions\HttpClientException; use Symfony\Component\Console\Helper\ProgressBar; +use Quantum\Storage\Factories\FileSystemFactory; use Quantum\Service\Exceptions\ServiceException; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Input\ArrayInput; use Quantum\Config\Exceptions\ConfigException; use Quantum\App\Exceptions\BaseException; -use Quantum\Libraries\Database\Database; use Bluemmb\Faker\PicsumPhotosProvider; use Quantum\Di\Exceptions\DiException; use Symfony\Component\Process\Process; +use Quantum\Database\Database; use Quantum\Console\QtCommand; use Ottaviano\Faker\Gravatar; use ReflectionException; @@ -42,51 +42,51 @@ class DemoCommand extends QtCommand { + /** + * Default password for generated users + */ + const DEFAULT_PASSWORD = 'password'; + /** * Command name - * @var string + * @var string|null */ - protected $name = 'install:demo'; + protected ?string $name = 'install:demo'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Generates demo users and posts'; + protected ?string $description = 'Generates demo users and posts'; /** * Command help text - * @var string + * @var string|null */ - protected $help = 'The command will create demo users and posts for your project'; + protected ?string $help = 'The command will create demo users and posts for your project'; /** * The default action for all confirmations * @var array */ - protected $options = [ + protected array $options = [ ['yes', 'y', 'none', 'Acceptance of the confirmations'] ]; /** * @var Generator */ - protected $faker; + protected Generator $faker; /** * @var array */ - private $generatedUsers = []; + private array $generatedUsers = []; /** * @var array */ - private $generatedPosts = []; - - /** - * Default password for generated users - */ - const DEFAULT_PASSWORD = 'password'; + private array $generatedPosts = []; /** * Static values for user and post counts. diff --git a/shared/Commands/PostCreateCommand.php b/shared/Commands/PostCreateCommand.php index 0bcaebb9..46046ff0 100644 --- a/shared/Commands/PostCreateCommand.php +++ b/shared/Commands/PostCreateCommand.php @@ -9,17 +9,17 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; use Quantum\Service\Exceptions\ServiceException; use Quantum\App\Exceptions\BaseException; -use Quantum\Libraries\Validation\Rule; use Quantum\Di\Exceptions\DiException; use Shared\Services\PostService; use Quantum\Console\QtCommand; +use Quantum\Validation\Rule; use ReflectionException; /** @@ -33,27 +33,27 @@ class PostCreateCommand extends QtCommand /** * Command name - * @var string + * @var string|null */ - protected $name = 'post:create'; + protected ?string $name = 'post:create'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Allows to create a post record'; + protected ?string $description = 'Allows to create a post record'; /** * Command help text - * @var string + * @var string|null */ - protected $help = 'Use the following format to create a post record:' . PHP_EOL . 'php qt post:create `Title` `Description` `[Image]` `[Author]`'; + protected ?string $help = 'Use the following format to create a post record:' . PHP_EOL . 'php qt post:create `Title` `Description` `[Image]` `[Author]`'; /** * Command arguments * @var array[] */ - protected $args = [ + protected array $args = [ ['title', 'required', 'Post title'], ['description', 'required', 'Post description'], ['user_uuid', 'required', 'Author uuid'], @@ -63,10 +63,7 @@ class PostCreateCommand extends QtCommand /** * Executes the command - * @throws DiException - * @throws ReflectionException - * @throws ServiceException - * @throws BaseException + * @throws BaseException|DiException|ServiceException|ReflectionException */ public function exec() { diff --git a/shared/Commands/PostDeleteCommand.php b/shared/Commands/PostDeleteCommand.php index 3961b191..21a85878 100644 --- a/shared/Commands/PostDeleteCommand.php +++ b/shared/Commands/PostDeleteCommand.php @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; @@ -30,21 +30,21 @@ class PostDeleteCommand extends QtCommand /** * Command name - * @var string + * @var string|null */ - protected $name = 'post:delete'; + protected ?string $name = 'post:delete'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Deletes a post by UUID or clears the entire posts table with confirmation'; + protected ?string $description = 'Deletes a post by UUID or clears the entire posts table with confirmation'; /** * Command help text - * @var string + * @var string|null */ - protected $help = << * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; use Quantum\Service\Exceptions\ServiceException; use Quantum\App\Exceptions\BaseException; -use Quantum\Libraries\Validation\Rule; use Quantum\Di\Exceptions\DiException; use Shared\Services\PostService; use Quantum\Console\QtCommand; +use Quantum\Validation\Rule; use ReflectionException; /** @@ -33,27 +33,27 @@ class PostUpdateCommand extends QtCommand /** * Command name - * @var string + * @var string|null */ - protected $name = 'post:update'; + protected ?string $name = 'post:update'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Allows to update a post record'; + protected ?string $description = 'Allows to update a post record'; /** * Command help text - * @var string + * @var string|null */ - protected $help = 'Use the following format to update the post:' . PHP_EOL . 'php qt post:update `[Post uuid]` -t `Title` -d `Description` [-i `Image`] [-a `Author`]'; + protected ?string $help = 'Use the following format to update the post:' . PHP_EOL . 'php qt post:update `[Post uuid]` -t `Title` -d `Description` [-i `Image`] [-a `Author`]'; /** * Command arguments * @var array */ - protected $args = [ + protected array $args = [ ['uuid', 'required', 'Post uuid'] ]; @@ -61,7 +61,7 @@ class PostUpdateCommand extends QtCommand * Command options * @var array */ - protected $options = [ + protected array $options = [ ['title', 't', 'optional', 'Post title'], ['description', 'd', 'optional', 'Post description'], ['image', 'i', 'optional', 'Post image'], @@ -69,10 +69,7 @@ class PostUpdateCommand extends QtCommand /** * Executes the command - * @throws DiException - * @throws ReflectionException - * @throws ServiceException - * @throws BaseException + * @throws BaseException|DiException|ServiceException|ReflectionException */ public function exec() { diff --git a/shared/Commands/UserCreateCommand.php b/shared/Commands/UserCreateCommand.php index e45e09b7..f96fe3ae 100644 --- a/shared/Commands/UserCreateCommand.php +++ b/shared/Commands/UserCreateCommand.php @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; @@ -17,10 +17,11 @@ use Quantum\Service\Exceptions\ServiceException; use Quantum\App\Exceptions\BaseException; use Quantum\Di\Exceptions\DiException; -use Quantum\Libraries\Validation\Rule; -use Quantum\Libraries\Hasher\Hasher; +use Quantum\Validation\Validator; use Shared\Services\AuthService; use Quantum\Console\QtCommand; +use Quantum\Validation\Rule; +use Quantum\Hasher\Hasher; use ReflectionException; use Shared\Models\User; @@ -35,29 +36,29 @@ class UserCreateCommand extends QtCommand /** * Command name - * @var string + * @var string|null */ - protected $name = 'user:create'; + protected ?string $name = 'user:create'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Allows to create a user'; + protected ?string $description = 'Allows to create a user'; /** * Command help text - * @var string + * @var string|null */ - protected $help = 'Use the following format to create a user record:' . PHP_EOL . 'php qt user:create `Email` `Password` `[Role]` `[Firstname]` `[Lastname]`'; + protected ?string $help = 'Use the following format to create a user record:' . PHP_EOL . 'php qt user:create `Email` `Password` `[Role]` `[Firstname]` `[Lastname]`'; - protected $validator; + protected Validator $validator; /** * Command arguments * @var array[] */ - protected $args = [ + protected array $args = [ ['email', 'required', 'User email'], ['password', 'required', 'User password'], ['firstname', 'required', 'User firstname'], diff --git a/shared/Commands/UserDeleteCommand.php b/shared/Commands/UserDeleteCommand.php index 5aefe502..c74527f5 100644 --- a/shared/Commands/UserDeleteCommand.php +++ b/shared/Commands/UserDeleteCommand.php @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Commands; @@ -30,21 +30,21 @@ class UserDeleteCommand extends QtCommand /** * Command name - * @var string + * @var string|null */ - protected $name = 'user:delete'; + protected ?string $name = 'user:delete'; /** * Command description - * @var string + * @var string|null */ - protected $description = 'Deletes a user by UUID or clears the entire posts table with confirmation'; + protected ?string $description = 'Deletes a user by UUID or clears the entire posts table with confirmation'; /** * Command help text - * @var string + * @var string|null */ - protected $help = << * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Models; -use Quantum\Libraries\Database\Enums\Relation; +use Quantum\Model\Traits\HasTimestamps; use Quantum\Model\Traits\SoftDeletes; -use Quantum\Model\QtModel; +use Quantum\Database\Enums\Relation; +use Quantum\Model\DbModel; /** * Class Comment * @package Shared\Models */ -class Comment extends QtModel +class Comment extends DbModel { + use HasTimestamps; use SoftDeletes; /** * ID column of table * @var string */ - public $idColumn = 'id'; + public string $idColumn = 'id'; /** * The table name * @var string */ - public $table = 'comments'; + public string $table = 'comments'; /** * Fillable properties * @var array */ - public $fillable = [ + public array $fillable = [ 'uuid', 'post_uuid', 'user_uuid', 'content', - 'created_at', - 'updated_at' ]; /** diff --git a/shared/Models/Post.php b/shared/Models/Post.php index 0ac14cfc..4227b7cb 100644 --- a/shared/Models/Post.php +++ b/shared/Models/Post.php @@ -9,48 +9,48 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Models; -use Quantum\Libraries\Database\Enums\Relation; +use Quantum\Model\Traits\HasTimestamps; use Quantum\Model\Traits\SoftDeletes; -use Quantum\Model\QtModel; +use Quantum\Database\Enums\Relation; +use Quantum\Model\DbModel; /** * Class Post * @package Shared\Models */ -class Post extends QtModel +class Post extends DbModel { + use HasTimestamps; use SoftDeletes; /** * ID column of table * @var string */ - public $idColumn = 'id'; + public string $idColumn = 'id'; /** * The table name * @var string */ - public $table = 'posts'; + public string $table = 'posts'; /** * Fillable properties * @var array */ - public $fillable = [ + public array $fillable = [ 'uuid', 'user_uuid', 'title', 'content', 'image', - 'created_at', - 'updated_at', ]; /** diff --git a/shared/Models/User.php b/shared/Models/User.php index 9830aab7..e6fba2ab 100644 --- a/shared/Models/User.php +++ b/shared/Models/User.php @@ -14,32 +14,35 @@ namespace Shared\Models; -use Quantum\Model\QtModel; +use Quantum\Model\Traits\HasTimestamps; +use Quantum\Model\DbModel; /** * Class User * @package Shared\Models */ -class User extends QtModel +class User extends DbModel { + use HasTimestamps; + /** * ID column of table * @var string */ - public $idColumn = 'id'; + public string $idColumn = 'id'; /** * The table name * @var string */ - public $table = 'users'; + public string $table = 'users'; /** * Fillable properties * @var array */ - public $fillable = [ + public array $fillable = [ 'uuid', 'firstname', 'lastname', @@ -55,7 +58,5 @@ class User extends QtModel 'otp', 'otp_expires', 'otp_token', - 'created_at', - 'updated_at', ]; } \ No newline at end of file diff --git a/shared/Services/AuthService.php b/shared/Services/AuthService.php index e72f7ae4..c669b7af 100644 --- a/shared/Services/AuthService.php +++ b/shared/Services/AuthService.php @@ -9,20 +9,19 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Services; -use Quantum\Libraries\Auth\Contracts\AuthServiceInterface; +use Quantum\Auth\Contracts\AuthServiceInterface; use Quantum\Config\Exceptions\ConfigException; use Quantum\Model\Exceptions\ModelException; -use Quantum\Libraries\Auth\User as AuthUser; use Quantum\App\Exceptions\BaseException; use Quantum\Di\Exceptions\DiException; +use Quantum\Auth\User as AuthUser; use Quantum\Model\ModelCollection; use Quantum\Service\QtService; -use Quantum\Model\QtModel; use ReflectionException; use Shared\Models\User; @@ -34,9 +33,9 @@ class AuthService extends QtService implements AuthServiceInterface { /** - * @var QtModel + * @var User */ - private $model; + private User $model; /** * @throws BaseException @@ -95,12 +94,11 @@ public function get(string $field, $value): ?AuthUser public function add(array $data): AuthUser { $data['uuid'] = $data['uuid'] ?? uuid_ordered(); - $data['created_at'] = date('Y-m-d H:i:s'); $this->createUserDirectory($data['uuid']); $user = $this->model->create(); - $user->fillObjectProps($data); + $user->fill($data); $user->save(); return (new AuthUser())->setData($data); @@ -121,9 +119,9 @@ public function update(string $field, ?string $value, array $data): ?AuthUser return null; } - $data['updated_at'] = date('Y-m-d H:i:s'); + unset($data['id']); - $user->fillObjectProps($data); + $user->fill($data); $user->save(); return (new AuthUser())->setData($this->model->findOneBy($field, $value)->asArray()); @@ -144,7 +142,7 @@ public function delete(string $uuid): bool */ public function deleteAllUsers() { - $this->model->deleteTable(); + $this->model->truncate(); } /** diff --git a/shared/Services/CommentService.php b/shared/Services/CommentService.php index 969601d1..98931fad 100644 --- a/shared/Services/CommentService.php +++ b/shared/Services/CommentService.php @@ -93,13 +93,12 @@ public function getComment(string $uuid): Comment public function addComment(array $data): array { $data['uuid'] = $data['uuid'] ?? uuid_ordered(); - $data['created_at'] = date('Y-m-d H:i:s'); $comment = $this->model->create(); - $comment->fillObjectProps($data); + $comment->fill($data); $comment->save(); - return $data; + return $comment->asArray(); } /** @@ -118,7 +117,7 @@ public function deleteComment(string $uuid): bool */ public function deleteAllComments() { - $this->model->deleteTable(); + $this->model->truncate(); } /** diff --git a/shared/Services/PostService.php b/shared/Services/PostService.php index b78b7e46..a7b26726 100644 --- a/shared/Services/PostService.php +++ b/shared/Services/PostService.php @@ -9,26 +9,25 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Services; -use Quantum\Libraries\Storage\Exceptions\FileUploadException; -use Quantum\Libraries\Storage\Exceptions\FileSystemException; -use Quantum\Libraries\Storage\Factories\FileSystemFactory; +use Quantum\Storage\Exceptions\FileUploadException; +use Quantum\Storage\Exceptions\FileSystemException; +use Quantum\Storage\Factories\FileSystemFactory; use Quantum\Environment\Exceptions\EnvException; use Quantum\Config\Exceptions\ConfigException; use Quantum\Model\Exceptions\ModelException; -use Quantum\Libraries\Storage\UploadedFile; use Quantum\App\Exceptions\BaseException; -use Quantum\Model\Factories\ModelFactory; use Shared\Transformers\PostTransformer; use Quantum\Di\Exceptions\DiException; use Quantum\Model\ModelCollection; +use Quantum\Storage\UploadedFile; use Gumlet\ImageResizeException; use Quantum\Service\QtService; -use Quantum\Model\QtModel; +use Quantum\Model\DbModel; use ReflectionException; use Shared\Models\User; use Shared\Models\Post; @@ -41,14 +40,14 @@ class PostService extends QtService { /** - * @var QtModel + * @var DbModel */ private $model; /** * @var PostTransformer */ - private $transformer; + private PostTransformer $transformer; /** * @param PostTransformer $transformer @@ -161,10 +160,9 @@ public function getMyPosts(string $userUuid): ?ModelCollection public function addPost(array $data): Post { $data['uuid'] = $data['uuid'] ?? uuid_ordered(); - $data['created_at'] = date('Y-m-d H:i:s'); $post = $this->model->create(); - $post->fillObjectProps($data); + $post->fill($data); $post->save(); return $this->getPost($data['uuid']); @@ -180,10 +178,8 @@ public function addPost(array $data): Post */ public function updatePost(string $uuid, array $data): Post { - $data['updated_at'] = date('Y-m-d H:i:s'); - $post = $this->model->findOneBy('uuid', $uuid); - $post->fillObjectProps($data); + $post->fill($data); $post->save(); return $this->getPost($post->uuid); @@ -193,7 +189,7 @@ public function updatePost(string $uuid, array $data): Post * Deletes post * @param string $uuid * @return bool - * @throws ModelException + * @throws ModelException|BaseException */ public function deletePost(string $uuid): bool { @@ -206,7 +202,7 @@ public function deletePost(string $uuid): bool */ public function deleteAllPosts() { - $this->model->deleteTable(); + $this->model->truncate(); } /** diff --git a/shared/Transformers/CommentTransformer.php b/shared/Transformers/CommentTransformer.php index f29c85c1..582e0077 100644 --- a/shared/Transformers/CommentTransformer.php +++ b/shared/Transformers/CommentTransformer.php @@ -9,12 +9,12 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.9 + * @since 3.0.0 */ namespace Shared\Transformers; -use Quantum\Libraries\Transformer\Contracts\TransformerInterface; +use Quantum\Transformer\Contracts\TransformerInterface; /** * Class CommentTransformer diff --git a/shared/Transformers/PostTransformer.php b/shared/Transformers/PostTransformer.php index 930aacd5..f328cd34 100644 --- a/shared/Transformers/PostTransformer.php +++ b/shared/Transformers/PostTransformer.php @@ -9,12 +9,12 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.0 + * @since 3.0.0 */ namespace Shared\Transformers; -use Quantum\Libraries\Transformer\Contracts\TransformerInterface; +use Quantum\Transformer\Contracts\TransformerInterface; /** * Class PostTransformer diff --git a/tests/Feature/AppTestCase.php b/tests/Feature/AppTestCase.php index cb862a35..abd42f61 100644 --- a/tests/Feature/AppTestCase.php +++ b/tests/Feature/AppTestCase.php @@ -10,25 +10,22 @@ class AppTestCase extends TestCase { - protected $defaultEmail = 'default@quantumphp.io'; + protected string $defaultEmail = 'default@quantumphp.io'; - protected $defaultPassword = 'password'; + protected string $defaultPassword = 'password'; - protected $firstname = 'John'; + protected string $firstname = 'John'; - protected $lastname = 'Doe'; + protected string $lastname = 'Doe'; - protected static $app; - - public static function setUpBeforeClass(): void - { - self::$app = createApp(App::WEB, PROJECT_ROOT); - } + protected static App $app; public function setUp(): void { parent::setUp(); ob_start(); + + self::$app = createApp(App::WEB, PROJECT_ROOT); } public function tearDown(): void diff --git a/tests/Feature/modules/Api/AuthControllerTest.php b/tests/Feature/modules/Api/AuthControllerTest.php index 75238a55..d0858ecd 100644 --- a/tests/Feature/modules/Api/AuthControllerTest.php +++ b/tests/Feature/modules/Api/AuthControllerTest.php @@ -7,12 +7,13 @@ use Quantum\Http\Response; use Quantum\Http\Request; use Shared\Models\User; +use Faker\Generator; use Faker\Factory; class AuthControllerTest extends AppTestCase { - private $faker; + private Generator $faker; public function setUp(): void { @@ -180,16 +181,17 @@ public function testModuleApiResetEndpointWithIncorrectToken() public function testModuleApiVerifyEndpoint() { $email = $this->faker->email(); - $otp = $this->faker->uuid(); + $otp = random_int(100000, 999999); // Generate 6-digit integer OTP $user = createUser([ 'email' => $email, 'otp_token' => base64_encode($otp), - 'otp' => $otp, + 'otp' => (string)$otp, + 'otp_expires' => date('Y-m-d H:i:s', time() + 300), // 5 minutes from now ]); $response = $this->request('post', '/api/en/verify', [ - 'otp' => $otp, + 'otp' => (string)$otp, 'code' => base64_encode($otp), ]); diff --git a/tests/Feature/modules/Api/CommentControllerTest.php b/tests/Feature/modules/Api/CommentControllerTest.php index 7055e705..47086653 100644 --- a/tests/Feature/modules/Api/CommentControllerTest.php +++ b/tests/Feature/modules/Api/CommentControllerTest.php @@ -2,7 +2,6 @@ namespace Quantum\Tests\Feature\modules\Api; - use Quantum\Model\Factories\ModelFactory; use Quantum\Tests\Feature\AppTestCase; use Shared\Models\Comment; @@ -12,7 +11,7 @@ class CommentControllerTest extends AppTestCase { - private $tokens = []; + private array $tokens = []; private $post = null; @@ -58,7 +57,6 @@ public function testModuleApiCommentCreateEndpoint() $this->assertArrayHasKey('user_uuid', $comment); $this->assertArrayHasKey('post_uuid', $comment); $this->assertArrayHasKey('content', $comment); - $this->assertArrayHasKey('created_at', $comment); } public function testModuleApiCommentDeleteEndpoint() diff --git a/tests/Helpers/functions.php b/tests/Helpers/functions.php index b08dab95..c804566b 100644 --- a/tests/Helpers/functions.php +++ b/tests/Helpers/functions.php @@ -1,15 +1,17 @@ addModuleConfig(); - Router::setCurrentRoute(['module' => $moduleName]); + $route = new Route(['GET'], 'dummy', null, null, function () {}); + $route->module($moduleName); + $matchedRoute = new MatchedRoute($route, []); + Request::setMatchedRoute($matchedRoute); ob_end_clean(); } diff --git a/tests/Unit/shared/Services/AuthServiceTest.php b/tests/Unit/shared/Services/AuthServiceTest.php index d986e324..621649f5 100644 --- a/tests/Unit/shared/Services/AuthServiceTest.php +++ b/tests/Unit/shared/Services/AuthServiceTest.php @@ -2,8 +2,8 @@ namespace Quantum\Tests\Unit\shared\Services; -use Quantum\Libraries\Auth\User as AuthUser; use Quantum\Service\Factories\ServiceFactory; +use Quantum\Auth\User as AuthUser; use Quantum\Model\ModelCollection; use Shared\Services\AuthService; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/shared/Services/PostServiceTest.php b/tests/Unit/shared/Services/PostServiceTest.php index a8d18c80..38b2e9df 100644 --- a/tests/Unit/shared/Services/PostServiceTest.php +++ b/tests/Unit/shared/Services/PostServiceTest.php @@ -2,9 +2,9 @@ namespace Quantum\Tests\Unit\shared\Services; -use Quantum\Libraries\Storage\UploadedFile; use Quantum\Service\Factories\ServiceFactory; use Quantum\Model\ModelCollection; +use Quantum\Storage\UploadedFile; use Quantum\Paginator\Paginator; use Shared\Services\AuthService; use Shared\Services\PostService; @@ -21,8 +21,6 @@ class PostServiceTest extends TestCase protected $postService; - private $initialPosts; - public function setUp(): void { parent::setUp(); @@ -84,7 +82,7 @@ public function testPostServiceGetPostsWithSearch() 'title' => $title, 'content' => $content, 'image' => '', - 'updated_at' => date('Y-m-d H:i:s'), + ]); $searchTerm = 'SEARCH_TOKEN'; @@ -115,8 +113,6 @@ public function testPostServiceGetSinglePost() $this->assertArrayHasKey('content', $postData); - $this->assertArrayHasKey('updated_at', $postData); - } public function testPostServiceGetMyPosts() @@ -145,7 +141,7 @@ public function testPostServiceAddNewPost() 'title' => 'Just another post', 'content' => 'Content of just another post', 'image' => '', - 'updated_at' => $date + ]); $post = $this->postService->getPost($newPost->uuid); @@ -154,7 +150,7 @@ public function testPostServiceAddNewPost() $this->assertEquals('Content of just another post', $post->content); - $this->assertEquals($date, $post->updated_at); + $this->postService->deletePost($newPost->uuid); } @@ -171,7 +167,6 @@ public function testPostServiceUpdatePost() 'title' => 'Walt Disney Jr.', 'content' => 'The best way to get started is to quit talking and begin doing.', 'image' => 'image.jpg', - 'updated_at' => $date ]); $post = $this->postService->getPost($uuid); @@ -184,7 +179,7 @@ public function testPostServiceUpdatePost() $this->assertEquals('image.jpg', $post->image); - $this->assertEquals($date, $post->updated_at); + } public function testPostServiceDeletePost() @@ -200,7 +195,6 @@ public function testPostServiceDeletePost() 'title' => 'Just another post', 'content' => 'Content of just another post', 'image' => '', - 'updated_at' => date('Y-m-d H:i:s') ]); $this->assertCount(11, $this->postService->getPosts()); @@ -214,12 +208,18 @@ public function testPostServiceSaveAndDeleteImage() { $this->fileMeta = [ 'size' => 500, - 'name' => 'foo.jpg', + 'name' => 'foo.jpeg', 'tmp_name' => base_dir() . DS . 'tmp' . DS . 'php8fe1.tmp', - 'type' => 'image/jpg', + 'type' => 'image/jpeg', 'error' => 0, ]; + if (!is_dir(base_dir() . DS . 'tmp')) { + mkdir(base_dir() . DS . 'tmp'); + } + + file_put_contents($this->fileMeta['tmp_name'], hex2bin('FFD8FFE0')); + $users = $this->authService->getAll(); $userUuid = $users->first()->uuid; diff --git a/tests/_root/helpers/functions.php b/tests/_root/helpers/functions.php index c8888c8f..5bc6d94e 100644 --- a/tests/_root/helpers/functions.php +++ b/tests/_root/helpers/functions.php @@ -1,29 +1,8 @@ - * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) - * @link http://quantum.softberg.org/ - * @since 2.9.8 - */ - -use Quantum\Libraries\HttpClient\Exceptions\HttpClientException; -use Quantum\Libraries\Storage\Factories\FileSystemFactory; -use Quantum\Config\Exceptions\ConfigException; -use Quantum\Libraries\HttpClient\HttpClient; -use Quantum\App\Exceptions\BaseException; -use Quantum\Di\Exceptions\DiException; - -/** - * Gets the url with selected language - * @param string $lang - * @return string - */ +use Quantum\Storage\Factories\FileSystemFactory; +use Quantum\HttpClient\HttpClient; + function url_with_lang(string $lang): string { if (!in_array($lang, (array)config()->get('lang.supported'))) { @@ -57,23 +36,10 @@ function url_with_lang(string $lang): string $url .= '/' . ($index == $langSegmentIndex ? $lang : $segment); } } -dd($url); + return $url; } -/** - * Saves remote image - * @param string $imageUrl - * @param string $userDirectory - * @param string $imageName - * @return string - * @throws ErrorException - * @throws HttpClientException - * @throws ReflectionException - * @throws BaseException - * @throws ConfigException - * @throws DiException - */ function save_remote_image(string $imageUrl, string $userDirectory, string $imageName): string { $fs = FileSystemFactory::get(); @@ -91,11 +57,6 @@ function save_remote_image(string $imageUrl, string $userDirectory, string $imag return $imageName; } -/** - * Cleans up text for titles/descriptions. - * @param string $text - * @return array|string|string[] - */ function textCleanUp(string $text) { return str_replace(['"', '\'', '-'], '', $text); diff --git a/tests/_root/logs/app.log b/tests/_root/logs/app.log deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/_root/tmp/php8fe1.tmp b/tests/_root/tmp/php8fe1.tmp index e134ce2d6ce4ab2c8b6e73f5a829a06344a22025..6255ad5ebe76b0462d44542596044fd3283f3310 100644 GIT binary patch literal 4 Lcmex=jK^3!2K(U`h{u0j$Q}RSp|KN+g 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 From 64365ab57706304c268a7d8efc85146c5f59a270 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sun, 15 Mar 2026 18:05:33 +0400 Subject: [PATCH 02/10] Updating php versions on github workflow --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index c245b97d..c1b69cf2 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: operating-system: [ ubuntu-latest ] - php-versions: [ '7.3', '7.4' ] + php-versions: ['7.4', '8.0', '8.1' ] runs-on: ${{ matrix.operating-system }} From 79d2c1586d3d3e290035710783405aee283b7572 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sun, 15 Mar 2026 23:32:25 +0400 Subject: [PATCH 03/10] Resting Di container before each test --- tests/Feature/AppTestCase.php | 2 ++ tests/Helpers/functions.php | 1 + 2 files changed, 3 insertions(+) diff --git a/tests/Feature/AppTestCase.php b/tests/Feature/AppTestCase.php index abd42f61..0e7a4241 100644 --- a/tests/Feature/AppTestCase.php +++ b/tests/Feature/AppTestCase.php @@ -6,6 +6,7 @@ use Quantum\Http\Response; use Quantum\Http\Request; use Quantum\App\App; +use Quantum\Di\Di; class AppTestCase extends TestCase { @@ -42,6 +43,7 @@ public function request( array $files = [] ): Response { + Di::resetContainer(); Request::create($method, $url, $params, $headers, $files); self::$app->start(); return new Response(); diff --git a/tests/Helpers/functions.php b/tests/Helpers/functions.php index c804566b..4c483dfd 100644 --- a/tests/Helpers/functions.php +++ b/tests/Helpers/functions.php @@ -15,6 +15,7 @@ use Shared\Models\User; use Quantum\App\App; use Faker\Factory; +use Quantum\Di\Di; function createEnvFile() { From a68bbf6ca2e4e97b2b773fb930ba149f3bc5de2c Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sun, 15 Mar 2026 23:56:47 +0400 Subject: [PATCH 04/10] Making sure to clean up remove module and remove unused tearDown method --- tests/Unit/shared/Services/AuthServiceTest.php | 6 ++++++ tests/bootstrap.php | 2 ++ 2 files changed, 8 insertions(+) diff --git a/tests/Unit/shared/Services/AuthServiceTest.php b/tests/Unit/shared/Services/AuthServiceTest.php index 621649f5..ba56993d 100644 --- a/tests/Unit/shared/Services/AuthServiceTest.php +++ b/tests/Unit/shared/Services/AuthServiceTest.php @@ -21,8 +21,14 @@ public function setUp(): void $this->authService = ServiceFactory::create(AuthService::class); } + public function tearDown(): void + { + parent::tearDown(); + } + public function testAuthServiceGetAll() { + $this->authService = ServiceFactory::create(AuthService::class); $users = $this->authService->getAll(); $this->assertInstanceOf(ModelCollection::class, $users); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index b3192e6b..930937ec 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -16,6 +16,8 @@ createApp(App::CONSOLE, PROJECT_ROOT); +removeModule(); + createModule('Api', 'DemoApi'); $user = createUser(); From 45f3a96a49c8dc6ab4e841850747ee692ac15171 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:32:31 +0400 Subject: [PATCH 05/10] Adding long app key as part of JWT requirement --- tests/_root/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/_root/.env.example b/tests/_root/.env.example index a48ae446..501460a9 100644 --- a/tests/_root/.env.example +++ b/tests/_root/.env.example @@ -1,3 +1,3 @@ -APP_KEY=XYZ1234567890 +APP_KEY=d4cf7e1c08d431d836dbc4bdc6f34bff4ac5988ee48ff4fdafe27e57b4156574 DEBUG=false TWO_FA=false \ No newline at end of file From cfe940be8b61afe46370056e0d92c9f2d87aa832 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:35:49 +0400 Subject: [PATCH 06/10] Adding app.log --- logs/app.log | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 logs/app.log diff --git a/logs/app.log b/logs/app.log new file mode 100644 index 00000000..e69de29b From 1d5465ebd30e8068a674343383186932068eeb96 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:26:38 +0400 Subject: [PATCH 07/10] Adding .gitkeep to keep the log folder --- tests/_root/logs/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/_root/logs/.gitkeep diff --git a/tests/_root/logs/.gitkeep b/tests/_root/logs/.gitkeep new file mode 100644 index 00000000..e69de29b From bd944b38368224aba6222515fb12bd178be9f1fb Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:59:04 +0400 Subject: [PATCH 08/10] Fix CommentControllerTest and clean up test data --- .../modules/Api/CommentControllerTest.php | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/Feature/modules/Api/CommentControllerTest.php b/tests/Feature/modules/Api/CommentControllerTest.php index 47086653..1180a8fd 100644 --- a/tests/Feature/modules/Api/CommentControllerTest.php +++ b/tests/Feature/modules/Api/CommentControllerTest.php @@ -15,9 +15,9 @@ class CommentControllerTest extends AppTestCase private $post = null; - public function setUp(): void - { - parent::setUp(); + public function setUp(): void + { + parent::setUp(); $this->tokens = $this->signInAndGetTokens(); @@ -29,15 +29,15 @@ public function setUp(): void Request::flush(); Response::flush(); - } + } public function tearDown(): void { parent::tearDown(); } - public function testModuleApiCommentCreateEndpoint() - { + public function testModuleApiCommentCreateEndpoint() + { $method = 'POST'; $endpoint = '/api/comments/create/'; $body = ['content' => 'My first comment']; @@ -57,18 +57,26 @@ public function testModuleApiCommentCreateEndpoint() $this->assertArrayHasKey('user_uuid', $comment); $this->assertArrayHasKey('post_uuid', $comment); $this->assertArrayHasKey('content', $comment); - } + + ModelFactory::get(Comment::class)->findOneBy('uuid', $comment['uuid'])->delete(); + } public function testModuleApiCommentDeleteEndpoint() { + $method = 'POST'; + $endpoint = '/api/comments/create/'; + $body = ['content' => 'Comment to be deleted']; + $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; + + $response = $this->request($method, $endpoint . $this->post['uuid'], $body, $headers); + + $comment = $response->get('data'); + $method = 'DELETE'; $endpoint = '/api/comments/delete/'; $body = []; - $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; - - $comment = ModelFactory::get(Comment::class)->first(); - $response = $this->request($method, $endpoint . $comment->uuid, $body, $headers); + $response = $this->request($method, $endpoint . $comment['uuid'], $body, $headers); $this->assertIsObject($response); From 6ffb7393f1b8525dc6c452445124f07375aeb368 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 16 Mar 2026 17:01:29 +0400 Subject: [PATCH 09/10] Debugging on CI --- .../modules/Api/AuthControllerTest.php | 12 +++++----- .../shared/Services/CommentServiceTest.php | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/Feature/modules/Api/AuthControllerTest.php b/tests/Feature/modules/Api/AuthControllerTest.php index d0858ecd..ac880d06 100644 --- a/tests/Feature/modules/Api/AuthControllerTest.php +++ b/tests/Feature/modules/Api/AuthControllerTest.php @@ -181,17 +181,17 @@ public function testModuleApiResetEndpointWithIncorrectToken() public function testModuleApiVerifyEndpoint() { $email = $this->faker->email(); - $otp = random_int(100000, 999999); // Generate 6-digit integer OTP + $otp = random_int(100000, 999999); - $user = createUser([ - 'email' => $email, + createUser([ + 'email' => $email, 'otp_token' => base64_encode($otp), - 'otp' => (string)$otp, + 'otp' => (string)$otp, 'otp_expires' => date('Y-m-d H:i:s', time() + 300), // 5 minutes from now ]); $response = $this->request('post', '/api/en/verify', [ - 'otp' => (string)$otp, + 'otp' => (string)$otp, 'code' => base64_encode($otp), ]); @@ -207,7 +207,7 @@ public function testModuleApiVerifyEndpoint() public function testModuleApiVerifyEndpointWithIncorrectOtp() { $response = $this->request('post', '/api/en/verify', [ - 'otp' => 'wrong-otp', + 'otp' => 'wrong-otp', 'code' => 'wrong-code', ]); diff --git a/tests/Unit/shared/Services/CommentServiceTest.php b/tests/Unit/shared/Services/CommentServiceTest.php index eae4da4e..2c2a3780 100644 --- a/tests/Unit/shared/Services/CommentServiceTest.php +++ b/tests/Unit/shared/Services/CommentServiceTest.php @@ -2,7 +2,9 @@ namespace Quantum\Tests\Unit\shared\Services; +use Quantum\Model\Factories\ModelFactory; use Quantum\Service\Factories\ServiceFactory; +use Shared\Models\Comment; use Shared\Services\CommentService; use Quantum\Model\ModelCollection; use Shared\Services\AuthService; @@ -31,6 +33,28 @@ public function testCommentServiceGetCommentsByPost() { $post = $this->postService->getPosts()->first(); + $rawComments = ModelFactory::get(Comment::class)->withTrashed()->criteria('post_uuid', '=', $post->uuid)->get(); + $allRaw = ModelFactory::get(Comment::class)->withTrashed()->get(); + $user = $this->authService->getAll()->first(); + + fwrite(STDERR, sprintf( + "\n[DIAG] post_uuid=%s, user_uuid=%s, raw_for_post=%d, total_raw=%d\n", + $post->uuid, + $user->uuid, + count($rawComments), + count($allRaw) + )); + + if (count($allRaw) > 0) { + $first = $allRaw->first(); + fwrite(STDERR, sprintf( + "[DIAG] first_comment: post_uuid=%s, user_uuid=%s, deleted_at=%s\n", + $first->prop('post_uuid') ?? 'NULL', + $first->prop('user_uuid') ?? 'NULL', + $first->prop('deleted_at') ?? 'NULL' + )); + } + $comments = $this->commentService->getCommentsByPost($post->uuid); $this->assertInstanceOf(ModelCollection::class, $comments); From 47b867c90578eaa6a1f5932449e00956352fe2db Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Mon, 16 Mar 2026 17:35:14 +0400 Subject: [PATCH 10/10] Refactor tests, commands, and CI workflow for better reliability --- .github/workflows/php.yml | 6 ++--- .../Api/PostManagementControllerTest.php | 25 +++++++++++++------ .../shared/Services/CommentServiceTest.php | 22 ---------------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index c1b69cf2..d24db0d7 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -35,12 +35,12 @@ jobs: uses: actions/cache@v3 with: path: vendor - key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ hashFiles('**/composer.json') }} restore-keys: | - ${{ runner.os }}-php- + ${{ runner.os }}-php-${{ matrix.php-versions }}- - name: Install dependencies - run: composer install --prefer-dist --no-progress + run: composer update --prefer-dist --no-progress - name: Create env run: php qt core:env diff --git a/tests/Feature/modules/Api/PostManagementControllerTest.php b/tests/Feature/modules/Api/PostManagementControllerTest.php index 5bc6ba93..cda567b8 100644 --- a/tests/Feature/modules/Api/PostManagementControllerTest.php +++ b/tests/Feature/modules/Api/PostManagementControllerTest.php @@ -91,6 +91,7 @@ public function testModuleApiPostCreateEndpoint() $this->assertArrayHasKey('date', $post); $this->assertArrayHasKey('author', $post); + ModelFactory::get(Post::class)->findOneBy('uuid', $post['uuid'])->delete(); } public function testModuleApiAmendPostEndpoint() @@ -127,20 +128,30 @@ public function testModuleApiAmendPostEndpoint() public function testModuleApiDeletePostEndpoint() { + $method = 'POST'; + $endpoint = '/api/my-posts/create'; + $body = [ + 'title' => 'Post to be deleted', + 'content' => 'Temporary post for deletion test', + 'image' => '', + ]; + $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; + + $response = $this->request($method, $endpoint, $body, $headers); + + $post = $response->get('data'); + $method = 'DELETE'; $endpoint = '/api/my-posts/delete/'; $body = []; - $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; - $post = ModelFactory::get(Post::class)->first(); + $response = $this->request($method, $endpoint . $post['uuid'], $body, $headers); - $response = $this->request($method, $endpoint . $post->uuid, $body, $headers); + $this->assertIsObject($response); - $this->assertIsObject($response); - - $this->assertEquals('success', $response->get('status')); + $this->assertEquals('success', $response->get('status')); - $this->assertEquals('Deleted successfully', $response->get('message')); + $this->assertEquals('Deleted successfully', $response->get('message')); } public function testModuleApiDeletePostImageEndpoint() diff --git a/tests/Unit/shared/Services/CommentServiceTest.php b/tests/Unit/shared/Services/CommentServiceTest.php index 2c2a3780..f69b0bb9 100644 --- a/tests/Unit/shared/Services/CommentServiceTest.php +++ b/tests/Unit/shared/Services/CommentServiceTest.php @@ -33,28 +33,6 @@ public function testCommentServiceGetCommentsByPost() { $post = $this->postService->getPosts()->first(); - $rawComments = ModelFactory::get(Comment::class)->withTrashed()->criteria('post_uuid', '=', $post->uuid)->get(); - $allRaw = ModelFactory::get(Comment::class)->withTrashed()->get(); - $user = $this->authService->getAll()->first(); - - fwrite(STDERR, sprintf( - "\n[DIAG] post_uuid=%s, user_uuid=%s, raw_for_post=%d, total_raw=%d\n", - $post->uuid, - $user->uuid, - count($rawComments), - count($allRaw) - )); - - if (count($allRaw) > 0) { - $first = $allRaw->first(); - fwrite(STDERR, sprintf( - "[DIAG] first_comment: post_uuid=%s, user_uuid=%s, deleted_at=%s\n", - $first->prop('post_uuid') ?? 'NULL', - $first->prop('user_uuid') ?? 'NULL', - $first->prop('deleted_at') ?? 'NULL' - )); - } - $comments = $this->commentService->getCommentsByPost($post->uuid); $this->assertInstanceOf(ModelCollection::class, $comments);