package uk.ac.ox.zoo.seeg.abraid.mp.common.dto;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import org.junit.Test;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dto.json.WrappedList;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import static com.googlecode.catchexception.CatchException.catchException;
import static com.googlecode.catchexception.CatchException.caughtException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Tests for CSVMessageConverter.
* Copyright (c) 2014 University of Oxford
*/
public class CSVMessageConverterTest {
@Test
public void canWriteReturnsFalseForUnsuitableJavaTypes() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act / Assert
assertThat(target.canWrite(List.class, MediaType.parseMediaType("application/csv"))).isFalse();
assertThat(target.canWrite(String.class, MediaType.parseMediaType("application/csv"))).isFalse();
assertThat(target.canWrite(Object.class, MediaType.parseMediaType("application/csv"))).isFalse();
assertThat(target.canWrite(CSVMessageConverter.class, MediaType.parseMediaType("application/csv"))).isFalse();
}
@Test
public void canWriteReturnsFalseForUnsuitableMediaTypes() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act / Assert
assertThat(target.canWrite(WrappedList.class, MediaType.parseMediaType("application/json"))).isFalse();
assertThat(target.canWrite(WrappedList.class, MediaType.parseMediaType("text/csv"))).isFalse();
assertThat(target.canWrite(WrappedList.class, MediaType.parseMediaType("text/html"))).isFalse();
assertThat(target.canWrite(WrappedList.class, MediaType.parseMediaType("application/xml"))).isFalse();
}
@Test
public void canWriteReturnsTrueForSuitableJavaTypeAndSuitableMediaTypes() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act
boolean result = target.canWrite(WrappedList.class, MediaType.parseMediaType("application/csv"));
// Assert
assertThat(result).isTrue();
}
@Test
public void canWriteReturnsTrueForSuitableJavaTypeAndMissingMediaTypes() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act
boolean result = target.canWrite(WrappedList.class, null);
// Assert
assertThat(result).isTrue();
}
@Test
public void supportsThrowsUnsupportedOperationException() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act
catchException(target).supports((new WrappedList<>()).getClass());
// Assert
assertThat(caughtException()).isInstanceOf(UnsupportedOperationException.class);
}
@Test
public void canReadReturnsFalse() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act
boolean result = target.canRead((new WrappedList<>()).getClass(), MediaType.parseMediaType("application/csv"));
// Assert
assertThat(result).isFalse();
}
@Test
public void readInternalThrowsUnsupportedOperationException() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(mock(CsvMapper.class));
// Act
catchException(target).readInternal(null, mock(HttpInputMessage.class));
// Assert
assertThat(caughtException()).isInstanceOf(UnsupportedOperationException.class);
}
@Test
public void writeInternalProducesCorrectString() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(new CsvMapper());
WrappedList<Animal> list = new WrappedList<>(Arrays.asList(new Animal("cat", 10, true), new Animal("dog", null, true), new Animal("bird", 10, false)));
HttpOutputMessage message = mock(HttpOutputMessage.class);
when(message.getBody()).thenReturn(new ByteArrayOutputStream());
// Act
target.writeInternal(list, message);
// Assert
assertThat(message.getBody().toString()).isEqualTo(
"age,isMale,name\n" +
"10,true,cat\n" +
",true,dog\n" +
"10,false,bird\n");
}
@Test
public void writeInternalThrowForMixedCollection() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(new CsvMapper());
WrappedList<Animal> list = new WrappedList<>(Arrays.asList(new Dog("dog", 10, true, "pug"), new Animal("cat", 10, false)));
HttpOutputMessage message = mock(HttpOutputMessage.class);
when(message.getBody()).thenReturn(new ByteArrayOutputStream());
// Act
catchException(target).writeInternal(list, message);
// Assert
assertThat(caughtException()).isInstanceOf(HttpMessageNotWritableException.class);
assertThat(caughtException()).hasMessage("Cannot write collection containing mixed types");
}
@Test
public void writeInternalThrowForCollectionWithNull() throws Exception {
// Arrange
CSVMessageConverter target = new CSVMessageConverter(new CsvMapper());
WrappedList<Animal> list = new WrappedList<>(Arrays.asList(new Animal("cat", 10, false), null));
HttpOutputMessage message = mock(HttpOutputMessage.class);
when(message.getBody()).thenReturn(new ByteArrayOutputStream());
// Act
catchException(target).writeInternal(list, message);
// Assert
assertThat(caughtException()).isInstanceOf(HttpMessageNotWritableException.class);
assertThat(caughtException()).hasMessage("Cannot write collection containing null");
}
///CHECKSTYLE:OFF VisibilityModifier|JavadocType|FinalClass
private class Animal {
public Boolean isMale;
public String name;
public Integer age;
private Animal(String name, Integer age, Boolean isMale) {
this.name = name;
this.age = age;
this.isMale = isMale;
}
}
private class Dog extends Animal {
public String breed;
private Dog(String name, Integer age, Boolean isMale, String breed) {
super(name, age, isMale);
this.breed = breed;
}
}
///CHECKSTYLE:ON
}