From 5f05a7f898a6fdbc2e7c5eadd89776016754e42f Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Fri, 16 Sep 2011 11:33:55 +0100 Subject: [PATCH] Unit tests for private messages. --- .../sf/briar/db/DatabaseComponentImpl.java | 6 +- .../sf/briar/db/DatabaseComponentTest.java | 220 +++++++++++++++++- 2 files changed, 211 insertions(+), 15 deletions(-) diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java index 5ecded11a1..7ccc8277ec 100644 --- a/components/net/sf/briar/db/DatabaseComponentImpl.java +++ b/components/net/sf/briar/db/DatabaseComponentImpl.java @@ -178,7 +178,7 @@ DatabaseCleaner.Callback { */ protected boolean storeGroupMessage(Txn txn, Message m, ContactId sender) throws DbException { - assert m.getGroup() != null; + if(m.getGroup() == null) throw new IllegalArgumentException(); boolean stored = db.addGroupMessage(txn, m); // Mark the message as seen by the sender MessageId id = m.getId(); @@ -228,8 +228,8 @@ DatabaseCleaner.Callback { */ protected boolean storePrivateMessage(Txn txn, Message m, ContactId c, boolean incoming) throws DbException { - assert m.getGroup() == null; - assert m.getAuthor() == null; + if(m.getGroup() != null) throw new IllegalArgumentException(); + if(m.getAuthor() != null) throw new IllegalArgumentException(); if(!db.addPrivateMessage(txn, m, c)) return false; MessageId id = m.getId(); if(incoming) db.setStatus(txn, c, id, Status.SEEN); diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java index a90b64e5b9..cacd90547d 100644 --- a/test/net/sf/briar/db/DatabaseComponentTest.java +++ b/test/net/sf/briar/db/DatabaseComponentTest.java @@ -52,7 +52,7 @@ public abstract class DatabaseComponentTest extends TestCase { private final long timestamp; private final int size; private final byte[] raw; - private final Message message; + private final Message message, privateMessage; private final Group group; private final Map<String, Map<String, String>> transports; private final byte[] secret; @@ -70,6 +70,8 @@ public abstract class DatabaseComponentTest extends TestCase { raw = new byte[size]; message = new TestMessage(messageId, null, groupId, authorId, timestamp, raw); + privateMessage = + new TestMessage(messageId, null, null, null, timestamp, raw); group = new TestGroup(groupId, "The really exciting group", null); transports = Collections.singletonMap("foo", Collections.singletonMap("bar", "baz")); @@ -166,11 +168,11 @@ public abstract class DatabaseComponentTest extends TestCase { assertEquals(connectionWindow, db.getConnectionWindow(contactId, 123)); assertEquals(secret, db.getSharedSecret(contactId)); assertEquals(transports, db.getTransports(contactId)); - db.subscribe(group); - db.subscribe(group); // Again - check listeners aren't called + db.subscribe(group); // First time - check listeners are called + db.subscribe(group); // Second time - check listeners aren't called assertEquals(Collections.singletonList(groupId), db.getSubscriptions()); - db.unsubscribe(groupId); - db.unsubscribe(groupId); // Again - check listeners aren't called + db.unsubscribe(groupId); // First time - check listeners are called + db.unsubscribe(groupId); // Second time - check listeners aren't called db.setConnectionWindow(contactId, 123, connectionWindow); db.removeContact(contactId); db.removeListener(listener); @@ -180,7 +182,7 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testNoParentStopsBackwardInclusion() throws DbException { + public void testNullParentStopsBackwardInclusion() throws DbException { Mockery context = new Mockery(); @SuppressWarnings("unchecked") final Database<Object> database = context.mock(Database.class); @@ -241,7 +243,8 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testChangingGroupsStopsBackwardInclusion() throws DbException { + public void testParentInAnotherGroupStopsBackwardInclusion() + throws DbException { final GroupId groupId1 = new GroupId(TestUtils.getRandomId()); Mockery context = new Mockery(); @SuppressWarnings("unchecked") @@ -277,6 +280,42 @@ public abstract class DatabaseComponentTest extends TestCase { context.assertIsSatisfied(); } + @Test + public void testPrivateParentStopsBackwardInclusion() throws DbException { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + context.checking(new Expectations() {{ + // setRating(Rating.GOOD) + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).setRating(txn, authorId, Rating.GOOD); + // The sendability of the author's messages should be incremented + oneOf(database).getMessagesByAuthor(txn, authorId); + will(returnValue(Collections.singletonList(messageId))); + oneOf(database).getSendability(txn, messageId); + will(returnValue(0)); + oneOf(database).setSendability(txn, messageId, 1); + // The parent exists and is in the database + oneOf(database).getParent(txn, messageId); + will(returnValue(parentId)); + oneOf(database).containsMessage(txn, parentId); + will(returnValue(true)); + // The parent is a private message + oneOf(database).getGroup(txn, messageId); + will(returnValue(groupId)); + oneOf(database).getGroup(txn, parentId); + will(returnValue(null)); + oneOf(database).commitTransaction(txn); + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.setRating(authorId, Rating.GOOD); + + context.assertIsSatisfied(); + } + @Test public void testUnaffectedParentStopsBackwardInclusion() throws DbException { @@ -360,7 +399,7 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testMessagesAreNotStoredUnlessSubscribed() + public void testGroupMessagesAreNotStoredUnlessSubscribed() throws DbException { Mockery context = new Mockery(); @SuppressWarnings("unchecked") @@ -382,7 +421,7 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testDuplicateMessagesAreNotStored() throws DbException { + public void testDuplicateGroupMessagesAreNotStored() throws DbException { Mockery context = new Mockery(); @SuppressWarnings("unchecked") final Database<Object> database = context.mock(Database.class); @@ -472,6 +511,49 @@ public abstract class DatabaseComponentTest extends TestCase { context.assertIsSatisfied(); } + @Test + public void testDuplicatePrivateMessagesAreNotStored() throws DbException { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + context.checking(new Expectations() {{ + // addLocalPrivateMessage(privateMessage, contactId) + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).addPrivateMessage(txn, privateMessage, contactId); + will(returnValue(false)); + oneOf(database).commitTransaction(txn); + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.addLocalPrivateMessage(privateMessage, contactId); + + context.assertIsSatisfied(); + } + + @Test + public void testAddLocalPrivateMessage() throws DbException { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + context.checking(new Expectations() {{ + // addLocalPrivateMessage(privateMessage, contactId) + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).addPrivateMessage(txn, privateMessage, contactId); + will(returnValue(true)); + oneOf(database).setStatus(txn, contactId, messageId, Status.NEW); + oneOf(database).commitTransaction(txn); + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.addLocalPrivateMessage(privateMessage, contactId); + + context.assertIsSatisfied(); + } + @Test public void testVariousMethodsThrowExceptionIfContactIsMissing() throws Exception { @@ -845,7 +927,69 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testReceiveBatchDoesNotStoreIfNotSubscribed() throws Exception { + public void testReceiveBatchStoresPrivateMessage() throws Exception { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + final Batch batch = context.mock(Batch.class); + context.checking(new Expectations() {{ + allowing(database).startTransaction(); + will(returnValue(txn)); + allowing(database).commitTransaction(txn); + allowing(database).containsContact(txn, contactId); + will(returnValue(true)); + oneOf(batch).getMessages(); + will(returnValue(Collections.singletonList(privateMessage))); + // The message is stored + oneOf(database).addPrivateMessage(txn, privateMessage, contactId); + will(returnValue(true)); + oneOf(database).setStatus(txn, contactId, messageId, Status.SEEN); + // The batch must be acked + oneOf(batch).getId(); + will(returnValue(batchId)); + oneOf(database).addBatchToAck(txn, contactId, batchId); + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.receiveBatch(contactId, batch); + + context.assertIsSatisfied(); + } + + @Test + public void testReceiveBatchWithDuplicatePrivateMessage() throws Exception { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + final Batch batch = context.mock(Batch.class); + context.checking(new Expectations() {{ + allowing(database).startTransaction(); + will(returnValue(txn)); + allowing(database).commitTransaction(txn); + allowing(database).containsContact(txn, contactId); + will(returnValue(true)); + oneOf(batch).getMessages(); + will(returnValue(Collections.singletonList(privateMessage))); + // The message is stored, but it's a duplicate + oneOf(database).addPrivateMessage(txn, privateMessage, contactId); + will(returnValue(false)); + // The batch must still be acked + oneOf(batch).getId(); + will(returnValue(batchId)); + oneOf(database).addBatchToAck(txn, contactId, batchId); + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.receiveBatch(contactId, batch); + + context.assertIsSatisfied(); + } + + @Test + public void testReceiveBatchDoesNotStoreGroupMessageUnlessSubscribed() + throws Exception { Mockery context = new Mockery(); @SuppressWarnings("unchecked") final Database<Object> database = context.mock(Database.class); @@ -1103,7 +1247,7 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testAddingMessageCallsListeners() throws Exception { + public void testAddingGroupMessageCallsListeners() throws Exception { Mockery context = new Mockery(); @SuppressWarnings("unchecked") final Database<Object> database = context.mock(Database.class); @@ -1138,7 +1282,34 @@ public abstract class DatabaseComponentTest extends TestCase { } @Test - public void testDuplicateMessageDoesNotCallListeners() throws Exception { + public void testAddingPrivateMessageCallsListeners() throws Exception { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + final DatabaseListener listener = context.mock(DatabaseListener.class); + context.checking(new Expectations() {{ + // addLocalPrivateMessage(privateMessage, contactId) + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).addPrivateMessage(txn, privateMessage, contactId); + will(returnValue(true)); + oneOf(database).setStatus(txn, contactId, messageId, Status.NEW); + oneOf(database).commitTransaction(txn); + // The message was added, so the listener should be called + oneOf(listener).eventOccurred(Event.MESSAGES_ADDED); + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.addListener(listener); + db.addLocalPrivateMessage(privateMessage, contactId); + + context.assertIsSatisfied(); + } + + @Test + public void testAddingDuplicateGroupMessageDoesNotCallListeners() + throws Exception { Mockery context = new Mockery(); @SuppressWarnings("unchecked") final Database<Object> database = context.mock(Database.class); @@ -1163,6 +1334,31 @@ public abstract class DatabaseComponentTest extends TestCase { context.assertIsSatisfied(); } + @Test + public void testAddingDuplicatePrivateMessageDoesNotCallListeners() + throws Exception { + Mockery context = new Mockery(); + @SuppressWarnings("unchecked") + final Database<Object> database = context.mock(Database.class); + final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); + final DatabaseListener listener = context.mock(DatabaseListener.class); + context.checking(new Expectations() {{ + // addLocalPrivateMessage(privateMessage, contactId) + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).addPrivateMessage(txn, privateMessage, contactId); + will(returnValue(false)); + oneOf(database).commitTransaction(txn); + // The message was not added, so the listener should not be called + }}); + DatabaseComponent db = createDatabaseComponent(database, cleaner); + + db.addListener(listener); + db.addLocalPrivateMessage(privateMessage, contactId); + + context.assertIsSatisfied(); + } + @Test public void testTransportPropertiesChangedCallsListeners() throws Exception { -- GitLab