Adobe-Consulting-Services/acs-aem-commons

View on GitHub
bundle/src/test/java/com/adobe/acs/commons/mcp/form/SyntheticDialogTest.java

Summary

Maintainability
A
0 mins
Test Coverage
/*
 * ACS AEM Commons
 *
 * Copyright (C) 2013 - 2023 Adobe
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.adobe.acs.commons.mcp.form;

import java.util.Iterator;
import java.util.List;
import org.apache.sling.api.resource.Resource;
import org.junit.Before;
import org.junit.Test;

import static com.adobe.acs.commons.mcp.form.MultifieldComponent.NODE_PATH;
import static org.junit.Assert.*;

/**
 * Assert the generation behavior of synthetic dialogs from a java bean -- which
 * could be a sling model also. Also try various components and initialization
 * behaviors.
 */
public class SyntheticDialogTest {

    TestPojo testPojo;

    @Before
    public void init() {
        testPojo = new TestPojo();
        testPojo.init();
        testPojo.getFieldComponents();
    }

    @Test
    public void testDialogInit() {
        assertFieldExists("textField");
        assertFieldExists("multiField");
        assertFieldExists("simpleMultiField");
        assertFieldExists("readOnly");
        assertFieldExists("tags");
        assertFieldExists("textArea");
        assertFieldExists("beanProperty");
        assertFieldExists("booleanProperty");
    }

    public void assertFieldExists(String name) {
        assertNotNull("Checking for field " + name, testPojo.getFieldComponents().get(name));
        assertEquals("Validating field name " + name, name, testPojo.getFieldComponents().get(name).getName());
    }

    @Test
    public void testCompositeMultifieldComponentGeneration() {
        MultifieldComponent component = (MultifieldComponent) testPojo.getFieldComponents().get("multiField");
        component.setPath("/test/path");
        assertNotNull(component.getFieldComponents().get("subField1"));
        assertNotNull(component.getFieldComponents().get("subField2"));
        assertNotNull(component.getFieldComponents().get("subField3"));
        assertNotNull(component.getFieldComponents().get("subField4"));
        assertNotNull(component.getFieldComponents().get("subField5"));
        assertNotNull(component.getFieldComponents().get("subField6"));
        assertTrue(component.isComposite());
        AbstractResourceImpl res = (AbstractResourceImpl) component.buildComponentResource();
        assertNotNull(res);
        assertEquals("/test/path", res.getPath());
        assertNotNull("Multifield structure check 1", res.getChild("field"));
        assertNotNull("Multifield structure check 2", res.getChild("field/items"));
        // Fields should be grouped in a fieldset, but not divided into categories
        assertNotNull("Should include subfield1 component", res.getChild("field/items/fields/items/subField1"));
        assertNotNull("Should include subfield2 component", res.getChild("field/items/fields/items/subField2"));
        assertNotNull("Should include subfield3 component", res.getChild("field/items/fields/items/subField3"));
        assertNotNull("Should include subfield4 component", res.getChild("field/items/fields/items/subField4"));
        assertNotNull("Should include subfield5 component", res.getChild("field/items/fields/items/subField5"));
        assertNotNull("Should include subfield5 component", res.getChild("field/items/fields/items/subField6"));
    }

    @Test
    public void testGroupingBehavior() {
        AbstractResourceImpl res = (AbstractResourceImpl) testPojo.getFormResource();
        assertNotNull("Form structure -- Confirm form container", res.getChild("items"));
        assertNotNull("Form structure -- Confirm presence of tab container", res.getChild("items/tabs"));
        assertNotNull("Form structure -- Confirm tab items list", res.getChild("items/tabs/items"));
        assertEquals("Should have 4 tabs", 4, res.getChild("items/tabs/items").getChildren().spliterator().getExactSizeIfKnown());
        for (Resource tab : res.getChild("items/tabs/items").getChildren()) {
            assertNotEquals("Should not have a 'Misc' tab", AbstractGroupingContainerComponent.GENERIC_GROUP, tab.getResourceMetadata().get("jcr:title"));
        }
    }

    @Test
    public void testSimpleMultifieldComponentGeneration() {
        MultifieldComponent component = (MultifieldComponent) testPojo.getFieldComponents().get("simpleMultiField");
        component.setPath("/test/path");
        assertFalse(component.isComposite());
        AbstractResourceImpl res = (AbstractResourceImpl) component.buildComponentResource();
        assertNotNull(res);
        assertEquals("/test/path", res.getPath());
        assertNotNull("Multifield node check", res.getChild("field"));
    }

