public interface Review extends Resource<Review>, Custom, WithKey
If you do not need any approval process, skip this part.
If we have an approval process for a review to be used for a product or a channel, we model the approval process with a state machine.
First of all, once per Project, we create the approved state. Then we create the initial to-approve state, which has a possible transition to the approved state:
import io.sphere.sdk.client.BlockingSphereClient;
import io.sphere.sdk.states.*;
import io.sphere.sdk.states.commands.StateCreateCommand;
import java.util.List;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
public class CreateReviewStates { public static List<State> createStates(final BlockingSphereClient client) { final StateDraft approvedStateDraft = StateDraftDsl.of("approved", StateType.REVIEW_STATE).withRoles(StateRole.REVIEW_INCLUDED_IN_STATISTICS); final State approvedState = client.executeBlocking(StateCreateCommand.of(approvedStateDraft)); final StateDraft initialStateDraft = StateDraftDsl.of("to-approve", StateType.REVIEW_STATE) .withInitial(true) .withTransitions(singleton(approvedState.toReference())); final State initialState = client.executeBlocking(StateCreateCommand.of(initialStateDraft)); return asList(initialState, approvedState); } }
See the test code.
StateRole.REVIEW_INCLUDED_IN_STATISTICS
makes review ratings count in statistics.
Now we can create a review in the initial state to-approve:
import io.sphere.sdk.client.BlockingSphereClient;
import io.sphere.sdk.models.Reference;
import io.sphere.sdk.models.ResourceIdentifier;
import io.sphere.sdk.products.Product;
import io.sphere.sdk.reviews.Review;
import io.sphere.sdk.reviews.ReviewDraft;
import io.sphere.sdk.reviews.ReviewDraftBuilder;
import io.sphere.sdk.reviews.commands.ReviewCreateCommand;
import static org.assertj.core.api.Assertions.assertThat;
public class CreateReviewToApprove { public static Review createReview(final BlockingSphereClient client, final Reference<Product> productReference) { final ReviewDraft reviewDraft = ReviewDraftBuilder .ofRating(4) .title("review title") .target(productReference) .state(ResourceIdentifier.ofKey("to-approve"))//you know the initial state by key and don't need a ref .build(); final Review review = client.executeBlocking(ReviewCreateCommand.of(reviewDraft)); assertThat(review.getState()).isNotNull(); assertThat(review.getRating()).isEqualTo(4); return review; } }
See the test code.
import io.sphere.sdk.client.BlockingSphereClient;
import io.sphere.sdk.reviews.Review;
import io.sphere.sdk.reviews.queries.ReviewQuery;
import io.sphere.sdk.states.State;
import io.sphere.sdk.states.queries.StateQuery;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class QueryReviewsToApprove { public static List<Review> query(final BlockingSphereClient client, final State initialState) { //this ID can be cached final String initialStateId = client.executeBlocking(StateQuery.of().byKey("to-approve")).head().get().getId(); final ReviewQuery reviewQuery = ReviewQuery.of() .withPredicates(m -> m.state().id().is(initialStateId)) .withSort(m -> m.createdAt().sort().asc());//oldest first final List<Review> reviewsToApprove = client.executeBlocking(reviewQuery).getResults(); assertThat(reviewsToApprove).extracting(review -> review.getTitle()).contains("review title"); return reviewsToApprove; } }
See the test code.
import io.sphere.sdk.client.BlockingSphereClient;
import io.sphere.sdk.models.ResourceIdentifier;
import io.sphere.sdk.reviews.Review;
import io.sphere.sdk.reviews.commands.ReviewUpdateCommand;
import io.sphere.sdk.reviews.commands.updateactions.TransitionState;
import io.sphere.sdk.states.State;
import static org.assertj.core.api.Assertions.assertThat;
public class ApprovingAReview { public static Review approveReview(final BlockingSphereClient client, final Review reviewToApprove) { final ResourceIdentifier<State> state = ResourceIdentifier.ofKey("approved");//we know the state by key final ReviewUpdateCommand cmd = ReviewUpdateCommand.of(reviewToApprove, TransitionState.of(state)); final Review approvedReview = client.executeBlocking(cmd); assertThat(reviewToApprove.getState()).isNotEqualTo(approvedReview.getState()); return approvedReview; } }
See the test code.
We can display all products that:
final List<FacetRange<BigDecimal>> facetRanges = IntStream.range(LOWEST_RATING, HIGHEST_RATING) .mapToObj(i -> FacetRange.of(new BigDecimal(i), new BigDecimal(i + 1))) .collect(toList()); assertThat(facetRanges.toString()).isEqualTo("[[0 to 1), [1 to 2), [2 to 3), [3 to 4), [4 to 5)]"); final ProductProjectionSearch searchRequest = ProductProjectionSearch.ofStaged()//in prod it would be current .withResultFilters(m -> m.reviewRatingStatistics().averageRating().isGreaterThanOrEqualTo(new BigDecimal(2))) .withFacets(m -> m.reviewRatingStatistics().averageRating().onlyRange(facetRanges)) .withSort(m -> m.reviewRatingStatistics().averageRating().desc()); assertEventually(Duration.ofSeconds(60), Duration.ofMillis(100), () -> { final PagedSearchResult<ProductProjection> result = client().executeBlocking(searchRequest); assertThat(result.getResults()).hasSize(2); final ProductProjection productProjection = result.getResults().get(0); assertThat(productProjection.getReviewRatingStatistics().getCount()).isEqualTo(REVIEWS_PER_PRODUCT); final RangeFacetResult facetResult = (RangeFacetResult) result.getFacetResult("reviewRatingStatistics.averageRating"); assertThat(facetResult.getRanges().get(2)).isEqualTo(RangeStats.of("2.0", "3.0", 2L, null, "2.2", "2.7", "4.9", 2.45)); });
See the test code.
final String productId = product.getId(); final ReviewQuery reviewQuery = ReviewQuery.of() .withPredicates(review -> review.includedInStatistics().is(true).and(review.target().id().is(productId))) .withSort(m -> m.createdAt().sort().desc()) .withLimit(REVIEWS_PER_PRODUCT); final List<Review> reviews = client().executeBlocking(reviewQuery).getResults(); assertThat(reviews).hasSize(REVIEWS_PER_PRODUCT); assertThat(reviews).extracting(r -> r.getTarget().getId()).containsOnlyElementsOf(singletonList(productId)); assertThat(reviews).extracting(r -> r.isIncludedInStatistics()).containsOnlyElementsOf(singletonList(true));
See the test code.
final String productId = product.getId(); final ReviewQuery reviewQuery = ReviewQuery.of() .withPredicates(m -> m.target().id().is(productId)) .withSort(m -> m.createdAt().sort().desc()) .withLimit(REVIEWS_PER_PRODUCT); final List<Review> reviews = client().executeBlocking(reviewQuery).getResults(); assertThat(reviews).hasSize(REVIEWS_PER_PRODUCT); assertThat(reviews).extracting(r -> r.getTarget().getId()).containsOnlyElementsOf(singletonList(productId));
See the test code.
Modifier and Type | Method and Description |
---|---|
String |
getAuthorName()
The name of the author which created this review or null.
|
CustomFields |
getCustom()
Gets the custom fields of this review or null.
|
Reference<Customer> |
getCustomer()
Gets the customer which created this review or null.
|
String |
getKey()
Gets the key assigned to this review or null.
|
Locale |
getLocale()
Gets the locale (language) in which the text and title are or null.
|
Integer |
getRating()
Gets the rating or null.
|
Reference<State> |
getState()
Gets the state of this review or null.
|
Reference<?> |
getTarget()
Identifies the target of the review.
|
String |
getText()
Gets the text of this review or null.
|
String |
getTitle()
Gets the title of this review or null.
|
String |
getUniquenessValue() |
Boolean |
isIncludedInStatistics()
Indicates if this review is taken into account in the ratings statistics of the target.
|
static Reference<Review> |
referenceOfId(String id)
Creates a reference for one item of this class by a known ID.
|
static String |
referenceTypeId()
A type hint for references which resource type is linked in a reference.
|
static String |
resourceTypeId()
An identifier for this resource which supports
CustomFields . |
default Reference<Review> |
toReference()
Creates a reference to this resource, the reference may not be filled.
|
static com.fasterxml.jackson.core.type.TypeReference<Review> |
typeReference()
Creates a container which contains the full Java type information to deserialize this class from JSON.
|
getCreatedAt, getId, getLastModifiedAt, getVersion
hasSameIdAs, toResourceIdentifier
@Nullable String getAuthorName()
SetAuthorName
@Nullable CustomFields getCustom()
getCustom
in interface Custom
SetCustomField
,
SetCustomType
@Nullable Reference<Customer> getCustomer()
SetCustomer
@Nullable Locale getLocale()
@Nullable Integer getRating()
SetRating
@Nullable Reference<State> getState()
TransitionState
@Nullable Reference<?> getTarget()
SetTarget
@Nullable String getText()
SetText
@Nullable String getTitle()
SetTitle
Boolean isIncludedInStatistics()
static String referenceTypeId()
Reference.getTypeId()
static String resourceTypeId()
CustomFields
.TypeDraft.getResourceTypeIds()
,
Custom
static com.fasterxml.jackson.core.type.TypeReference<Review> typeReference()
static Reference<Review> referenceOfId(String id)
An example for categories but this applies for other resources, too:
final String categoryIdFromFormOrSession = "84ac4271-0fec-49d0-9fee-55586c565c58"; final Reference<Category> categoryReference = Category.referenceOfId(categoryIdFromFormOrSession); assertThat(categoryReference.getId()).isEqualTo(categoryIdFromFormOrSession);
See the test code.
If you already have a resource object, then use toReference()
instead:
final Category category = getCategory1(); final Reference<Category> categoryReference = category.toReference(); assertThat(category.getId()).isEqualTo(categoryReference.getId());
See the test code.
id
- the ID of the resource which should be referenced.default Reference<Review> toReference()
Referenceable
toReference
in interface Referenceable<Review>
toReference
in interface Resource<Review>