// Copyright 2013 Square, Inc.
package retrofit.converter;
import com.google.common.io.BaseEncoding;
import com.google.protobuf.InvalidProtocolBufferException;
import org.junit.Test;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedOutput;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static retrofit.converter.PhoneProtos.Phone;
public final class ProtoConverterTest
{
private static final Phone PROTO = Phone.newBuilder().setNumber("(519) 867-5309").build();
private static final String ENCODED_PROTO = "Cg4oNTE5KSA4NjctNTMwOQ==";
private final ProtoConverter protoConverter = new ProtoConverter();
@Test
public void serialize() throws Exception
{
TypedOutput protoBytes = protoConverter.toBody(PROTO);
assertThat(protoBytes.mimeType()).isEqualTo("application/x-protobuf");
assertThat(bytesOf(protoBytes)).isEqualTo(bytesOf(decodeBase64(ENCODED_PROTO)));
}
@Test
public void deserialize() throws Exception
{
Object proto = protoConverter.fromBody(decodeBase64(ENCODED_PROTO), Phone.class);
assertThat(proto).isEqualTo(PROTO);
}
@Test
public void deserializeWrongClass() throws Exception
{
try
{
protoConverter.fromBody(decodeBase64(ENCODED_PROTO), String.class);
fail();
}
catch (IllegalArgumentException e)
{
assertThat(e).hasMessage("Expected a protobuf message but was java.lang.String");
}
}
@Test
public void deserializeWrongType() throws Exception
{
try
{
protoConverter.fromBody(decodeBase64(ENCODED_PROTO), ArrayList.class.getGenericSuperclass());
fail();
}
catch (IllegalArgumentException e)
{
assertThat(e).hasMessage("Expected a raw Class<?> but was java.util.AbstractList<E>");
}
}
@Test
public void deserializeWrongValue() throws Exception
{
try
{
protoConverter.fromBody(decodeBase64("////"), Phone.class);
fail();
}
catch (ConversionException expected)
{
assertThat(expected.getCause() instanceof InvalidProtocolBufferException);
}
}
@Test
public void deserializeWrongMime() throws Exception
{
try
{
protoConverter.fromBody(decodeBase64("////", "yummy/bytes"), Phone.class);
fail();
}
catch (ConversionException e)
{
assertThat(e).hasMessage("Response content type was not a proto: yummy/bytes");
}
}
private static byte[] bytesOf(TypedOutput protoBytes) throws IOException
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
protoBytes.writeTo(bytes);
return bytes.toByteArray();
}
private static TypedByteArray decodeBase64(String base64) throws UnsupportedEncodingException
{
return decodeBase64(base64, "application/x-protobuf");
}
private static TypedByteArray decodeBase64(String base64, String mime) throws UnsupportedEncodingException
{
return new TypedByteArray(mime, BaseEncoding.base64().decode(base64));
}
}