diff --git a/shared/Services/PostService.php b/shared/Services/PostService.php index 7d27068..22ed685 100644 --- a/shared/Services/PostService.php +++ b/shared/Services/PostService.php @@ -152,10 +152,10 @@ public function getMyPosts(string $userUuid): ?ModelCollection /** * Add post * @param array $data - * @return array + * @return Post * @throws ModelException */ - public function addPost(array $data): array + public function addPost(array $data): Post { $data['uuid'] = $data['uuid'] ?? uuid_ordered(); $data['created_at'] = date('Y-m-d H:i:s'); @@ -164,22 +164,25 @@ public function addPost(array $data): array $post->fillObjectProps($data); $post->save(); - return $data; + return $this->getPost($post->uuid); } /** * Update post * @param string $uuid * @param array $data + * @return Post * @throws ModelException */ - public function updatePost(string $uuid, array $data) + 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->save(); + + return $this->getPost($post->uuid); } /** diff --git a/tests/Feature/AppTestCase.php b/tests/Feature/AppTestCase.php index 85c3f67..cb862a3 100644 --- a/tests/Feature/AppTestCase.php +++ b/tests/Feature/AppTestCase.php @@ -52,7 +52,7 @@ public function request( protected function signInAndGetTokens(): array { - $response = $this->request('post', '/api/en/signin', [ + $response = $this->request('post', '/api/signin', [ 'email' => $this->defaultEmail, 'password' => $this->defaultPassword ]); diff --git a/tests/Feature/modules/Api/CommentControllerTest.php b/tests/Feature/modules/Api/CommentControllerTest.php new file mode 100644 index 0000000..7055e70 --- /dev/null +++ b/tests/Feature/modules/Api/CommentControllerTest.php @@ -0,0 +1,81 @@ +tokens = $this->signInAndGetTokens(); + + $response = $this->request('get', '/api/posts'); + + $postData = $response->get('data'); + + $this->post = $postData[0]; + + Request::flush(); + Response::flush(); + } + + public function tearDown(): void + { + parent::tearDown(); + } + + public function testModuleApiCommentCreateEndpoint() + { + $method = 'POST'; + $endpoint = '/api/comments/create/'; + $body = ['content' => 'My first comment']; + $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; + + $response = $this->request($method, $endpoint . $this->post['uuid'], $body, $headers); + + $this->assertEquals('success', $response->get('status')); + + $this->assertEquals('Created successfully', $response->get('message')); + + $comment = $response->get('data'); + + $this->assertIsArray($comment); + + $this->assertArrayHasKey('uuid', $comment); + $this->assertArrayHasKey('user_uuid', $comment); + $this->assertArrayHasKey('post_uuid', $comment); + $this->assertArrayHasKey('content', $comment); + $this->assertArrayHasKey('created_at', $comment); + } + + public function testModuleApiCommentDeleteEndpoint() + { + $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); + + $this->assertIsObject($response); + + $this->assertEquals('success', $response->get('status')); + + $this->assertEquals('Deleted successfully', $response->get('message')); + } +} \ No newline at end of file diff --git a/tests/Feature/modules/Api/PostControllerTest.php b/tests/Feature/modules/Api/PostControllerTest.php index 66f2d54..681f29e 100644 --- a/tests/Feature/modules/Api/PostControllerTest.php +++ b/tests/Feature/modules/Api/PostControllerTest.php @@ -9,15 +9,6 @@ class PostControllerTest extends AppTestCase { - /** - * @var string - */ - protected $email = 'test@test.test'; - - /** - * @var string - */ - protected $password = 'password'; public function setUp(): void { @@ -33,28 +24,40 @@ public function tearDown(): void public function testModuleApiPostsEndpoint() { - $response = $this->request('get', '/api/en/posts'); + $method = 'GET'; + $endpoint = '/api/posts'; + + $response = $this->request($method, $endpoint); $this->assertIsObject($response); + $this->assertEquals('success', $response->get('status')); $this->assertArrayHasKey('data', $response->all()); $postData = $response->get('data'); + $this->assertIsArray($postData); + $this->assertCount(8, $postData); - $this->assertArrayHasKey('uuid', $postData[0]); - $this->assertArrayHasKey('title', $postData[0]); - $this->assertArrayHasKey('content', $postData[0]); - $this->assertArrayHasKey('image', $postData[0]); - $this->assertArrayHasKey('date', $postData[0]); - $this->assertArrayHasKey('author', $postData[0]); + $firstPost = $postData[0]; + + $this->assertIsArray($firstPost); + + $this->assertArrayHasKey('uuid', $firstPost); + $this->assertArrayHasKey('title', $firstPost); + $this->assertArrayHasKey('content', $firstPost); + $this->assertArrayHasKey('image', $firstPost); + $this->assertArrayHasKey('date', $firstPost); + $this->assertArrayHasKey('author', $firstPost); $this->assertArrayHasKey('pagination', $response->all()); $pagination = $response->get('pagination'); + $this->assertIsArray($pagination); + $this->assertArrayHasKey('total_records', $pagination); $this->assertArrayHasKey('current_page', $pagination); $this->assertArrayHasKey('next_page', $pagination); @@ -68,114 +71,39 @@ public function testModuleApiPostsEndpoint() public function testModuleApiSinglePostEndpoint() { - $post = ModelFactory::get(Post::class)->first(); - - $response = $this->request('get', '/api/en/post/' . $post->uuid); - - $this->assertIsObject($response); - $this->assertEquals('success', $response->get('status')); - $this->assertArrayHasKey('data', $response->all()); - - $rawData = $response->get('data'); - - $this->assertArrayHasKey('uuid', $rawData); - $this->assertArrayHasKey('title', $rawData); - $this->assertArrayHasKey('content', $rawData); - $this->assertArrayHasKey('image', $rawData); - $this->assertArrayHasKey('date', $rawData); - $this->assertArrayHasKey('author', $rawData); - } - - public function testModuleApiMyPostsEndpoint() - { - $tokens = $this->signInAndGetTokens(); - - $response = $this->request('get', '/api/en/my-posts', [], [ - 'Authorization' => 'Bearer ' . $tokens['access_token'], - 'refresh_token' => $tokens['refresh_token'] - ]); - - $this->assertIsObject($response); - $this->assertEquals('success', $response->get('status')); - $this->assertArrayHasKey('data', $response->all()); - - $postData = $response->get('data'); - - $this->assertCount(10, $postData); + $method = 'GET'; + $endpoint = '/api/post/'; - $this->assertArrayHasKey('uuid', $postData[0]); - $this->assertArrayHasKey('title', $postData[0]); - $this->assertArrayHasKey('content', $postData[0]); - $this->assertArrayHasKey('image', $postData[0]); - $this->assertArrayHasKey('date', $postData[0]); - $this->assertArrayHasKey('author', $postData[0]); - } - - public function testModuleApiPostCreateEndpoint() - { - $tokens = $this->signInAndGetTokens(); - - $response = $this->request('post', '/api/en/my-posts/create', - [ - 'title' => 'test title', - 'content' => 'test content', - 'image' => '', - 'updated_at' => date('Y-m-d H:i:s'), - ], - ['Authorization' => 'Bearer ' . $tokens['access_token']] - ); - - $this->assertIsObject($response); - $this->assertEquals('success', $response->get('status')); - $this->assertEquals('Created successfully', $response->get('message')); - } - - public function testModuleApiAmendPostEndpoint() - { $post = ModelFactory::get(Post::class)->first(); - $tokens = $this->signInAndGetTokens(); - - $response = $this->request('put', '/api/en/my-posts/amend/' . $post->uuid, - [ - 'title' => 'test title123', - 'content' => 'test content123', - ], - ['Authorization' => 'Bearer ' . $tokens['access_token']] - ); + $response = $this->request($method, $endpoint . $post->uuid); $this->assertIsObject($response); - $this->assertEquals('success', $response->get('status')); - $this->assertEquals('Updated successfully', $response->get('message')); - } - public function testDeletePostApi() - { - $post = ModelFactory::get(Post::class)->first(); + $this->assertEquals('success', $response->get('status')); - $tokens = $this->signInAndGetTokens(); + $this->assertArrayHasKey('data', $response->all()); - $response = $this->request('delete', '/api/en/my-posts/delete/' . $post->uuid, [], [ - 'Authorization' => 'Bearer ' . $tokens['access_token'] - ]); + $post = $response->get('data'); - $this->assertIsObject($response); - $this->assertEquals('success', $response->get('status')); - $this->assertEquals('Deleted successfully', $response->get('message')); - } + $this->assertIsArray($post); - public function testDeleteImagePostApi() - { - $post = ModelFactory::get(Post::class)->first(); + $this->assertArrayHasKey('uuid', $post); + $this->assertArrayHasKey('title', $post); + $this->assertArrayHasKey('content', $post); + $this->assertArrayHasKey('image', $post); + $this->assertArrayHasKey('date', $post); + $this->assertArrayHasKey('author', $post); + $this->assertArrayHasKey('comments', $post); - $tokens = $this->signInAndGetTokens(); + $firstComment = $post['comments'][0]; - $response = $this->request('delete', '/api/en/my-posts/delete-image/' . $post->uuid, [], [ - 'Authorization' => 'Bearer ' . $tokens['access_token'] - ]); + $this->assertIsArray($firstComment); - $this->assertIsObject($response); - $this->assertEquals('success', $response->get('status')); - $this->assertEquals('Deleted successfully', $response->get('message')); + $this->assertArrayHasKey('uuid', $firstComment); + $this->assertArrayHasKey('author', $firstComment); + $this->assertArrayHasKey('author', $firstComment); + $this->assertArrayHasKey('content', $firstComment); + $this->assertArrayHasKey('date', $firstComment); } } \ No newline at end of file diff --git a/tests/Feature/modules/Api/PostManagementControllerTest.php b/tests/Feature/modules/Api/PostManagementControllerTest.php new file mode 100644 index 0000000..5bc6ba9 --- /dev/null +++ b/tests/Feature/modules/Api/PostManagementControllerTest.php @@ -0,0 +1,163 @@ +tokens = $this->signInAndGetTokens(); + + Request::flush(); + } + + public function tearDown(): void + { + parent::tearDown(); + } + + public function testModuleApiMyPostsEndpoint() + { + $method = 'GET'; + $endpoint = '/api/my-posts'; + $body = []; + $headers = [ + 'Authorization' => 'Bearer ' . $this->tokens['access_token'], + 'refresh_token' => $this->tokens['refresh_token'] + ]; + + $response = $this->request($method, $endpoint, $body, $headers); + + $this->assertIsObject($response); + + $this->assertEquals('success', $response->get('status')); + + $this->assertArrayHasKey('data', $response->all()); + + $postData = $response->get('data'); + + $this->assertCount(10, $postData); + + $firstPost = $postData[0]; + + $this->assertIsArray($firstPost); + + $this->assertArrayHasKey('uuid', $firstPost); + $this->assertArrayHasKey('title', $firstPost); + $this->assertArrayHasKey('content', $firstPost); + $this->assertArrayHasKey('image', $firstPost); + $this->assertArrayHasKey('date', $firstPost); + $this->assertArrayHasKey('author', $firstPost); + } + + public function testModuleApiPostCreateEndpoint() + { + $method = 'POST'; + $endpoint = '/api/my-posts/create'; + $body = [ + 'title' => 'test title', + 'content' => 'test content', + 'image' => '', + 'updated_at' => date('Y-m-d H:i:s'), + ]; + $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; + + $response = $this->request($method, $endpoint, $body, $headers); + + $this->assertIsObject($response); + + $this->assertEquals('success', $response->get('status')); + + $this->assertEquals('Created successfully', $response->get('message')); + + $post = $response->get('data'); + + $this->assertIsArray($post); + + $this->assertArrayHasKey('uuid', $post); + $this->assertArrayHasKey('title', $post); + $this->assertArrayHasKey('content', $post); + $this->assertArrayHasKey('image', $post); + $this->assertArrayHasKey('date', $post); + $this->assertArrayHasKey('author', $post); + + } + + public function testModuleApiAmendPostEndpoint() + { + $method = 'PUT'; + $endpoint = '/api/my-posts/amend/'; + $body = [ + 'title' => 'test title123', + 'content' => 'test content123', + ]; + $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; + + $post = ModelFactory::get(Post::class)->first(); + + $response = $this->request($method, $endpoint . $post->uuid, $body, $headers); + + $this->assertIsObject($response); + + $this->assertEquals('success', $response->get('status')); + + $this->assertEquals('Updated successfully', $response->get('message')); + + $post = $response->get('data'); + + $this->assertIsArray($post); + + $this->assertArrayHasKey('uuid', $post); + $this->assertArrayHasKey('title', $post); + $this->assertArrayHasKey('content', $post); + $this->assertArrayHasKey('image', $post); + $this->assertArrayHasKey('date', $post); + $this->assertArrayHasKey('author', $post); + } + + public function testModuleApiDeletePostEndpoint() + { + $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); + + $this->assertIsObject($response); + + $this->assertEquals('success', $response->get('status')); + + $this->assertEquals('Deleted successfully', $response->get('message')); + } + + public function testModuleApiDeletePostImageEndpoint() + { + $method = 'DELETE'; + $endpoint = '/api/my-posts/delete-image/'; + $body = []; + $headers = ['Authorization' => 'Bearer ' . $this->tokens['access_token']]; + + $post = ModelFactory::get(Post::class)->first(); + + $response = $this->request($method, $endpoint . $post->uuid, $body, $headers); + + $this->assertIsObject($response); + + $this->assertEquals('success', $response->get('status')); + + $this->assertEquals('Deleted successfully', $response->get('message')); + } +} \ No newline at end of file diff --git a/tests/Helpers/functions.php b/tests/Helpers/functions.php index 5beadad..b08dab9 100644 --- a/tests/Helpers/functions.php +++ b/tests/Helpers/functions.php @@ -1,9 +1,11 @@ add( array_merge([ @@ -91,22 +93,47 @@ function createUser(array $overrides = []) ], $overrides)); } -function createUserPosts($user) +function createUserPosts(AuthUser $user): array { $postCountPerUser = 10; $faker = Factory::create(); + $posts = []; + for ($i = 0; $i < $postCountPerUser; $i++) { $title = textCleanUp($faker->realText(50)); - ServiceFactory::get(PostService::class)->addPost([ + $posts[] = ServiceFactory::create(PostService::class)->addPost([ 'title' => $title, 'content' => textCleanUp($faker->realText(100)), 'image' => slugify($title) . '.jpg', 'user_uuid' => $user->uuid, ]); } + + return $posts; +} + +function createPostComments(AuthUser $user, array $posts): array +{ + $commentCountPerUser = 3; + + $faker = Factory::create(); + + $comments = []; + + foreach ($posts as $post) { + for ($i = 0; $i < $commentCountPerUser; $i++) { + $comments[] = ServiceFactory::create(CommentService::class)->addComment([ + 'post_uuid' => $post->uuid, + 'user_uuid' => $user->uuid, + 'content' => textCleanUp($faker->realText(rand(20, 100))), + ]); + } + } + + return $comments; } function deleteUserByEmail(string $email) @@ -120,4 +147,5 @@ function dbCleanUp() { ServiceFactory::get(AuthService::class)->deleteAllUsers(); ServiceFactory::get(PostService::class)->deleteAllPosts(); + ServiceFactory::get(CommentService::class)->deleteAllComments(); } \ No newline at end of file diff --git a/tests/Unit/AppTestCase.php b/tests/Unit/AppTestCase.php deleted file mode 100644 index f14f758..0000000 --- a/tests/Unit/AppTestCase.php +++ /dev/null @@ -1,23 +0,0 @@ -authService = ServiceFactory::create(AuthService::class); - - $this->postService = ServiceFactory::create(PostService::class); - } -} \ No newline at end of file diff --git a/tests/Unit/shared/Services/AuthServiceTest.php b/tests/Unit/shared/Services/AuthServiceTest.php index 5da1709..d986e32 100644 --- a/tests/Unit/shared/Services/AuthServiceTest.php +++ b/tests/Unit/shared/Services/AuthServiceTest.php @@ -3,23 +3,22 @@ namespace Quantum\Tests\Unit\shared\Services; use Quantum\Libraries\Auth\User as AuthUser; -use Quantum\Tests\Unit\AppTestCase; +use Quantum\Service\Factories\ServiceFactory; use Quantum\Model\ModelCollection; +use Shared\Services\AuthService; +use PHPUnit\Framework\TestCase; use Shared\Models\User; -class AuthServiceTest extends AppTestCase +class AuthServiceTest extends TestCase { - public $authService; + protected $authService; public function setUp(): void { parent::setUp(); - } - public function tearDown(): void - { - parent::tearDown(); + $this->authService = ServiceFactory::create(AuthService::class); } public function testAuthServiceGetAll() diff --git a/tests/Unit/shared/Services/CommentServiceTest.php b/tests/Unit/shared/Services/CommentServiceTest.php new file mode 100644 index 0000000..eae4da4 --- /dev/null +++ b/tests/Unit/shared/Services/CommentServiceTest.php @@ -0,0 +1,109 @@ +authService = ServiceFactory::create(AuthService::class); + $this->postService = ServiceFactory::create(PostService::class); + $this->commentService = ServiceFactory::create(CommentService::class); + } + + public function testCommentServiceGetCommentsByPost() + { + $post = $this->postService->getPosts()->first(); + + $comments = $this->commentService->getCommentsByPost($post->uuid); + + $this->assertInstanceOf(ModelCollection::class, $comments); + $this->assertCount(3, $comments); + } + + public function testCommentServiceGetComment() + { + $paginatedPosts = $this->postService->getPosts(5, 1); + $post = $paginatedPosts->data()->first(); + + $comments = $this->commentService->getCommentsByPost($post->uuid); + $comment = $comments->first(); + + $singleComment = $this->commentService->getComment($comment->uuid); + + $commentData = $singleComment->asArray(); + + $this->assertArrayHasKey('content', $commentData); + + $this->assertArrayHasKey('post_uuid', $commentData); + + $this->assertArrayHasKey('user_uuid', $commentData); + + $this->assertArrayHasKey('created_at', $commentData); + } + + public function testCommentServiceAddComment() + { + $post = $this->postService->getPosts()->first(); + $user = $this->authService->getAll()->first(); + + $data = $this->commentService->addComment([ + 'user_uuid' => $user->uuid, + 'post_uuid' => $post->uuid, + 'content' => 'New comment content', + ]); + + $this->assertArrayHasKey('uuid', $data); + + $comment = $this->commentService->getComment($data['uuid']); + $this->assertEquals('New comment content', $comment->content); + + $this->commentService->deleteComment($data['uuid']); + } + + public function testCommentServiceDeleteComment() + { + $post = $this->postService->getPosts()->first(); + $user = $this->authService->getAll()->first(); + + $data = $this->commentService->addComment([ + 'user_uuid' => $user->uuid, + 'post_uuid' => $post->uuid, + 'content' => 'To be deleted' + ]); + + $uuid = $data['uuid']; + + $this->assertCount( + 4, + $this->commentService->getCommentsByPost($post->uuid) + ); + + $this->assertTrue($this->commentService->deleteComment($uuid)); + + $this->assertCount( + 3, + $this->commentService->getCommentsByPost($post->uuid) + ); + + $comment = $this->commentService->getComment($uuid); + + $this->assertTrue($comment->isEmpty()); + } +} \ No newline at end of file diff --git a/tests/Unit/shared/Services/PostServiceTest.php b/tests/Unit/shared/Services/PostServiceTest.php index d235482..a8d18c8 100644 --- a/tests/Unit/shared/Services/PostServiceTest.php +++ b/tests/Unit/shared/Services/PostServiceTest.php @@ -3,27 +3,32 @@ namespace Quantum\Tests\Unit\shared\Services; use Quantum\Libraries\Storage\UploadedFile; -use Quantum\Tests\Unit\AppTestCase; +use Quantum\Service\Factories\ServiceFactory; use Quantum\Model\ModelCollection; use Quantum\Paginator\Paginator; +use Shared\Services\AuthService; +use Shared\Services\PostService; +use PHPUnit\Framework\TestCase; use Shared\Models\Post; -class PostServiceTest extends AppTestCase +class PostServiceTest extends TestCase { const PER_PAGE = 10; const CURRENT_PAGE = 1; + protected $authService; + + protected $postService; + private $initialPosts; public function setUp(): void { parent::setUp(); - $this->initialPosts = $this->postService - ->getPosts(self::PER_PAGE, self::CURRENT_PAGE) - ->data() - ->all(); + $this->authService = ServiceFactory::create(AuthService::class); + $this->postService = ServiceFactory::create(PostService::class); } public function tearDown(): void @@ -67,21 +72,33 @@ public function testPostServiceGetPaginatedPosts() public function testPostServiceGetPostsWithSearch() { - $randomKey = array_rand($this->initialPosts); + $users = $this->authService->getAll(); + $userUuid = $users->first()->uuid; - $post = $this->initialPosts[$randomKey]; + $uniqueKeyword = 'SEARCH_TOKEN_' . uniqid(); + $title = "Title with {$uniqueKeyword}"; + $content = "Some content"; - $searchTerm = substr($post->title, 10, 10); + $post = $this->postService->addPost([ + 'user_uuid' => $userUuid, + 'title' => $title, + 'content' => $content, + 'image' => '', + 'updated_at' => date('Y-m-d H:i:s'), + ]); - $paginatedPosts = $this->postService->getPosts(self::PER_PAGE, self::CURRENT_PAGE, $searchTerm); + $searchTerm = 'SEARCH_TOKEN'; - $this->assertInstanceOf(Paginator::class, $paginatedPosts); + $results = $this->postService + ->getPosts(self::PER_PAGE, self::CURRENT_PAGE, $searchTerm) + ->data(); - $posts = $paginatedPosts->data(); + $this->assertInstanceOf(ModelCollection::class, $results); - $this->assertInstanceOf(ModelCollection::class, $posts); + $this->assertCount(1, $results); + $this->assertEquals($post->uuid, $results->first()->uuid); - $this->assertCount(1, $posts); + $this->postService->deletePost($post->uuid); } public function testPostServiceGetSinglePost() @@ -131,9 +148,7 @@ public function testPostServiceAddNewPost() 'updated_at' => $date ]); - $uuid = $newPost['uuid']; - - $post = $this->postService->getPost($uuid); + $post = $this->postService->getPost($newPost->uuid); $this->assertEquals('Just another post', $post->title); @@ -141,7 +156,7 @@ public function testPostServiceAddNewPost() $this->assertEquals($date, $post->updated_at); - $this->postService->deletePost($uuid); + $this->postService->deletePost($newPost->uuid); } public function testPostServiceUpdatePost() @@ -190,7 +205,7 @@ public function testPostServiceDeletePost() $this->assertCount(11, $this->postService->getPosts()); - $this->postService->deletePost($post['uuid']); + $this->postService->deletePost($post->uuid); $this->assertCount(10, $this->postService->getPosts(self::PER_PAGE, self::CURRENT_PAGE)->data()); } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 4786310..b3192e6 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -19,7 +19,8 @@ createModule('Api', 'DemoApi'); $user = createUser(); -createUserPosts($user); +$posts = createUserPosts($user); +createPostComments($user, $posts); register_shutdown_function(function () { removeEnvFile();