org.slc.sli.dashboard.unit.manager.CustomizationAssemblyFactoryTest.java Source code

Java tutorial

Introduction

Here is the source code for org.slc.sli.dashboard.unit.manager.CustomizationAssemblyFactoryTest.java

Source

/*
 * Copyright 2012 Shared Learning Collaborative, LLC
 *
 * 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 org.slc.sli.dashboard.unit.manager;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import junit.framework.Assert;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slc.sli.dashboard.entity.Config;
import org.slc.sli.dashboard.entity.Config.Item;
import org.slc.sli.dashboard.entity.GenericEntity;
import org.slc.sli.dashboard.entity.ModelAndViewConfig;
import org.slc.sli.dashboard.manager.Manager.EntityMapping;
import org.slc.sli.dashboard.manager.Manager.EntityMappingManager;
import org.slc.sli.dashboard.manager.component.impl.CustomizationAssemblyFactoryImpl;
import org.slc.sli.dashboard.util.DashboardException;
import org.slc.sli.dashboard.util.JsonConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Test CustomizationAssemblyFactory features
 * 
 * @author agrebneva
 * 
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/application-context.xml" })
public class CustomizationAssemblyFactoryTest {
    @Autowired
    ApplicationContext applicationContext;

    private static final String DEFAULT_LAYOUT_JSON = "{id : 'studentProfile', type: 'LAYOUT', "
            + " data :{entity: 'mock', alias: 'mock' }, "
            + " items: [{id : 'panel', name: 'Student Info', type: 'PANEL'},"
            + "         {id: 'tab2', condition: {field: 'gender', value: ['male']}, name: 'Attendance and Discipline', type : 'TAB', "
            + "          items: [{id : 'panel', type: 'PANEL'}]}]}";
    private static final String DEFAULT_LAYOUT_TOO_DEEP_JSON = "{id : 'deep', type: 'LAYOUT', "
            + " data :{entity: 'mock', alias: 'mock' }, "
            + " items: [{id : 'deep', name: 'Student Info', type: 'PANEL'}]}";
    private static final String DEFAULT_PANEL_JSON = "{id : 'panel', type: 'PANEL', condition: {field: 'gender', value: ['male']}, data :{entity: 'test',alias: 'mock' }}";

    private static final String DEFAULT_PANEL1_JSON = "{id : 'panel1', type: 'PANEL', condition: {field: 'gradeNumeric', value: [1,2,5]}, data :{entity: 'test',alias: 'mock' }}";

    private static final String DEFAULT_PANEL_EXCEPTION_JSON = "{id : 'panelException', type: 'PANEL', condition: {field: 'gradeNumeric', value: [1,2,5]}, data :{entity: 'testException',alias: 'mock' }}";

    private static final String PANEL_WITH_DYNAMIC_HEADERS = "{id : 'dynamicHeaders', type: 'PANEL', items: [{name: '${meta.name.first}'}, {name: '${meta.id}'}]}";

    private static GenericEntity simpleMaleStudentEntity;
    private static GenericEntity simpleFemaleStudentEntity;
    private static GenericEntity simpleCacheData;

    private static Map<String, Config> configMap;

    private static Map<String, GenericEntity> sampleEntityMap;

    private static GenericEntity simpleNoGenderInfoStudentEntity;

    private static final String CACHE_TEST_JSON = "{\"id\":\"section\",\"parentId\":\"section\",\"name\":\"SLC - Section Profile\",\"type\":\"LAYOUT\",\"data\":{\"entity\":\"sectionInfo\",\"cacheKey\":\"sectionInfo\",\"lazy\":true},\"items\":[{\"id\":\"tab3\",\"parentId\":\"tab3\",\"name\":\"List of Students\",\"type\":\"TAB\",\"items\":[{\"id\":\"listOfStudents\",\"parentId\":\"listOfStudents\",\"type\":\"PANEL\"}]},{\"id\":\"tab4\",\"name\":\"LOS\",\"type\":\"TAB\",\"items\":[{\"id\":\"listOfStudents\",\"parentId\":\"listOfStudents\",\"type\":\"PANEL\"}]}]}";
    private static final String LIST_OF_STUDENTS_JSON = "{ id : \"listOfStudents\", type : \"PANEL\", data :{ lazy: true, entity: \"listOfStudents\", cacheKey: \"listOfStudents\" }, root: 'students', items : [ {name: \"Default View\", items: [ {name: \"Student\", width: 150, field: \"name.fullName\", formatter:restLink, style:'ui-ellipsis', params: {link:'student', target:\"_self\"}}, {name: \"\", width: 60, field: \"programParticipation\", formatter: Lozenge}, {name: \"Grade\", field: \"score.grade\", width:50, formatter: TearDrop}, {name: \"Absence Count\", field: \"attendances.absenceCount\", width:100, sorter: 'int', formatter: CutPointReverse, params:{cutPoints:{0:{style:'color-widget-darkgreen'}, 1:{style:'color-widget-green'}, 6:{style: 'color-widget-yellow'}, 11:{style:'color-widget-red'}}}}, {name: \"Tardy Count\", field: \"attendances.tardyCount\", width:100, sorter: 'int', formatter: CutPointReverse, params:{cutPoints:{0:{style:'color-widget-darkgreen'}, 1:{style: 'color-widget-green'}, 6:{style:'color-widget-yellow'}, 11:{style:'color-widget-red'}}}} ] } ] }";
    private static final String LIST_OF_STUDENTS_ENTITY = "{\"students\":[{\"studentGradebookEntries\":[],\"sex\":\"Male\",\"studentCharacteristics\":[],\"hispanicLatinoEthnicity\":false,\"disabilities\":[],\"cohortYears\":[],\"section504Disabilities\":[],\"studentSectionAssociation\":[{\"id\":\"2012rh-0c7659b7-e000-11e1-9f3b-3c07546832b4\",\"sectionId\":\"2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4\",\"studentId\":\"2012zv-0665ebcb-e000-11e1-9f3b-3c07546832b4\",\"entityType\":\"studentSectionAssociation\"}],\"race\":[],\"programParticipations\":[],\"id\":\"2012zv-0665ebcb-e000-11e1-9f3b-3c07546832b4\",\"studentUniqueStateId\":\"800000025\",\"languages\":[],\"attendances\":{\"tardyRate\":0,\"attendanceRate\":95,\"tardyCount\":0,\"absenceCount\":4},\"name\":{\"middleName\":\"Joseph\",\"generationCodeSuffix\":\"Jr\",\"lastSurname\":\"Sollars\",\"fullName\":\"Matt Sollars\",\"firstName\":\"Matt\"},\"birthData\":{\"birthDate\":\"2000-04-23\"},\"otherName\":[],\"studentIndicators\":[],\"homeLanguages\":[],\"limitedEnglishProficiency\":\"Limited\",\"studentIdentificationCode\":[],\"address\":[],\"electronicMail\":[{\"emailAddress\":\"m.sollars@gmail.com\",\"emailAddressType\":\"Other\"}],\"gradeLevel\":\"Eighth grade\",\"schoolId\":\"2012ye-0b0a45f5-e000-11e1-9f3b-3c07546832b4\",\"telephone\":[{\"telephoneNumber\":\"309-555-2449\",\"primaryTelephoneNumberIndicator\":true,\"telephoneNumberType\":\"Home\"}],\"previousSemester\":[{\"letterGrade\":\"A-\",\"courseTitle\":\"ELA 6A\"}]}]}";
    private static final String SECTION_ENTITY = "{\"id\":\"2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4\",\"sessionId\":\"2012yw-0b7a6d39-e000-11e1-9f3b-3c07546832b4\",\"courseOfferingId\":\"2012wq-0ba85b67-e000-11e1-9f3b-3c07546832b4\",\"populationServed\":\"Regular Students\",\"sequenceOfCourse\":3,\"uniqueSectionCode\":\"6th Grade English - Sec 4\",\"mediumOfInstruction\":\"Independent study\",\"programReference\":[],\"links\":[{\"linkName\":\"self\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sections/2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"custom\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sections/2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4/custom\"},{\"linkName\":\"getSchool\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/schools/2012ye-0b0a45f5-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"getEducationOrganization\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/educationOrganizations/2012ye-0b0a45f5-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"getSession\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sessions/2012yw-0b7a6d39-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"getCourseOffering\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/courseOfferings/2012wq-0ba85b67-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"getGradebookEntries\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/gradebookEntries?sectionId\u003d2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"getStudentGradebookEntries\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/studentGradebookEntries?sectionId\u003d2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4\"},{\"linkName\":\"getStudentSectionAssociations\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sections/2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4/studentSectionAssociations\"},{\"linkName\":\"getStudents\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sections/2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4/studentSectionAssociations/students\"},{\"linkName\":\"getTeacherSectionAssociations\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sections/2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4/teacherSectionAssociations\"},{\"linkName\":\"getTeachers\",\"resource\":\"http://local.slidev.org:8080/api/rest/v1/sections/2012pd-0bb098cf-e000-11e1-9f3b-3c07546832b4/teacherSectionAssociations/teachers\"}],\"schoolId\":\"2012ye-0b0a45f5-e000-11e1-9f3b-3c07546832b4\",\"sectionName\":\"6th Grade English - Sec 4\",\"teacherName\":{\"verification\":\"Life insurance policy\",\"lastSurname\":\"Kim\",\"personalTitlePrefix\":\"Mrs\",\"firstName\":\"Linda\"},\"courseTitle\":\"6th Grade English\",\"subjectArea\":\"English Language and Literature\"}";

    /**
     * Expose some methods
     * 
     * @author agrebneva
     * 
     */
    class MockCustomizationAssemblyFactoryImpl extends CustomizationAssemblyFactoryImpl {

        @Override
        protected String getTokenId() {
            return "1";
        }

        @Override
        protected Config getConfig(String componentId) {

            return configMap.get(componentId);
        }

        @Override
        public Collection<Config> getWidgetConfigs() {
            return Collections.emptyList();
        }

        @Override
        public GenericEntity getDataComponent(String componentId, Object entityKey, Config.Data config) {
            return sampleEntityMap.get(entityKey);
        }

        public boolean hasInvokableSet(String entityRef) {
            return getInvokableSet(entityRef) != null;
        }

        public GenericEntity getDataComponentForTest(String componentId, Object entityKey, Config.Data config) {
            return super.getDataComponent(componentId, entityKey, config);
        }

        @Override
        protected Config.Item[] getUpdatedDynamicHeaderTemplate(Config config, GenericEntity entity) {
            return super.getUpdatedDynamicHeaderTemplate(config, entity);
        }
    };

    private MockCustomizationAssemblyFactoryImpl customizationAssemblyFactory = new MockCustomizationAssemblyFactoryImpl();

    /**
     * Duplicate entity reference config
     * 
     * @author agrebneva
     * 
     */
    @Configuration
    static class ContextConfigurationWithBadEntityRefSignature {
        @Bean
        public BadManagerWithWrongEntitySignature badManager() {
            return new BadManagerWithWrongEntitySignature();
        }
    }

    /**
     * Mock Manager with bad signature
     * 
     * @author agrebneva
     * 
     */
    @Component
    @EntityMappingManager
    public static class BadManagerWithWrongEntitySignature {

        /**
         * Bad signature mapping
         * 
         * @param token
         * @param studentId
         * @param config
         * @return
         */
        @EntityMapping("testBad")
        public GenericEntity getTest1(String token, Object studentId) {
            return simpleMaleStudentEntity;
        }
    }

    /**
     * Duplicate entity reference config
     * 
     * @author agrebneva
     * 
     */
    @Configuration
    static class ContextConfigurationWithDuplicates {
        @Bean
        public BadManagerWithDuplicate badManager() {
            return new BadManagerWithDuplicate();
        }
    }

    /**
     * Mock Manager with bad signature
     * 
     * @author agrebneva
     * 
     */
    @Component
    @EntityMappingManager
    public static class BadManagerWithDuplicate {

        /**
         * Good
         * 
         * @param token
         * @param studentId
         * @param config
         * @return
         */
        @EntityMapping("test")
        public GenericEntity getTest(String token, Object studentId, Config.Data data) {
            return simpleMaleStudentEntity;
        }

        /**
         * Bad signature mapping
         * 
         * @param token
         * @param studentId
         * @param config
         * @return
         */
        @EntityMapping("test")
        public GenericEntity getTestDuplicate(String token, Object studentId, Config.Data data) {
            return simpleFemaleStudentEntity;
        }
    }

    /**
     * Duplicate entity reference config
     * 
     * @author agrebneva
     * 
     */
    @Configuration
    static class ContextConfigurationWithGoodMananger {
        @Bean
        public GoodManager goodManager() {
            return new GoodManager();
        }
    }

    /**
     * Mock Manager with bad signature
     * 
     * @author agrebneva
     * 
     */
    @Component
    @EntityMappingManager
    public static class GoodManager {

        /**
         * Good signature mapping
         * 
         * @param token
         * @param studentId
         * @param config
         * @return
         */
        @EntityMapping("test")
        public GenericEntity getTest1(String token, Object studentId, Config.Data config) {
            return simpleMaleStudentEntity;
        }

        /**
         * Good signature mapping but throws an exception
         * 
         * @param token
         * @param studentId
         * @param config
         * @return
         */
        @EntityMapping("testException")
        public GenericEntity getTestException(String token, Object studentId, Config.Data config) throws Exception {
            throw new Exception("Something bad happened");
        }
    }

    @BeforeClass
    public static void setupAll() {
        Gson gson = new GsonBuilder().create();
        configMap = new HashMap<String, Config>();
        configMap.put("studentProfile", gson.fromJson(DEFAULT_LAYOUT_JSON, Config.class));
        configMap.put("panel", gson.fromJson(DEFAULT_PANEL_JSON, Config.class));
        configMap.put("panel1", gson.fromJson(DEFAULT_PANEL1_JSON, Config.class));
        configMap.put("deep", gson.fromJson(DEFAULT_LAYOUT_TOO_DEEP_JSON, Config.class));
        configMap.put("panelException", gson.fromJson(DEFAULT_PANEL_EXCEPTION_JSON, Config.class));
        configMap.put("dynamicHeaders", gson.fromJson(PANEL_WITH_DYNAMIC_HEADERS, Config.class));
        configMap.put("test", gson.fromJson(CACHE_TEST_JSON, Config.class));
        configMap.put("listOfStudents", gson.fromJson(LIST_OF_STUDENTS_JSON, Config.class));

        simpleMaleStudentEntity = new GenericEntity();
        simpleMaleStudentEntity.put("id", "1");
        simpleMaleStudentEntity.put("gender", "male");
        simpleMaleStudentEntity.put("gradeNumeric", 5);
        simpleFemaleStudentEntity = new GenericEntity();
        simpleFemaleStudentEntity.put("id", "2");
        simpleFemaleStudentEntity.put("gender", "female");
        simpleFemaleStudentEntity.put("gradeNumeric", 7);

        simpleNoGenderInfoStudentEntity = new GenericEntity();
        simpleNoGenderInfoStudentEntity.put("id", "3");
        simpleNoGenderInfoStudentEntity.put("gradeNumeric", 7);

        simpleCacheData = new GenericEntity();
        simpleCacheData.put("id", "testEntityKey");
        simpleCacheData.put("data", "testData1");

        sampleEntityMap = new HashMap<String, GenericEntity>();
        sampleEntityMap.put(simpleMaleStudentEntity.getString("id"), simpleMaleStudentEntity);
        sampleEntityMap.put(simpleFemaleStudentEntity.getString("id"), simpleFemaleStudentEntity);
        sampleEntityMap.put(simpleNoGenderInfoStudentEntity.getString("id"), simpleNoGenderInfoStudentEntity);
        sampleEntityMap.put(simpleCacheData.getString("id"), simpleCacheData);
        sampleEntityMap.put("section", JsonConverter.fromJson(SECTION_ENTITY, GenericEntity.class));
        sampleEntityMap.put("listOfStudents", JsonConverter.fromJson(LIST_OF_STUDENTS_ENTITY, GenericEntity.class));
    }

    @Before
    public void setup() {
        customizationAssemblyFactory.setApplicationContext(applicationContext);
    }

    /**
     * Test entity reference map contains student mapping
     */
    @Test
    public void testEntityReferenceMap() {
        Assert.assertTrue("Student entity reference must exists",
                customizationAssemblyFactory.hasCachedEntityMapperReference("student"));
        Assert.assertTrue(customizationAssemblyFactory.hasInvokableSet("student"));
    }

    /**
     * Test simple layout contains expected number of configs
     */
    @Test
    public void testSimpleLayout() {
        ModelAndViewConfig viewAndConfig = customizationAssemblyFactory.getModelAndViewConfig("studentProfile",
                simpleMaleStudentEntity.get("id"));

        Assert.assertEquals(3, viewAndConfig.getConfig().size());
    }

    /**
     * Test conditional layout contains different number of items depending on entity
     */
    @Test
    public void testConditionalLayout() {
        ModelAndViewConfig viewAndConfig = customizationAssemblyFactory.getModelAndViewConfig("studentProfile",
                simpleMaleStudentEntity.get("id"));

        Assert.assertEquals(3, viewAndConfig.getConfig().size());
        viewAndConfig = customizationAssemblyFactory.getModelAndViewConfig("studentProfile",
                simpleFemaleStudentEntity.get("id"));
        Assert.assertEquals(1, viewAndConfig.getConfig().size());
    }

    /**
     * Test not to allow infinite recursion
     */
    @Test
    public void testConfigTooDeep() {
        try {
            customizationAssemblyFactory.getModelAndViewConfig("deep", simpleMaleStudentEntity.get("id"));
            Assert.fail("Should not allow deep config structures");
        } catch (Throwable t) {
            Assert.assertEquals("The items hierarchy is too deep - only allow 5 elements", t.getMessage());
        }
    }

    /**
     * Test data domain condition
     */
    @Test
    public void testCondition() {
        Config panel = configMap.get("panel");
        Assert.assertTrue("Must be true for a student with gender = 'male'",
                customizationAssemblyFactory.checkCondition(panel, panel, simpleMaleStudentEntity));
        Assert.assertFalse("Must be true for a student with gender = 'male'",
                customizationAssemblyFactory.checkCondition(panel, panel, simpleFemaleStudentEntity));

        Assert.assertFalse("Must be false for a student with no gender field available",
                customizationAssemblyFactory.checkCondition(panel, panel, simpleNoGenderInfoStudentEntity));

        panel = configMap.get("panel1");
        Assert.assertTrue("Must be true for a student with gradeNumeric = 5",
                customizationAssemblyFactory.checkCondition(panel, panel, simpleMaleStudentEntity));
        Assert.assertFalse("Must be false for a student with gradeNumeric = 7",
                customizationAssemblyFactory.checkCondition(panel, panel, simpleFemaleStudentEntity));

    }

    /**
     * Test not to allow bad signature entity references
     */
    @Test
    public void testBadEntityReference() {
        ApplicationContext badContext = new AnnotationConfigApplicationContext(
                new Class<?>[] { ContextConfigurationWithBadEntityRefSignature.class });
        try {
            customizationAssemblyFactory.setApplicationContext(badContext);
            Assert.fail("Should not allow testBad - bad signature");
        } catch (DashboardException de) {
            Assert.assertEquals("Wrong signature for the method for testBad. Expected is "
                    + Arrays.asList(CustomizationAssemblyFactoryImpl.ENTITY_REFERENCE_METHOD_EXPECTED_SIGNATURE)
                    + "!!!", de.getMessage());

        }

        badContext = new AnnotationConfigApplicationContext(
                new Class<?>[] { ContextConfigurationWithDuplicates.class });
        try {
            customizationAssemblyFactory.setApplicationContext(badContext);
            Assert.fail("Should not allow testBad - duplicate entity reference");
        } catch (DashboardException de) {
            Assert.assertEquals("Duplicate entity mapping references found for test. Fix!!!", de.getMessage());

        }
    }

    /**
     * Test getting a component for a test
     */
    @Test
    public void testDataComponent() {
        ApplicationContext goodContext = new AnnotationConfigApplicationContext(
                new Class<?>[] { ContextConfigurationWithGoodMananger.class });
        customizationAssemblyFactory.setApplicationContext(goodContext);
        // test good one
        Assert.assertEquals(simpleMaleStudentEntity, customizationAssemblyFactory.getDataComponentForTest("panel",
                "1", configMap.get("panel").getData()));
        // test an entity mapping that throws an exception
        Assert.assertNull(customizationAssemblyFactory.getDataComponentForTest("panelException", "1",
                configMap.get("panelException").getData()));

        // test non-existent one
        Config.Data fakeDataConfig = new Config.Data("fake", "fake", false, null);
        Assert.assertNotNull(fakeDataConfig);
        try {
            customizationAssemblyFactory.getDataComponentForTest("panel", "1", fakeDataConfig);
            Assert.fail("Must not be able to find fake entity reference and throw an exception");
        } catch (DashboardException de) {
            Assert.assertEquals(
                    "No entity mapping references found for " + fakeDataConfig.getEntityRef() + ". Fix!!!",
                    de.getMessage());
        }
    }

    @Test
    public void testDynamicHeaders() {
        Config panel = configMap.get("dynamicHeaders");
        GenericEntity meta = new GenericEntity();
        meta.put("id", "Funky ID");
        GenericEntity name = new GenericEntity();
        name.put("first", "AAA");
        meta.put("name", name);
        GenericEntity entity = new GenericEntity();
        entity.put("meta", meta);
        Config.Item[] items = customizationAssemblyFactory.getUpdatedDynamicHeaderTemplate(panel, entity);
        Assert.assertEquals("AAA", items[0].getName());
        Assert.assertEquals("Funky ID", items[1].getName());
    }

    @Test
    public void testCache() {
        ApplicationContext goodContext = new AnnotationConfigApplicationContext(
                new Class<?>[] { ContextConfigurationWithGoodMananger.class });
        customizationAssemblyFactory.setApplicationContext(goodContext);
        ModelAndViewConfig modelAndViewConfig = customizationAssemblyFactory.getModelAndViewConfig("test",
                "section", true);
        Config testConfig = modelAndViewConfig.getConfig().get("test");
        Assert.assertEquals("section", testConfig.getId());
        Assert.assertEquals("section", testConfig.getParentId());
        Assert.assertEquals("SLC - Section Profile", testConfig.getName());
        Assert.assertEquals("LAYOUT", testConfig.getType().toString());
        Item[] items = testConfig.getItems();
        Assert.assertEquals(2, items.length);
        Assert.assertEquals("tab3", items[0].getId());
        Assert.assertEquals("List of Students", items[0].getName());
        Item[] itemA = items[0].getItems();
        Assert.assertEquals(1, itemA.length);
        Assert.assertEquals("listOfStudents", itemA[0].getId());
        Item[] itemAA = itemA[0].getItems();
        Assert.assertEquals(1, itemAA.length);
        Assert.assertEquals("Default View", itemAA[0].getName());
        Item[] itemAAA = itemAA[0].getItems();
        Assert.assertEquals(5, itemAAA.length);
        Assert.assertEquals("Student", itemAAA[0].getName());
        Assert.assertEquals("", itemAAA[1].getName());
        Assert.assertEquals("Grade", itemAAA[2].getName());
        Assert.assertEquals("Absence Count", itemAAA[3].getName());
        Assert.assertEquals("Tardy Count", itemAAA[4].getName());

        Assert.assertEquals("tab4", items[1].getId());
        Assert.assertEquals("LOS", items[1].getName());
        Item[] itemB = items[1].getItems();
        Assert.assertEquals(1, itemB.length);
        Assert.assertEquals("listOfStudents", itemB[0].getId());
        Item[] itemBA = itemB[0].getItems();
        Assert.assertEquals(1, itemBA.length);
        Assert.assertEquals("Default View", itemBA[0].getName());
        Item[] itemBAA = itemBA[0].getItems();
        Assert.assertEquals(5, itemBAA.length);
        Assert.assertEquals("Student", itemBAA[0].getName());
        Assert.assertEquals("", itemBAA[1].getName());
        Assert.assertEquals("Grade", itemBAA[2].getName());
        Assert.assertEquals("Absence Count", itemBAA[3].getName());
        Assert.assertEquals("Tardy Count", itemBAA[4].getName());
    }
}