/** * Gets the products belonging to the given categories, up to {@code numProducts}, most expensive products first. * @param categoryIds the category IDs to get products from * @param numProducts the number of products the returned set should contain * @return the products related to these categories */ private CompletionStage<Set<ProductProjection>> productsFromCategoryIds(final Iterable<String> categoryIds, final int numProducts) { final ProductProjectionSearch request = ProductProjectionSearch.ofCurrent() .withLimit(numProducts) .withQueryFilters(product -> product.categories().id().containsAny(categoryIds)) .withSort(product -> product.allVariants().price().desc()) .withPriceSelection(PriceUtils.createPriceSelection(userContext)); return sphereClient.execute(request) .whenCompleteAsync((result, t) -> logProductRequest(LOGGER, request, result), HttpExecution.defaultContext()) .thenApply(SunriseProductRecommendation::resultToProductSet); }
@SuppressWarnings("unchecked") @Test public void isInSubtree() { withCategoryAndParentCategory(client(), (Category cat, Category parent) -> { withProduct(client(), builder -> builder.categoriesAsObjectList(singletonList(cat)), product -> { final String parentId = parent.getId(); assertThat(product.getMasterData().getStaged().getCategories()) .contains(cat.toReference()) .doesNotContain(parent.toReference()); assertEventually(() -> { //search for products directly in parent category final ProductProjectionSearch requestForDirectCategories = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().is(parentId)); assertThat(client().executeBlocking(requestForDirectCategories).getResults()).isEmpty(); //search for products in parent category or its descendants final ProductProjectionSearch requestForTree = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().isInSubtree(parentId)); final List<ProductProjection> results = client().executeBlocking(requestForTree).getResults(); assertThat(results).hasSize(1); }); }); }); } }
@Test public void categorySubtree() { final List<String> expressionsWithoutSubtrees = ProductProjectionSearch.ofStaged().withQueryFilters(m -> m.categories().id().isIn(asList("id1", "id2"))).queryFilters().stream().map(e -> e.expression()).collect(Collectors.toList()); assertThat(expressionsWithoutSubtrees.get(0)).isEqualTo("categories.id:\"id1\",\"id2\""); final List<FilterExpression<ProductProjection>> filterExpressions = ProductProjectionSearch.ofStaged().withQueryFilters(m -> m.categories().id().isInSubtreeOrInCategory(asList("id1", "id2"), asList("id3", "id4"))).queryFilters(); final List<String> collect = filterExpressions.stream().map(e -> e.expression()).collect(Collectors.toList()); final String expected = "categories.id:subtree(\"id1\"),subtree(\"id2\"),\"id3\",\"id4\""; assertThat(collect).hasSize(1); assertThat(collect.get(0)).isEqualTo(expected); }
@Test public void canAccessCategories() throws Exception { assertThat(FACET_MODEL.categories().id().allTerms().expression()).isEqualTo("categories.id"); assertThat(FILTER_MODEL.categories().id().is("some-id")).extracting(expression()).containsExactly("categories.id:\"some-id\""); }
@Test public void isInSubtree() { final List<String> categoryIds1 = getCategoryIds("B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("B-1-2", "C-1-3"); final List<String> categoryIds3 = getCategoryIds("B-3", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> { final String categoryId = getCategoryIds("B-1").get(0); return m.categories().id().isInSubtree(categoryId); }) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product1, product2)); }); }); }); }); }
@Test public void containsAll() { final List<String> categoryIds1 = getCategoryIds("A", "B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("A", "B-1"); final List<String> categoryIds3 = getCategoryIds("A", "B", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().containsAll(categoryIds1)) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product1)); }); }); }); }); }
@Test public void containsAnyIncludingSubtrees() { final List<String> categoryIds1 = getCategoryIds("A", "B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("A", "B-1"); final List<String> categoryIds3 = getCategoryIds("A", "B", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().containsAnyIncludingSubtrees(getCategoryIds("C-2"))) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product1)); }); }); }); }); }
@Test public void containsAllIncludingSubtrees() { final List<String> categoryIds1 = getCategoryIds("B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("B-1-2", "C-1-3"); final List<String> categoryIds3 = getCategoryIds("B-3", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().containsAllIncludingSubtrees(getCategoryIds("C", "B-1"))) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product1, product2)); }); }); }); }); }
@Test public void isInSubtreeOrInCategory() { final List<String> categoryIds1 = getCategoryIds("C-2-2"); final List<String> categoryIds2 = getCategoryIds("C-1-3"); final List<String> categoryIds3 = getCategoryIds("B-3"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> { final List<String> categoryIdsSubtree = getCategoryIds("B");//somehow in B final List<String> categoryIdsDirectly = getCategoryIds("C-1-3");//but directly in C-1-3 return m.categories().id().isInSubtreeOrInCategory(categoryIdsSubtree, categoryIdsDirectly); }) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product2, product3)); }); }); }); }); }
private static List<ProductProjection> searchForCategoryAndSort(final String categoryId) { final ProductProjectionSearch searchRequest = ProductProjectionSearch.ofStaged() .withQueryFilters(productModel -> productModel.categories().id().is(categoryId)) .withSort(productModel -> productModel.categoryOrderHints().category(categoryId).asc()); return client().executeBlocking(searchRequest).getResults(); }
@Test public void containsAny() { final List<String> categoryIds1 = getCategoryIds("A", "B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("A", "B-1"); final List<String> categoryIds3 = getCategoryIds("A", "B", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().containsAny(categoryIds1)) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product1, product2, product3)); }); }); }); }); }
@Test public void is() { final List<String> categoryIds1 = getCategoryIds("A", "B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("A", "B-1"); final List<String> categoryIds3 = getCategoryIds("A", "B", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.categories().id().containsAny(getCategoryIds("B-1"))) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); assertThat(client().executeBlocking(request)).has(onlyProducts(product1, product2)); }); }); }); }); }