From 6d7907d140306bd0c8aa7c229b7335cfab4c6857 Mon Sep 17 00:00:00 2001 From: divyesh000 Date: Thu, 23 May 2024 22:11:47 +0400 Subject: [PATCH 1/3] refactore ReviewTest.php: update testValidate method, add new test cases for testSave, testGetNestedComments, and testIsVerified, and modifie existing test cases --- tests/ReviewTest.php | 121 ++++++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 30 deletions(-) diff --git a/tests/ReviewTest.php b/tests/ReviewTest.php index 16ce6d49..f2cb7f90 100644 --- a/tests/ReviewTest.php +++ b/tests/ReviewTest.php @@ -133,27 +133,28 @@ public function testToArray(): void public function testValidate(): void { - // Test validation with valid data - $errors = $this->dummy_review->validate(); - $this->assertEmpty($errors); - // Test validation with empty text - $invalidReview = new Review( - 1, 1, 1, "", 0, new DateTime("2024-03-10") - ); - $errors = $invalidReview->validate(); - $this->assertNotEmpty($errors); - $this->assertArrayHasKey('text', $errors); - $this->assertEquals('Review text must have at least 2 characters', $errors['text']); // Assert specific message - // Test validation with invalid rating - $invalidReview = new Review( - 1, 1, 1, "Valid Text", -1, new DateTime("2024-03-10") - ); - $errors = $invalidReview->validate(); - $this->assertNotEmpty($errors); - $this::assertArrayHasKey('rating', $errors); - $this->assertEquals('Rating must be between 1 and 5', $errors['rating']); // Assert specific message + // Test with valid data + $validReview = new Review(1, 1, 1, "Valid review text", 5, new DateTime("2024-03-10")); + $validErrors = $validReview->validate(); + $this->assertEmpty($validErrors); + + // Test with invalid text + $invalidTextReview = new Review(1, 1, 1, "", 5, new DateTime("2024-03-10")); + $textErrors = $invalidTextReview->validate(); + $this->assertArrayHasKey('text', $textErrors); + + // Test with invalid rating + $invalidRatingReview = new Review(1, 1, 1, "Invalid rating review", 6, new DateTime("2024-03-10")); + $ratingErrors = $invalidRatingReview->validate(); + $this->assertArrayHasKey('rating', $ratingErrors); + + // Test with future date + $futureDateReview = new Review(1, 1, 1, "Future date review", 5, new DateTime("2030-01-01")); + $dateErrors = $futureDateReview->validate(); + $this->assertArrayHasKey('date', $dateErrors); } + public function testGetByID(): void { $fetched_review = Review::getByID($this->dummy_review->getReviewID()); @@ -176,17 +177,77 @@ public function testGetByID(): void public function testSave(): void { - // Create a DateTime object for the review date - $date = new DateTime('now'); - // Create a mock Review object with mock data - $review = $this->getMockBuilder(Review::class) - ->setConstructorArgs([1, 1, 1, 'Test review', 5, $date]) - ->onlyMethods(['save']) // Mocking the save method + // Create an invalid review with empty text + $invalidReview = new Review(1, 1, 1, "", 0, new DateTime("2024-03-10")); + + // Attempt to save the invalid review + $success = $invalidReview->save(); + + // Assert that the save operation failed + $this->assertFalse($success); + } + + public function testGetNestedComments(): void + { + // Create a mock review with review_id 1 + $mockReview = new Review( + 1, + $this->dummy_product->getProductID(), + $this->reviewer->getUserID(), + "Test review", + 5, + new DateTime("2024-03-10") + ); + + // Create mock comments + $comment1 = (object) [ + 'comment_id' => 1, + 'review_id' => 1, + 'parent_comment_id' => null, + 'text' => 'Comment 1', + 'created_date' => '2024-03-10 10:00:00' + ]; + + $comment2 = (object) [ + 'comment_id' => 2, + 'review_id' => 1, + 'parent_comment_id' => 1, + 'text' => 'Reply to Comment 1', + 'created_date' => '2024-03-10 10:01:00' + ]; + + // Mock the query method of Review class to return the mock comments + $mockReview->query = function ($query, $params) use ($comment1, $comment2) { + return ($params['review_id'] == 1) ? [$comment1, $comment2] : []; + }; + + // Call the getNestedComments method + $nestedComments = $mockReview->getNestedComments(); + + // Assert that the nested comments are properly structured + $this->assertCount(1, $nestedComments); // Only one root-level comment + $this->assertEquals($comment1->text, $nestedComments[0]->text); // Check text of the root comment + $this->assertCount(1, $nestedComments[0]->children); // One child comment under the root comment + $this->assertEquals($comment2->text, $nestedComments[0]->children[0]->text); // Check text of the child comment + } + + public function testIsVerified(): void + { + // Mock the get_row method of Review class to return a result indicating verified purchase + $mockReview = $this->getMockBuilder(Review::class) + ->onlyMethods(['get_row']) ->getMock(); - // Set up the mock to expect the save method to be called once - $review->expects($this->once()) - ->method('save'); - // Call the save method - $review->save(); + + $mockReview->method('get_row')->willReturn((object)['purchase_count' => 1]); + + // Set product_id and review_id for the mock review + $mockReview->setProductID($this->dummy_product->getProductID()); + $mockReview->setReviewID($this->dummy_review->getReviewID()); + + // Call the isVerified method + $isVerified = $mockReview->isVerified(); + + // Assert that the review is verified + $this->assertTrue($isVerified); } } \ No newline at end of file From 99fe71bf424c3dee77911504b6f09b76a2abca96 Mon Sep 17 00:00:00 2001 From: divyesh000 Date: Sat, 1 Jun 2024 19:06:48 +0400 Subject: [PATCH 2/3] update test cases for Review class, add data provider for testValidate, and modify testSave to include more scenarios --- tests/ReviewTest.php | 217 +++++++++++++++++++++++++------------------ 1 file changed, 126 insertions(+), 91 deletions(-) diff --git a/tests/ReviewTest.php b/tests/ReviewTest.php index f2cb7f90..0ef9d524 100644 --- a/tests/ReviewTest.php +++ b/tests/ReviewTest.php @@ -37,16 +37,20 @@ public function setUp(): void "Each bottle contains 90% Pure Coffee powder and 10% Velvet bean Powder", new DateTime() ); - + $success = $this->dummy_product->save(); if (!$success) { throw new Exception('Unable to save product'); } - + // create a client object and save to database $this->reviewer = new Client( - "john_u@gmail.com", "john", "johhny", "User0", - "13213431", new Location("Royal Road", "Curepipe", 1) + "john_u@gmail.com", + "john", + "johhny", + "User0", + "13213431", + new Location("Royal Road", "Curepipe", 1) ); $success = $this->reviewer->save(); @@ -131,29 +135,49 @@ public function testToArray(): void self::assertEquals(5, $result['rating']); } - public function testValidate(): void + /** + * Data provider for testValidate. + * + * @return array + */ + public static function validateDataProvider(): array { - // Test with valid data - $validReview = new Review(1, 1, 1, "Valid review text", 5, new DateTime("2024-03-10")); - $validErrors = $validReview->validate(); - $this->assertEmpty($validErrors); - - // Test with invalid text - $invalidTextReview = new Review(1, 1, 1, "", 5, new DateTime("2024-03-10")); - $textErrors = $invalidTextReview->validate(); - $this->assertArrayHasKey('text', $textErrors); - - // Test with invalid rating - $invalidRatingReview = new Review(1, 1, 1, "Invalid rating review", 6, new DateTime("2024-03-10")); - $ratingErrors = $invalidRatingReview->validate(); - $this->assertArrayHasKey('rating', $ratingErrors); - - // Test with future date - $futureDateReview = new Review(1, 1, 1, "Future date review", 5, new DateTime("2030-01-01")); - $dateErrors = $futureDateReview->validate(); - $this->assertArrayHasKey('date', $dateErrors); + return [ + 'valid review' => [ + 'text' => 'Great product!', + 'rating' => 5, + 'created_date' => new DateTime('2023-01-01'), + 'expectedErrors' => [] + ], + 'short text' => [ + 'text' => 'A', + 'rating' => 3, + 'created_date' => new DateTime('2023-01-01'), + 'expectedErrors' => ['text' => 'Review text must have at least 2 characters'] + ], + 'invalid rating' => [ + 'text' => 'Good product', + 'rating' => 6, + 'created_date' => new DateTime('2023-01-01'), + 'expectedErrors' => ['rating' => 'Rating must be between 1 and 5'] + ], + 'future date' => [ + 'text' => 'Good product', + 'rating' => 4, + 'created_date' => new DateTime('2030-01-01'), + 'expectedErrors' => ['date' => 'Review date cannot be in the future'] + ] + ]; } + /** + * @dataProvider validateDataProvider + */ + public function testValidate(string $text, int $rating, DateTime $created_date, array $expectedErrors): void + { + $review = new Review(text: $text, rating: $rating, created_date: $created_date); + $this->assertEquals($expectedErrors, $review->validate()); + } public function testGetByID(): void { @@ -177,77 +201,88 @@ public function testGetByID(): void public function testSave(): void { - // Create an invalid review with empty text - $invalidReview = new Review(1, 1, 1, "", 0, new DateTime("2024-03-10")); - - // Attempt to save the invalid review - $success = $invalidReview->save(); - - // Assert that the save operation failed - $this->assertFalse($success); + // Create an invalid review with empty text + $invalidReview = new Review(1, 1, 1, "", 0, new DateTime("2024-03-10")); + // Attempt to save the invalid review + $success = $invalidReview->save(); + // Assert that the save operation failed + $this->assertFalse($success); + + // Create a valid review + $validReview = new Review( + product_id: $this->dummy_product->getProductID(), + client_id: $this->reviewer->getUserID(), + text: "Another test review", + rating: 4, + created_date: new DateTime() + ); + // Attempt to save the valid review + $success = $validReview->save(); + // Assert that the save operation succeeded + $this->assertTrue($success); + $this->assertGreaterThan(0, $validReview->getReviewID()); + + // Create a review with special characters + $specialCharReview = new Review( + product_id: $this->dummy_product->getProductID(), + client_id: $this->reviewer->getUserID(), + text: "Review with special characters: !@#$%^&*()", + rating: 4, + created_date: new DateTime() + ); + // Attempt to save the review with special characters + $success = $specialCharReview->save(); + // Assert that the save operation succeeded + $this->assertTrue($success); + $this->assertGreaterThan(0, $specialCharReview->getReviewID()); + + // Create a review with extremely long text + $longTextReview = new Review( + product_id: $this->dummy_product->getProductID(), + client_id: $this->reviewer->getUserID(), + text: str_repeat("A", 10000), + rating: 4, + created_date: new DateTime() + ); + // Attempt to save the review with long text + $success = $longTextReview->save(); + // Assert that the save operation succeeded + $this->assertTrue($success); + $this->assertGreaterThan(0, $longTextReview->getReviewID()); + + // Test saving duplicate reviews + $duplicateReview = new Review( + product_id: $this->dummy_product->getProductID(), + client_id: $this->reviewer->getUserID(), + text: "This is a test review.", + rating: 5, + created_date: new DateTime() + ); + // Attempt to save the duplicate review + $success = $duplicateReview->save(); + // Assert that the save operation succeeded (assuming duplicates are allowed) + $this->assertTrue($success); + $this->assertGreaterThan(0, $duplicateReview->getReviewID()); } - - public function testGetNestedComments(): void + public function testGetNestedComments(): void { - // Create a mock review with review_id 1 - $mockReview = new Review( - 1, - $this->dummy_product->getProductID(), - $this->reviewer->getUserID(), - "Test review", - 5, - new DateTime("2024-03-10") - ); - - // Create mock comments - $comment1 = (object) [ - 'comment_id' => 1, - 'review_id' => 1, - 'parent_comment_id' => null, - 'text' => 'Comment 1', - 'created_date' => '2024-03-10 10:00:00' - ]; - - $comment2 = (object) [ - 'comment_id' => 2, - 'review_id' => 1, - 'parent_comment_id' => 1, - 'text' => 'Reply to Comment 1', - 'created_date' => '2024-03-10 10:01:00' - ]; - - // Mock the query method of Review class to return the mock comments - $mockReview->query = function ($query, $params) use ($comment1, $comment2) { - return ($params['review_id'] == 1) ? [$comment1, $comment2] : []; - }; - - // Call the getNestedComments method - $nestedComments = $mockReview->getNestedComments(); - - // Assert that the nested comments are properly structured - $this->assertCount(1, $nestedComments); // Only one root-level comment - $this->assertEquals($comment1->text, $nestedComments[0]->text); // Check text of the root comment - $this->assertCount(1, $nestedComments[0]->children); // One child comment under the root comment - $this->assertEquals($comment2->text, $nestedComments[0]->children[0]->text); // Check text of the child comment + $review = new Review(review_id: 1); + $comments = $review->getNestedComments(); + + $this->assertIsArray($comments); + foreach ($comments as $comment) { + $this->assertObjectHasAttribute('children', $comment); + if (!empty($comment->children)) { + foreach ($comment->children as $childComment) { + $this->assertObjectHasAttribute('children', $childComment); + } + } + } } public function testIsVerified(): void { - // Mock the get_row method of Review class to return a result indicating verified purchase - $mockReview = $this->getMockBuilder(Review::class) - ->onlyMethods(['get_row']) - ->getMock(); - - $mockReview->method('get_row')->willReturn((object)['purchase_count' => 1]); - - // Set product_id and review_id for the mock review - $mockReview->setProductID($this->dummy_product->getProductID()); - $mockReview->setReviewID($this->dummy_review->getReviewID()); - - // Call the isVerified method - $isVerified = $mockReview->isVerified(); - - // Assert that the review is verified - $this->assertTrue($isVerified); + $review = new Review(review_id: 2, product_id: 2); + $this->assertFalse($review->isVerified()); } -} \ No newline at end of file +} From 0976373cb9b70b78280860a00f0ec3be899c62ba Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Sat, 1 Jun 2024 21:11:38 +0400 Subject: [PATCH 3/3] save should return false when review size exceeds 2000 --- tests/ReviewTest.php | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/ReviewTest.php b/tests/ReviewTest.php index 0ef9d524..fa61a80c 100644 --- a/tests/ReviewTest.php +++ b/tests/ReviewTest.php @@ -84,7 +84,10 @@ public function tearDown(): void $this->dummy_product = null; // clear all data from review and client tables - self::query('DELETE FROM comment; DELETE FROM review; DELETE FROM client; DELETE FROM user; DELETE FROM store_product; DELETE FROM product;'); + self::query( + 'DELETE FROM comment; DELETE FROM review; DELETE FROM client; + DELETE FROM user; DELETE FROM store_product; DELETE FROM product;' + ); } public function testConstructor(): void @@ -236,6 +239,20 @@ public function testSave(): void $this->assertTrue($success); $this->assertGreaterThan(0, $specialCharReview->getReviewID()); + + // Create a review of length exactly 2000 + $longTextReview = new Review( + product_id: $this->dummy_product->getProductID(), + client_id: $this->reviewer->getUserID(), + text: str_repeat("A", 2000), + rating: 4, + created_date: new DateTime() + ); + // Attempt to save the review with long text + $success = $longTextReview->save(); + // Assert that the save operation failed because max length of review is 2000 + $this->assertTrue($success); + // Create a review with extremely long text $longTextReview = new Review( product_id: $this->dummy_product->getProductID(), @@ -246,9 +263,9 @@ public function testSave(): void ); // Attempt to save the review with long text $success = $longTextReview->save(); - // Assert that the save operation succeeded - $this->assertTrue($success); - $this->assertGreaterThan(0, $longTextReview->getReviewID()); + // Assert that the save operation failed because max length of review is 2000 + $this->assertFalse($success); + // Test saving duplicate reviews $duplicateReview = new Review( @@ -264,6 +281,7 @@ public function testSave(): void $this->assertTrue($success); $this->assertGreaterThan(0, $duplicateReview->getReviewID()); } + public function testGetNestedComments(): void { $review = new Review(review_id: 1);