package com.leandronunes85.messaging.avro.serializer;

import com.leandronunes85.messaging.api.model.Message;
import com.leandronunes85.messaging.api.serializer.IntegerSerializer;
import com.leandronunes85.messaging.api.serializer.Serializer;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import static org.testng.Assert.assertEquals;

public class AvroMessageSerializerTest {

    private AvroMessageSerializer<Integer> victim;

    private Serializer<Integer> payloadSerializer;

    @BeforeMethod
    public void setUp() throws Exception {
        payloadSerializer = spy(new IntegerSerializer());
        victim = new AvroMessageSerializer<>(payloadSerializer);
    }

    @Test
    public void shouldUseGivenSerializerToSerializePayload() throws Exception {
        Message<Integer> message = new Message<>(10);

        victim.serialize(message);

        verify(payloadSerializer).serialize(10);
    }

    @Test
    public void shouldDeserializeSerializedData() throws Exception {
        Message<Integer> expected = new Message<>(10);
        expected.putHeader("Key1", "Value1");
        expected.putHeader("Key2", "Value2");

        Message<Integer> actual = victim.deserialize(victim.serialize(expected));

        assertEquals(actual.getHeader("Key1"), expected.getHeader("Key1"));
        assertEquals(actual.getHeader("Key2"), expected.getHeader("Key2"));

        assertEquals(actual.getPayload().intValue(), 10);
    }

    @Test
    public void shouldLazilyDeserializePayload() throws Exception {
        Message<Integer> expected = new Message<>(10);

        Message<Integer> actual = victim.deserialize(victim.serialize(expected));

        verify(payloadSerializer, never()).deserialize(any(byte[].class));

        actual.getPayload();

        verify(payloadSerializer).deserialize(any(byte[].class));
    }

    public void produce() {
        // Prepare serializers:
        // You code this one
        Serializer<MyDomainObject> myDomainObjectSerializer = new MyDomainObjectSerializer();
        // And the library provides you with this one
        Serializer<Message<MyDomainObject>> serializer = new AvroMessageSerializer<>(myDomainObjectSerializer);

        // Create your domain object
        MyDomainObject myDomainObject = new MyDomainObject();
        // Use it to create a Message
        Message<MyDomainObject> message = new Message<>(myDomainObject);
        // And set all the headers you want
        message.putHeader("year", "2015");

        // Now transform the whole message into a byte array
        byte[] bytes = serializer.serialize(message);
    }

    public void consume() {
        // Prepare serializers:
        // You code this one
        Serializer<MyDomainObject> myDomainObjectSerializer = new MyDomainObjectSerializer();
        // And the library provides you with this one
        Serializer<Message<MyDomainObject>> serializer = new AvroMessageSerializer<>(myDomainObjectSerializer);


        byte[] bytes = null; //...;
        // Deserialize the message. Only headers will be deserialized here
        Message<MyDomainObject> message = serializer.deserialize(bytes);

        // Check the headers
        if ("2015".equals(message.getHeader("year").get())) {
            // This is where the payload deserialization occurs, when you're sure you'll need it!
            processThisYearMessage(message.getPayload());
        }
    }

    class MyDomainObjectSerializer implements Serializer<MyDomainObject> {

        @Override
        public byte[] serialize(MyDomainObject obj) {
            return new byte[0];
        }

        @Override
        public MyDomainObject deserialize(byte[] bytes) {
            return null;
        }
    }

    class MyDomainObject {

    }
}
@@ -1941,1920 +1941,6 @@
    %7D
-%0A%0A    public void produce() %7B%0A        // Prepare serializers:%0A        // You code this one%0A        Serializer%3CMyDomainObject%3E myDomainObjectSerializer = new MyDomainObjectSerializer();%0A        // And the library provides you with this one%0A        Serializer%3CMessage%3CMyDomainObject%3E%3E serializer = new AvroMessageSerializer%3C%3E(myDomainObjectSerializer);%0A%0A        // Create your domain object%0A        MyDomainObject myDomainObject = new MyDomainObject();%0A        // Use it to create a Message%0A        Message%3CMyDomainObject%3E message = new Message%3C%3E(myDomainObject);%0A        // And set all the headers you want%0A        message.putHeader(%22year%22, %222015%22);%0A%0A        // Now transform the whole message into a byte array%0A        byte%5B%5D bytes = serializer.serialize(message);%0A    %7D%0A%0A    public void consume() %7B%0A        // Prepare serializers:%0A        // You code this one%0A        Serializer%3CMyDomainObject%3E myDomainObjectSerializer = new MyDomainObjectSerializer();%0A        // And the library provides you with this one%0A        Serializer%3CMessage%3CMyDomainObject%3E%3E serializer = new AvroMessageSerializer%3C%3E(myDomainObjectSerializer);%0A%0A%0A        byte%5B%5D bytes = null; //...;%0A        // Deserialize the message. Only headers will be deserialized here%0A        Message%3CMyDomainObject%3E message = serializer.deserialize(bytes);%0A%0A        // Check the headers%0A        if (%222015%22.equals(message.getHeader(%22year%22).get())) %7B%0A            // This is where the payload deserialization occurs, when you're sure you'll need it!%0A            processThisYearMessage(message.getPayload());%0A        %7D%0A    %7D%0A%0A    class MyDomainObjectSerializer implements Serializer%3CMyDomainObject%3E %7B%0A%0A        @Override%0A        public byte%5B%5D serialize(MyDomainObject obj) %7B%0A            return new byte%5B0%5D;%0A        %7D%0A%0A        @Override%0A        public MyDomainObject deserialize(byte%5B%5D bytes) %7B%0A            return null;%0A        %7D%0A    %7D%0A%0A    class MyDomainObject %7B%0A%0A    %7D
 %0A%7D

Remove code