/** * The contents of this file are subject to the OpenMRS Public License * Version 1.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://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.aop; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import org.junit.Assert; import org.junit.Test; import org.openmrs.BaseOpenmrsObject; import org.openmrs.Location; import org.openmrs.OpenmrsObject; import org.openmrs.api.APIException; import org.openmrs.api.impl.ConceptServiceImpl; import org.openmrs.test.Verifies; /** * Tests the {@link RequiredDataAdvice} class. */ public class RequiredDataAdviceTest { /** * Class that extends {@link OpenmrsObject} so can */ private class MiniOpenmrsObject extends BaseOpenmrsObject { private List<Location> locations; public List<Location> getLocations() { return locations; } public void setLocations(List<Location> locs) { this.locations = locs; } public Integer getId() { return null; } public void setId(Integer id) { } } /** * @see {@link RequiredDataAdvice#getChildCollection(OpenmrsObject,Field)} */ @Test @Verifies(value = "should get value of given child collection on given field", method = "getChildCollection(OpenmrsObject,Field)") public void getChildCollection_shouldGetValueOfGivenChildCollectionOnGivenField() throws Exception { MiniOpenmrsObject oo = new MiniOpenmrsObject(); List<Location> locs = new ArrayList<Location>(); locs.add(new Location(1)); oo.setLocations(locs); Collection<OpenmrsObject> fetchedLocations = RequiredDataAdvice.getChildCollection(oo, MiniOpenmrsObject.class .getDeclaredField("locations")); Assert.assertTrue(fetchedLocations.contains(new Location(1))); } /** * @see {@link RequiredDataAdvice#getChildCollection(OpenmrsObject,Field)} */ @Test @Verifies(value = "should be able to get private fields in fieldAccess list", method = "getChildCollection(OpenmrsObject,Field)") public void getChildCollection_shouldBeAbleToGetPrivateFieldsInFieldAccessList() throws Exception { MiniOpenmrsObject oo = new MiniOpenmrsObject(); oo.setLocations(new ArrayList<Location>()); Assert.assertNotNull(RequiredDataAdvice .getChildCollection(oo, MiniOpenmrsObject.class.getDeclaredField("locations"))); } /** * Class that has a mismatched getter name instead of the correct getter name */ private class ClassWithBadGetter extends BaseOpenmrsObject { private Set<Location> locations; public Set<Location> getMyLocations() { return locations; } public void setMyLocations(Set<Location> locs) { this.locations = locs; } public Integer getId() { return null; } public void setId(Integer id) { } } /** * @see {@link RequiredDataAdvice#getChildCollection(OpenmrsObject,Field)} */ @Test(expected = APIException.class) @Verifies(value = "should throw APIException if getter method not found", method = "getChildCollection(OpenmrsObject,Field)") public void getChildCollection_shouldThrowAPIExceptionIfGetterMethodNotFound() throws Exception { ClassWithBadGetter oo = new ClassWithBadGetter(); oo.setMyLocations(new HashSet<Location>()); RequiredDataAdvice.getChildCollection(oo, ClassWithBadGetter.class.getDeclaredField("locations")); } /** * A class that has normal fields and non{@link OpenmrsObject} on it. */ private class ClassWithOtherFields extends BaseOpenmrsObject { private Set<Locale> locales; private List<Map<String, String>> nestedGenericProperty; private Integer id; public List<Map<String, String>> getNestedGenericProperty() { return nestedGenericProperty; } public void setNestedGenericProperty(List<Map<String, String>> nestedGenericProperty) { this.nestedGenericProperty = nestedGenericProperty; } public Set<Locale> getLocales() { return locales; } public void setLocales(Set<Locale> locs) { this.locales = locs; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } } /** * @see {@link RequiredDataAdvice#isOpenmrsObjectCollection(Field)} */ @Test @Verifies(value = "should return false if field is collection of other objects", method = "isOpenmrsObjectCollection(Field)") public void isOpenmrsObjectCollection_shouldReturnFalseIfFieldIsCollectionOfOtherObjects() throws Exception { Assert.assertFalse(RequiredDataAdvice.isOpenmrsObjectCollection(ClassWithOtherFields.class .getDeclaredField("locales"))); } /** * @see {@link RequiredDataAdvice#isOpenmrsObjectCollection(Field)} */ @Test @Verifies(value = "should return false if field is collection of parameterized type", method = "isOpenmrsObjectCollection(Field)") public void isOpenmrsObjectCollection_shouldReturnFalseIfFieldIsCollectionOfParameterizedType() throws Exception { Assert.assertFalse(RequiredDataAdvice.isOpenmrsObjectCollection(ClassWithOtherFields.class .getDeclaredField("nestedGenericProperty"))); } /** * @see {@link RequiredDataAdvice#isOpenmrsObjectCollection(Field)} */ @Test @Verifies(value = "should return false if field is not a collection", method = "isOpenmrsObjectCollection(Field)") public void isOpenmrsObjectCollection_shouldReturnFalseIfFieldIsNotACollection() throws Exception { Assert.assertFalse(RequiredDataAdvice.isOpenmrsObjectCollection(ClassWithOtherFields.class.getDeclaredField("id"))); } /** * @see RequiredDataAdvice#isOpenmrsObjectCollection(Class<*>,Object) */ @Test @Verifies(value = "should return true if class is openmrsObject list", method = "isOpenmrsObjectCollection(Object)") public void isOpenmrsObjectCollection_shouldReturnTrueIfClassIsOpenmrsObjectList() throws Exception { List<Location> locations = new ArrayList<Location>(); Assert.assertTrue(RequiredDataAdvice.isOpenmrsObjectCollection(locations)); } /** * @see RequiredDataAdvice#isOpenmrsObjectCollection(Class<*>,Object) */ @Test @Verifies(value = "should return true if class is openmrsObject set", method = "isOpenmrsObjectCollection(Object)") public void isOpenmrsObjectCollection_shouldReturnTrueIfClassIsOpenmrsObjectSet() throws Exception { Set<Location> locations = new HashSet<Location>(); Assert.assertTrue(RequiredDataAdvice.isOpenmrsObjectCollection(locations)); } /** * @see {@link RequiredDataAdvice#before(Method,null,Object)} */ @Test @Verifies(value = "should not fail on update method with no arguments", method = "before(Method,null,Object)") public void before_shouldNotFailOnUpdateMethodWithNoArguments() throws Throwable { Method method = ConceptServiceImpl.class.getMethod("updateConceptWords", (Class[]) null); new RequiredDataAdvice().before(method, null, new ConceptServiceImpl()); new RequiredDataAdvice().before(method, new Object[] {}, new ConceptServiceImpl()); } }