Skip to content

Commit 7cf982f

Browse files
authored
CIF-1244 - CIF Core Component fail gracefully (#231)
* fix exception in webpage and error.log for category list, product, product list, product teaser, and related products components when the graphqlclient is not available
1 parent 166435d commit 7cf982f

File tree

11 files changed

+125
-28
lines changed

11 files changed

+125
-28
lines changed

bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/categorylist/FeaturedCategoryListImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ private void initModel() {
105105

106106
if (categoryIds.size() > 0) {
107107
MagentoGraphqlClient magentoGraphqlClient = MagentoGraphqlClient.create(resource);
108-
categoriesRetriever = new CategoriesRetriever(magentoGraphqlClient);
109-
categoriesRetriever.setIdentifiers(categoryIds);
108+
if (magentoGraphqlClient != null) {
109+
categoriesRetriever = new CategoriesRetriever(magentoGraphqlClient);
110+
categoriesRetriever.setIdentifiers(categoryIds);
111+
}
110112
}
111113
}
112114
}

bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,25 +112,26 @@ private void initModel() {
112112

113113
// Get MagentoGraphqlClient from the resource.
114114
MagentoGraphqlClient magentoGraphqlClient = MagentoGraphqlClient.create(resource);
115-
116-
if (StringUtils.isNotBlank(slug)) {
117-
productRetriever = new ProductRetriever(magentoGraphqlClient);
118-
productRetriever.setIdentifier(slug);
119-
loadClientPrice = properties.get(PN_LOAD_CLIENT_PRICE, currentStyle.get(PN_LOAD_CLIENT_PRICE, LOAD_CLIENT_PRICE_DEFAULT));
120-
} else if (!wcmMode.isDisabled()) {
121-
// In AEM Sites editor, load some dummy placeholder data for the component.
122-
try {
123-
productRetriever = new ProductPlaceholderRetriever(magentoGraphqlClient, PLACEHOLDER_DATA);
124-
} catch (IOException e) {
125-
LOGGER.warn("Cannot use placeholder data", e);
115+
if (magentoGraphqlClient != null) {
116+
if (StringUtils.isNotBlank(slug)) {
117+
productRetriever = new ProductRetriever(magentoGraphqlClient);
118+
productRetriever.setIdentifier(slug);
119+
loadClientPrice = properties.get(PN_LOAD_CLIENT_PRICE, currentStyle.get(PN_LOAD_CLIENT_PRICE, LOAD_CLIENT_PRICE_DEFAULT));
120+
} else if (!wcmMode.isDisabled()) {
121+
// In AEM Sites editor, load some dummy placeholder data for the component.
122+
try {
123+
productRetriever = new ProductPlaceholderRetriever(magentoGraphqlClient, PLACEHOLDER_DATA);
124+
} catch (IOException e) {
125+
LOGGER.warn("Cannot use placeholder data", e);
126+
}
127+
loadClientPrice = false;
126128
}
127-
loadClientPrice = false;
128129
}
129130
}
130131

131132
@Override
132133
public Boolean getFound() {
133-
return productRetriever.fetchProduct() != null;
134+
return productRetriever != null && productRetriever.fetchProduct() != null;
134135
}
135136

136137
@Override
@@ -171,7 +172,7 @@ public Boolean getInStock() {
171172
@Override
172173
public Boolean isConfigurable() {
173174
if (configurable == null) {
174-
configurable = productRetriever.fetchProduct() instanceof ConfigurableProduct;
175+
configurable = productRetriever != null && productRetriever.fetchProduct() instanceof ConfigurableProduct;
175176
}
176177

177178
return configurable;

bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/productlist/ProductListImpl.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ private void initModel() {
139139
@Nullable
140140
@Override
141141
public String getTitle() {
142-
return categoryRetriever.fetchCategory() != null ? categoryRetriever.fetchCategory().getName() : StringUtils.EMPTY;
142+
return categoryRetriever != null && categoryRetriever.fetchCategory() != null ? categoryRetriever.fetchCategory().getName()
143+
: StringUtils.EMPTY;
143144
}
144145

145146
@Override
@@ -174,10 +175,14 @@ public int getNextNavPage() {
174175

175176
@Override
176177
public String getImage() {
177-
if (StringUtils.isEmpty(categoryRetriever.fetchCategory().getImage())) {
178+
if (categoryRetriever != null) {
179+
if (StringUtils.isEmpty(categoryRetriever.fetchCategory().getImage())) {
180+
return StringUtils.EMPTY;
181+
}
182+
return categoryRetriever.fetchCategory().getImage();
183+
} else {
178184
return StringUtils.EMPTY;
179185
}
180-
return categoryRetriever.fetchCategory().getImage();
181186
}
182187

183188
@Override
@@ -211,7 +216,7 @@ public List<Integer> getPageList() {
211216
public Collection<ProductListItem> getProducts() {
212217
Collection<ProductListItem> listItems = new ArrayList<>();
213218

214-
if (categoryRetriever.fetchCategory() != null) {
219+
if (categoryRetriever != null && categoryRetriever.fetchCategory() != null) {
215220
final CategoryProducts products = categoryRetriever.fetchCategory().getProducts();
216221
if (products != null) {
217222
for (ProductInterface product : products.getItems()) {

bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/productteaser/ProductTeaserImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ protected void initModel() {
9494
}
9595

9696
private ProductInterface getProduct() {
97+
if (productRetriever == null) {
98+
return null;
99+
}
100+
97101
ProductInterface baseProduct = productRetriever.fetchProduct();
98102
if (combinedSku.getRight() != null && baseProduct instanceof ConfigurableProduct) {
99103
ConfigurableProduct configurableProduct = (ConfigurableProduct) baseProduct;

bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/relatedproducts/RelatedProductsImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ private void initModel() {
8686

8787
if (magentoGraphqlClient == null) {
8888
LOGGER.error("Cannot get a GraphqlClient using the resource at {}", resource.getPath());
89+
} else {
90+
configureProductsRetriever();
8991
}
90-
91-
configureProductsRetriever();
9292
}
9393

9494
@Override
@@ -117,7 +117,7 @@ private void configureProductsRetriever() {
117117

118118
@Override
119119
public List<ProductListItem> getProducts() {
120-
if (!isConfigured()) {
120+
if (productsRetriever == null || !isConfigured()) {
121121
return Collections.emptyList();
122122
}
123123

bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/categorylist/FeaturedCategoryListImplTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class FeaturedCategoryListImplTest {
4646

4747
private FeaturedCategoryListImpl slingModelConfigured;
4848
private FeaturedCategoryListImpl slingModelNotConfigured;
49+
private FeaturedCategoryListImpl slingModelConfiguredNoGraphqlClient;
4950
private List<CategoryTree> categories = new ArrayList<>();
5051

5152
private static final String CATEGORY_PAGE = "/content/category-page";
@@ -58,13 +59,17 @@ public class FeaturedCategoryListImplTest {
5859

5960
private static final String COMPONENT_PATH = "/content/pageA/jcr:content/root/responsivegrid/featuredcategorylist";
6061
private static final String COMPONENT_PATH_NOCONFIG = "/content/pageA/jcr:content/root/responsivegrid/featuredcategorylist2";
62+
private static final String COMPONENT_PATH_NOCLIENT = "/content/pageA/jcr:content/root/responsivegrid/featuredcategorylist3";
6163

6264
@Rule
6365
public final AemContext contextConfigured = createContext("/context/jcr-content.json");
6466

6567
@Rule
6668
public final AemContext contextNotConfigured = createContext("/context/jcr-content.json");
6769

70+
@Rule
71+
public final AemContext contextNotConfiguredClient = createContext("/context/jcr-content.json");
72+
6873
@Before
6974
public void setup() throws Exception {
7075

@@ -102,6 +107,16 @@ public void setup() throws Exception {
102107
slingBindings.setResource(resource);
103108
slingBindings.put("currentPage", page);
104109
slingModelNotConfigured = contextNotConfigured.request().adaptTo(FeaturedCategoryListImpl.class);
110+
111+
// init slingmodel with no graphql client
112+
when(resource.adaptTo(GraphqlClient.class)).thenReturn(null);
113+
resource = Mockito.spy(contextConfigured.resourceResolver().getResource(COMPONENT_PATH_NOCLIENT));
114+
contextNotConfiguredClient.currentResource(resource);
115+
slingBindings = (SlingBindings) contextNotConfiguredClient.request().getAttribute(SlingBindings.class.getName());
116+
slingBindings.setResource(resource);
117+
slingBindings.put(WCMBindings.WCM_MODE, new SightlyWCMMode(contextNotConfiguredClient.request()));
118+
slingBindings.put("currentPage", page);
119+
slingModelConfiguredNoGraphqlClient = contextNotConfiguredClient.request().adaptTo(FeaturedCategoryListImpl.class);
105120
}
106121

107122
@Test
@@ -142,6 +157,16 @@ public void verifyNotConfigured() {
142157
Assert.assertEquals(categories.size(), 0);
143158
}
144159

160+
@Test
161+
public void verifyGraphQLClientNotConfigured() {
162+
Assert.assertNotNull(slingModelConfiguredNoGraphqlClient);
163+
Assert.assertNull(slingModelConfiguredNoGraphqlClient.getCategoriesRetriever());
164+
Assert.assertTrue(slingModelConfiguredNoGraphqlClient.isConfigured());
165+
categories = slingModelConfiguredNoGraphqlClient.getCategories();
166+
Assert.assertNotNull(categories);
167+
Assert.assertEquals(0, categories.size());
168+
}
169+
145170
@Test
146171
public void verifyIgnoreInvalidAsset() {
147172
categories = slingModelConfigured.getCategories();

bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImplTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,14 @@ public void testDiscountedPrice() {
331331
Assert.assertEquals(12.0, price.getDiscountAmount(), 0.001);
332332
Assert.assertEquals(20.69, price.getDiscountPercent(), 0.001);
333333
}
334+
335+
@Test
336+
public void testProductNoGraphqlClient() {
337+
Mockito.when(productResource.adaptTo(GraphqlClient.class)).thenReturn(null);
338+
339+
productModel = context.request().adaptTo(ProductImpl.class);
340+
Assert.assertFalse(productModel.getFound());
341+
Assert.assertFalse(productModel.isConfigurable());
342+
Assert.assertNull(productModel.getProductRetriever());
343+
}
334344
}

bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/productlist/ProductListImplTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,14 @@ public void testEditModePlaceholderData() throws IOException {
308308
Assert.assertEquals(category.getName(), productListModel.getTitle());
309309
Assert.assertEquals(category.getProducts().getItems().size(), productListModel.getProducts().size());
310310
}
311+
312+
@Test
313+
public void testProductListNoGraphqlClient() throws IOException {
314+
Mockito.when(productListResource.adaptTo(GraphqlClient.class)).thenReturn(null);
315+
productListModel = context.request().adaptTo(ProductListImpl.class);
316+
317+
Assert.assertTrue(productListModel.getTitle().isEmpty());
318+
Assert.assertTrue(productListModel.getImage().isEmpty());
319+
Assert.assertTrue(productListModel.getProducts().isEmpty());
320+
}
311321
}

bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/productteaser/ProductTeaserImplTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ private static AemContext createContext(String contentPath) {
6060
private static final String PRODUCTTEASER_SIMPLE = "/content/pageA/jcr:content/root/responsivegrid/productteaser-simple";
6161
private static final String PRODUCTTEASER_VARIANT = "/content/pageA/jcr:content/root/responsivegrid/productteaser-variant";
6262
private static final String PRODUCTTEASER_PATH = "/content/pageA/jcr:content/root/responsivegrid/productteaser-path";
63+
private static final String PRODUCTTEASER_NOCLIENT = "/content/pageA/jcr:content/root/responsivegrid/productteaser-noclient";
6364

6465
private Resource teaserResource;
6566

@@ -155,4 +156,23 @@ public void verifyProductVariant() throws Exception {
155156

156157
Assert.assertEquals(variant.getImage().getUrl(), productTeaser.getImage());
157158
}
159+
160+
@Test
161+
public void verifyProductTeaserNoGraphqlCLient() {
162+
Page page = context.currentPage(PAGE);
163+
context.currentResource(PRODUCTTEASER_NOCLIENT);
164+
Resource teaserResource = Mockito.spy(context.resourceResolver().getResource(PRODUCTTEASER_NOCLIENT));
165+
Mockito.when(teaserResource.adaptTo(GraphqlClient.class)).thenReturn(null);
166+
167+
// This sets the page attribute injected in the models with @Inject or @ScriptVariable
168+
SlingBindings slingBindings = (SlingBindings) context.request().getAttribute(SlingBindings.class.getName());
169+
slingBindings.setResource(teaserResource);
170+
slingBindings.put(WCMBindingsConstants.NAME_CURRENT_PAGE, page);
171+
slingBindings.put(WCMBindingsConstants.NAME_PROPERTIES, teaserResource.getValueMap());
172+
173+
ProductTeaserImpl productTeaserNoClient = context.request().adaptTo(ProductTeaserImpl.class);
174+
175+
Assert.assertNull(productTeaserNoClient.getProductRetriever());
176+
Assert.assertNull(productTeaserNoClient.getUrl());
177+
}
158178
}

bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/relatedproducts/RelatedProductsImplTest.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,13 @@ private void setUp(RelationType relationType, String jsonResponsePath, boolean a
9999
requestPathInfo.setSelectorString("endurance-watch");
100100
}
101101

102-
Query rootQuery = Utils.getQueryFromResource(jsonResponsePath);
103-
ProductInterface product = rootQuery.getProducts().getItems().get(0);
104-
products = PRODUCTS_GETTER.get(relationType).apply(product);
105-
106-
GraphqlClient graphqlClient = Utils.setupGraphqlClientWithHttpResponseFrom(jsonResponsePath);
102+
GraphqlClient graphqlClient = null;
103+
if (jsonResponsePath != null) {
104+
Query rootQuery = Utils.getQueryFromResource(jsonResponsePath);
105+
ProductInterface product = rootQuery.getProducts().getItems().get(0);
106+
products = PRODUCTS_GETTER.get(relationType).apply(product);
107+
graphqlClient = Utils.setupGraphqlClientWithHttpResponseFrom(jsonResponsePath);
108+
}
107109
Mockito.when(relatedProductsResource.adaptTo(GraphqlClient.class)).thenReturn(graphqlClient);
108110

109111
// This sets the page attribute injected in the models with @Inject or @ScriptVariable
@@ -145,6 +147,12 @@ public void testIsNotConfigured() throws Exception {
145147
Assert.assertTrue(relatedProducts.getProducts().isEmpty());
146148
}
147149

150+
@Test
151+
public void testNoGraphqlClient() throws Exception {
152+
setUp(RelationType.UPSELL_PRODUCTS, null, true);
153+
Assert.assertTrue(relatedProducts.getProducts().isEmpty());
154+
}
155+
148156
@Test
149157
public void testQueryExtensions() throws Exception {
150158
setUp(RelationType.RELATED_PRODUCTS, "graphql/magento-graphql-relatedproducts-result.json", false);

0 commit comments

Comments
 (0)