package forklift;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import forklift.connectors.ConnectorException;
import forklift.connectors.ForkliftConnectorI;
import forklift.connectors.ForkliftMessage;
import forklift.consumer.Consumer;
import forklift.decorators.Headers;
import forklift.decorators.Message;
import forklift.decorators.Properties;
import forklift.decorators.Queue;
import forklift.decorators.Topic;
import forklift.message.Header;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class ConsumerTest {
private Forklift forklift;
private ForkliftConnectorI connector;
@Before
public void setup() {
forklift = mock(Forklift.class);
connector = mock(ForkliftConnectorI.class);
when(connector.supportsQueue()).thenReturn(true);
when(connector.supportsTopic()).thenReturn(true);
when(forklift.getConnector()).thenReturn(connector);
}
@Test(expected = IllegalArgumentException.class)
public void createBadConsumer() {
new Consumer(BadConsumer.class, forklift, this.getClass().getClassLoader());
}
@Test(expected = IllegalArgumentException.class)
public void createDoubleConsumer() {
new Consumer(DoubleConsumer.class, forklift, this.getClass().getClassLoader());
}
@Test
public void createQueueConsumer() {
Consumer c = new Consumer(QueueConsumer.class, forklift, this.getClass().getClassLoader());
assertTrue(c.getName().matches("abc:\\d+"));
}
@Test
public void createTopicConsumer() {
Consumer c = new Consumer(TopicConsumer.class, forklift, this.getClass().getClassLoader());
assertTrue(c.getName().matches("xyz:\\d+"));
}
@Test
public void inject() throws ConnectorException {
Consumer test = new Consumer(ExampleConsumer.class, forklift, this.getClass().getClassLoader());
ExampleConsumer ec = new ExampleConsumer();
ForkliftMessage msg = new ForkliftMessage();
msg.setId("1");
msg.setMsg("x=y\nname=Scooby Doo\n");
test.inject(msg, ec);
// Now assert ec properties and make sure they are correct.
assertEquals(2, ec.kv.size());
assertEquals("y", ec.kv.get("x"));
assertEquals("Scooby Doo", ec.kv.get("name"));
assertEquals("x=y\nname=Scooby Doo\n", ec.fmsg.getMsg());
assertEquals("1", ec.fmsg.getId());
assertEquals("x=y\nname=Scooby Doo\n", ec.str);
}
// TODO put this back in with a real test.
// The system should hand the bad json to the consumer, and let the consumer mark the message as invalid to avoid redelivery of a bad message.
// @Test(expected=RuntimeException.class)
public void injectBadJson() {
Consumer test = new Consumer(ExampleJsonConsumer.class, null, this.getClass().getClassLoader());
ExampleJsonConsumer ec = new ExampleJsonConsumer();
ForkliftMessage msg = new ForkliftMessage();
msg.setId("1");
msg.setMsg("x=y");
test.inject(msg, ec);
}
@Test
public void injectEmptyJson() {
Consumer test = new Consumer(ExampleJsonConsumer.class, forklift, this.getClass().getClassLoader());
ExampleJsonConsumer ec = new ExampleJsonConsumer();
ForkliftMessage msg = new ForkliftMessage();
msg.setId("1");
msg.setMsg("{}");
test.inject(msg, ec);
assertNotNull(ec.msg);
assertNull(ec.msg.ideas);
assertNull(ec.msg.name);
assertNull(ec.msg.url);
}
@Test
public void injectJson() {
Consumer test = new Consumer(ExampleJsonConsumer.class, forklift, this.getClass().getClassLoader());
ExampleJsonConsumer ec = new ExampleJsonConsumer();
ForkliftMessage msg = new ForkliftMessage();
msg.setId("1");
msg.setMsg("{\"name\":\"Fred Jones\", \"url\":\"http://forklift\", \"ideas\":[\"scanning\", \"verifying\"]}");
test.inject(msg, ec);
assertNotNull(ec.msg);
assertTrue("scanning".equals(ec.msg.ideas[0]));
assertEquals(2, ec.msg.ideas.length);
assertEquals("Fred Jones", ec.msg.name);
assertEquals("http://forklift", ec.msg.url);
assertNotNull(ec.headers);
assertNotNull(ec.properties);
assertEquals(0, ec.headers.size());
assertEquals(0, ec.properties.size());
assertNull(ec.cid);
assertEquals(ec.producer, "replace");
assertEquals("default", ec.strval);
}
@Test
public void testHeadersAndProperties() {
Consumer test = new Consumer(ExampleJsonConsumer.class, forklift, this.getClass().getClassLoader());
ExampleJsonConsumer ec = new ExampleJsonConsumer();
ForkliftMessage msg = new ForkliftMessage();
msg.setId("1");
msg.setMsg("{}");
Map<Header, Object> headers = new HashMap<>();
headers.put(Header.DeliveryCount, "3");
headers.put(Header.Producer, "testing");
headers.put(Header.Priority, "1");
headers.put(Header.CorrelationId, "abcd");
msg.setHeaders(headers);
Map<String, String> properties = new HashMap<>();
properties.put("mystrval", "blah");
msg.setProperties(properties);
test.inject(msg, ec);
assertEquals(4, ec.headers.size());
assertEquals(1, ec.properties.size());
assertEquals("blah", ec.mystrval);
assertEquals("blah", ec.strval);
assertEquals(ec.cid, "abcd");
assertEquals(ec.producer, "testing");
}
// Class doesn't have queue or topic should throw IllegalArgException
public class BadConsumer {
}
@Queue("q")
@Topic("a")
public class DoubleConsumer {
}
@Queue("abc")
public class QueueConsumer {
}
@Topic("xyz")
public class TopicConsumer {
}
@Queue("abc")
public class ExampleConsumer {
@Message
ForkliftMessage fmsg;
@Message
Map<String, String> kv;
@Message
String str;
}
@Queue("a")
public class ExampleJsonConsumer {
@Headers
Map<Headers, String> headers;
@Headers
String cid;
@Headers(Header.Producer)
String producer = "replace";
@Properties
Map<String, Object> properties;
@Properties("mystrval")
String strval = "default";
@Properties
String mystrval;
@Message
ForkliftMessage fmsg;
@Message
Map<String, String> kv;
@Message
String str;
@Message
ExpectedMsg msg;
}
public static class ExpectedMsg {
public String name;
public String url;
public String[] ideas;
public ExpectedMsg() {
}
}
}