    @Test
    public void testClientLibraryHandling() {
        assertEquals(1, testPojo.getAllClientLibraries().size());
        assertEquals(1, testPojo.getJsClientLibraries().size());
        assertEquals(1, testPojo.getCssClientLibraries().size());
        assert(testPojo.getAllClientLibraries().contains("component-all"));
        assert(testPojo.getJsClientLibraries().contains("component-js"));
        assert(testPojo.getCssClientLibraries().contains("component-css"));
    }

    @Test
    public void testSubclassBehaviors() {
        TestInherited subclass = new TestInherited();
        subclass.init();
        subclass.getFieldComponents();
        Resource form = subclass.getFormResource();
        // Check for correct number of categories
        AbstractResourceImpl tabs = (AbstractResourceImpl) form.getChild("items/tabs/items");
        assertEquals("Should have 4 tabs", 4, tabs.children.size());
        // Assert correct number and order of tabs
        Iterator<Resource> children = tabs.listChildren();
        assertEquals("Tab 1 should be first", "1", children.next().getValueMap().get("jcr:title"));
        assertEquals("Tab 2 should be second", "2", children.next().getValueMap().get("jcr:title"));
        assertEquals("Tab 3 should be third", "3", children.next().getValueMap().get("jcr:title"));
        assertEquals("Tab 4 should be fourth", "4", children.next().getValueMap().get("jcr:title"));
        // Check if somethingElse is last
        AbstractResourceImpl tab3 = (AbstractResourceImpl) tabs.children.get(2).getChild("items");
        assertEquals("readOnly should be first", "readOnly", tab3.children.get(0).getName());
        assertEquals("tags should be second", "tags", tab3.children.get(1).getName());
        assertEquals("somethingElse should be last", "somethingElse", tab3.children.get(2).getName());
        // Check if additionalTestArea is last
        AbstractResourceImpl tab4 = (AbstractResourceImpl) tabs.children.get(3).getChild("items");
        assertEquals("additionalTextArea should be last", "additionalTextArea", tab4.children.get(1).getName());
    }

    public static class ComponentWithClientLibraries extends FieldComponent {
        @Override
        public void init() {
            addClientLibraries(FieldComponent.ClientLibraryType.JS, "component-js");
            addClientLibraries(FieldComponent.ClientLibraryType.CSS, "component-css");
            addClientLibrary("component-all");
        }
    }

    public static class TestPojo extends GeneratedDialog {
        @FormField(component = TextfieldComponent.class, name = "Text Field", category="1")
        String textField;

        @FormField(component = MultifieldComponent.class, name = "Multifield (composite)", category="1")
        List<TestSubtype> multiField;

        @FormField(component = MultifieldComponent.class, name = "Multifield (simple)", category="2", options = NODE_PATH)
        List<String> simpleMultiField;

        @FormField(component = MultifieldComponent.class, name = "Multifield (simple)", category="2")
        String[] simpleArrayMultiField;

        @FormField(component = ReadonlyTextfieldComponent.class, name = "Read-only", category="3")
        String readOnly;

        @FormField(component = TagPickerComponent.class, name = "tags", category="3")
        List<String> tags;

        @FormField(component = TextareaComponent.class, name = "Text Area", category="4")
        String textArea;

        String beanProperty;

        @FormField(name = "Bean property", category="4")
        public String getBeanProperty() {
            return beanProperty;
        }

        boolean booleanProperty;

        @FormField(component = CheckboxComponent.class, name = "Boolean property", category="4")
        public boolean isBooleanProperty() {
            return booleanProperty;
        }
    }

    public static class TestSubtype {

        @FormField(component = TextfieldComponent.class, name = "Text Field")
        String subField1;

        @FormField(component = TextfieldComponent.class, name = "Text Field")
        String subField2;

        @FormField(component = ReadonlyTextfieldComponent.class, name = "Read-only")
        String subField3;

        @FormField(component = TagPickerComponent.class, name = "tags")
        List<String> subField4;

        @FormField(component = TextareaComponent.class, name = "Text Area")
        String subField5;

        @FormField(component = ComponentWithClientLibraries.class, name = "Component with client libs")
        String subField6;
    }

    public static class TestInherited extends TestPojo {
        @FormField(component = TextareaComponent.class, name = "Something Else", category="3")
        String somethingElse;

        @FormField(component = TextareaComponent.class, name = "Text Area", category="4")
        String additionalTextArea;
    }
}