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

Avatar

Avatar

rohan_raj1

Avatar

rohan_raj1

rohan_raj1

22-10-2020

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>

 

 

 

 

AME Mock io.wcm junit

Accepted Solutions (0)

Answers (0)