From 11fcad89c6ef53fc802f273cccd40ea8630b85d4 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Wed, 16 Nov 2016 14:32:22 +0000
Subject: [PATCH] Unit tests for BdfMessageValidator.

---
 .../org/briarproject/BriarMockTestCase.java   |  14 ++
 .../org/briarproject/ValidatorTestCase.java   |  23 +++
 .../clients/BdfMessageValidatorTest.java      | 189 ++++++++++++++++++
 .../PrivateMessageValidatorTest.java          |  52 ++---
 4 files changed, 240 insertions(+), 38 deletions(-)
 create mode 100644 briar-tests/src/org/briarproject/BriarMockTestCase.java
 create mode 100644 briar-tests/src/org/briarproject/ValidatorTestCase.java
 create mode 100644 briar-tests/src/org/briarproject/clients/BdfMessageValidatorTest.java

diff --git a/briar-tests/src/org/briarproject/BriarMockTestCase.java b/briar-tests/src/org/briarproject/BriarMockTestCase.java
new file mode 100644
index 0000000000..45b662013b
--- /dev/null
+++ b/briar-tests/src/org/briarproject/BriarMockTestCase.java
@@ -0,0 +1,14 @@
+package org.briarproject;
+
+import org.jmock.Mockery;
+import org.junit.After;
+
+public abstract class BriarMockTestCase extends BriarTestCase {
+
+	protected final Mockery context = new Mockery();
+
+	@After
+	public void checkExpectations() {
+		context.assertIsSatisfied();
+	}
+}
diff --git a/briar-tests/src/org/briarproject/ValidatorTestCase.java b/briar-tests/src/org/briarproject/ValidatorTestCase.java
new file mode 100644
index 0000000000..a340994ed9
--- /dev/null
+++ b/briar-tests/src/org/briarproject/ValidatorTestCase.java
@@ -0,0 +1,23 @@
+package org.briarproject;
+
+import org.briarproject.api.sync.ClientId;
+import org.briarproject.api.sync.Group;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.Message;
+import org.briarproject.api.sync.MessageId;
+
+public abstract class ValidatorTestCase extends BriarMockTestCase {
+
+	protected final MessageId messageId =
+			new MessageId(TestUtils.getRandomId());
+	protected final GroupId groupId = new GroupId(TestUtils.getRandomId());
+	protected final long timestamp = 1234567890 * 1000L;
+	protected final byte[] raw = TestUtils.getRandomBytes(123);
+	protected final Message message =
+			new Message(messageId, groupId, timestamp, raw);
+	protected final ClientId clientId =
+			new ClientId(TestUtils.getRandomString(123));
+	protected final byte[] descriptor = TestUtils.getRandomBytes(123);
+	protected final Group group = new Group(groupId, clientId, descriptor);
+
+}
diff --git a/briar-tests/src/org/briarproject/clients/BdfMessageValidatorTest.java b/briar-tests/src/org/briarproject/clients/BdfMessageValidatorTest.java
new file mode 100644
index 0000000000..8c567e295e
--- /dev/null
+++ b/briar-tests/src/org/briarproject/clients/BdfMessageValidatorTest.java
@@ -0,0 +1,189 @@
+package org.briarproject.clients;
+
+import org.briarproject.ValidatorTestCase;
+import org.briarproject.api.FormatException;
+import org.briarproject.api.clients.BdfMessageContext;
+import org.briarproject.api.clients.ClientHelper;
+import org.briarproject.api.data.BdfDictionary;
+import org.briarproject.api.data.BdfList;
+import org.briarproject.api.data.MetadataEncoder;
+import org.briarproject.api.db.Metadata;
+import org.briarproject.api.sync.Group;
+import org.briarproject.api.sync.InvalidMessageException;
+import org.briarproject.api.sync.Message;
+import org.briarproject.api.sync.MessageContext;
+import org.briarproject.api.system.Clock;
+import org.jmock.Expectations;
+import org.jmock.lib.legacy.ClassImposteriser;
+import org.junit.Test;
+
+import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
+import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+public class BdfMessageValidatorTest extends ValidatorTestCase {
+
+	private final ClientHelper clientHelper = context.mock(ClientHelper.class);
+	private final MetadataEncoder metadataEncoder =
+			context.mock(MetadataEncoder.class);
+	private final Clock clock = context.mock(Clock.class);
+
+	private final BdfList body = BdfList.of(123, 456);
+	private final BdfDictionary dictionary = new BdfDictionary();
+	private final Metadata meta = new Metadata();
+
+	public BdfMessageValidatorTest() {
+		context.setImposteriser(ClassImposteriser.INSTANCE);
+	}
+
+	@Test(expected = InvalidMessageException.class)
+	public void testRejectsFarFutureTimestamp() throws Exception {
+		context.checking(new Expectations() {{
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE - 1));
+		}});
+
+		BdfMessageValidator v = new BdfMessageValidator(clientHelper,
+				metadataEncoder, clock) {
+			@Override
+			protected BdfMessageContext validateMessage(Message m, Group g,
+					BdfList b) throws InvalidMessageException, FormatException {
+				fail();
+				return null;
+			}
+		};
+		v.validateMessage(message, group);
+	}
+
+	@Test
+	public void testAcceptsMaxTimestamp() throws Exception {
+		context.checking(new Expectations() {{
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE));
+			oneOf(clientHelper).toList(raw, MESSAGE_HEADER_LENGTH,
+					raw.length - MESSAGE_HEADER_LENGTH);
+			will(returnValue(body));
+			oneOf(metadataEncoder).encode(dictionary);
+			will(returnValue(meta));
+		}});
+
+		BdfMessageValidator v = new BdfMessageValidator(clientHelper,
+				metadataEncoder, clock) {
+			@Override
+			protected BdfMessageContext validateMessage(Message m, Group g,
+					BdfList b) throws InvalidMessageException, FormatException {
+				assertSame(message, m);
+				assertSame(group, g);
+				assertSame(body, b);
+				return new BdfMessageContext(dictionary);
+			}
+		};
+		MessageContext messageContext = v.validateMessage(message, group);
+		assertEquals(0, messageContext.getDependencies().size());
+		assertSame(meta, messageContext.getMetadata());
+	}
+
+	@Test(expected = InvalidMessageException.class)
+	public void testRejectsTooShortMessage() throws Exception {
+		final byte[] invalidRaw = new byte[MESSAGE_HEADER_LENGTH];
+		// Use a mock message so the length of the raw message can be invalid
+		final Message invalidMessage = context.mock(Message.class);
+
+		context.checking(new Expectations() {{
+			oneOf(invalidMessage).getTimestamp();
+			will(returnValue(timestamp));
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(timestamp));
+			oneOf(invalidMessage).getRaw();
+			will(returnValue(invalidRaw));
+		}});
+
+		BdfMessageValidator v = new BdfMessageValidator(clientHelper,
+				metadataEncoder, clock) {
+			@Override
+			protected BdfMessageContext validateMessage(Message m, Group g,
+					BdfList b) throws InvalidMessageException, FormatException {
+				fail();
+				return null;
+			}
+		};
+		v.validateMessage(invalidMessage, group);
+	}
+
+	@Test
+	public void testAcceptsMinLengthMessage() throws Exception {
+		final byte[] shortRaw = new byte[MESSAGE_HEADER_LENGTH + 1];
+		final Message shortMessage =
+				new Message(messageId, groupId, timestamp, shortRaw);
+
+		context.checking(new Expectations() {{
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(timestamp));
+			oneOf(clientHelper).toList(shortRaw, MESSAGE_HEADER_LENGTH,
+					shortRaw.length - MESSAGE_HEADER_LENGTH);
+			will(returnValue(body));
+			oneOf(metadataEncoder).encode(dictionary);
+			will(returnValue(meta));
+		}});
+
+		BdfMessageValidator v = new BdfMessageValidator(clientHelper,
+				metadataEncoder, clock) {
+			@Override
+			protected BdfMessageContext validateMessage(Message m, Group g,
+					BdfList b) throws InvalidMessageException, FormatException {
+				assertSame(shortMessage, m);
+				assertSame(group, g);
+				assertSame(body, b);
+				return new BdfMessageContext(dictionary);
+			}
+		};
+		MessageContext messageContext = v.validateMessage(shortMessage, group);
+		assertEquals(0, messageContext.getDependencies().size());
+		assertSame(meta, messageContext.getMetadata());
+	}
+
+	@Test(expected = InvalidMessageException.class)
+	public void testRejectsInvalidBdfList() throws Exception {
+		context.checking(new Expectations() {{
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(timestamp));
+			oneOf(clientHelper).toList(raw, MESSAGE_HEADER_LENGTH,
+					raw.length - MESSAGE_HEADER_LENGTH);
+			will(throwException(new FormatException()));
+		}});
+
+		BdfMessageValidator v = new BdfMessageValidator(clientHelper,
+				metadataEncoder, clock) {
+			@Override
+			protected BdfMessageContext validateMessage(Message m, Group g,
+					BdfList b) throws InvalidMessageException, FormatException {
+				fail();
+				return null;
+			}
+		};
+		v.validateMessage(message, group);
+	}
+
+	@Test(expected = InvalidMessageException.class)
+	public void testRethrowsFormatExceptionFromSubclass() throws Exception {
+		context.checking(new Expectations() {{
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(timestamp));
+			oneOf(clientHelper).toList(raw, MESSAGE_HEADER_LENGTH,
+					raw.length - MESSAGE_HEADER_LENGTH);
+			will(returnValue(body));
+		}});
+
+		BdfMessageValidator v = new BdfMessageValidator(clientHelper,
+				metadataEncoder, clock) {
+			@Override
+			protected BdfMessageContext validateMessage(Message m, Group g,
+					BdfList b) throws InvalidMessageException, FormatException {
+				throw new FormatException();
+			}
+		};
+		v.validateMessage(message, group);
+	}
+}
diff --git a/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java b/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java
index f73d02f966..d9b62b5a33 100644
--- a/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java
+++ b/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java
@@ -1,21 +1,14 @@
 package org.briarproject.messaging;
 
