package io.dropwizard.jersey.jackson;
import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import io.dropwizard.jersey.AbstractJerseyTest;
import io.dropwizard.jersey.DropwizardResourceConfig;
import org.glassfish.jersey.client.ClientConfig;
import org.junit.Test;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import static org.assertj.core.api.Assertions.assertThat;
public class JsonProcessingExceptionMapperTest extends AbstractJerseyTest {
@Override
protected Application configure() {
return DropwizardResourceConfig.forTesting(new MetricRegistry())
.packages("io.dropwizard.jersey.jackson");
}
@Override
protected void configureClient(ClientConfig config) {
final ObjectMapper mapper = new ObjectMapper();
final JacksonMessageBodyProvider provider = new JacksonMessageBodyProvider(mapper);
config.register(provider);
}
@Test
public void returnsA500ForNonDeserializableRepresentationClasses() throws Exception {
Response response = target("/json/broken").request(MediaType.APPLICATION_JSON)
.post(Entity.entity(new BrokenRepresentation(ImmutableList.of("whee")), MediaType.APPLICATION_JSON));
assertThat(response.getStatus()).isEqualTo(500);
assertThat(response.getMediaType()).isEqualTo(MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void returnsA500ForListNonDeserializableRepresentationClasses() throws Exception {
final ImmutableList<BrokenRepresentation> ent =
ImmutableList.of(new BrokenRepresentation(ImmutableList.of()),
new BrokenRepresentation(ImmutableList.of("whoo")));
Response response = target("/json/brokenList").request(MediaType.APPLICATION_JSON)
.post(Entity.entity(ent, MediaType.APPLICATION_JSON));
assertThat(response.getStatus()).isEqualTo(500);
assertThat(response.getMediaType()).isEqualTo(MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void returnsA500ForNonSerializableRepresentationClassesOutbound() throws Exception {
Response response = target("/json/brokenOutbound").request(MediaType.APPLICATION_JSON).get();
assertThat(response.getStatus()).isEqualTo(500);
assertThat(response.getMediaType()).isEqualTo(MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void returnsA500ForAbstractEntity() throws Exception {
Response response = target("/json/interface").request(MediaType.APPLICATION_JSON)
.post(Entity.entity("\"hello\"", MediaType.APPLICATION_JSON));
assertThat(response.getStatus()).isEqualTo(500);
assertThat(response.getMediaType()).isEqualTo(MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void returnsA500ForAbstractEntities() throws Exception {
Response response = target("/json/interfaceList").request(MediaType.APPLICATION_JSON)
.post(Entity.entity("[\"hello\"]", MediaType.APPLICATION_JSON));
assertThat(response.getStatus()).isEqualTo(500);
assertThat(response.getMediaType()).isEqualTo(MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void returnsA500ForBadDeserializers() throws Exception {
Response response = target("/json/custom").request(MediaType.APPLICATION_JSON)
.post(Entity.entity("{}", MediaType.APPLICATION_JSON));
assertThat(response.getStatus()).isEqualTo(500);
assertThat(response.getMediaType()).isEqualTo(MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void returnsA400ForMalformedInputCausingIoException() throws Exception {
assertEndpointReturns400("url", "\"no-scheme.com\"");
}
@Test
public void returnsA400ForListWrongInputType() throws Exception {
assertEndpointReturns400("urlList", "\"no-scheme.com\"");
}
@Test
public void returnsA400ForMalformedListInputCausingIoException() throws Exception {
assertEndpointReturns400("urlList", "[\"no-scheme.com\"]");
}
@Test
public void returnsA400ForNonDeserializableRequestEntities() throws Exception {
assertEndpointReturns400("ok", new UnknownRepresentation(100));
}
@Test
public void returnsA400ForWrongInputType() throws Exception {
assertEndpointReturns400("ok", "false");
}
@Test
public void returnsA400ForInvalidFormatRequestEntities() throws Exception {
assertEndpointReturns400("ok", "{\"message\": \"a\", \"date\": \"2016-01-01\"}");
}
@Test
public void returnsA400ForInvalidFormatRequestEntitiesWrapped() throws Exception {
assertEndpointReturns400("ok", "{\"message\": \"1\", \"date\": \"a\"}");
}
@Test
public void returnsA400ForInvalidFormatRequestEntitiesArray() throws Exception {
assertEndpointReturns400("ok", "{\"message\": \"1\", \"date\": [1,1,1,1]}");
}
@Test
public void returnsA400ForSemanticInvalidDate() throws Exception {
assertEndpointReturns400("ok", "{\"message\": \"1\", \"date\": [-1,-1,-1]}");
}
private <T> void assertEndpointReturns400(String endpoint, T entity) {
Response response = target(String.format("/json/%s", endpoint))
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(entity, MediaType.APPLICATION_JSON));
assertThat(response.getStatus()).isEqualTo(400);
JsonNode errorMessage = response.readEntity(JsonNode.class);
assertThat(errorMessage.get("code").asInt()).isEqualTo(400);
assertThat(errorMessage.get("message").asText()).isEqualTo("Unable to process JSON");
assertThat(errorMessage.has("details")).isFalse();
}
}