/** * 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; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.Collection; import java.util.Locale; import org.junit.Assert; import org.junit.Test; import org.openmrs.test.Verifies; /** * Behavior-driven tests of the Concept class. */ public class ConceptTest { /** * The concept should provide a short name even if no names are tagged as short. <br/> * <br/> * precondition: no short names in mock concept * * @see {@link Concept#getBestShortName(Locale)} */ @Test @Verifies(value = "should always return a short name even if no names are tagged as short", method = "getBestShortName(Locale)") public void getBestShortName_shouldAlwaysReturnAShortNameEvenIfNoNamesAreTaggedAsShort() throws Exception { Locale primaryLocale = Locale.US; Concept testConcept = createMockConcept(1, primaryLocale); ConceptName shortName = testConcept.getBestShortName(primaryLocale); assertFalse(shortName.isShort()); // precondition: no shorts available assertNotNull(shortName); } /** * The concept should provide the preferred concept name for a locale when more than one name is * available. * * @see {@link Concept#getName(Locale)} */ @Test @Verifies(value = "should get preferred fully specified country", method = "getName(Locale)") public void getName_shouldGetPreferredFullySpecifiedCountry() throws Exception { Locale primaryLocale = Locale.US; Concept testConcept = createMockConcept(1, primaryLocale); ConceptName preferredName = testConcept.getName(primaryLocale); assertTrue(preferredName.isPreferredInCountry(primaryLocale.getCountry())); } /** * When asked for a collection of compatible names, the returned collection should not include * any incompatible names. * * @see {@link Concept#getCompatibleNames(Locale)} */ @Test @Verifies(value = "should exclude incompatible country locales", method = "getCompatibleNames(Locale)") public void getCompatibleNames_shouldExcludeIncompatibleCountryLocales() throws Exception { Locale primaryLocale = Locale.US; Concept testConcept = createMockConcept(1, primaryLocale); // concept should only have US and generic english names. // add an incompatible name -- en_UK int initialNameCollectionSize = testConcept.getNames().size(); ConceptName name_en_UK = ConceptNameTest.createMockConceptName(initialNameCollectionSize + 1, Locale.UK); testConcept.addName(name_en_UK); Collection<ConceptName> compatibleNames = testConcept.getCompatibleNames(primaryLocale); assertFalse(compatibleNames.contains(name_en_UK)); } /** * When asked for a collection of compatible names, the returned collection should not include * any incompatible names. * * @see {@link Concept#getCompatibleNames(Locale)} */ @Test @Verifies(value = "should exclude incompatible language locales", method = "getCompatibleNames(Locale)") public void getCompatibleNames_shouldExcludeIncompatibleLanguageLocales() throws Exception { Concept concept = new Concept(); concept.addName(new ConceptName("some name", new Locale("fr"))); Assert.assertEquals(0, concept.getCompatibleNames(new Locale("en")).size()); } /** * The Concept should change the tagging of concept-names to enforce the rule that only one may * be marked as preferred for a locale. * * @see {@link Concept#setPreferredName(Locale,ConceptName)} */ @Test @Verifies(value = "should only allow one preferred name", method = "setPreferredName(Locale,ConceptName)") public void setPreferredName_shouldOnlyAllowOnePreferredName() throws Exception { Locale primaryLocale = Locale.US; Concept testConcept = createMockConcept(1, primaryLocale); ConceptNameTag preferredTag = ConceptNameTag.preferredCountryTagFor(primaryLocale); ConceptName initialPreferred = testConcept.getPreferredName(primaryLocale); ConceptName expectedPreferred = ConceptNameTest.createMockConceptName(initialPreferred.getConceptNameId() + 10, primaryLocale); testConcept.setPreferredName(primaryLocale, expectedPreferred); ConceptName actualPreferred = testConcept.getPreferredName(primaryLocale); assertNotSame(initialPreferred, actualPreferred); assertSame(expectedPreferred, actualPreferred); assertFalse(initialPreferred.hasTag(preferredTag)); assertTrue(expectedPreferred.hasTag(preferredTag)); } /** * When there is a preferred name for a locale, it should also be the "best" name for that * locale. * * @see {@link Concept#getPreferredName(Locale)} */ @Test @Verifies(value = "should match to best name", method = "getPreferredName(Locale)") public void getPreferredName_shouldMatchToBestName() throws Exception { Locale primaryLocale = Locale.US; Concept testConcept = createMockConcept(1, primaryLocale); ConceptName preferredName = testConcept.getPreferredName(primaryLocale); ConceptName bestName = testConcept.getBestName(primaryLocale); assertSame(preferredName, bestName); } /** * The concept should always provide a "best" name even if there are no names available for the * requested locale. * * @see {@link Concept#getBestName(Locale)} */ @Test @Verifies(value = "should always have a best name even if none match locale", method = "getBestName(Locale)") public void getBestName_shouldAlwaysHaveABestNameEvenIfNoneMatchLocale() throws Exception { Locale primaryLocale = Locale.US; Concept testConcept = createMockConcept(1, primaryLocale); ConceptName bestNameForNonExistentLocale = testConcept.getBestName(Locale.JAPAN); assertNotNull(bestNameForNonExistentLocale); assertFalse(Locale.JAPAN.equals(bestNameForNonExistentLocale.getLocale())); } /** * The deprecated getName(Locale) should support getting a name that is only tagged as * "preferred" -- with no language or country indicated -- even when searching for a specific * language_country locale. * * @see {@link Concept#getName(Locale,null)} */ @Test @Verifies(value = "should support plain preferred", method = "getName(Locale,null)") public void getName_shouldSupportPlainPreferred() throws Exception { Locale testLocale = Locale.ENGLISH; Concept testConcept = new Concept(); testConcept.setConceptId(1); ConceptName preferredName = ConceptNameTest.createMockConceptName(1, testLocale); preferredName.addTag(ConceptNameTag.PREFERRED); testConcept.addName(preferredName); ConceptName shortName = ConceptNameTest.createMockConceptName(2, testLocale); shortName.addTag(ConceptNameTag.SHORT); testConcept.addName(shortName); ConceptName actualName = testConcept.getName(Locale.US); assertEquals(preferredName, actualName); } /** * getPreferredName(Locale) should support getting a name that is only tagged as "preferred" -- * with no language or country indicated -- even when searching for a specific language_country * locale. * * @see {@link Concept#getPreferredName(Locale)} */ @Test @Verifies(value = "should support plain preferred", method = "getPreferredName(Locale)") public void getPreferredName_shouldSupportPlainPreferred() throws Exception { Locale testLocale = Locale.ENGLISH; Concept testConcept = new Concept(); testConcept.setConceptId(1); ConceptName preferredName = ConceptNameTest.createMockConceptName(1, testLocale); preferredName.addTag(ConceptNameTag.PREFERRED); testConcept.addName(preferredName); ConceptName shortName = ConceptNameTest.createMockConceptName(2, testLocale); shortName.addTag(ConceptNameTag.SHORT); testConcept.addName(shortName); ConceptName actualName = testConcept.getPreferredName(Locale.US); assertEquals(preferredName, actualName); } /** * getBestName(Locale) should support getting a name that is only tagged as "preferred" -- with * no language or country indicated -- even when searching for a specific language_country * locale. * * @see {@link Concept#getBestName(Locale)} */ @Test @Verifies(value = "should support plain preferred", method = "getBestName(Locale)") public void getBestName_shouldSupportPlainPreferred() throws Exception { Locale testLocale = Locale.ENGLISH; Concept testConcept = new Concept(); testConcept.setConceptId(1); ConceptName preferredName = ConceptNameTest.createMockConceptName(1, testLocale); preferredName.addTag(ConceptNameTag.PREFERRED); testConcept.addName(preferredName); ConceptName shortName = ConceptNameTest.createMockConceptName(2, testLocale); shortName.addTag(ConceptNameTag.SHORT); testConcept.addName(shortName); ConceptName actualName = testConcept.getBestName(Locale.US); assertEquals(preferredName, actualName); } /** * Convenient factory method to create a populated Concept. * * @return */ public static Concept createMockConcept(int conceptId, Locale primaryLocale) { Concept mockConcept = new Concept(); mockConcept.setConceptId(conceptId); ConceptName primaryName = ConceptNameTest.createMockConceptName(1, primaryLocale); mockConcept.setPreferredName(primaryLocale, primaryName); Locale generalLocale = new Locale(primaryLocale.getLanguage()); ConceptName generalName = ConceptNameTest.createMockConceptName(2, generalLocale); mockConcept.addName(generalName); return mockConcept; } /** * @see {@link Concept#getDescription(Locale,null)} */ @Test @Verifies(value = "should not return language only match for exact matches", method = "getDescription(Locale,boolean)") public void getDescription_shouldNotReturnLanguageOnlyMatchForExactMatches() throws Exception { Concept mockConcept = new Concept(); mockConcept.addDescription(new ConceptDescription("en desc", new Locale("en"))); Assert.assertNull(mockConcept.getDescription(new Locale("en", "US"), true)); } /** * @see {@link Concept#getDescription(Locale,null)} */ @Test @Verifies(value = "should not return match on language only if exact match exists", method = "getDescription(Locale,boolean)") public void getDescription_shouldNotReturnMatchOnLanguageOnlyIfExactMatchExists() throws Exception { Concept mockConcept = new Concept(); mockConcept.addDescription(new ConceptDescription("en desc", new Locale("en"))); mockConcept.addDescription(new ConceptDescription("en_US desc", new Locale("en", "US"))); Concept mockConcept2 = new Concept(); mockConcept2.addDescription(new ConceptDescription("en_US desc", new Locale("en", "US"))); mockConcept2.addDescription(new ConceptDescription("en desc", new Locale("en"))); Assert.assertEquals("en_US desc", mockConcept.getDescription(new Locale("en", "US"), false).getDescription()); Assert.assertEquals("en_US desc", mockConcept2.getDescription(new Locale("en", "US"), false).getDescription()); } /** * @see {@link Concept#getDescription(Locale,null)} */ @Test @Verifies(value = "should return match on language only", method = "getDescription(Locale,boolean)") public void getDescription_shouldReturnMatchOnLanguageOnly() throws Exception { Concept mockConcept = new Concept(); mockConcept.addDescription(new ConceptDescription("en desc", new Locale("en"))); Assert.assertEquals("en desc", mockConcept.getDescription(new Locale("en", "US"), false).getDescription()); } /** * @see {@link Concept#getDescription(Locale,null)} */ @Test @Verifies(value = "should return match on locale exactly", method = "getDescription(Locale,boolean)") public void getDescription_shouldReturnMatchOnLocaleExactly() throws Exception { Concept mockConcept = new Concept(); mockConcept.addDescription(new ConceptDescription("en_US desc", new Locale("en", "US"))); Assert.assertEquals("en_US desc", mockConcept.getDescription(new Locale("en", "US"), false).getDescription()); } /** * @see {@link Concept#getName(Locale,null)} */ @Test @Verifies(value = "should not fail if no names are defined", method = "getName(Locale,null)") public void getName_shouldNotFailIfNoNamesAreDefined() throws Exception { Concept concept = new Concept(); Assert.assertNull(concept.getName(new Locale("en"), false)); Assert.assertNull(concept.getName(new Locale("en"), true)); } /** * @see {@link Concept#getName(Locale,null)} */ @Test @Verifies(value = "should return any name if no locale match given exact equals false", method = "getName(Locale,null)") public void getName_shouldReturnAnyNameIfNoLocaleMatchGivenExactEqualsFalse() throws Exception { Locale definedNameLocale = new Locale("en", "US"); Locale localeToSearch = new Locale("fr"); Concept concept = new Concept(); concept.addName(new ConceptName("some name", definedNameLocale)); Assert.assertEquals("some name", concept.getName(localeToSearch, false).getName()); } /** * @see {@link Concept#getName(Locale,null)} */ @Test @Verifies(value = "should return exact name locale match given exact equals true", method = "getName(Locale,null)") public void getName_shouldReturnExactNameLocaleMatchGivenExactEqualsTrue() throws Exception { Locale definedNameLocale = new Locale("en", "US"); Locale localeToSearch = new Locale("en", "US"); Concept concept = new Concept(); concept.addName(new ConceptName("some name", definedNameLocale)); Assert.assertNull(concept.getName(localeToSearch, true)); } /** * @see {@link Concept#getName(Locale,null)} */ @Test @Verifies(value = "should return loose match given exact equals false", method = "getName(Locale,null)") public void getName_shouldReturnLooseMatchGivenExactEqualsFalse() throws Exception { Locale localeToSearch = new Locale("en", "US"); Locale definedNameLocale = new Locale("en"); Concept concept = new Concept(); concept.addName(new ConceptName("some name", definedNameLocale)); Assert.assertEquals("some name", concept.getName(localeToSearch, false).getName()); definedNameLocale = new Locale("en", "US"); localeToSearch = new Locale("en"); concept = new Concept(); concept.addName(new ConceptName("some name", definedNameLocale)); Assert.assertEquals("some name", concept.getName(localeToSearch, false).getName()); } /** * @see {@link Concept#getName(Locale,null)} */ @Test @Verifies(value = "should return null if no locale match and exact equals true", method = "getName(Locale,null)") public void getName_shouldReturnNullIfNoLocaleMatchAndExactEqualsTrue() throws Exception { Locale nonMatchingNameLocale = new Locale("en", "US"); Locale localeToSearch = new Locale("en"); Concept concept = new Concept(); concept.addName(new ConceptName("some name", nonMatchingNameLocale)); Assert.assertNull(concept.getName(localeToSearch, true)); } /** * @see {@link Concept#getNames(Boolean)} */ @Test @Verifies(value = "should not fail if getName(boolean) is only finding voided conceptNames when true", method = "getName(Boolean)") public void getNamesBoolean_shouldNotReturnVoidedConceptName() throws Exception { Locale localeToSearch = new Locale("en"); Concept concept = new Concept(); ConceptName conceptName = new ConceptName("some name", localeToSearch); conceptName.setVoided(true); concept.addName(conceptName); Collection<ConceptName> cns = concept.getNames(false); Assert.assertNotNull(cns); Assert.assertEquals(cns.size(), 0); cns = concept.getNames(true); Assert.assertEquals(cns.size(), 1); } /** * @see {@link Concept#getNames()} */ @Test @Verifies(value = "should not fail if getNames() is correctly calling getNames(false)", method = "getNames()") public void getNames_shouldNotReturnVoidedConceptName() throws Exception { Locale localeToSearch = new Locale("en"); Concept concept = new Concept(); ConceptName conceptName = new ConceptName("some name", localeToSearch); conceptName.setVoided(true); concept.addName(conceptName); Collection<ConceptName> cns = concept.getNames(); Assert.assertNotNull(cns); Assert.assertEquals(cns.size(), 0); } /** * @see {@link Concept#getBestName(Locale)} */ @Test @Verifies(value = "getBestName should not return voided conceptName, should return non-voided concept in other locale ", method = "getBestName(Locale)") public void getBestName_shouldReturnNonVoidedConceptName() throws Exception { Locale localeToSearch = new Locale("en"); Locale nonMatchingNameLocale = new Locale("fr"); Concept concept = new Concept(); ConceptName conceptName = new ConceptName("some name", localeToSearch); conceptName.setVoided(true); concept.addName(conceptName); ConceptName conceptNameOther = new ConceptName("some other name", nonMatchingNameLocale); concept.addName(conceptNameOther); ConceptName cn = concept.getBestName(localeToSearch); Assert.assertEquals(cn.getLocale(), nonMatchingNameLocale); Assert.assertEquals(cn.getName(), "some other name"); } /** * @see {@link Concept#getBestShortName(Locale)} */ @Test @Verifies(value = "getBestShortName should not return voided conceptName, should return non-voided concept in other locale even if not short", method = "getBestShortName(Locale)") public void getBestShortName_shouldReturnNonVoidedConceptName() throws Exception { Locale localeToSearch = new Locale("en"); Locale nonMatchingNameLocale = new Locale("fr"); Concept concept = new Concept(); ConceptName conceptName = new ConceptName("some name", localeToSearch); conceptName.setVoided(true); concept.setShortName(localeToSearch, conceptName); ConceptName conceptNameOther = new ConceptName("some other name", nonMatchingNameLocale); concept.addName(conceptNameOther); ConceptName cn = concept.getBestShortName(localeToSearch); Assert.assertEquals(cn.getLocale(), nonMatchingNameLocale); Assert.assertEquals(cn.getName(), "some other name"); } /** * @see {@link Concept#getNames(Locale)} */ @Test @Verifies(value = "getName(Locale) should not return voided conceptName, should return non-voided concept in other locale even if not short", method = "getName(Locale)") public void getNamesLocale_shouldReturnNonVoidedConceptName() throws Exception { Locale localeToSearch = new Locale("en"); Concept concept = new Concept(); ConceptName conceptName = new ConceptName("some name", localeToSearch); conceptName.setVoided(true); concept.addName(conceptName); Collection<ConceptName> cns = concept.getNames(localeToSearch); Assert.assertEquals(cns.size(), 0); } /** * @see {@link Concept#getNames(Locale)} */ @Test @Verifies(value = "getNames(Locale) should return an empty Collection if no concept names", method = "getBestName(Locale)") public void getNamesLocale_shouldReturnEmptyCollection() throws Exception { Locale localeToSearch = new Locale("en"); Concept concept = new Concept(); Collection<ConceptName> cns = concept.getNames(localeToSearch); Assert.assertEquals(cns.size(), 0); } /** * @see {@link Concept#getBestName(Locale)} */ @Test @Verifies(value = "getBestName should return null if no concept names", method = "getBestName(Locale)") public void getBestNameLocale_shouldReturnNull() throws Exception { Locale localeToSearch = new Locale("en"); Concept concept = new Concept(); ConceptName conceptName = concept.getBestName(localeToSearch); Assert.assertNull(conceptName); } /** * @see {@link Concept#equals(Object)} */ @Test @Verifies(value = "should confirm two new concept objects are equal", method = "equals(Object)") public void equals_shouldConfirmTwoNewConceptObjectsAreEqual() throws Exception { Concept concept = new Concept(); // an object with a null concept id Assert.assertTrue(concept.equals(concept)); } /** * @see {@link Concept#equals(Object)} */ @Test @Verifies(value = "should not fail if concept id is null", method = "equals(Object)") public void equals_shouldNotFailIfConceptIdIsNull() throws Exception { Concept left = new Concept(); // a null concept id Concept right = new Concept(1); // a non-null concept id Assert.assertFalse(left.equals(right)); } /** * @see {@link Concept#equals(Object)} */ @Test @Verifies(value = "should not fail if given obj has null conceptid", method = "equals(Object)") public void equals_shouldNotFailIfGivenObjHasNullConceptid() throws Exception { Concept left = new Concept(1); // a non-null concept id Concept right = new Concept(); // a null concept id Assert.assertFalse(left.equals(right)); } /** * @see {@link Concept#equals(Object)} */ @Test @Verifies(value = "should not fail if given obj is null", method = "equals(Object)") public void equals_shouldNotFailIfGivenObjIsNull() throws Exception { Concept left = new Concept(1); // a non-null concept id Assert.assertFalse(left.equals(null)); } /** * @see {@link Concept#addAnswer(ConceptAnswer)} */ @Test @Verifies(value = "should not fail if answers list is null", method = "addAnswer(ConceptAnswer)") public void addAnswer_shouldNotFailIfAnswersListIsNull() throws Exception { ConceptAnswer ca = new ConceptAnswer(123); Concept c = new Concept(); c.setAnswers(null); // make sure the list is null c.addAnswer(ca); } /** * @see {@link Concept#equals(Object)} */ @Test @Verifies(value = "should confirm two new different concepts are not equal when their ConceptId are null", method = "equals(Object)") public void equals_shouldConfirmTwoNewDifferentConceptsAreNotEqualWhenTheirConceptIdAreNull() throws Exception { Concept one = new Concept(); Concept two = new Concept(); Assert.assertFalse(one.equals(two)); } }