AemMock is not able to return page.getTemplate() in a Model adaptable to SlingHttpServletRequest | Community
Skip to main content
Level 2
October 22, 2020
Solved

AemMock is not able to return page.getTemplate() in a Model adaptable to SlingHttpServletRequest

  • October 22, 2020
  • 1 reply
  • 2367 views

I am trying to test a Model adaptable as SlingHttpServletRequest. Its basically a Custom RenderCondition checks for the Template of the page to show or hide dialog field/tab. It will be a great help if anyt one could point any issue in my test fixture, following the documents from io.wcm here - https://wcm.io/testing/aem-mock/usage.html#JUnit_4_AEM_Context_JUnit_Rule it should work on page.getTemplate() after adapting resource as Page.

I Now the test cases are failing Due to its not able to get the page.getTemplate(); it always returns Null but at the same time if I use resource API its can get "cq:template" as string and passes the test.

 

package com.abc.models; import com.adobe.cq.sightly.WCMBindings; import com.adobe.granite.ui.components.rendercondition.RenderCondition; import com.adobe.granite.ui.components.rendercondition.SimpleRenderCondition; import com.amex.gem.AppAemContext; import com.day.cq.wcm.api.*; import com.google.common.collect.ImmutableMap; import io.wcm.testing.mock.aem.junit.AemContext; import io.wcm.testing.mock.aem.*; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.scripting.SlingBindings; import org.apache.sling.models.factory.ModelFactory; import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @RunWith(MockitoJUnitRunner.class) public class TemplateTypeRenderConditionTest { private static final String DEST_ROOT = "/content/sample/abc"; private static final String TEMPLATE_PATH = "/conf/homepage/settings/wcm/templates/homepage"; private static final String PAGE_ROOT = "/content/sample/abc/index"; private TemplateTypeRenderCondition underTestModel; public final AemContext CONTEXT = AppAemContext.newAemContext(); @Mock PageManager pageManager; SlingBindings slingBindings; Resource pageResource ; Page pageToTest = null; @Before public void setUp() throws NoSuchFieldException, WCMException { slingBindings = (SlingBindings) CONTEXT.request().getAttribute(SlingBindings.class.getName()); slingBindings.put(WCMBindings.PAGE_MANAGER, pageManager); slingBindings.put(SlingBindings.RESOURCE, CONTEXT.resourceResolver().getResource(DEST_ROOT)); CONTEXT.request().setAttribute(SlingBindings.class.getName(), slingBindings); // prepare sling request CONTEXT.request().setResource(CONTEXT.resourceResolver().getResource(DEST_ROOT)); CONTEXT.request().setQueryString("item=/content/sample/abc/index"); CONTEXT.pageManager().create("/content/sample/abc", "index", TEMPLATE_PATH, "title1"); } public void itShouldReturnTheResourceMatchesTheTemplateTypeFromItemParamter() throws WCMException { CONTEXT.pageManager().create("/content/sample/abc", "index", TEMPLATE_PATH, "title1"); pageResource = CONTEXT.resourceResolver().getResource(PAGE_ROOT); pageToTest = CONTEXT.pageManager().getPage(PAGE_ROOT); underTestModel = CONTEXT.getService(ModelFactory.class).createModel(CONTEXT.request(), TemplateTypeRenderCondition.class); assertEquals(pageToTest.getTemplate().getPath(),TEMPLATE_PATH); assertEquals(pageToTest.getResource().getValueMap().get("cq:template", String.class), TEMPLATE_PATH); } }

 

The first assert is failing for getting template object but not the second one. Saying .getTemplate is returning null

 

My Unit test passes this assert

 

underTestModel = CONTEXT.getService(ModelFactory.class).createModel(CONTEXT.request(), TemplateTypeRenderCondition.class);SimpleRenderCondition resultingRenderCond = (SimpleRenderCondition) CONTEXT.request().getAttribute(RenderCondition.class.getName()); assertTrue(resultingRenderCond.check());

 

If I am using this code to get the Template in my class:

 

final Resource pageResource = page.getContentResource(); templatePathOfCurrentPage = pageResource.getValueMap().get("cq:template", String.class);

 

But fails if the AEM Page API being used for accessing template name:

 

final Template pageTemplate = page.getTemplate(); templatePathOfCurrentPage = pageTemplate.getPath();

 

 

Class under test:

 

package com.abc.models; import com.adobe.granite.ui.components.rendercondition.RenderCondition; import com.adobe.granite.ui.components.rendercondition.SimpleRenderCondition; import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageManager; import com.day.cq.wcm.api.Template; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.ScriptVariable; import org.apache.sling.models.annotations.injectorspecific.Self; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import java.util.Arrays; import java.util.List; @Model(adaptables = SlingHttpServletRequest.class) public class TemplateTypeRenderCondition { private final Logger logger = LoggerFactory.getLogger(TemplateTypeRenderCondition.class); private SlingHttpServletRequest request; @ScriptVariable private PageManager pageManager; @ValueMapValue private String[] templatePath; @PostConstruct public void init() { // Get the resource page path for which propery is being edited final String pathPage = request.getParameter("item"); //Assign suffix as path for Create Page wizard final String suffix = request.getRequestPathInfo().getSuffix();; // Still cannot found the through exception if (pathPage == null && suffix == null) { throw new IllegalArgumentException("Could not determine page from <" + request.getPathInfo() + "> , neither suffix in create page wizard or, item in editor"); } logger.info("Path Info for the page property editing from RenderCondition is {}", request.getPathInfo()); String templatePathOfCurrentPage = null; if(pathPage != null) { final Page page = pageManager.getPage(pathPage); if (page == null) { throw new IllegalArgumentException("Resource at <" + pathPage + "> is not a page"); } //Failing with this code // final Template pageTemplate = page.getTemplate(); //templatePathOfCurrentPage = pageTemplate.getPath(); final Resource pageResource = page.getContentResource(); templatePathOfCurrentPage = pageResource.getValueMap().get("cq:template", String.class); } else if( suffix != null){ templatePathOfCurrentPage = suffix; } // Check if we have the template from page if(templatePath.length < 1) { throw new IllegalArgumentException("Could not get page template match from <" + request.getPathInfo() + ">"); } final List<String> listTemplates = Arrays.asList(templatePath); final boolean show = listTemplates.contains(templatePathOfCurrentPage); // Add the render condition based on check if list of templatePath has current page template allowed request.setAttribute(RenderCondition.class.getName(), new SimpleRenderCondition(show)); } public String[] getTemplatePath(){ return templatePath; } }

 

 

 I am trying to test it and so here is my Context setup for test:

 

package com.abc; import com.abc.models.TemplateTypeRenderCondition; import com.google.common.base.Function; import io.wcm.testing.mock.aem.junit.AemContext; import io.wcm.testing.mock.aem.junit.AemContextCallback; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.testing.mock.sling.ResourceResolverType; import javax.annotation.Nullable; public class AppAemContext { private static final String DEST_ROOT = "/content/sample/abc"; private static final String TEST_JSON = "/templaterendercond/test-content.json"; private static final String PAGE_ROOT = "/content/sample/abc/index"; private static final String TEST_PAGE_JSON = "/templaterendercond/test-page.json"; public static AemContext newAemContext() { return new AemContext(new SetUpCallback(), ResourceResolverType.JCR_MOCK); } private static TemplateTypeRenderCondition mockTemplateTypeRenderCondition = new TemplateTypeRenderCondition(); private static final class SetUpCallback implements AemContextCallback { public void execute(AemContext context) { context.registerAdapter(SlingHttpServletRequest.class, TemplateTypeRenderCondition.class, new Function<SlingHttpServletRequest, TemplateTypeRenderCondition>() { public TemplateTypeRenderCondition apply(@Nullable SlingHttpServletRequest request) { return mockTemplateTypeRenderCondition; } }); // register models from package context.addModelsForPackage("com.abc.models"); context.load().json(TEST_JSON, DEST_ROOT); context.load().json(TEST_PAGE_JSON, PAGE_ROOT); } } }

 

 

This is my POM fixture for Test:

 

<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>junit-addons</groupId> <artifactId>junit-addons</artifactId> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> <version>2.18.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.adapter</artifactId> <version>2.1.6</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.jcr.api</artifactId> <version>2.4.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.jcr.resource</artifactId> <version>3.0.18</version> <scope>test</scope> </dependency> <!-- for testing we need the new ResourceTypeBasedResourcePicker --> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.models.impl</artifactId> <version>1.4.12</version> <scope>test</scope> </dependency> <!-- Added for Powemock --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito-common</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-easymock</artifactId> <version>1.5.5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.osgi-mock</artifactId> <version>2.4.14</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.jcr-mock</artifactId> <version>1.4.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId> <version>1.1.26</version> <scope>test</scope> </dependency> <dependency> <groupId>io.wcm</groupId> <artifactId>io.wcm.sling.commons</artifactId> <version>1.3.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId> <version>2.4.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.sling-mock-oak</artifactId> <version>2.1.6</version> <scope>test</scope> </dependency> <dependency> <groupId>io.wcm</groupId> <artifactId>io.wcm.testing.aem-mock.junit4</artifactId> <version>3.0.0</version> <scope>test</scope> </dependency>

 

 

 

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by Suraj_Kamdi

@rohan_raj1 Use the following code snippet to create mock page and page template object

//Add following code snippet @BeforeEach void setUp() throws WCMException { context.load().json("<PAGE_TEMPLATE_RESOURCE_JSON_PATH>", "<TEMPLATE_PATH>"); final PageManager pageManager = context.resourceResolver().adaptTo(PageManager.class); context.create().page("/content/mysite/us/en/home"); final Page currentPage = pageManager.create("/content/mysite/us/en/home", "sample-page", "<TEMPLATE_PATH>", "Page Title", true); context.currentPage(currentPage); context.currentResource(<yourComponentResource>); myComponentModel= (ContentHeroModelImpl) context.request().adaptTo( MyComponentModel.class); }

1 reply

Suraj_Kamdi
Community Advisor
Suraj_KamdiCommunity AdvisorAccepted solution
Community Advisor
May 27, 2024

@rohan_raj1 Use the following code snippet to create mock page and page template object

//Add following code snippet @BeforeEach void setUp() throws WCMException { context.load().json("<PAGE_TEMPLATE_RESOURCE_JSON_PATH>", "<TEMPLATE_PATH>"); final PageManager pageManager = context.resourceResolver().adaptTo(PageManager.class); context.create().page("/content/mysite/us/en/home"); final Page currentPage = pageManager.create("/content/mysite/us/en/home", "sample-page", "<TEMPLATE_PATH>", "Page Title", true); context.currentPage(currentPage); context.currentResource(<yourComponentResource>); myComponentModel= (ContentHeroModelImpl) context.request().adaptTo( MyComponentModel.class); }