-import org.briarproject.BriarTestCase;
 import org.briarproject.TestUtils;
+import org.briarproject.ValidatorTestCase;
 import org.briarproject.api.FormatException;
 import org.briarproject.api.clients.BdfMessageContext;
 import org.briarproject.api.clients.ClientHelper;
 import org.briarproject.api.data.BdfDictionary;
 import org.briarproject.api.data.BdfList;
 import org.briarproject.api.data.MetadataEncoder;
-import org.briarproject.api.sync.ClientId;
-import org.briarproject.api.sync.Group;
-import org.briarproject.api.sync.GroupId;
-import org.briarproject.api.sync.Message;
-import org.briarproject.api.sync.MessageId;
 import org.briarproject.api.system.Clock;
-import org.jmock.Mockery;
-import org.junit.After;
 import org.junit.Test;
 
 import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
@@ -23,32 +16,15 @@ import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
-public class PrivateMessageValidatorTest extends BriarTestCase {
+public class PrivateMessageValidatorTest extends ValidatorTestCase {
 
-	private final Mockery context = new Mockery();
 	private final ClientHelper clientHelper = context.mock(ClientHelper.class);
 	private final MetadataEncoder metadataEncoder =
 			context.mock(MetadataEncoder.class);
 	private final Clock clock = context.mock(Clock.class);
 
-	private final MessageId messageId = new MessageId(TestUtils.getRandomId());
-	private final GroupId groupId = new GroupId(TestUtils.getRandomId());
-	private final long timestamp = 1234567890 * 1000L;
-	private final byte[] raw = TestUtils.getRandomBytes(123);
-	private final Message message =
-			new Message(messageId, groupId, timestamp, raw);
-	private final ClientId clientId =
-			new ClientId(TestUtils.getRandomString(123));
-	private final byte[] descriptor = TestUtils.getRandomBytes(123);
-	private final Group group = new Group(groupId, clientId, descriptor);
-
-	@After
-	public void checkExpectations() {
-		context.assertIsSatisfied();
-	}
-
 	@Test(expected = FormatException.class)
-	public void testRejectsEmptyBody() throws Exception {
+	public void testRejectsTooShortBody() throws Exception {
 		PrivateMessageValidator v = new PrivateMessageValidator(clientHelper,
 				metadataEncoder, clock);
 		v.validateMessage(message, group, new BdfList());
@@ -58,7 +34,7 @@ public class PrivateMessageValidatorTest extends BriarTestCase {
 	public void testRejectsTooLongBody() throws Exception {
 		PrivateMessageValidator v = new PrivateMessageValidator(clientHelper,
 				metadataEncoder, clock);
-		v.validateMessage(message, group, BdfList.of("", ""));
+		v.validateMessage(message, group, BdfList.of(1, 2));
 	}
 
 	@Test(expected = FormatException.class)
@@ -79,9 +55,9 @@ public class PrivateMessageValidatorTest extends BriarTestCase {
 	public void testRejectsTooLongContent() throws Exception {
 		PrivateMessageValidator v = new PrivateMessageValidator(clientHelper,
 				metadataEncoder, clock);
-		String content =
+		String invalidContent =
 				TestUtils.getRandomString(MAX_PRIVATE_MESSAGE_BODY_LENGTH + 1);
-		v.validateMessage(message, group, BdfList.of(content));
+		v.validateMessage(message, group, BdfList.of(invalidContent));
 	}
 
 	@Test
@@ -90,27 +66,27 @@ public class PrivateMessageValidatorTest extends BriarTestCase {
 				metadataEncoder, clock);
 		String content =
 				TestUtils.getRandomString(MAX_PRIVATE_MESSAGE_BODY_LENGTH);
-		BdfMessageContext context =
+		BdfMessageContext messageContext =
 				v.validateMessage(message, group, BdfList.of(content));
-		assertExpectedContext(context);
+		assertExpectedContext(messageContext);
 	}
 
 	@Test
-	public void testAcceptsEmptyContent() throws Exception {
+	public void testAcceptsMinLengthContent() throws Exception {
 		PrivateMessageValidator v = new PrivateMessageValidator(clientHelper,
 				metadataEncoder, clock);
-		BdfMessageContext context =
+		BdfMessageContext messageContext =
 				v.validateMessage(message, group, BdfList.of(""));
-		assertExpectedContext(context);
+		assertExpectedContext(messageContext);
 	}
 
-	private void assertExpectedContext(BdfMessageContext context)
+	private void assertExpectedContext(BdfMessageContext messageContext)
 			throws FormatException {
-		assertEquals(0, context.getDependencies().size());
-		BdfDictionary meta = context.getDictionary();
+		BdfDictionary meta = messageContext.getDictionary();
 		assertEquals(3, meta.size());
 		assertEquals(Long.valueOf(timestamp), meta.getLong("timestamp"));
 		assertFalse(meta.getBoolean("local"));
 		assertFalse(meta.getBoolean(MSG_KEY_READ));
+		assertEquals(0, messageContext.getDependencies().size());
 	}
 }
-- 
GitLab