/** * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package org.openmrs.module.webservices.rest.web.v1_0.controller.openmrs1_9; import org.apache.commons.beanutils.PropertyUtils; import org.hamcrest.CoreMatchers; import org.hamcrest.FeatureMatcher; import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.openmrs.Concept; import org.openmrs.ConceptAnswer; import org.openmrs.ConceptMap; import org.openmrs.ConceptName; import org.openmrs.ConceptReferenceTerm; import org.openmrs.ConceptSet; import org.openmrs.Drug; import org.openmrs.api.APIException; import org.openmrs.api.ConceptNameType; import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.webservices.rest.SimpleObject; import org.openmrs.module.webservices.rest.test.Util; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.RestTestConstants1_8; import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; import org.openmrs.module.webservices.rest.web.response.ConversionException; import org.openmrs.module.webservices.rest.web.response.InvalidSearchException; import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.web.bind.annotation.RequestMethod; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Locale; import java.util.Map; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; /** * Tests functionality of {@link ConceptController}. This does not use @should annotations because * the controller inherits those methods from a subclass */ public class ConceptController1_8Test extends MainResourceControllerTest { private ConceptService service; @Before public void before() { this.service = Context.getConceptService(); } @Test public void shouldGetAConceptByUuid() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/15f83cd6-64e9-4e06-a5f9-364d3b14a43d"); SimpleObject result = deserialize(handle(req)); Util.log("Concept fetched", result); Assert.assertNotNull(result); Assert.assertEquals("15f83cd6-64e9-4e06-a5f9-364d3b14a43d", PropertyUtils.getProperty(result, "uuid")); Assert.assertEquals("ASPIRIN", PropertyUtils.getProperty(PropertyUtils.getProperty(result, "name"), "name")); } @Test public void shouldGetAConceptByUuidInXML() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/15f83cd6-64e9-4e06-a5f9-364d3b14a43d"); req.addHeader("Accept", "application/xml"); MockHttpServletResponse result = handle(req); String xml = result.getContentAsString(); printXML(xml); Assert.assertEquals("15f83cd6-64e9-4e06-a5f9-364d3b14a43d", evaluateXPath(xml, "//uuid")); Assert.assertEquals("ASPIRIN", evaluateXPath(xml, "//name/name")); } @Test public void shouldReturnFullRepXML() throws Exception { MockHttpServletRequest request = newGetRequest(getURI() + "/" + getUuid(), new Parameter( RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL)); request.addHeader("Accept", "application/xml"); MockHttpServletResponse result = handle(request); String xml = result.getContentAsString(); printXML(xml); } @Test(expected = IllegalArgumentException.class) public void shouldFailIfYouTryToSpecifyDefaultRepOnGetConceptByUuid() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/15f83cd6-64e9-4e06-a5f9-364d3b14a43d"); req.setParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_DEFAULT); deserialize(handle(req)); } @Test public void shouldListAllUnRetiredConcepts() throws Exception { int totalCount = service.getAllConcepts(null, true, true).size(); MockHttpServletRequest req = request(RequestMethod.GET, getURI()); SimpleObject result = deserialize(handle(req)); Assert.assertNotNull(result); Assert.assertTrue(totalCount > result.size()); Assert.assertEquals(24, Util.getResultsList(result).size()); // there are 25 concepts and one is retired, so should only get 24 here } @Test public void shouldGetRefRepresentationForGetAllByDefault() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI()); SimpleObject result = deserialize(handle(req)); Object aResult = Util.getResultsList(result).get(0); Assert.assertNull(PropertyUtils.getProperty(aResult, "datatype")); } @Test public void shouldGetSpecifiedRepresentationForGetAll() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI()); req.setParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_DEFAULT); SimpleObject result = deserialize(handle(req)); Object aResult = Util.getResultsList(result).get(0); Assert.assertNotNull(PropertyUtils.getProperty(aResult, "datatype")); } @Test public void shouldCreateAConcept() throws Exception { int originalCount = service.getAllConcepts().size(); String json = "{ \"names\": [{\"name\":\"test concept\", \"locale\":\"en\", \"conceptNameType\":\"" + ConceptNameType.FULLY_SPECIFIED + "\"}], \"datatype\":\"8d4a4c94-c2cc-11de-8d13-0010c6dffd0f\", \"conceptClass\":\"Diagnosis\" }"; MockHttpServletRequest req = request(RequestMethod.POST, getURI()); req.setContent(json.getBytes()); Object newConcept = deserialize(handle(req)); Assert.assertNotNull(PropertyUtils.getProperty(newConcept, "uuid")); Assert.assertEquals(originalCount + 1, service.getAllConcepts().size()); } @Test public void shouldEditFullySpecifiedNameOfAConcept() throws Exception { final String changedName = "TESTING NAME"; String json = "{ \"name\":\"" + changedName + "\" }"; MockHttpServletRequest req = request(RequestMethod.POST, getURI() + "/f923524a-b90c-4870-a948-4125638606fd"); req.setContent(json.getBytes()); handle(req); Concept updated = service.getConceptByUuid("f923524a-b90c-4870-a948-4125638606fd"); Assert.assertNotNull(updated); Assert.assertEquals(changedName, updated.getFullySpecifiedName(Context.getLocale()).getName()); } @Test public void shouldEditAConcept() throws Exception { final String changedVersion = "1.2.3"; String json = "{ \"version\":\"" + changedVersion + "\" }"; MockHttpServletRequest req = request(RequestMethod.POST, getURI() + "/f923524a-b90c-4870-a948-4125638606fd"); req.setContent(json.getBytes()); handle(req); Concept updated = service.getConceptByUuid("f923524a-b90c-4870-a948-4125638606fd"); Assert.assertNotNull(updated); Assert.assertEquals(changedVersion, updated.getVersion()); } @Test public void shouldRetireAConcept() throws Exception { String uuid = "0a9afe04-088b-44ca-9291-0a8c3b5c96fa"; Concept concept = service.getConceptByUuid(uuid); Assert.assertFalse(concept.isRetired()); MockHttpServletRequest req = request(RequestMethod.DELETE, getURI() + "/" + uuid); req.addParameter("!purge", ""); req.addParameter("reason", "really ridiculous random reason"); handle(req); concept = service.getConceptByUuid(uuid); Assert.assertTrue(concept.isRetired()); Assert.assertEquals("really ridiculous random reason", concept.getRetireReason()); } @Test public void shouldPurgeAConcept() throws Exception { int originalCount = service.getAllConcepts().size(); String uuid = "11716f9c-1434-4f8d-b9fc-9aa14c4d6129"; MockHttpServletRequest req = request(RequestMethod.DELETE, getURI() + "/" + uuid); req.addParameter("purge", ""); handle(req); Assert.assertNull(service.getConceptByUuid(uuid)); Assert.assertEquals(originalCount - 1, service.getAllConcepts().size()); } @Test public void shouldReturnTheAuditInfoForTheFullRepresentation() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/0dde1358-7fcf-4341-a330-f119241a46e8"); req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL); SimpleObject result = deserialize(handle(req)); Assert.assertNotNull(result); Assert.assertNotNull(PropertyUtils.getProperty(result, "auditInfo")); } //Custom matcher FeatureMatcher<Object, String> hasUuid(String uuid) { return new FeatureMatcher<Object, String>( CoreMatchers.equalTo(uuid), "uuid", "uuid") { @Override protected String featureValueOf(Object o) { try { return (String) PropertyUtils.getProperty(o, "uuid"); } catch (Exception e) { throw new RuntimeException(e); } } }; } @Test public void shouldSearchAndReturnConceptsThatEqualsToClassAndName() throws Exception { service.updateConceptIndex(service.getConceptByUuid("15f83cd6-64e9-4e06-a5f9-364d3b14a43d")); MockHttpServletRequest req = request(RequestMethod.GET, getURI()); SimpleObject result; List<Object> hits; String conceptClassUuid = "3d065ed4-b0b9-4710-9a17-6d8c4fd259b7"; // DRUG String name = "Aspirin"; //ASPIRIN String searchType = "equals"; req.addParameter("class", conceptClassUuid); req.addParameter("name", name); req.addParameter("searchType", searchType); result = deserialize(handle(req)); hits = result.get("results"); assertThat(hits, contains(hasUuid("15f83cd6-64e9-4e06-a5f9-364d3b14a43d"))); //Should not find it when it has partial name: name = "Asp"; req.setParameter("name", name); result = deserialize(handle(req)); hits = result.get("results"); assertThat(hits, is(empty())); } @Test public void shouldNotReturnAnythingWhenConceptDoesntMatchClass() throws Exception { service.updateConceptIndex(service.getConceptByUuid("a09ab2c5-878e-4905-b25d-5784167d0216")); MockHttpServletRequest req = request(RequestMethod.GET, getURI()); SimpleObject result; List<Object> hits; String conceptClassUuid = "97097dd9-b092-4b68-a2dc-e5e5be961d42"; // TEST String name = "CD4 COU"; //CD4 COUNT String searchType = "fuzzy"; req.addParameter("class", conceptClassUuid); req.addParameter("name", name); req.addParameter("searchType", searchType); result = deserialize(handle(req)); hits = result.get("results"); assertThat(hits, contains(hasUuid("a09ab2c5-878e-4905-b25d-5784167d0216"))); //Should not find it when it has partial name: conceptClassUuid = "3d065ed4-b0b9-4710-9a17-6d8c4fd259b7"; // DRUG req.setParameter("class", conceptClassUuid); result = deserialize(handle(req)); hits = result.get("results"); assertThat(hits, is(empty())); } @Test public void shouldSearchAndReturnConceptsThatContainsNamePartInRequest() throws Exception { service.updateConceptIndex(service.getConceptByUuid("15f83cd6-64e9-4e06-a5f9-364d3b14a43d")); MockHttpServletRequest req = request(RequestMethod.GET, getURI()); SimpleObject result; List<Object> hits; String conceptClassUuid = "3d065ed4-b0b9-4710-9a17-6d8c4fd259b7"; // DRUG String name = "Asp"; //ASPIRIN String searchType = "fuzzy"; req.addParameter("class", conceptClassUuid); req.addParameter("name", name); req.addParameter("searchType", searchType); result = deserialize(handle(req)); hits = result.get("results"); assertThat(hits, contains(hasUuid("15f83cd6-64e9-4e06-a5f9-364d3b14a43d"))); } @Test(expected = IllegalStateException.class) public void shouldThrowExceptionWhenSearchRequiredParametersAreCalledTwice() throws Exception { new SearchQuery.Builder("Some search description").withRequiredParameters("source").withRequiredParameters("name") // <- Exception .withOptionalParameters("code").build(); } @Test(expected = IllegalStateException.class) public void shouldThrowExceptionWhenSearchOptionalParametersAreCalledTwice() throws Exception { new SearchQuery.Builder("Some search description").withRequiredParameters("source").withOptionalParameters("name") // <- Exception .withOptionalParameters("code").build(); } @Test(expected = InvalidSearchException.class) public void shouldThrowExceptionWhenSearchTypeParameterIsInvalid() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI()); SimpleObject result; String conceptClassUuid = "3d065ed4-b0b9-4710-9a17-6d8c4fd259b7"; // DRUG String name = "Aspirin"; //ASPIRIN String searchType = "equalz"; req.addParameter("class", conceptClassUuid); req.addParameter("name", name); req.addParameter("searchType", searchType); result = deserialize(handle(req)); } @Test @Ignore("TRUNK-1956: H2 cannot execute the generated SQL because it requires all fetched columns to be included in the group by clause") public void shouldSearchAndReturnAListOfConceptsMatchingTheQueryString() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI()); req.addParameter("q", "food"); SimpleObject result = deserialize(handle(req)); List<Object> hits = (List<Object>) result.get("results"); Assert.assertEquals(2, hits.size()); Assert.assertEquals("0dde1358-7fcf-4341-a330-f119241a46e8", PropertyUtils.getProperty(hits.get(0), "uuid")); Assert.assertEquals("0f97e14e-cdc2-49ac-9255-b5126f8a5147", PropertyUtils.getProperty(hits.get(1), "uuid")); } @Test @Ignore("TRUNK-1956: H2 cannot execute the generated SQL because it requires all fetched columns to be included in the group by clause") public void doSearch_shouldReturnMembersOfConcept() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI()); String memberOfUuid = "0f97e14e-cdc2-49ac-9255-b5126f8a5147"; // FOOD CONSTRUCT req.addParameter("memberOf", memberOfUuid); req.addParameter("q", "no"); SimpleObject result = deserialize(handle(req)); List<Object> hits = (List<Object>) result.get("results"); Assert.assertEquals(1, hits.size()); Assert.assertEquals("f4d0b584-6ce5-40e2-9ce5-fa7ec07b32b4", PropertyUtils.getProperty(hits.get(0), "uuid")); // FAVORITE FOOD, NON-CODED } @Test @Ignore("TRUNK-1956: H2 cannot execute the generated SQL because it requires all fetched columns to be included in the group by clause") public void doSearch_shouldReturnAnswersToConcept() throws Exception { MockHttpServletRequest req = request(RequestMethod.GET, getURI()); String answerToUuid = "95312123-e0c2-466d-b6b1-cb6e990d0d65"; // FOOD ASSISTANCE FOR ENTIRE FAMILY req.addParameter("answerTo", answerToUuid); req.addParameter("q", "no"); SimpleObject result = deserialize(handle(req)); List<Object> hits = (List<Object>) result.get("results"); Assert.assertEquals(1, hits.size()); Assert.assertEquals("b98a6ed4-77e7-4cee-aae2-81957fcd7f48", PropertyUtils.getProperty(hits.get(0), "uuid")); // NO } /** * {@link ConceptResource1_8#getByUniqueId(String)} * * @throws Exception */ /** * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getURI() */ @Override public String getURI() { return "concept"; } /** * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getUuid() */ @Override public String getUuid() { return RestTestConstants1_8.CONCEPT_UUID; } /** * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getAllCount() */ @Override public long getAllCount() { return 24; } @Test public void shouldAddSetMembersToConcept() throws Exception { MockHttpServletRequest request = request(RequestMethod.POST, getURI() + "/" + getUuid()); String json = "{ \"setMembers\": [\"0dde1358-7fcf-4341-a330-f119241a46e8\", \"54d2dce5-0357-4253-a91a-85ce519137f5\"] }"; request.setContent(json.getBytes()); handle(request); Concept concept = Context.getConceptService().getConceptByUuid(getUuid()); Assert.assertEquals(2, concept.getSetMembers().size()); } @Test public void shouldModifySetMembersOnConcept() throws Exception { MockHttpServletRequest request = request(RequestMethod.POST, getURI() + "/" + getUuid()); String json = "{ \"setMembers\": [\"0dde1358-7fcf-4341-a330-f119241a46e8\", \"54d2dce5-0357-4253-a91a-85ce519137f5\"] }"; request.setContent(json.getBytes()); handle(request); Concept concept = Context.getConceptService().getConceptByUuid(getUuid()); Assert.assertEquals(2, concept.getSetMembers().size()); json = "{ \"setMembers\": [\"0dde1358-7fcf-4341-a330-f119241a46e8\"] }"; request.setContent(json.getBytes()); handle(request); concept = Context.getConceptService().getConceptByUuid(getUuid()); Assert.assertEquals(1, concept.getSetMembers().size()); } @Test public void shouldAddAnswersToConcept() throws Exception { MockHttpServletRequest request = request(RequestMethod.POST, getURI() + "/" + getUuid()); String json = "{ \"answers\": [\"0dde1358-7fcf-4341-a330-f119241a46e8\", \"54d2dce5-0357-4253-a91a-85ce519137f5\", \"05ec820a-d297-44e3-be6e-698531d9dd3f\"] }"; request.setContent(json.getBytes()); handle(request); Concept concept = service.getConceptByUuid(getUuid()); Concept answer1 = service.getConceptByUuid("0dde1358-7fcf-4341-a330-f119241a46e8"); Concept answer2 = service.getConceptByUuid("54d2dce5-0357-4253-a91a-85ce519137f5"); Drug drug = Context.getConceptService().getDrugByUuid("05ec820a-d297-44e3-be6e-698531d9dd3f"); Assert.assertTrue(hasAnswer(concept, answer1)); Assert.assertTrue(hasAnswer(concept, answer2)); Assert.assertTrue(hasAnswer(concept, drug)); } /** * Convenience helper method to look for the given answer amongst the answers on the question * concept * * @param question the concept on which to call getAnswers() * @param answer the concept that is hidden in a ConceptAnswer object on the given concept * (maybe) * @return true if the answer is found on the concept */ private boolean hasAnswer(Concept question, Concept answer) { for (ConceptAnswer conceptAnswerObject : question.getAnswers()) { if (conceptAnswerObject.getAnswerConcept().equals(answer)) return true; } // answer was not found return false; } /** * Convenience helper method to look for the given answer amongst the answers on the question * concept * * @param question the concept on which to call getAnswers() * @param druganswer the drug that is hidden in a ConceptAnswer object on the given concept * (maybe) * @return true if the answer is found on the concept */ private boolean hasAnswer(Concept question, Drug druganswer) { for (ConceptAnswer conceptAnswerObject : question.getAnswers()) { if (conceptAnswerObject.getAnswerDrug() != null && conceptAnswerObject.getAnswerDrug().equals(druganswer)) return true; } // answer was not found return false; } @Test public void shouldRemoveAnswersFromConcept() throws Exception { String conceptWithAnswersUuid = "95312123-e0c2-466d-b6b1-cb6e990d0d65"; String existingAnswerUuid = "b055abd8-a420-4a11-8b98-02ee170a7b54"; String newAnswerUuid = "32d3611a-6699-4d52-823f-b4b788bac3e3"; // sanity check to make sure this concept has the existing answer and not the other Concept concept = Context.getConceptService().getConceptByUuid(conceptWithAnswersUuid); Assert.assertTrue(hasAnswer(concept, service.getConceptByUuid(existingAnswerUuid))); Assert.assertFalse(hasAnswer(concept, service.getConceptByUuid(newAnswerUuid))); Assert.assertEquals(3, concept.getAnswers().size()); MockHttpServletRequest request = request(RequestMethod.POST, getURI() + "/" + conceptWithAnswersUuid); String json = "{ \"answers\": [\"" + existingAnswerUuid + "\", \"" + newAnswerUuid + "\"] }"; request.setContent(json.getBytes()); handle(request); // get the object again so we have the new answers (will this bork hibernate because we fetched it earlier?) concept = Context.getConceptService().getConceptByUuid(conceptWithAnswersUuid); Concept answer1 = service.getConceptByUuid(existingAnswerUuid); Concept answer2 = service.getConceptByUuid(newAnswerUuid); Assert.assertTrue(hasAnswer(concept, answer1)); Assert.assertTrue(hasAnswer(concept, answer2)); Assert.assertEquals(2, concept.getAnswers().size()); } @Test public void shouldSetMappingsOnConcept() throws Exception { //before adding Concept concept = service.getConceptByUuid(getUuid()); assertThat(concept.getConceptMappings().size(), is(0)); //add one mapping MockHttpServletRequest request = request(RequestMethod.POST, getURI() + "/" + getUuid()); ConceptReferenceTerm referenceTerm = service.getAllConceptReferenceTerms().get(0); String mapTypeUuid = service.getDefaultConceptMapType().getUuid(); String json = "{ \"mappings\": [{\"conceptReferenceTerm\":\"" + referenceTerm.getUuid() + "\",\"conceptMapType\":\"" + mapTypeUuid + "\"}]}"; request.setContent(json.getBytes()); handle(request); concept = service.getConceptByUuid(getUuid()); assertThat(concept.getConceptMappings().size(), is(1)); assertThat(concept.getConceptMappings(), hasItem(hasTerm(referenceTerm))); //set mappings to empty MockHttpServletRequest requestEmpty = request(RequestMethod.POST, getURI() + "/" + getUuid()); String jsonEmpty = "{ \"mappings\": []}"; requestEmpty.setContent(jsonEmpty.getBytes()); handle(requestEmpty); assertThat(concept.getConceptMappings().size(), is(0)); } private Matcher<ConceptMap> hasTerm(final ConceptReferenceTerm term) { return new FeatureMatcher<ConceptMap, ConceptReferenceTerm>( equalTo(term), "conceptReferenceTerm", "conceptReferenceTerm") { @Override protected ConceptReferenceTerm featureValueOf(final ConceptMap actual) { return actual.getConceptReferenceTerm(); } }; } @Test public void shouldReturnDefaultAndSelfLinkForCustomUuid() throws Exception { String conceptUuid = "95312123-e0c2-466d-b6b1-cb6e990d0d65"; MockHttpServletRequest request = request(RequestMethod.GET, getURI() + "/" + conceptUuid); request.addParameter("v", "custom:(links)"); MockHttpServletResponse response = handle(request); SimpleObject object = deserialize(response); List<Map<String, String>> data = (List<Map<String, String>>) object.get("links"); Assert.assertThat( data, contains( allOf(hasEntry("rel", "self"), hasEntry("uri", "http://localhost/ws/rest/v1/concept/95312123-e0c2-466d-b6b1-cb6e990d0d65")), allOf(hasEntry("rel", "default"), hasEntry("uri", "http://localhost/ws/rest/v1/concept/95312123-e0c2-466d-b6b1-cb6e990d0d65?v=default")))); } @Test public void shouldReturnCustomRepresentation() throws Exception { String conceptUuid = "95312123-e0c2-466d-b6b1-cb6e990d0d65"; MockHttpServletRequest request = request(RequestMethod.GET, getURI() + "/" + conceptUuid); request.addParameter("v", "custom:(uuid,datatype:(uuid,name),conceptClass,names:ref)"); MockHttpServletResponse response = handle(request); SimpleObject object = deserialize(response); Assert.assertEquals("95312123-e0c2-466d-b6b1-cb6e990d0d65", object.get("uuid")); Assert.assertEquals(4, object.size()); @SuppressWarnings("unchecked") Map<Object, Object> datatype = (Map<Object, Object>) object.get("datatype"); Assert.assertEquals(2, datatype.size()); Assert.assertEquals("8d4a48b6-c2cc-11de-8d13-0010c6dffd0f", datatype.get("uuid")); Assert.assertEquals("Coded", datatype.get("name")); @SuppressWarnings("unchecked") Map<Object, Object> conceptClass = (Map<Object, Object>) object.get("conceptClass"); Assert.assertEquals(7, conceptClass.size()); Assert.assertEquals("a82ef63c-e4e4-48d6-988a-fdd74d7541a7", conceptClass.get("uuid")); Assert.assertEquals("Question", conceptClass.get("display")); Assert.assertEquals("Question", conceptClass.get("name")); Assert.assertEquals("Question (eg, patient history, SF36 items)", conceptClass.get("description")); Assert.assertEquals(false, conceptClass.get("retired")); Assert.assertNotNull(conceptClass.get("links")); Assert.assertNotNull(conceptClass.get("resourceVersion")); @SuppressWarnings("unchecked") List<Object> names = (List<Object>) object.get("names"); Assert.assertEquals(1, names.size()); @SuppressWarnings("unchecked") Map<Object, Object> name = (Map<Object, Object>) names.get(0); Assert.assertEquals(3, name.size()); Assert.assertEquals("325391a8-db12-4e24-863f-5d66f7a4d713", name.get("uuid")); Assert.assertEquals("FOOD ASSISTANCE FOR ENTIRE FAMILY", name.get("display")); Assert.assertNotNull(name.get("links")); } @SuppressWarnings("unchecked") @Test public void shouldIncludeAllUnretiredConceptAnswersForAQuestionConcept() throws Exception { final String conceptUuid = "89ca642a-dab6-4f20-b712-e12ca4fc6d36"; Concept questionConcept = service.getConceptByUuid(conceptUuid); //for the test to stay valid, the sort weights should always be the same(null in this case) for (ConceptAnswer ca : questionConcept.getAnswers(false)) { Assert.assertNull(ca.getSortWeight()); } int expectedAnswerCount = service.getConceptByUuid(conceptUuid).getAnswers(false).size(); MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/" + conceptUuid); SimpleObject result = deserialize(handle(req)); Assert.assertNotNull(result); Assert.assertEquals(expectedAnswerCount, ((List<Object>) PropertyUtils.getProperty(result, "answers")).size()); } @SuppressWarnings("unchecked") @Test public void shouldIncludeAllSetMembersForAConceptSet() throws Exception { final String conceptUuid = "0f97e14e-cdc2-49ac-9255-b5126f8a5147"; Concept parentConcept = service.getConceptByUuid(conceptUuid); //for testing purposes set the same weight for the set members for (ConceptSet conceptSet : parentConcept.getConceptSets()) { conceptSet.setSortWeight(2.0); } service.saveConcept(parentConcept); int expectedMemberCount = service.getConceptByUuid(conceptUuid).getConceptSets().size(); MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/" + conceptUuid); SimpleObject result = deserialize(handle(req)); Assert.assertNotNull(result); Assert.assertEquals(expectedMemberCount, ((List<Object>) PropertyUtils.getProperty(result, "setMembers")).size()); } @Test public void shouldFindConceptsBySourceAndCode() throws Exception { SimpleObject response = deserialize(handle(newGetRequest(getURI(), new Parameter("source", "Some Standardized Terminology"), new Parameter("code", "WGT234")))); List<Object> results = Util.getResultsList(response); assertThat(results.size(), is(1)); Object next = results.iterator().next(); assertThat((String) PropertyUtils.getProperty(next, "uuid"), is("c607c80f-1ea9-4da3-bb88-6276ce8868dd")); } @Test public void shouldFindConceptsBySource() throws Exception { SimpleObject response = deserialize(handle(newGetRequest(getURI(), new Parameter("source", "Some Standardized Terminology")))); List<Object> results = Util.getResultsList(response); assertThat(results.size(), is(6)); } @Test public void shouldFindConceptsBySourceUuid() throws Exception { SimpleObject response = deserialize(handle(newGetRequest(getURI(), new Parameter("source", "00001827-639f-4cb4-961f-1e025bf80000")))); List<Object> results = Util.getResultsList(response); assertThat(results.size(), is(6)); } @Test public void shouldFindConceptsByName() throws Exception { SimpleObject response = deserialize(handle(newGetRequest(getURI(), new Parameter("name", "WEIGHT (KG)")))); List<Object> results = Util.getResultsList(response); Assert.assertEquals(results.size(), 1); Object next = results.iterator().next(); Assert.assertThat((String) PropertyUtils.getProperty(next, "uuid"), is("c607c80f-1ea9-4da3-bb88-6276ce8868dd")); } @Test(expected = APIException.class) public void shouldFailToFetchAConceptByNameIfTheNameIsNeitherPreferredNorFullySpecified() throws Exception { SimpleObject response = deserialize(handle(newGetRequest(getURI(), new Parameter("name", "WT")))); List<Object> results = Util.getResultsList(response); Assert.assertEquals(results.size(), 0); } @Test public void shouldReturnFullSetMembersOnAllLevelsForFullChildren() throws Exception { Concept conceptLevel1 = newConcept("level1"); Concept conceptLevel2 = newConcept("level2"); Concept conceptLevel3 = newConcept("level3"); Concept conceptLevel4 = newConcept("level4"); Concept conceptLevel5 = newConcept("level5"); conceptLevel1.addSetMember(conceptLevel2); conceptLevel2.addSetMember(conceptLevel3); conceptLevel3.addSetMember(conceptLevel4); conceptLevel4.addSetMember(conceptLevel5); service.saveConcept(conceptLevel5); service.saveConcept(conceptLevel4); service.saveConcept(conceptLevel3); service.saveConcept(conceptLevel2); service.saveConcept(conceptLevel1); //should include levels when accessing directly SimpleObject level1 = deserialize(handle(newGetRequest(getURI() + "/" + conceptLevel1.getUuid(), new Parameter("v", "fullchildren")))); assertThatLevelsIncluded(level1, conceptLevel2, conceptLevel3, conceptLevel4, conceptLevel5); //should include levels when searching level1 = deserialize(handle(newGetRequest(getURI(), new Parameter("v", "fullchildren"), new Parameter("name", "level1")))); List<Object> results = Util.getResultsList(level1); assertThatLevelsIncluded((Map<String, Object>) results.get(0), conceptLevel2, conceptLevel3, conceptLevel4, conceptLevel5); } @Test(expected = ConversionException.class) public void shouldFailForFullChildrenWhenCyclesDetected() throws Exception { Concept conceptLevel1 = newConcept("level1"); Concept conceptLevel2 = newConcept("level2"); Concept conceptLevel3 = newConcept("level3"); Concept conceptLevel4 = newConcept("level4"); Concept conceptLevel5 = newConcept("level5"); conceptLevel1.addSetMember(conceptLevel2); conceptLevel2.addSetMember(conceptLevel3); conceptLevel3.addSetMember(conceptLevel4); conceptLevel4.addSetMember(conceptLevel5); service.saveConcept(conceptLevel5); service.saveConcept(conceptLevel4); service.saveConcept(conceptLevel3); service.saveConcept(conceptLevel2); service.saveConcept(conceptLevel1); //Create cycle conceptLevel5.addSetMember(conceptLevel1); service.saveConcept(conceptLevel5); deserialize(handle(newGetRequest(getURI() + "/" + conceptLevel1.getUuid(), new Parameter("v", "fullchildren")))); } private void assertThatLevelsIncluded(Map<String, Object> level1, Concept conceptLevel2, Concept conceptLevel3, Concept conceptLevel4, Concept conceptLevel5) { Map<String, Object> level2 = getFirst(level1.get("setMembers")); assertThat((String) level2.get("uuid"), is(conceptLevel2.getUuid())); assertThat(level2.get("auditInfo"), is(notNullValue())); Map<String, Object> level3 = getFirst(level2.get("setMembers")); assertThat((String) level3.get("uuid"), is(conceptLevel3.getUuid())); assertThat(level3.get("auditInfo"), is(notNullValue())); Map<String, Object> level4 = getFirst(level3.get("setMembers")); assertThat((String) level4.get("uuid"), is(conceptLevel4.getUuid())); assertThat(level4.get("auditInfo"), is(notNullValue())); Map<String, Object> level5 = getFirst(level4.get("setMembers")); assertThat((String) level5.get("uuid"), is(conceptLevel5.getUuid())); assertThat(level5.get("auditInfo"), is(notNullValue())); } private Map<String, Object> getFirst(Object object) { return ((List<Map<String, Object>>) object).get(0); } private Concept newConcept(String name) { Concept concept = new Concept(); concept.addName(new ConceptName(name, Locale.ENGLISH)); return concept; } }