package eu.europeana.cloud.service.mcs.rest; import com.google.common.collect.ImmutableMap; import com.google.common.hash.Hashing; import eu.europeana.cloud.common.model.DataProvider; import eu.europeana.cloud.common.model.File; import eu.europeana.cloud.common.model.Representation; import eu.europeana.cloud.common.web.ParamConstants; import eu.europeana.cloud.service.mcs.ApplicationContextUtils; import eu.europeana.cloud.service.mcs.RecordService; import eu.europeana.cloud.service.mcs.UISClientHandler; import eu.europeana.cloud.test.CassandraTestRunner; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.media.multipart.FormDataMultiPart; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.test.JerseyTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import javax.ws.rs.Path; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Application; import javax.ws.rs.core.Response; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE; import static org.junit.Assert.*; /** * FileResourceTest */ @RunWith(CassandraTestRunner.class) public class FilesResourceTest extends JerseyTest { private RecordService recordService; private Representation rep; private File file; private WebTarget filesWebTarget; private UISClientHandler uisHandler; @Before public void mockUp() throws Exception { ApplicationContext applicationContext = ApplicationContextUtils.getApplicationContext(); recordService = applicationContext.getBean(RecordService.class); uisHandler = applicationContext.getBean(UISClientHandler.class); Mockito.doReturn(new DataProvider()).when(uisHandler).getProvider(Mockito.anyString()); Mockito.doReturn(true).when(uisHandler).existsCloudId(Mockito.anyString()); DataProvider dp = new DataProvider(); dp.setId("1"); rep = recordService.createRepresentation("1", "1", "1"); file = new File(); file.setFileName("fileName"); file.setMimeType(APPLICATION_OCTET_STREAM_TYPE.toString()); Map<String, Object> allPathParams = ImmutableMap.<String, Object> of(ParamConstants.P_CLOUDID, rep.getCloudId(), ParamConstants.P_REPRESENTATIONNAME, rep.getRepresentationName(), ParamConstants.P_VER, rep.getVersion()); filesWebTarget = target(FilesResource.class.getAnnotation(Path.class).value()).resolveTemplates(allPathParams); } @After public void cleanUp() throws Exception { recordService.deleteRepresentation(rep.getCloudId(), rep.getRepresentationName()); } @Override public Application configure() { return new JerseyConfig().property("contextConfigLocation", "classpath:spiedPersistentServicesTestContext.xml"); } @Override protected void configureClient(ClientConfig config) { config.register(MultiPartFeature.class); } @Test public void shouldUploadDataWithPostWithoutFileName() throws Exception { // given particular (random in this case) content in service byte[] content = new byte[1000]; ThreadLocalRandom.current().nextBytes(content); String contentMd5 = Hashing.md5().hashBytes(content).toString(); // when content is added to record representation FormDataMultiPart multipart = new FormDataMultiPart().field(ParamConstants.F_FILE_MIME, file.getMimeType()) .field(ParamConstants.F_FILE_DATA, new ByteArrayInputStream(content), APPLICATION_OCTET_STREAM_TYPE); Response postFileResponse = filesWebTarget.request().post(Entity.entity(multipart, multipart.getMediaType())); assertEquals("Unexpected status code", Response.Status.CREATED.getStatusCode(), postFileResponse.getStatus()); assertEquals("File content tag mismatch", contentMd5, postFileResponse.getEntityTag().getValue ()); // then data should be in record service rep = recordService.getRepresentation(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion()); assertEquals(1, rep.getFiles().size()); File insertedFile = rep.getFiles().get(0); ByteArrayOutputStream contentBos = new ByteArrayOutputStream(); recordService.getContent(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion(), insertedFile.getFileName(), contentBos); assertEquals("MD5 file mismatch", contentMd5, insertedFile.getMd5()); assertEquals(content.length, insertedFile.getContentLength()); assertArrayEquals(content, contentBos.toByteArray()); } @Test public void shouldUploadDataWithPostWithFileName() throws Exception { // given particular (random in this case) content in service byte[] content = new byte[1000]; ThreadLocalRandom.current().nextBytes(content); String contentMd5 = Hashing.md5().hashBytes(content).toString(); // when content is added to record representation FormDataMultiPart multipart = new FormDataMultiPart() .field(ParamConstants.F_FILE_MIME, file.getMimeType()) .field(ParamConstants.F_FILE_DATA, new ByteArrayInputStream(content), APPLICATION_OCTET_STREAM_TYPE).field(ParamConstants.F_FILE_NAME, file.getFileName()); Response postFileResponse = filesWebTarget.request().post(Entity.entity(multipart, multipart.getMediaType())); assertEquals("Unexpected status code", Response.Status.CREATED.getStatusCode(), postFileResponse.getStatus()); assertEquals("File content tag mismatch", contentMd5, postFileResponse.getEntityTag().getValue()); // then data should be in record service rep = recordService.getRepresentation(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion()); assertEquals(1, rep.getFiles().size()); File insertedFile = rep.getFiles().get(0); ByteArrayOutputStream contentBos = new ByteArrayOutputStream(); recordService.getContent(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion(), insertedFile.getFileName(), contentBos); assertEquals("FileName mismatch", file.getFileName(), insertedFile.getFileName()); assertEquals("MD5 file mismatch", contentMd5, insertedFile.getMd5()); assertEquals(content.length, insertedFile.getContentLength()); assertArrayEquals(content, contentBos.toByteArray()); } @Test public void shouldBeReturn409WhenFileAlreadyExist() throws Exception { // given particular (random in this case) content in service byte[] content = { 1, 2, 3, 4 }; String contentMd5 = Hashing.md5().hashBytes(content).toString(); recordService.putContent(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion(), file, new ByteArrayInputStream(content)); byte[] modifiedContent = { 5, 6, 7 }; ThreadLocalRandom.current().nextBytes(modifiedContent); String modifiedContentMd5 = Hashing.md5().hashBytes(content).toString(); // when content is added to record representation FormDataMultiPart multipart = new FormDataMultiPart() .field(ParamConstants.F_FILE_MIME, file.getMimeType()) .field(ParamConstants.F_FILE_DATA, new ByteArrayInputStream(modifiedContent), APPLICATION_OCTET_STREAM_TYPE).field(ParamConstants.F_FILE_NAME, file.getFileName()); Response postFileResponse = filesWebTarget.request().post(Entity.entity(multipart, multipart.getMediaType())); assertEquals("Unexpected status code", Response.Status.CONFLICT.getStatusCode(), postFileResponse.getStatus()); //assertEquals("File content tag mismatch", contentMd5, postFileResponse.getEntityTag().getValue()); // then data should be in record service rep = recordService.getRepresentation(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion()); assertEquals(1, rep.getFiles().size()); File insertedFile = rep.getFiles().get(0); ByteArrayOutputStream contentBos = new ByteArrayOutputStream(); recordService.getContent(rep.getCloudId(), rep.getRepresentationName(), rep.getVersion(), insertedFile.getFileName(), contentBos); assertNotSame("MD5 file mismatch", modifiedContentMd5, insertedFile.getMd5()); assertNotSame(modifiedContent.length, insertedFile.getContentLength()); } }