Skip to content

Commit

Permalink
Merge pull request #6501 from Zales0123/product-reviews-on-shop
Browse files Browse the repository at this point in the history
[ProductReview] Product reviews on shop
  • Loading branch information
pjedrzejewski committed Oct 24, 2016
2 parents 0119185 + 224ece3 commit 3a8b9a0
Show file tree
Hide file tree
Showing 47 changed files with 1,359 additions and 24 deletions.
@@ -0,0 +1,18 @@
@adding_product_review
Feature: Adding product review as a customer
In order to share my opinion about product with other customers
As a Customer
I want to be able to add product review

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Necronomicon"
And I am a logged in customer

@ui @javascript
Scenario: Adding product reviews as a logged in customer
Given I want to review product "Necronomicon"
When I leave a comment "Great book for every advanced sorcerer.", titled "Scary but astonishing"
And I rate it with 5 points
And I add it
Then I should be notified that my review is waiting for the acceptation
@@ -0,0 +1,17 @@
@adding_product_review
Feature: Adding product review as a guest
In order to share my opinion about product with other customers
As a Visitor
I want to be able to add product review

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Necronomicon"

@ui @javascript
Scenario: Adding product reviews as a guest
Given I want to review product "Necronomicon"
When I leave a comment "I'm never gonna read this terrible book again.", titled "Never again" as "castiel@heaven.com"
And I rate it with 1 point
And I add it
Then I should be notified that my review is waiting for the acceptation
67 changes: 67 additions & 0 deletions features/product/adding_product_reviews/review_validation.feature
@@ -0,0 +1,67 @@
@adding_product_review
Feature: Review validation
In order to avoid making mistakes while submitting a new product review
As a Visitor
I want to be prevented from submitting invalid review

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Necronomicon"

@ui
Scenario: Adding a product review without specifying a rate
Given I want to review product "Necronomicon"
When I leave a comment "This book made me sad, but plot was fine.", titled "Not good, not bad" as "bartholomew@heaven.com"
But I do not rate it
And I add it
Then I should be notified that I must check review rating

@ui @javascript
Scenario: Adding a product review without specifying a title
Given I want to review product "Necronomicon"
When I leave a comment "This book made me sad, but plot was fine." as "bartholomew@heaven.com"
And I rate it with 3 points
And I add it
Then I should be notified that title is required

@ui @javascript
Scenario: Adding a product review with too short title
Given I want to review product "Necronomicon"
When I leave a comment "This book made me sad, but plot was fine.", titled "X" as "bartholomew@heaven.com"
And I rate it with 3 points
And I add it
Then I should be notified that title must have at least 2 characters

@ui @javascript
Scenario: Adding a product review with too long title
Given I want to review product "Necronomicon"
When I leave a comment "This book made me sad, but plot was fine." as "bartholomew@heaven.com"
And I title it with very long title
And I rate it with 3 points
And I add it
Then I should be notified that title must have at most 255 characters

@ui @javascript
Scenario: Adding a product review without specifying a comment
Given I want to review product "Necronomicon"
When I leave a review titled "Not good, not bad" as "bartholomew@heaven.com"
And I rate it with 3 points
And I add it
Then I should be notified that comment is required

@ui @javascript
Scenario: Adding a product review without specifying an author email
Given I want to review product "Necronomicon"
When I leave a comment "Not good, not bad", titled "Not good, not bad"
And I rate it with 3 points
And I add it
Then I should be notified that I must enter my email

@ui @javascript
Scenario: Adding a product review with specifying already registerd author email
Given there is a customer account "sam@winchester.com" identified by "familybusiness"
And I want to review product "Necronomicon"
When I leave a comment "Really good book, with many important info.", titled "Usefull" as "sam@winchester.com"
And I rate it with 4 points
And I add it
Then I should be notified that this email is already registered
@@ -0,0 +1,21 @@
@viewing_product_reviews
Feature: Viewing product reviews on product's details page
In order to know other customer's opinion about product
As a Customer
I want to read product reviews on product's details page

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Necronomicon"
And this product has a review titled "Great book" and rated 5 added by customer "h.p.lovecraft@arkham.com", created 3 days ago
And this product has also a review titled "Scary and dark" and rated 4 added by customer "robert.e.howard@conan.com"
And this product has also a review titled "Too gloomy" and rated 3 added by customer "jrr.tolkien@middle-earth.com"
And this product has also a review titled "Classic" and rated 5 added by customer "sir.terry@pratchett.com"
And I am a logged in customer

