/* * 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()); } }