How to Adapt ContentFragment in tests

aliaksandr_hvoz

05-06-2020

Hello.

Could you please tell me how to properly adapt the Resource to the ContentFragment in the tests. Since I do, I get null all the time, but the resource content fragment is not null. And in the class for which the test is written, adaptation works correctly.

 

1.jpg2.jpg

 

 

 

Accepted Solutions (1)

Accepted Solutions (1)

Theo_Pendle

MVP

07-06-2020

Hello @aliaksandr_hvoz,

The issue is likely with your JSON content. In order for the AEMMock resource resolver to correctly identify the your resource as a content fragment, it must satisfy some basic elements of what a content fragment is. This is the same for any JSON-based test resource.

One thing that you maybe overlooked is the presence of the metadata child which is necessary to instantiate a ContentFragment. Here is a working example:

JSON:

{
    "dam": {
        "content-fragment": {
            "jcr:primaryType": "dam:Asset",
            "jcr:content": {
                "jcr:primaryType": "dam:AssetContent",
                "jcr:title": "Lorem Ipsum 1",
                "contentFragment": true,
                "cq:name": "lorem-ipsum-1",
                "metadata": {
                    "jcr:primaryType": "nt:unstructured"
                }
            }
        }
    }
}

Java:

import com.adobe.cq.dam.cfm.ContentFragment;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import org.apache.sling.api.resource.Resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(AemContextExtension.class)
class ContentFragmentTest {

    private final AemContext context = new AemContext();

    @BeforeEach
    public void setUp() throws Exception {
        context.load().json("/test.json", "/content");
    }

    @Test
    public void testSomething() {
        final Resource resource = context.resourceResolver().getResource("/content/dam/content-fragment");
        final ContentFragment contentFragment = resource.adaptTo(ContentFragment.class);
        Assertions.assertNotNull(contentFragment);
    }

}

 If you add these files to your project and run the test, you will be able to adapt the /content/dam/content-fragment to a ContentFragment and therefore pass the test 🙂

Selection_157.png

However, if you then delete the metadata node from the test JSON, the test will fail:

Selection_158.png

Without seeing your JSON, I can't guarantee that this is the problem, but it seems likely 😉

If you don't know what the minimum requirements for a test JSON resource are, I recommend:

  • Finding an example on your AEM instance (eg: I used /content/dam/tipi/content-fragments/lorem-ipsum-1 on my instance)
  • Using the JSON exporter to get some valid JSON (eg: visit /content/dam/tipi/content-fragments/lorem-ipsum-1.infinity.json in your browser)
  • Remove the unneeded nodes and properties until you arrive at the minimum, essential properties (usually that's the jcr:primaryType, the sling:resourceType, sling:resourceSuperType, that kind of thing)

Note: You can also see in my JSON that the dam node has no properties. That's because it's purely a structural node used to create a realistic path.

Hope that helps!

Answers (2)

Answers (2)

arpitv27529355

05-06-2020

Hi @aliaksandr_hvoz 

 

Your code seems to be correct. However, you can go through this link https://docs.adobe.com/content/help/en/experience-manager-64/developing/extending-aem/customizing-co...

 

Also, Could you please confirm which type of resource resolver you are using?

Are you creating resource resolver via service user? If yes, could you please verify whether the corresponding service user has the read access to the content fragment and service mapping is present in OSGI. (refer this http://www.aemcq5tutorials.com/tutorials/create-system-user-in-aem/)

 

Regards,

Arpit