diff --git a/api-2.0/src/test/java/org/openmrs/module/attachments/AttachmentsServiceTest.java b/api-2.0/src/test/java/org/openmrs/module/attachments/AttachmentsServiceTest.java index 2ddb8f98..b4beebd6 100644 --- a/api-2.0/src/test/java/org/openmrs/module/attachments/AttachmentsServiceTest.java +++ b/api-2.0/src/test/java/org/openmrs/module/attachments/AttachmentsServiceTest.java @@ -12,6 +12,7 @@ import org.junit.Before; import org.junit.Test; import org.openmrs.Concept; +import org.openmrs.ConceptComplex; import org.openmrs.Encounter; import org.openmrs.Obs; import org.openmrs.Patient; @@ -19,6 +20,7 @@ import org.openmrs.Visit; import org.openmrs.api.APIException; import org.openmrs.module.attachments.obs.Attachment; +import org.openmrs.module.attachments.obs.DefaultAttachmentHandler; import org.openmrs.module.attachments.obs.TestHelper; import org.openmrs.test.BaseModuleContextSensitiveTest; import org.springframework.beans.factory.annotation.Autowired; @@ -305,4 +307,27 @@ public void getAttachments_shouldThrowWhenFetchingNonComplexObs() throws Excepti // as.getAttachments(patient, encounter, true); } + + @Test + public void getAttachments_shouldReturnAttachmentsAssociatedWithSpecifiedConcept() throws Exception { + // + // setup + // + ConceptComplex conceptComplex = testHelper.createConceptComplex("f4fab86d-4a1d-4245-8aa2-19f49b5ab07a", + "Random files", DefaultAttachmentHandler.class.getSimpleName(), "Random binary files"); + Patient patient = ctx.getPatientService().getPatient(2); + Obs obs = testHelper.saveComplexObs(null, conceptComplex, null, 1, 0).get(0); + + // + // replay + // + List attachments = as.getAttachments(patient, conceptComplex); + + // + // verify + // + Assert.assertEquals(1, attachments.size()); + Assert.assertEquals(obs.getUuid(), attachments.get(0).getUuid()); + + } } diff --git a/api/src/main/java/org/openmrs/module/attachments/AttachmentsService.java b/api/src/main/java/org/openmrs/module/attachments/AttachmentsService.java index 77a9620d..b47d8033 100644 --- a/api/src/main/java/org/openmrs/module/attachments/AttachmentsService.java +++ b/api/src/main/java/org/openmrs/module/attachments/AttachmentsService.java @@ -2,6 +2,7 @@ import java.util.List; +import org.openmrs.Concept; import org.openmrs.Encounter; import org.openmrs.Patient; import org.openmrs.Visit; @@ -60,5 +61,13 @@ public interface AttachmentsService { */ List getAttachments(Patient patient, Visit visit, boolean includeVoided); + /** + * Get a patient's attachments that are associated with a specified concept. + * + * @param concept + * @throws APIException if non-complex obs are mistakenly returned + */ + List getAttachments(Patient patient, Concept concept); + Attachment save(Attachment attachment, String reason); } diff --git a/api/src/main/java/org/openmrs/module/attachments/AttachmentsServiceImpl.java b/api/src/main/java/org/openmrs/module/attachments/AttachmentsServiceImpl.java index 975a72e6..9b3d2b47 100644 --- a/api/src/main/java/org/openmrs/module/attachments/AttachmentsServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/attachments/AttachmentsServiceImpl.java @@ -120,6 +120,21 @@ public List getAttachments(Patient patient, final Visit visit, boole return attachments; } + @Override + public List getAttachments(Patient patient, Concept concept) { + List obsList = ctx.getObsService().getObservationsByPersonAndConcept(patient, concept); + List attachments = new ArrayList<>(); + for (Obs obs : obsList) { + if (!obs.isComplex()) { + throw new APIException(NON_COMPLEX_OBS_ERR); + } + obs = getComplexObs(obs); + attachments.add(new Attachment(obs, ctx.getComplexDataHelper())); + } + + return attachments; + } + // Get list of attachment complex concepts protected List getAttachmentConcepts() { List conceptsComplex = ctx.getConceptComplexList(); @@ -161,4 +176,5 @@ private Obs getComplexObs(Obs obs) { String view = ctx.getComplexViewHelper().getView(obs, AttachmentsConstants.ATT_VIEW_THUMBNAIL); return ctx.getObsService().getComplexObs(obs.getId(), view); } + } diff --git a/api/src/main/java/org/openmrs/module/attachments/ComplexObsSaver.java b/api/src/main/java/org/openmrs/module/attachments/ComplexObsSaver.java index a7c11de4..af4605d7 100644 --- a/api/src/main/java/org/openmrs/module/attachments/ComplexObsSaver.java +++ b/api/src/main/java/org/openmrs/module/attachments/ComplexObsSaver.java @@ -9,7 +9,15 @@ */ package org.openmrs.module.attachments; -import net.coobird.thumbnailator.Thumbnails; +import static org.openmrs.module.attachments.AttachmentsConstants.ContentFamily.IMAGE; +import static org.openmrs.module.attachments.AttachmentsConstants.ContentFamily.OTHER; +import static org.openmrs.module.attachments.AttachmentsContext.getCompressionRatio; + +import java.io.IOException; +import java.util.Date; + +import javax.imageio.ImageIO; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.ConceptComplex; @@ -17,19 +25,13 @@ import org.openmrs.Obs; import org.openmrs.Person; import org.openmrs.Visit; -import org.openmrs.module.attachments.AttachmentsConstants.ContentFamily; import org.openmrs.module.attachments.obs.ComplexDataHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -import javax.imageio.ImageIO; - -import static org.openmrs.module.attachments.AttachmentsContext.getCompressionRatio; - -import java.io.IOException; -import java.util.Date; +import net.coobird.thumbnailator.Thumbnails; @Component(AttachmentsConstants.COMPONENT_COMPLEXOBS_SAVER) public class ComplexObsSaver { @@ -48,28 +50,29 @@ public class ComplexObsSaver { @Qualifier(AttachmentsConstants.COMPONENT_VISIT_COMPATIBILITY) protected VisitCompatibility visitCompatibility; - protected Obs obs = new Obs(); - - protected ConceptComplex conceptComplex; - - public Obs getObs() { - return obs; - } - - protected void prepareComplexObs(Visit visit, Person person, Encounter encounter, String fileCaption) { - obs = new Obs(person, conceptComplex, + protected Obs newObs(ConceptComplex conceptComplex, Visit visit, Person person, Encounter encounter, String comment) { + Obs obs = new Obs(person, conceptComplex, visit == null || visit.getStopDatetime() == null ? new Date() : visit.getStopDatetime(), encounter != null ? encounter.getLocation() : null); obs.setEncounter(encounter); // may be null - obs.setComment(fileCaption); + obs.setComment(comment); + return obs; } - public Obs saveImageAttachment(Visit visit, Person person, Encounter encounter, String fileCaption, - MultipartFile multipartFile, String instructions) throws IOException { + public Obs saveImageObs(Visit visit, Person person, Encounter encounter, String comment, MultipartFile multipartFile, + String instructions) throws IOException { + return saveImageObs(visit, person, encounter, context.getConceptComplex(IMAGE), comment, multipartFile, + instructions); + } + + public Obs saveImageObs(Visit visit, Person person, Encounter encounter, ConceptComplex conceptComplex, + String fileCaption, MultipartFile multipartFile, String instructions) throws IOException { - conceptComplex = context.getConceptComplex(ContentFamily.IMAGE); - prepareComplexObs(visit, person, encounter, fileCaption); + if (conceptComplex == null) { + conceptComplex = context.getConceptComplex(IMAGE); + } + Obs obs = newObs(conceptComplex, visit, person, encounter, fileCaption); Object image = multipartFile.getInputStream(); double compressionRatio = getCompressionRatio(multipartFile.getSize(), 1000000 * context.getMaxStorageFileSize()); if (compressionRatio < 1) { @@ -78,18 +81,27 @@ public Obs saveImageAttachment(Visit visit, Person person, Encounter encounter, obs.setComplexData( complexDataHelper.build(instructions, multipartFile.getOriginalFilename(), image, multipartFile.getContentType()) .asComplexData()); - obs = context.getObsService().saveObs(obs, getClass().toString()); - return obs; + + return context.getObsService().saveObs(obs, getClass().toString()); + } + + public Obs saveOtherObs(Visit visit, Person person, Encounter encounter, String comment, MultipartFile multipartFile, + String instructions) throws IOException { + return saveOtherObs(visit, person, encounter, context.getConceptComplex(OTHER), comment, multipartFile, + instructions); } - public Obs saveOtherAttachment(Visit visit, Person person, Encounter encounter, String fileCaption, + public Obs saveOtherObs(Visit visit, Person person, Encounter encounter, ConceptComplex conceptComplex, String comment, MultipartFile multipartFile, String instructions) throws IOException { - conceptComplex = context.getConceptComplex(ContentFamily.OTHER); - prepareComplexObs(visit, person, encounter, fileCaption); + if (conceptComplex == null) { + conceptComplex = context.getConceptComplex(OTHER); + } + + Obs obs = newObs(conceptComplex, visit, person, encounter, comment); obs.setComplexData(complexDataHelper.build(instructions, multipartFile.getOriginalFilename(), multipartFile.getBytes(), multipartFile.getContentType()).asComplexData()); - obs = context.getObsService().saveObs(obs, getClass().toString()); - return obs; + + return context.getObsService().saveObs(obs, getClass().toString()); } } diff --git a/api/src/main/java/org/openmrs/module/attachments/obs/Attachment.java b/api/src/main/java/org/openmrs/module/attachments/obs/Attachment.java index 3fd38d69..1536186c 100644 --- a/api/src/main/java/org/openmrs/module/attachments/obs/Attachment.java +++ b/api/src/main/java/org/openmrs/module/attachments/obs/Attachment.java @@ -30,7 +30,6 @@ public class Attachment extends BaseOpenmrsData implements java.io.Serializable protected ComplexData complexData = null; - public Attachment() { } diff --git a/api/src/test/java/org/openmrs/module/attachments/obs/TestHelper.java b/api/src/test/java/org/openmrs/module/attachments/obs/TestHelper.java index 17053977..59f3a408 100644 --- a/api/src/test/java/org/openmrs/module/attachments/obs/TestHelper.java +++ b/api/src/test/java/org/openmrs/module/attachments/obs/TestHelper.java @@ -1,13 +1,18 @@ package org.openmrs.module.attachments.obs; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Random; +import javax.imageio.ImageIO; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.RandomStringUtils; @@ -23,6 +28,7 @@ import org.openmrs.Patient; import org.openmrs.Provider; import org.openmrs.Visit; +import org.openmrs.api.ConceptService; import org.openmrs.api.EncounterService; import org.openmrs.api.context.Context; import org.openmrs.module.attachments.AttachmentsActivator; @@ -182,7 +188,7 @@ public Obs getTestComplexObs() throws IOException { Encounter encounter = context.getAttachmentEncounter(patient, visit, provider); String fileCaption = RandomStringUtils.randomAlphabetic(12); - return obsSaver.saveOtherAttachment(visit, patient, encounter, fileCaption, getTestDefaultFile(), + return obsSaver.saveOtherObs(visit, patient, encounter, fileCaption, getTestDefaultFile(), ValueComplex.INSTRUCTIONS_DEFAULT); } @@ -207,7 +213,7 @@ public Obs saveImageAttachment(String imagePath, String mimeType) throws IOExcep mimeType, IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream(imagePath))); String fileCaption = RandomStringUtils.randomAlphabetic(12); - return obsSaver.saveImageAttachment(visit, patient, encounter, fileCaption, lastSavedMultipartImageFile, + return obsSaver.saveImageObs(visit, patient, encounter, fileCaption, lastSavedMultipartImageFile, ValueComplex.INSTRUCTIONS_DEFAULT); } @@ -232,7 +238,7 @@ public Obs getTestComplexObsWithoutAssociatedEncounterOrVisit() throws Exception Patient patient = Context.getPatientService().getPatient(2); String fileCaption = RandomStringUtils.randomAlphabetic(12); - return obsSaver.saveOtherAttachment(null, patient, null, fileCaption, getTestDefaultFile(), + return obsSaver.saveOtherObs(null, patient, null, fileCaption, getTestDefaultFile(), ValueComplex.INSTRUCTIONS_DEFAULT); } @@ -257,6 +263,22 @@ public String getTestComplexObsFilePath() { * @return List of saved attachments/complex obs. */ public List saveComplexObs(Encounter encounter, int count, int otherCount) throws IOException { + return saveComplexObs(encounter, null, null, count, otherCount); + } + + /** + * Boilerplate method to save a collection of complex obs based on the encounter. + * + * @param encounter target encounter for save the complex obs. Leave null to save encounter-less + * complex obs. + * @param conceptComplex The concept that will be associated with attachment obs to be saved. + * @param otherConcept The concept that will be associated with other complex obs to be saved. + * @param count The number of the attachments/complex obs to be saved. + * @param otherCount The number of other complex obs to be saved. + * @return List of saved attachments/complex obs. + */ + public List saveComplexObs(Encounter encounter, ConceptComplex conceptComplex, Concept otherConcept, int count, + int otherCount) throws IOException { List obsList = new ArrayList<>(); byte[] randomData = new byte[20]; Patient patient = (encounter == null) ? context.getPatientService().getPatient(2) : encounter.getPatient(); @@ -270,14 +292,14 @@ public List saveComplexObs(Encounter encounter, int count, int otherCount) String filename = RandomStringUtils.randomAlphabetic(7) + ".ext"; MockMultipartFile multipartRandomFile = new MockMultipartFile(FilenameUtils.getBaseName(filename), filename, "application/octet-stream", randomData); - obsList.add(obsSaver.saveOtherAttachment(visit, patient, encounter, fileCaption, multipartRandomFile, + obsList.add(obsSaver.saveOtherObs(visit, patient, encounter, conceptComplex, fileCaption, multipartRandomFile, ValueComplex.INSTRUCTIONS_DEFAULT)); } // Saves a complex obs as if they had been saved outside of Attachments for (int i = 0; i < otherCount; i++) { Obs obs = new Obs(); - obs.setConcept(otherConceptComplex); + obs.setConcept(otherConcept != null ? otherConcept : otherConceptComplex); obs.setObsDatetime(new Date()); obs.setPerson(patient); obs.setEncounter(encounter); @@ -294,4 +316,32 @@ public List saveComplexObs(Encounter encounter, int count, int otherCount) } return obsList; } + + /** + * Convenience method that constructs and saves a ConceptComplex object. + */ + public ConceptComplex createConceptComplex(String uuid, String name, String handler, String description) { + ConceptService conceptService = Context.getConceptService(); + ConceptComplex conceptComplex = new ConceptComplex(); + conceptComplex.setUuid(uuid); + conceptComplex.setHandler(handler); + ConceptName conceptName = new ConceptName(name, Locale.ENGLISH); + conceptComplex.setFullySpecifiedName(conceptName); + conceptComplex.setPreferredName(conceptName); + conceptComplex.setConceptClass(conceptService.getConceptClassByName("Question")); + conceptComplex.setDatatype(conceptService.getConceptDatatypeByUuid(ConceptDatatype.COMPLEX_UUID)); + conceptComplex.addDescription(new ConceptDescription(description, Locale.ENGLISH)); + + return (ConceptComplex) conceptService.saveConcept(conceptComplex); + } + + public static byte[] loadImageResourceToByteArray(ClassLoader loader, String imageName, String contentType) + throws IOException { + InputStream inputStream = loader.getResourceAsStream(imageName); + BufferedImage img = ImageIO.read(inputStream); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(img, contentType, baos); + + return baos.toByteArray(); + } } diff --git a/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java b/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java index 37b4e131..bdaf58b4 100644 --- a/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java +++ b/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java @@ -14,12 +14,15 @@ import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; +import org.openmrs.Concept; +import org.openmrs.ConceptComplex; import org.openmrs.Encounter; import org.openmrs.Obs; import org.openmrs.Patient; import org.openmrs.Provider; import org.openmrs.Visit; import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; import org.openmrs.api.EncounterService; import org.openmrs.api.context.Context; import org.openmrs.module.attachments.AttachmentsConstants; @@ -27,8 +30,6 @@ import org.openmrs.module.attachments.AttachmentsService; import org.openmrs.module.attachments.ComplexObsSaver; import org.openmrs.module.attachments.obs.Attachment; -import org.openmrs.module.attachments.obs.ComplexDataHelper; -import org.openmrs.module.attachments.obs.ComplexDataHelper1_10; import org.openmrs.module.attachments.obs.ValueComplex; import org.openmrs.module.webservices.rest.web.ConversionUtil; import org.openmrs.module.webservices.rest.web.RequestContext; @@ -57,8 +58,8 @@ public class AttachmentResource1_10 extends DataDelegatingCrudResource search(AttachmentsService as, Patient patient, Visit visit, Encounter encounter, - String includeEncounterless, boolean includeVoided) { + String includeEncounterless, Concept concept, boolean includeVoided) { List attachmentList = new ArrayList<>(); @@ -218,10 +235,12 @@ public List search(AttachmentsService as, Patient patient, Visit vis if (visit != null && encounter == null) { attachmentList = as.getAttachments(patient, visit, includeVoided); } - if (encounter == null && visit == null) { + if (encounter == null && visit == null && concept == null) { attachmentList = as.getAttachments(patient, includeVoided); } - + if (concept != null) { + attachmentList = as.getAttachments(patient, concept); + } } return attachmentList; } @@ -245,6 +264,7 @@ protected PageableResult doSearch(RequestContext context) { Encounter encounter = Context.getEncounterService().getEncounterByUuid(context.getParameter("encounter")); String includeEncounterless = context.getParameter("includeEncounterless"); Boolean includeVoided = BooleanUtils.toBoolean(context.getParameter("includeVoided")); + Concept concept = Context.getConceptService().getConceptByUuid(context.getParameter("concept")); // Verify Parameters if (patient == null) { @@ -257,7 +277,7 @@ protected PageableResult doSearch(RequestContext context) { // Search Attachments List attachmentList = search(ctx.getAttachmentsService(), patient, visit, encounter, - includeEncounterless, includeVoided); + includeEncounterless, concept, includeVoided); if (attachmentList != null) { return new NeedsPaging(attachmentList, context); diff --git a/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentResourceTest.java b/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentResourceTest.java index 805c5293..98e185e8 100644 --- a/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentResourceTest.java +++ b/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentResourceTest.java @@ -10,6 +10,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.openmrs.Concept; import org.openmrs.Encounter; import org.openmrs.Patient; import org.openmrs.Visit; @@ -45,7 +46,7 @@ public void search_shouldInvokeApiForEncounterAttachments() { Encounter encounter = new Encounter(); // Replay - res.search(attachmentsService, patient, null, encounter, null, true); + res.search(attachmentsService, patient, null, encounter, null, null, true); // Verify verify(attachmentsService, times(1)).getAttachments(patient, encounter, true); @@ -61,7 +62,7 @@ public void search_shouldInvokeApiForVisitAttachments() { Visit visit = new Visit(); // Replay - res.search(attachmentsService, patient, visit, null, null, true); + res.search(attachmentsService, patient, visit, null, null, null, true); // Verify verify(attachmentsService, times(1)).getAttachments(patient, visit, true); @@ -76,7 +77,7 @@ public void search_shouldInvokeApiForAllAttachments() { Patient patient = new Patient(); // Replay - res.search(attachmentsService, patient, null, null, null, true); + res.search(attachmentsService, patient, null, null, null, null, true); // Verify verify(attachmentsService, times(1)).getAttachments(patient, true); @@ -91,7 +92,7 @@ public void search_shouldInvokeApiForEncounterlessAttachments() { Patient patient = new Patient(); // Replay - res.search(attachmentsService, patient, null, null, "only", true); + res.search(attachmentsService, patient, null, null, "only", null, true); // Verify verify(attachmentsService, times(1)).getEncounterlessAttachments(patient, true); @@ -106,10 +107,26 @@ public void search_shouldInvokeApiForAllAttachmentsButEncounterless() { Patient patient = new Patient(); // Replay - res.search(attachmentsService, patient, null, null, "false", true); + res.search(attachmentsService, patient, null, null, "false", null, true); // Verify verify(attachmentsService, times(1)).getAttachments(patient, false, true); verifyNoMoreInteractions(attachmentsService); } + + @Test + public void search_shouldInvokeApiForConceptAttachments() { + // Setup + AttachmentResource1_10 res = new AttachmentResource1_10(); + AttachmentsService attachmentsService = mock(AttachmentsService.class); + Patient patient = new Patient(); + Concept concept = new Concept(); + + // Replay + res.search(attachmentsService, patient, null, null, null, concept, true); + + // Verify + verify(attachmentsService, times(1)).getAttachments(patient, concept); + verifyNoMoreInteractions(attachmentsService); + } } diff --git a/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentRestController1_10Test.java b/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentRestController1_10Test.java index 0b00cde2..9014ffcd 100644 --- a/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentRestController1_10Test.java +++ b/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentRestController1_10Test.java @@ -50,6 +50,7 @@ import org.openmrs.module.attachments.obs.BaseComplexData; import org.openmrs.module.attachments.obs.ComplexDataHelper; import org.openmrs.module.attachments.obs.ComplexDataHelper1_10; +import org.openmrs.module.attachments.obs.ImageAttachmentHandler; import org.openmrs.module.attachments.obs.TestHelper; import org.openmrs.module.webservices.rest.SimpleObject; import org.openmrs.module.webservices.rest.web.response.IllegalRequestException; @@ -359,14 +360,10 @@ public void postAttachment_shouldUploadFileToEncounter() throws Exception { @Test public void postAttachment_shouldAcceptBase64Content() throws Exception { - // Read file OpenMRS_logo.png and copy bytes to baos - InputStream inputStream = getClass().getClassLoader().getResourceAsStream("OpenMRS_logo.png"); - BufferedImage img = ImageIO.read(inputStream); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageIO.write(img, "png", baos); + // Read file OpenMRS_logo.png and copy bytes to a buffer + byte[] bytesIn = TestHelper.loadImageResourceToByteArray(getClass().getClassLoader(), "OpenMRS_logo.png", "png"); // Build the request parameters - byte[] bytesIn = baos.toByteArray(); String fileCaption = "Test file caption"; String fileName = "testFile2.dat"; String base64Content = "data:image/png;base64," + Base64.encodeBase64String(bytesIn); @@ -395,6 +392,78 @@ public void postAttachment_shouldAcceptBase64Content() throws Exception { Assert.assertNull(obs.getEncounter()); } + @Test + public void postAttachment_shouldSupportConceptParam() throws Exception { + String fileCaption = "Openmrs Standard logo"; + final String conceptUuid = "c66422cd-2bf5-49c8-a530-689590134b3f"; + + // Setup + String fileName = "OpenMRS_logo.png"; + Patient patient = Context.getPatientService().getPatient(2); + Encounter encounter = testHelper.getTestEncounter(); + Concept complexConcept = testHelper.createConceptComplex(conceptUuid, "Patient Avatar", + ImageAttachmentHandler.class.getSimpleName(), "Patient Avatar"); + MockMultipartHttpServletRequest request = newUploadRequest(getURI()); + MockMultipartFile file = new MockMultipartFile("file", fileName, "image/png", + TestHelper.loadImageResourceToByteArray(getClass().getClassLoader(), "OpenMRS_logo.png", "png")); + + request.addFile(file); + request.addParameter("patient", patient.getUuid()); + request.addParameter("encounter", encounter.getUuid()); + request.addParameter("fileCaption", fileCaption); + request.addParameter("concept", complexConcept.getUuid()); + + // Replay + SimpleObject response = deserialize(handle(request)); + + Obs obs = Context.getObsService().getObsByUuid((String) response.get("uuid")); + Obs complexObs = Context.getObsService().getComplexObs(obs.getObsId(), null); + ComplexData complexData = complexObs.getComplexData(); + + // Verify + Assert.assertEquals(conceptUuid, obs.getConcept().getUuid()); + Assert.assertEquals(fileCaption, obs.getComment()); + Assert.assertEquals(fileName, complexData.getTitle()); + } + + @Test(expected = IllegalArgumentException.class) + public void postAttachment_shouldFailIfConceptIsNotFound() throws Exception { + // Setup + final String NON_EXISTING_CONCEPT_UUID = "d42c6057-1a16-4ba6-b6e9-6b3c760618af"; + Patient patient = Context.getPatientService().getPatient(2); + MockMultipartHttpServletRequest request = newUploadRequest(getURI()); + MockMultipartFile file = new MockMultipartFile("file", "OpenMRS_logo.png", "image/png", + TestHelper.loadImageResourceToByteArray(getClass().getClassLoader(), "OpenMRS_logo.png", "png")); + + request.addFile(file); + request.addParameter("patient", patient.getUuid()); + request.addParameter("encounter", testHelper.getTestEncounter().getUuid()); + request.addParameter("fileCaption", "Openmrs Standard logo"); + request.addParameter("concept", NON_EXISTING_CONCEPT_UUID); + + // Replay + deserialize(handle(request)); + } + + @Test(expected = IllegalArgumentException.class) + public void postAttachment_shouldFailIfConceptIsNotComplex() throws Exception { + // Setup + final String NON_CONCEPT_COMPLEX_UUID = Context.getConceptService().getConcept(3).getUuid(); + Patient patient = Context.getPatientService().getPatient(2); + MockMultipartHttpServletRequest request = newUploadRequest(getURI()); + MockMultipartFile file = new MockMultipartFile("file", "OpenMRS_logo.png", "image/png", + TestHelper.loadImageResourceToByteArray(getClass().getClassLoader(), "OpenMRS_logo.png", "png")); + + request.addFile(file); + request.addParameter("patient", patient.getUuid()); + request.addParameter("encounter", testHelper.getTestEncounter().getUuid()); + request.addParameter("fileCaption", "Openmrs Standard logo"); + request.addParameter("concept", NON_CONCEPT_COMPLEX_UUID); + + // Replay + deserialize(handle(request)); + } + @Test(expected = IllegalRequestException.class) public void postAttachment_shouldThrowWhenVisitAndEncounterDoNotMatch() throws Exception { // Setup