package eu.europeana.cloud.service.mcs.rest; import eu.europeana.cloud.common.model.File; import eu.europeana.cloud.common.model.Representation; import eu.europeana.cloud.common.response.ErrorInfo; import eu.europeana.cloud.service.mcs.ApplicationContextUtils; import eu.europeana.cloud.service.mcs.RecordService; import eu.europeana.cloud.service.mcs.exception.CannotModifyPersistentRepresentationException; import eu.europeana.cloud.service.mcs.exception.CannotPersistEmptyRepresentationException; import eu.europeana.cloud.service.mcs.exception.RepresentationNotExistsException; import eu.europeana.cloud.service.mcs.rest.exceptionmappers.CannotModifyPersistentRepresentationExceptionMapper; import eu.europeana.cloud.service.mcs.rest.exceptionmappers.CannotPersistEmptyRepresentationExceptionMapper; import eu.europeana.cloud.service.mcs.status.McsErrorCode; import eu.europeana.cloud.service.mcs.rest.exceptionmappers.RecordNotExistsExceptionMapper; import eu.europeana.cloud.service.mcs.rest.exceptionmappers.RepresentationNotExistsExceptionMapper; import eu.europeana.cloud.service.mcs.rest.exceptionmappers.VersionNotExistsExceptionMapper; import java.util.Arrays; import java.util.Date; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; import javax.ws.rs.core.Form; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import junitparams.JUnitParamsRunner; import static junitparams.JUnitParamsRunner.$; import junitparams.Parameters; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import org.springframework.context.ApplicationContext; import org.springframework.security.acls.model.MutableAclService; @RunWith(JUnitParamsRunner.class) public class RepresentationVersionResourceTest extends JerseyTest { private RecordService recordService; private MutableAclService mutableAclService; static final private String globalId = "1"; static final private String schema = "DC"; static final private String version = "1.0"; static final private String fileName = "1.xml"; static final private String persistPath = URITools.getPath(RepresentationVersionResource.class, "persistRepresentation", globalId, schema, version).toString(); static final private String copyPath = URITools.getPath(RepresentationVersionResource.class, "copyRepresentation", globalId, schema, version).toString(); static final private Representation representation = new Representation(globalId, schema, version, null, null, "DLF", Arrays.asList(new File(fileName, "text/xml", "91162629d258a876ee994e9233b2ad87", "2013-01-01", 12345, null)), null, true, new Date()); @Override public Application configure() { return new ResourceConfig().registerClasses(RepresentationVersionResource.class) .registerClasses(RecordNotExistsExceptionMapper.class) .registerClasses(RepresentationNotExistsExceptionMapper.class) .registerClasses(VersionNotExistsExceptionMapper.class) .registerClasses(CannotModifyPersistentRepresentationExceptionMapper.class) .registerClasses(CannotPersistEmptyRepresentationExceptionMapper.class) .property("contextConfigLocation", "classpath:testContext.xml"); } @Before public void mockUp() { ApplicationContext applicationContext = ApplicationContextUtils.getApplicationContext(); recordService = applicationContext.getBean(RecordService.class); mutableAclService = applicationContext.getBean(MutableAclService.class); Mockito.reset(recordService); } @SuppressWarnings("unused") private Object[] mimeTypes() { return $($(MediaType.APPLICATION_XML_TYPE), $(MediaType.APPLICATION_JSON_TYPE)); } @Test @Parameters(method = "mimeTypes") public void testGetRepresentationVersion(MediaType mediaType) throws Exception { Representation expected = new Representation(representation); URITools.enrich(expected, getBaseUri()); when(recordService.getRepresentation(globalId, schema, version)).thenReturn(new Representation(representation)); Response response = target(URITools.getVersionPath(globalId, schema, version).toString()).request(mediaType) .get(); assertThat(response.getStatus(), is(200)); assertThat(response.getMediaType(), is(mediaType)); Representation entity = response.readEntity(Representation.class); assertThat(entity, is(expected)); verify(recordService, times(1)).getRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } private Object[] errors() { return $($(new RepresentationNotExistsException(), McsErrorCode.REPRESENTATION_NOT_EXISTS.toString(), 404)); } @Test @Parameters(method = "errors") public void testGetRepresentationVersionReturns404IfRepresentationOrRecordOrVersionDoesNotExists( Throwable exception, String errorCode, int statusCode) throws Exception { when(recordService.getRepresentation(globalId, schema, version)).thenThrow(exception); Response response = target().path(URITools.getVersionPath(globalId, schema, version).toString()) .request(MediaType.APPLICATION_XML).get(); assertThat(response.getStatus(), is(statusCode)); ErrorInfo errorInfo = response.readEntity(ErrorInfo.class); assertThat(errorInfo.getErrorCode(), is(errorCode)); verify(recordService, times(1)).getRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } @Test public void testGetRepresentationVersionReturns406ForUnsupportedFormat() { Response response = target().path(URITools.getVersionPath(globalId, schema, version).toString()) .request(MediaType.APPLICATION_SVG_XML_TYPE).get(); assertThat(response.getStatus(), is(406)); } @Test public void testDeleteRepresentation() throws Exception { Response response = target().path(URITools.getVersionPath(globalId, schema, version).toString()).request() .delete(); assertThat(response.getStatus(), is(204)); verify(recordService, times(1)).deleteRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } @Test @Parameters(method = "errors") public void testDeleteRepresentationReturns404IfRecordOrRepresentationDoesNotExists(Throwable exception, String errorCode, int statusCode) throws Exception { Mockito.doThrow(exception).when(recordService).deleteRepresentation(globalId, schema, version); Response response = target().path(URITools.getVersionPath(globalId, schema, version).toString()).request() .delete(); assertThat(response.getStatus(), is(statusCode)); ErrorInfo errorInfo = response.readEntity(ErrorInfo.class); assertThat(errorInfo.getErrorCode(), is(errorCode)); verify(recordService, times(1)).deleteRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } @Test public void testPersistRepresentation() throws Exception { when(recordService.persistRepresentation(globalId, schema, version)).thenReturn( new Representation(representation)); Response response = target(persistPath).request().post( Entity.entity(new Form(), MediaType.APPLICATION_FORM_URLENCODED_TYPE)); assertThat(response.getStatus(), is(201)); assertThat(response.getLocation(), is(URITools.getVersionUri(getBaseUri(), globalId, schema, version))); verify(recordService, times(1)).persistRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } @Test @Parameters(method = "persistErrors") public void testPersistRepresentationReturns40XIfExceptionOccur(Throwable exception, String errorCode, int statusCode) throws Exception { when(recordService.persistRepresentation(globalId, schema, version)).thenThrow(exception); Response response = target().path(persistPath).request() .post(Entity.entity(new Form(), MediaType.APPLICATION_FORM_URLENCODED_TYPE)); assertThat(response.getStatus(), is(statusCode)); ErrorInfo errorInfo = response.readEntity(ErrorInfo.class); assertThat(errorInfo.getErrorCode(), is(errorCode)); verify(recordService, times(1)).persistRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } @SuppressWarnings("unused") private Object[] persistErrors() { return $( $(new RepresentationNotExistsException(), McsErrorCode.REPRESENTATION_NOT_EXISTS.toString(), 404), $(new CannotModifyPersistentRepresentationException(), McsErrorCode.CANNOT_MODIFY_PERSISTENT_REPRESENTATION.toString(), 405), $(new CannotPersistEmptyRepresentationException(), McsErrorCode.CANNOT_PERSIST_EMPTY_REPRESENTATION.toString(), 405)); } @Test public void testCopyRepresentation() throws Exception { when(recordService.copyRepresentation(globalId, schema, version)) .thenReturn(new Representation(representation)); Response response = target(copyPath).request().post( Entity.entity(new Form(), MediaType.APPLICATION_FORM_URLENCODED_TYPE)); assertThat(response.getStatus(), is(201)); assertThat(response.getLocation(), is(URITools.getVersionUri(getBaseUri(), globalId, schema, version))); verify(recordService, times(1)).copyRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } @Test @Parameters(method = "errors") public void testCopyRepresentationReturns404IfRepresentationOrRecordOrVersionDoesNotExists(Throwable exception, String errorCode, int statusCode) throws Exception { when(recordService.copyRepresentation(globalId, schema, version)).thenThrow(exception); Response response = target().path(copyPath).request() .post(Entity.entity(new Form(), MediaType.APPLICATION_FORM_URLENCODED_TYPE)); assertThat(response.getStatus(), is(statusCode)); ErrorInfo errorInfo = response.readEntity(ErrorInfo.class); assertThat(errorInfo.getErrorCode(), is(errorCode)); verify(recordService, times(1)).copyRepresentation(globalId, schema, version); verifyNoMoreInteractions(recordService); } }