@ui
Scenario: Viewing last 3 product reviews on product's details page
When I check this product's details
Then I should see 3 product reviews
And I should see reviews titled "Classic", "Too gloomy" and "Scary and dark"
But I should not see review titled "Good book"
@@ -0,0 +1,31 @@
@viewing_product_reviews
Feature: Viewing product reviews on product's reviews page
In order to know other customer's opinion about product
As a Customer
I want to read all product reviews on product's reviews page

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Necronomicon"
And this product has a review titled "Great book" and rated 5 added by customer "h.p.lovecraft@arkham.com"
And this product has also a review titled "Scary and dark" and rated 4 added by customer "robert.e.howard@conan.com"
And this product has also a review titled "Too gloomy" and rated 3 added by customer "jrr.tolkien@middle-earth.com"
And I am a logged in customer

@ui
Scenario: Viewing all accepted product reviews on product's reviews page
When I check this product's reviews
Then I should see 3 product reviews in the list

@ui
Scenario: Viewing only accepted product reviews on product's reviews page
Given this product has also a review titled "Classic" and rated 5 added by customer "sir.terry@pratchett.com" which is not accepted yet
When I check this product's reviews
Then I should see 3 product reviews in the list
But I should not see review titled "Classic" in the list

@ui
Scenario: Viewing no review message if there are no reviews
Given the store has a product "Lux perpetua"
When I check this product's reviews
Then I should be notified that there are no reviews
@@ -0,0 +1,25 @@
@viewing_products
Feature: Viewing product's average rating
In order to know product reviews summary
As a Customer
I want to read product's average rating

Background:
Given the store operates on a single channel in "United States"
And the store has a product "Necronomicon"
And the store has customer "J.R.R Tolkien" with email "jrr.tolkien@middle-earth.com"
And this product has accepted reviews rated 5, 3, 4, 4 and 1
And I am a logged in customer

@ui
Scenario: Viewing product's average rating
When I check this product's details
Then I should see "3.4" as its average rating

@ui
Scenario: Viewing product's average rating calculated only from accepted reviews
Given this product also has accepted reviews rated 5, 4 and 1
And this product also has review rated 3 which is not accepted yet
And this product also has review rated 1 which is rejected
When I check this product's details
Then I should see "3.38" as its average rating
119 changes: 113 additions & 6 deletions src/Sylius/Behat/Context/Setup/ProductReviewContext.php
Expand Up @@ -12,11 +12,14 @@
namespace Sylius\Behat\Context\Setup;

use Behat\Behat\Context\Context;
use Doctrine\Common\Persistence\ObjectManager;
use Sylius\Component\Core\Model\ProductInterface;
use SM\Factory\FactoryInterface as StateMachineFactoryInterface;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\ProductReviewTransitions;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\Review\Model\ReviewInterface;

/**
* @author Magdalena Banasiak <magdalena.banasiak@lakion.com>
Expand All @@ -38,33 +41,137 @@ final class ProductReviewContext implements Context
*/
private $productReviewRepository;

/**
* @var StateMachineFactoryInterface
*/
private $stateMachineFactory;

/**
* @param SharedStorageInterface $sharedStorage
* @param FactoryInterface $productReviewFactory
* @param RepositoryInterface $productReviewRepository
* @param StateMachineFactoryInterface $stateMachineFactory
*/
public function __construct(
SharedStorageInterface $sharedStorage,
FactoryInterface $productReviewFactory,
RepositoryInterface $productReviewRepository
RepositoryInterface $productReviewRepository,
StateMachineFactoryInterface $stateMachineFactory
) {
$this->sharedStorage = $sharedStorage;
$this->productReviewFactory = $productReviewFactory;
$this->productReviewRepository = $productReviewRepository;
$this->stateMachineFactory = $stateMachineFactory;
}

/**
* @Given /^(this product) has one review$/
*/
public function productHasAReview(ProductInterface $product)
{
$review = $this->createProductReview($product, 'Title', 5, 'Comment');

$this->productReviewRepository->add($review);
}

/**
* @Given /^(this product) has(?:| also) a review titled "([^"]+)" and rated (\d+) added by (customer "[^"]+")(?:|, created (\d+) days ago)$/
*/
public function thisProductHasAReviewTitledAndRatedAddedByCustomer(
ProductInterface $product,
$title,
$rating,
CustomerInterface $customer,
$daysSinceCreation = null
) {
$review = $this->createProductReview($product, $title, $rating, $title, $customer);
if (null !== $daysSinceCreation) {
$review->setCreatedAt(new \DateTime('-'.$daysSinceCreation.' days'));
}

$this->productReviewRepository->add($review);
}

/**
* @Given /^(this product) has(?:| also) a review titled "([^"]+)" and rated (\d+) added by (customer "[^"]+") which is not accepted yet$/
*/
public function thisProductHasAReviewTitledAndRatedAddedByCustomerWhichIsNotAcceptedYet(
ProductInterface $product,
$title,
$rating,
CustomerInterface $customer
) {
$review = $this->createProductReview($product, $title, $rating, $title, $customer, null);

$this->productReviewRepository->add($review);
}

/**
* @Given /^(this product)(?:| also) has accepted reviews rated (\d+), (\d+), (\d+), (\d+) and (\d+)$/
* @Given /^(this product)(?:| also) has accepted reviews rated (\d+), (\d+) and (\d+)$/
*/
public function thisProductHasAcceptedReviewsRated(ProductInterface $product, ...$rates)
{
$customer = $this->sharedStorage->get('customer');
foreach ($rates as $key => $rate) {
$review = $this->createProductReview($product, 'Title '.$key, $rate, 'Comment '.$key, $customer);
$this->productReviewRepository->add($review);
}
}

/**
* @Given /^(this product)(?:| also) has review rated (\d+) which is not accepted yet$/
*/
public function itAlsoHasReviewRatedWhichIsNotAcceptedYet(ProductInterface $product, $rate)
{
$customer = $this->sharedStorage->get('customer');
$review = $this->createProductReview($product, 'Title', $rate, 'Comment', $customer, null);
$this->productReviewRepository->add($review);
}

/**
* @Given /^(this product) also has review rated (\d+) which is rejected$/
*/
public function itAlsoHasReviewRatedWhichIsRejected(ProductInterface $product, $rate)
{
$customer = $this->sharedStorage->get('customer');
$review = $this->createProductReview($product, 'Title', $rate, 'Comment', $customer, ProductReviewTransitions::TRANSITION_REJECT);
$this->productReviewRepository->add($review);
}

/**
* @param ProductInterface $product
* @param string $title
* @param int $rating
* @param string $comment
* @param CustomerInterface|null $customer
* @param string $transition
*
* @return ReviewInterface
*/
private function createProductReview(
ProductInterface $product,
$title,
$rating,
$comment,
CustomerInterface $customer = null,
$transition = ProductReviewTransitions::TRANSITION_ACCEPT
) {
/** @var ReviewInterface $review */
$review = $this->productReviewFactory->createNew();
$review->setTitle('title');
$review->setRating(5);
$review->setTitle($title);
$review->setRating($rating);
$review->setComment($comment);
$review->setReviewSubject($product);
$review->setAuthor($customer);

$product->addReview($review);

$this->productReviewRepository->add($review);
if (null !== $transition) {
$stateMachine = $this->stateMachineFactory->get($review, ProductReviewTransitions::GRAPH);
$stateMachine->apply($transition);
}

return $review;
}
}

0 comments on commit 3a8b9a0

Please sign in to comment.