Replaced private messages with private groups.

Private messages are now the same as group messages, but groups can be
private or public. When a contact is added, a private group is created
and designated as the inbox for exchanging private messages with the
contact.
This commit is contained in:
akwizgran
2013-12-19 21:53:26 +00:00
parent 1d4213e9c6
commit 0dc869228b
61 changed files with 1717 additions and 2329 deletions

View File

@@ -95,7 +95,7 @@ public class ProtocolIntegrationTest extends BriarTestCase {
new Random().nextBytes(secret);
// Create a group
GroupFactory groupFactory = i.getInstance(GroupFactory.class);
group = groupFactory.createGroup("Group");
group = groupFactory.createGroup("Group", false);
// Create an author
AuthorFactory authorFactory = i.getInstance(AuthorFactory.class);
CryptoComponent crypto = i.getInstance(CryptoComponent.class);

View File

@@ -31,11 +31,11 @@ import net.sf.briar.api.db.NoSuchTransportException;
import net.sf.briar.api.db.event.ContactAddedEvent;
import net.sf.briar.api.db.event.ContactRemovedEvent;
import net.sf.briar.api.db.event.DatabaseListener;
import net.sf.briar.api.db.event.GroupMessageAddedEvent;
import net.sf.briar.api.db.event.LocalAuthorAddedEvent;
import net.sf.briar.api.db.event.LocalAuthorRemovedEvent;
import net.sf.briar.api.db.event.LocalSubscriptionsUpdatedEvent;
import net.sf.briar.api.db.event.PrivateMessageAddedEvent;
import net.sf.briar.api.db.event.MessageAddedEvent;
import net.sf.briar.api.db.event.MessageReceivedEvent;
import net.sf.briar.api.db.event.SubscriptionAddedEvent;
import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
import net.sf.briar.api.lifecycle.ShutdownManager;
@@ -68,12 +68,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
protected final Author author;
protected final AuthorId localAuthorId;
protected final LocalAuthor localAuthor;
protected final MessageId messageId, messageId1, privateMessageId;
protected final MessageId messageId, messageId1;
protected final String contentType, subject;
protected final long timestamp;
protected final int size;
protected final byte[] raw;
protected final Message message, privateMessage;
protected final Message message, message1;
protected final TransportId transportId;
protected final TransportProperties transportProperties;
protected final ContactId contactId;
@@ -83,7 +83,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
public DatabaseComponentTest() {
groupId = new GroupId(TestUtils.getRandomId());
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH]);
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH], true);
authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId());
@@ -91,7 +91,6 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100]);
messageId = new MessageId(TestUtils.getRandomId());
messageId1 = new MessageId(TestUtils.getRandomId());
privateMessageId = new MessageId(TestUtils.getRandomId());
contentType = "text/plain";
subject = "Foo";
timestamp = System.currentTimeMillis();
@@ -99,7 +98,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
raw = new byte[size];
message = new TestMessage(messageId, null, group, author, contentType,
subject, timestamp, raw);
privateMessage = new TestMessage(privateMessageId, null, null, null,
message1 = new TestMessage(messageId1, messageId, group, null,
contentType, subject, timestamp, raw);
transportId = new TransportId(TestUtils.getRandomId());
transportProperties = new TransportProperties(Collections.singletonMap(
@@ -136,13 +135,13 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
with(any(long.class)));
oneOf(shutdown).addShutdownHook(with(any(Runnable.class)));
will(returnValue(shutdownHandle));
// addLocalAuthor(localAuthor)
// addLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(listener).eventOccurred(with(any(
LocalAuthorAddedEvent.class)));
// addContact(author, localAuthorId)
// addContact()
oneOf(database).containsContact(txn, authorId);
will(returnValue(false));
oneOf(database).containsLocalAuthor(txn, localAuthorId);
@@ -153,43 +152,43 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
// getContacts()
oneOf(database).getContacts(txn);
will(returnValue(Arrays.asList(contact)));
// getRemoteProperties(transportId)
// getRemoteProperties()
oneOf(database).getRemoteProperties(txn, transportId);
will(returnValue(Collections.emptyMap()));
// subscribe(group)
oneOf(database).containsSubscription(txn, groupId);
// addGroup()
oneOf(database).containsGroup(txn, groupId);
will(returnValue(false));
oneOf(database).addSubscription(txn, group);
oneOf(database).addGroup(txn, group);
will(returnValue(true));
oneOf(listener).eventOccurred(with(any(
SubscriptionAddedEvent.class)));
// subscribe(group) again
oneOf(database).containsSubscription(txn, groupId);
// addGroup() again
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
// getMessageHeaders(groupId)
oneOf(database).containsSubscription(txn, groupId);
// getMessageHeaders()
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).getGroupMessageHeaders(txn, groupId);
oneOf(database).getMessageHeaders(txn, groupId);
will(returnValue(Collections.emptyList()));
// getSubscriptions()
oneOf(database).getSubscriptions(txn);
// getGroups()
oneOf(database).getGroups(txn);
will(returnValue(Arrays.asList(groupId)));
// unsubscribe(groupId)
oneOf(database).containsSubscription(txn, groupId);
// removeGroup()
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).getVisibility(txn, groupId);
will(returnValue(Collections.emptyList()));
oneOf(database).removeSubscription(txn, groupId);
oneOf(database).removeGroup(txn, groupId);
oneOf(listener).eventOccurred(with(any(
SubscriptionRemovedEvent.class)));
oneOf(listener).eventOccurred(with(any(
LocalSubscriptionsUpdatedEvent.class)));
// removeContact(contactId)
// removeContact()
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).removeContact(txn, contactId);
oneOf(listener).eventOccurred(with(any(ContactRemovedEvent.class)));
// removeLocalAuthor(localAuthorId)
// removeLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(true));
oneOf(database).getContacts(txn, localAuthorId);
@@ -212,12 +211,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
assertEquals(Arrays.asList(contact), db.getContacts());
assertEquals(Collections.emptyMap(),
db.getRemoteProperties(transportId));
db.subscribe(group); // First time - listeners called
db.subscribe(group); // Second time - not called
assertEquals(Collections.emptyList(),
db.getGroupMessageHeaders(groupId));
assertEquals(Arrays.asList(groupId), db.getSubscriptions());
db.unsubscribe(group);
db.addGroup(group); // First time - listeners called
db.addGroup(group); // Second time - not called
assertEquals(Collections.emptyList(), db.getMessageHeaders(groupId));
assertEquals(Arrays.asList(groupId), db.getGroups());
db.removeGroup(group);
db.removeContact(contactId);
db.removeLocalAuthor(localAuthorId);
db.removeListener(listener);
@@ -227,7 +225,29 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
}
@Test
public void testGroupMessagesAreNotStoredUnlessSubscribed()
public void testDuplicateLocalMessagesAreNotStored() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsMessage(txn, messageId);
will(returnValue(true));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalMessage(message);
context.assertIsSatisfied();
}
@Test
public void testLocalMessagesAreNotStoredUnlessSubscribed()
throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
@@ -235,125 +255,52 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsMessage(txn, messageId);
will(returnValue(false));
oneOf(database).containsGroup(txn, groupId);
will(returnValue(false));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
db.addLocalMessage(message);
context.assertIsSatisfied();
}
@Test
public void testDuplicateGroupMessagesAreNotStored() throws Exception {
public void testAddLocalMessage() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message, false);
oneOf(database).containsMessage(txn, messageId);
will(returnValue(false));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
context.assertIsSatisfied();
}
@Test
public void testAddLocalGroupMessage() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message, false);
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).addMessage(txn, message, false);
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).getContactIds(txn);
will(returnValue(Arrays.asList(contactId)));
oneOf(database).addStatus(txn, contactId, messageId, false);
oneOf(database).commitTransaction(txn);
// The message was added, so the listener should be called
oneOf(listener).eventOccurred(with(any(
MessageAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalGroupMessage(message);
context.assertIsSatisfied();
}
@Test
public void testDuplicatePrivateMessagesAreNotStored() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(false));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalPrivateMessage(privateMessage, contactId);
context.assertIsSatisfied();
}
@Test
public void testAddLocalPrivateMessage() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, privateMessageId, true);
oneOf(database).addStatus(txn, contactId, privateMessageId, false);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addLocalPrivateMessage(privateMessage, contactId);
db.addListener(listener);
db.addLocalMessage(message);
context.assertIsSatisfied();
}
@@ -383,7 +330,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
} catch(NoSuchContactException expected) {}
try {
db.addLocalPrivateMessage(privateMessage, contactId);
db.containsSendableMessages(contactId);
fail();
} catch(NoSuchContactException expected) {}
@@ -443,12 +390,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
} catch(NoSuchContactException expected) {}
try {
db.getVisibleSubscriptions(contactId);
fail();
} catch(NoSuchContactException expected) {}
try {
db.hasSendableMessages(contactId);
db.getInboxGroup(contactId);
fail();
} catch(NoSuchContactException expected) {}
@@ -522,6 +464,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
fail();
} catch(NoSuchContactException expected) {}
try {
db.setInboxGroup(contactId, group);
fail();
} catch(NoSuchContactException expected) {}
try {
db.setSeen(contactId, Arrays.asList(messageId));
fail();
@@ -582,7 +529,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
// Check whether the subscription is in the DB (which it's not)
exactly(5).of(database).startTransaction();
will(returnValue(txn));
exactly(5).of(database).containsSubscription(txn, groupId);
exactly(5).of(database).containsGroup(txn, groupId);
will(returnValue(false));
exactly(5).of(database).abortTransaction(txn);
}});
@@ -595,7 +542,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
} catch(NoSuchSubscriptionException expected) {}
try {
db.getGroupMessageHeaders(groupId);
db.getMessageHeaders(groupId);
fail();
} catch(NoSuchSubscriptionException expected) {}
@@ -605,12 +552,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
} catch(NoSuchSubscriptionException expected) {}
try {
db.setVisibility(groupId, Collections.<ContactId>emptyList());
db.removeGroup(group);
fail();
} catch(NoSuchSubscriptionException expected) {}
try {
db.unsubscribe(group);
db.setVisibility(groupId, Collections.<ContactId>emptyList());
fail();
} catch(NoSuchSubscriptionException expected) {}
@@ -626,14 +573,14 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
// addLocalAuthor(localAuthor)
// addLocalAuthor()
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(database).commitTransaction(txn);
// addContact(author, localAuthorId)
// addContact()
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsContact(txn, authorId);
@@ -830,12 +777,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// Get the sendable message IDs
oneOf(database).getMessagesToOffer(txn, contactId, 123);
will(returnValue(messagesToOffer));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -856,11 +803,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getRetentionUpdate(txn, contactId, Long.MAX_VALUE);
will(returnValue(null));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -880,11 +827,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getRetentionUpdate(txn, contactId, Long.MAX_VALUE);
will(returnValue(new RetentionUpdate(0, 1)));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -907,12 +854,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getSubscriptionUpdate(txn, contactId,
Long.MAX_VALUE);
will(returnValue(null));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -932,12 +879,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getSubscriptionUpdate(txn, contactId,
Long.MAX_VALUE);
will(returnValue(new SubscriptionUpdate(Arrays.asList(group), 1)));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -960,11 +907,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getTransportUpdates(txn, contactId, Long.MAX_VALUE);
will(returnValue(null));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -984,12 +931,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).getTransportUpdates(txn, contactId, Long.MAX_VALUE);
will(returnValue(Arrays.asList(new TransportUpdate(transportId,
transportProperties, 1))));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1016,12 +963,10 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// Get the acked messages
oneOf(database).removeOutstandingMessages(txn, contactId,
Arrays.asList(messageId));
oneOf(database).setStatusSeenIfVisible(txn, contactId, messageId);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1032,82 +977,92 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
}
@Test
public void testReceivePrivateMessage() throws Exception {
public void testReceiveMessage() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// The message is stored
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
true);
will(returnValue(true));
oneOf(database).addStatus(txn, contactId, privateMessageId, true);
// The message must be acked
oneOf(database).addMessageToAck(txn, contactId, privateMessageId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveMessage(contactId, privateMessage);
context.assertIsSatisfied();
}
@Test
public void testReceiveDuplicatePrivateMessage() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// The message is not stored, it's a duplicate
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
true);
oneOf(database).containsMessage(txn, messageId);
will(returnValue(false));
// The message must still be acked
oneOf(database).addMessageToAck(txn, contactId, privateMessageId);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.receiveMessage(contactId, privateMessage);
context.assertIsSatisfied();
}
@Test
public void testReceiveMessageDoesNotStoreGroupMessageUnlessSubscribed()
throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
will(returnValue(true));
// Only store messages belonging to visible, subscribed groups
oneOf(database).containsVisibleSubscription(txn, contactId,
groupId);
will(returnValue(false));
// The message is not stored but it must still be acked
oneOf(database).addMessage(txn, message, true);
oneOf(database).addStatus(txn, contactId, messageId, true);
oneOf(database).getContactIds(txn);
will(returnValue(Arrays.asList(contactId)));
oneOf(database).addMessageToAck(txn, contactId, messageId);
oneOf(database).commitTransaction(txn);
// The message was received and added
oneOf(listener).eventOccurred(with(any(
MessageReceivedEvent.class)));
oneOf(listener).eventOccurred(with(any(MessageAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.receiveMessage(contactId, message);
context.assertIsSatisfied();
}
@Test
public void testReceiveDuplicateMessage() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).containsMessage(txn, messageId);
will(returnValue(true));
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
will(returnValue(true));
// The message wasn't stored but it must still be acked
oneOf(database).addMessageToAck(txn, contactId, messageId);
oneOf(database).commitTransaction(txn);
// The message was received but not added
oneOf(listener).eventOccurred(with(any(
MessageReceivedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.receiveMessage(contactId, message);
context.assertIsSatisfied();
}
@Test
public void testReceiveMessageWithoutVisibleGroup() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).containsMessage(txn, messageId);
will(returnValue(false));
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
will(returnValue(false));
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1132,7 +1087,6 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// Get the offered messages
@@ -1142,6 +1096,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
will(returnValue(true)); // Visible - ack message # 1
oneOf(database).setStatusSeenIfVisible(txn, contactId, messageId2);
will(returnValue(false)); // Not visible - request message # 2
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1168,10 +1123,10 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).setRetentionUpdateAcked(txn, contactId, 1);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1192,10 +1147,10 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).setSubscriptionUpdateAcked(txn, contactId, 1);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1216,11 +1171,10 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).setSubscriptions(txn, contactId,
Arrays.asList(group), 1);
oneOf(database).setGroups(txn, contactId, Arrays.asList(group), 1);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1241,13 +1195,13 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).containsTransport(txn, transportId);
will(returnValue(true));
oneOf(database).setTransportUpdateAcked(txn, contactId,
transportId, 1);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1268,11 +1222,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
oneOf(database).setRemoteProperties(txn, contactId, transportId,
transportProperties, 1);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1284,132 +1238,6 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.assertIsSatisfied();
}
@Test
public void testAddingGroupMessageCallsListeners() throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
final Database<Object> database = context.mock(Database.class);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).getContactIds(txn);
will(returnValue(Arrays.asList(contactId)));
oneOf(database).addStatus(txn, contactId, messageId, false);
oneOf(database).commitTransaction(txn);
// The message was added, so the listener should be called
oneOf(listener).eventOccurred(with(any(
GroupMessageAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalGroupMessage(message);
context.assertIsSatisfied();
}
@Test
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 ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, privateMessageId, true);
oneOf(database).addStatus(txn, contactId, privateMessageId, false);
// The message was added, so the listener should be called
oneOf(listener).eventOccurred(with(any(
PrivateMessageAddedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
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);
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
// addLocalGroupMessage(message)
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(false));
oneOf(database).commitTransaction(txn);
// The message was not added, so the listener should not be called
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalGroupMessage(message);
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 ShutdownManager shutdown = context.mock(ShutdownManager.class);
final DatabaseListener listener = context.mock(DatabaseListener.class);
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(false));
// The message was not added, so the listener should not be called
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
db.addListener(listener);
db.addLocalPrivateMessage(privateMessage, contactId);
context.assertIsSatisfied();
}
@Test
public void testChangingLocalTransportPropertiesCallsListeners()
throws Exception {
@@ -1477,11 +1305,10 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// setSeen(contactId, Arrays.asList(messageId))
oneOf(database).setStatusSeenIfVisible(txn, contactId, messageId);
oneOf(database).commitTransaction(txn);
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
shutdown);
@@ -1504,7 +1331,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).getVisibility(txn, groupId);
will(returnValue(both));
@@ -1539,7 +1366,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
context.checking(new Expectations() {{
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).getVisibility(txn, groupId);
will(returnValue(both));
@@ -1558,7 +1385,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
}
@Test
public void testSettingVisibleToAllTrueAffectsCurrentContacts()
public void testSettingVisibleToAllAffectsCurrentContacts()
throws Exception {
final ContactId contactId1 = new ContactId(123);
final Collection<ContactId> both = Arrays.asList(contactId, contactId1);
@@ -1572,7 +1399,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
// setVisibility()
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).getVisibility(txn, groupId);
will(returnValue(Collections.emptyList()));
@@ -1586,7 +1413,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
// setVisibleToAll()
oneOf(database).startTransaction();
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
oneOf(database).setVisibleToAll(txn, groupId, true);
oneOf(database).getVisibility(txn, groupId);

View File

@@ -33,7 +33,7 @@ import net.sf.briar.api.TransportId;
import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.clock.SystemClock;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.GroupMessageHeader;
import net.sf.briar.api.db.MessageHeader;
import net.sf.briar.api.messaging.Group;
import net.sf.briar.api.messaging.GroupId;
import net.sf.briar.api.messaging.GroupStatus;
@@ -59,25 +59,24 @@ public class H2DatabaseTest extends BriarTestCase {
private final Author author;
private final AuthorId localAuthorId;
private final LocalAuthor localAuthor;
private final MessageId messageId, messageId1;
private final MessageId messageId;
private final String contentType, subject;
private final long timestamp;
private final int size;
private final byte[] raw;
private final Message message, privateMessage;
private final Message message;
private final TransportId transportId;
private final ContactId contactId;
public H2DatabaseTest() throws Exception {
groupId = new GroupId(TestUtils.getRandomId());
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH]);
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH], false);
authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId());
localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100]);
messageId = new MessageId(TestUtils.getRandomId());
messageId1 = new MessageId(TestUtils.getRandomId());
contentType = "text/plain";
subject = "Foo";
timestamp = System.currentTimeMillis();
@@ -86,8 +85,6 @@ public class H2DatabaseTest extends BriarTestCase {
random.nextBytes(raw);
message = new TestMessage(messageId, null, group, author, contentType,
subject, timestamp, raw);
privateMessage = new TestMessage(messageId1, null, null, null,
contentType, subject, timestamp, raw);
transportId = new TransportId(TestUtils.getRandomId());
contactId = new ContactId(1);
}
@@ -106,15 +103,12 @@ public class H2DatabaseTest extends BriarTestCase {
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
assertTrue(db.containsContact(txn, contactId));
assertFalse(db.containsSubscription(txn, groupId));
db.addSubscription(txn, group);
assertTrue(db.containsSubscription(txn, groupId));
assertFalse(db.containsGroup(txn, groupId));
db.addGroup(txn, group);
assertTrue(db.containsGroup(txn, groupId));
assertFalse(db.containsMessage(txn, messageId));
db.addGroupMessage(txn, message, true);
db.addMessage(txn, message, true);
assertTrue(db.containsMessage(txn, messageId));
assertFalse(db.containsMessage(txn, messageId1));
db.addPrivateMessage(txn, privateMessage, contactId, true);
assertTrue(db.containsMessage(txn, messageId1));
db.commitTransaction(txn);
db.close();
@@ -122,18 +116,14 @@ public class H2DatabaseTest extends BriarTestCase {
db = open(true);
txn = db.startTransaction();
assertTrue(db.containsContact(txn, contactId));
assertTrue(db.containsSubscription(txn, groupId));
assertTrue(db.containsGroup(txn, groupId));
assertTrue(db.containsMessage(txn, messageId));
byte[] raw1 = db.getRawMessage(txn, messageId);
assertArrayEquals(raw, raw1);
assertTrue(db.containsMessage(txn, messageId1));
raw1 = db.getRawMessage(txn, messageId1);
assertArrayEquals(raw, raw1);
// Delete the records
db.removeMessage(txn, messageId);
db.removeMessage(txn, messageId1);
db.removeContact(txn, contactId);
db.removeSubscription(txn, groupId);
db.removeGroup(txn, groupId);
db.commitTransaction(txn);
db.close();
@@ -143,25 +133,24 @@ public class H2DatabaseTest extends BriarTestCase {
assertFalse(db.containsContact(txn, contactId));
assertEquals(Collections.emptyMap(),
db.getRemoteProperties(txn, transportId));
assertFalse(db.containsSubscription(txn, groupId));
assertFalse(db.containsGroup(txn, groupId));
assertFalse(db.containsMessage(txn, messageId));
assertFalse(db.containsMessage(txn, messageId1));
db.commitTransaction(txn);
db.close();
}
@Test
public void testUnsubscribingRemovesGroupMessage() throws Exception {
public void testUnsubscribingRemovesMessage() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group and store a message
db.addSubscription(txn, group);
db.addGroupMessage(txn, message, false);
db.addGroup(txn, group);
db.addMessage(txn, message, false);
// Unsubscribing from the group should remove the message
assertTrue(db.containsMessage(txn, messageId));
db.removeSubscription(txn, groupId);
db.removeGroup(txn, groupId);
assertFalse(db.containsMessage(txn, messageId));
db.commitTransaction(txn);
@@ -169,105 +158,27 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testRemovingContactRemovesPrivateMessage() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and store a private message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addPrivateMessage(txn, privateMessage, contactId, false);
// Removing the contact should remove the message
assertTrue(db.containsMessage(txn, messageId1));
db.removeContact(txn, contactId);
assertFalse(db.containsMessage(txn, messageId1));
db.commitTransaction(txn);
db.close();
}
@Test
public void testSendablePrivateMessagesMustHaveSeenFlagFalse()
throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and store a private message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addPrivateMessage(txn, privateMessage, contactId, false);
// The message has no status yet, so it should not be sendable
assertFalse(db.hasSendableMessages(txn, contactId));
Iterator<MessageId> it =
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertFalse(it.hasNext());
// Adding a status with seen = false should make the message sendable
db.addStatus(txn, contactId, messageId1, false);
assertTrue(db.hasSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertTrue(it.hasNext());
assertEquals(messageId1, it.next());
assertFalse(it.hasNext());
db.commitTransaction(txn);
db.close();
}
@Test
public void testSendablePrivateMessagesMustFitCapacity()
throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and store a private message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addPrivateMessage(txn, privateMessage, contactId, false);
db.addStatus(txn, contactId, messageId1, false);
// The message is sendable, but too large to send
assertTrue(db.hasSendableMessages(txn, contactId));
Iterator<MessageId> it =
db.getSendableMessages(txn, contactId, size - 1).iterator();
assertFalse(it.hasNext());
// The message is just the right size to send
assertTrue(db.hasSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, size).iterator();
assertTrue(it.hasNext());
assertEquals(messageId1, it.next());
assertFalse(it.hasNext());
db.commitTransaction(txn);
db.close();
}
@Test
public void testSendableGroupMessagesMustHaveSeenFlagFalse()
throws Exception {
public void testSendableMessagesMustHaveSeenFlagFalse() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
// The message has no status yet, so it should not be sendable
assertFalse(db.hasSendableMessages(txn, contactId));
assertFalse(db.containsSendableMessages(txn, contactId));
Iterator<MessageId> it =
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertFalse(it.hasNext());
// Adding a status with seen = false should make the message sendable
db.addStatus(txn, contactId, messageId, false);
assertTrue(db.hasSendableMessages(txn, contactId));
assertTrue(db.containsSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertTrue(it.hasNext());
assertEquals(messageId, it.next());
@@ -275,7 +186,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Changing the status to seen = true should make the message unsendable
db.setStatusSeenIfVisible(txn, contactId, messageId);
assertFalse(db.hasSendableMessages(txn, contactId));
assertFalse(db.containsSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertFalse(it.hasNext());
@@ -284,35 +195,35 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testSendableGroupMessagesMustBeSubscribed() throws Exception {
public void testSendableMessagesMustBeSubscribed() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.addGroupMessage(txn, message, false);
db.addMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// The contact is not subscribed, so the message should not be sendable
assertFalse(db.hasSendableMessages(txn, contactId));
assertFalse(db.containsSendableMessages(txn, contactId));
Iterator<MessageId> it =
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertFalse(it.hasNext());
// The contact subscribing should make the message sendable
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
assertTrue(db.hasSendableMessages(txn, contactId));
db.setGroups(txn, contactId, Arrays.asList(group), 1);
assertTrue(db.containsSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertTrue(it.hasNext());
assertEquals(messageId, it.next());
assertFalse(it.hasNext());
// The contact unsubscribing should make the message unsendable
db.setSubscriptions(txn, contactId, Collections.<Group>emptyList(), 2);
assertFalse(db.hasSendableMessages(txn, contactId));
db.setGroups(txn, contactId, Collections.<Group>emptyList(), 2);
assertFalse(db.containsSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertFalse(it.hasNext());
@@ -321,27 +232,27 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testSendableGroupMessagesMustFitCapacity() throws Exception {
public void testSendableMessagesMustFitCapacity() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// The message is sendable, but too large to send
assertTrue(db.hasSendableMessages(txn, contactId));
assertTrue(db.containsSendableMessages(txn, contactId));
Iterator<MessageId> it =
db.getSendableMessages(txn, contactId, size - 1).iterator();
assertFalse(it.hasNext());
// The message is just the right size to send
assertTrue(db.hasSendableMessages(txn, contactId));
assertTrue(db.containsSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, size).iterator();
assertTrue(it.hasNext());
assertEquals(messageId, it.next());
@@ -352,28 +263,28 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testSendableGroupMessagesMustBeVisible() throws Exception {
public void testSendableMessagesMustBeVisible() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.addGroup(txn, group);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// The subscription is not visible to the contact, so the message
// should not be sendable
assertFalse(db.hasSendableMessages(txn, contactId));
assertFalse(db.containsSendableMessages(txn, contactId));
Iterator<MessageId> it =
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertFalse(it.hasNext());
// Making the subscription visible should make the message sendable
db.addVisibility(txn, contactId, groupId);
assertTrue(db.hasSendableMessages(txn, contactId));
assertTrue(db.containsSendableMessages(txn, contactId));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertTrue(it.hasNext());
assertEquals(messageId, it.next());
@@ -389,6 +300,7 @@ public class H2DatabaseTest extends BriarTestCase {
Connection txn = db.startTransaction();
// Add a contact and some messages to ack
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addMessageToAck(txn, contactId, messageId);
@@ -443,10 +355,10 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// Retrieve the message from the database and mark it as sent
@@ -463,7 +375,7 @@ public class H2DatabaseTest extends BriarTestCase {
assertFalse(it.hasNext());
// Pretend that the message was acked
db.removeOutstandingMessages(txn, contactId, Arrays.asList(messageId));
db.setStatusSeenIfVisible(txn, contactId, messageId);
// The message still should not be sendable
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
@@ -482,9 +394,9 @@ public class H2DatabaseTest extends BriarTestCase {
Connection txn = db.startTransaction();
// Subscribe to a group and store two messages
db.addSubscription(txn, group);
db.addGroupMessage(txn, message, false);
db.addGroupMessage(txn, message1, false);
db.addGroup(txn, group);
db.addMessage(txn, message, false);
db.addMessage(txn, message1, false);
// Allowing enough capacity for one message should return the older one
Iterator<MessageId> it = db.getOldMessages(txn, size).iterator();
@@ -507,7 +419,7 @@ public class H2DatabaseTest extends BriarTestCase {
public void testGetFreeSpace() throws Exception {
byte[] largeBody = new byte[ONE_MEGABYTE];
for(int i = 0; i < largeBody.length; i++) largeBody[i] = (byte) i;
Message message1 = new TestMessage(messageId, null, group, author,
Message message = new TestMessage(messageId, null, group, author,
contentType, subject, timestamp, largeBody);
Database<Connection> db = open(false);
@@ -521,8 +433,8 @@ public class H2DatabaseTest extends BriarTestCase {
// Storing a message should reduce the free space
Connection txn = db.startTransaction();
db.addSubscription(txn, group);
db.addGroupMessage(txn, message1, false);
db.addGroup(txn, group);
db.addMessage(txn, message, false);
db.commitTransaction(txn);
assertTrue(db.getFreeSpace() < free);
@@ -741,9 +653,9 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
// The message is not in the database
assertNull(db.getRawMessageIfSendable(txn, contactId, messageId));
@@ -760,10 +672,10 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
// Set the status to seen = true
db.addStatus(txn, contactId, messageId, true);
@@ -784,11 +696,11 @@ public class H2DatabaseTest extends BriarTestCase {
// the message is older than the contact's retention time
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.setRetentionTime(txn, contactId, timestamp + 1, 1);
db.addGroupMessage(txn, message, false);
db.addMessage(txn, message, false);
// Set the status to seen = false
db.addStatus(txn, contactId, messageId, false);
@@ -808,10 +720,10 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
// Set the status to seen = false
db.addStatus(txn, contactId, messageId, false);
@@ -833,9 +745,9 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
// The message is not in the database
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
@@ -853,7 +765,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact with a subscription
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
// There's no local subscription for the group
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
@@ -871,9 +783,9 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.addGroupMessage(txn, message, false);
db.addMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// There's no contact subscription for the group
@@ -892,9 +804,9 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.addGroup(txn, group);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// The subscription is not visible
@@ -913,10 +825,10 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
// The message has already been seen by the contact
db.addStatus(txn, contactId, messageId, true);
@@ -936,10 +848,10 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact, subscribe to a group and store a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message, false);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.addMessage(txn, message, false);
// The message has not been seen by the contact
db.addStatus(txn, contactId, messageId, false);
@@ -958,7 +870,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
// The group should not be visible to the contact
assertEquals(Collections.emptyList(), db.getVisibility(txn, groupId));
@@ -976,59 +888,59 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testGetGroupMessageParentWithNoParent() throws Exception {
public void testGetParentWithNoParent() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addSubscription(txn, group);
db.addGroup(txn, group);
// A message with no parent should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, null, group, null, contentType,
subject, timestamp, raw);
db.addGroupMessage(txn, child, false);
db.addMessage(txn, child, false);
assertTrue(db.containsMessage(txn, childId));
assertNull(db.getGroupMessageParent(txn, childId));
assertNull(db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetGroupMessageParentWithAbsentParent() throws Exception {
public void testGetParentWithAbsentParent() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addSubscription(txn, group);
db.addGroup(txn, group);
// A message with an absent parent should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, parentId, group, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child, false);
db.addMessage(txn, child, false);
assertTrue(db.containsMessage(txn, childId));
assertFalse(db.containsMessage(txn, parentId));
assertNull(db.getGroupMessageParent(txn, childId));
assertNull(db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetGroupMessageParentWithParentInAnotherGroup()
public void testGetParentWithParentInAnotherGroup()
throws Exception {
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
Group group1 = new Group(groupId1, "Another group",
new byte[GROUP_SALT_LENGTH]);
new byte[GROUP_SALT_LENGTH], false);
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to two groups
db.addSubscription(txn, group);
db.addSubscription(txn, group1);
db.addGroup(txn, group);
db.addGroup(txn, group1);
// A message with a parent in another group should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
@@ -1037,48 +949,24 @@ public class H2DatabaseTest extends BriarTestCase {
contentType, subject, timestamp, raw);
Message parent = new TestMessage(parentId, null, group1, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child, false);
db.addGroupMessage(txn, parent, false);
db.addMessage(txn, child, false);
db.addMessage(txn, parent, false);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, parentId));
assertNull(db.getGroupMessageParent(txn, childId));
assertNull(db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetGroupMessageParentWithPrivateParent() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
// A message with a private parent should return null
MessageId childId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, messageId1, group, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child, false);
db.addPrivateMessage(txn, privateMessage, contactId, false);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, messageId1));
assertNull(db.getGroupMessageParent(txn, childId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testGetGroupMessageParentWithParentInSameGroup()
public void testGetParentWithParentInSameGroup()
throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group
db.addSubscription(txn, group);
db.addGroup(txn, group);
// A message with a parent in the same group should return the parent
MessageId childId = new MessageId(TestUtils.getRandomId());
@@ -1087,11 +975,11 @@ public class H2DatabaseTest extends BriarTestCase {
contentType, subject, timestamp, raw);
Message parent = new TestMessage(parentId, null, group, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child, false);
db.addGroupMessage(txn, parent, false);
db.addMessage(txn, child, false);
db.addMessage(txn, parent, false);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, parentId));
assertEquals(parentId, db.getGroupMessageParent(txn, childId));
assertEquals(parentId, db.getParent(txn, childId));
db.commitTransaction(txn);
db.close();
@@ -1105,16 +993,17 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and subscribe to a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addGroup(txn, group);
// Store a couple of messages
int bodyLength = raw.length - 20;
Message message1 = new TestMessage(messageId, null, group, null,
Message message = new TestMessage(messageId, null, group, null,
contentType, subject, timestamp, raw, 5, bodyLength);
Message privateMessage1 = new TestMessage(messageId1, null, null,
null, contentType, subject, timestamp, raw, 10, bodyLength);
db.addGroupMessage(txn, message1, false);
db.addPrivateMessage(txn, privateMessage1, contactId, false);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, null,
contentType, subject, timestamp, raw, 10, bodyLength);
db.addMessage(txn, message, false);
db.addMessage(txn, message1, false);
// Calculate the expected message bodies
byte[] expectedBody = new byte[bodyLength];
@@ -1144,27 +1033,27 @@ public class H2DatabaseTest extends BriarTestCase {
Connection txn = db.startTransaction();
// Subscribe to a group
db.addSubscription(txn, group);
db.addGroup(txn, group);
// Store a couple of messages
db.addGroupMessage(txn, message, false);
db.addMessage(txn, message, false);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
long timestamp1 = System.currentTimeMillis();
Message message1 = new TestMessage(messageId1, parentId, group, author,
contentType, subject, timestamp1, raw);
db.addGroupMessage(txn, message1, false);
db.addMessage(txn, message1, false);
// Mark one of the messages read
assertFalse(db.setReadFlag(txn, messageId, true));
// Retrieve the message headers
Collection<GroupMessageHeader> headers =
db.getGroupMessageHeaders(txn, groupId);
Iterator<GroupMessageHeader> it = headers.iterator();
Collection<MessageHeader> headers =
db.getMessageHeaders(txn, groupId);
Iterator<MessageHeader> it = headers.iterator();
boolean messageFound = false, message1Found = false;
// First header (order is undefined)
assertTrue(it.hasNext());
GroupMessageHeader header = it.next();
MessageHeader header = it.next();
if(messageId.equals(header.getId())) {
assertHeadersMatch(message, header);
assertTrue(header.isRead());
@@ -1199,7 +1088,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.close();
}
private void assertHeadersMatch(Message m, GroupMessageHeader h) {
private void assertHeadersMatch(Message m, MessageHeader h) {
assertEquals(m.getId(), h.getId());
if(m.getParent() == null) assertNull(h.getParent());
else assertEquals(m.getParent(), h.getParent());
@@ -1216,8 +1105,8 @@ public class H2DatabaseTest extends BriarTestCase {
Connection txn = db.startTransaction();
// Subscribe to a group and store a message
db.addSubscription(txn, group);
db.addGroupMessage(txn, message, false);
db.addGroup(txn, group);
db.addMessage(txn, message, false);
// The message should be unread by default
assertFalse(db.getReadFlag(txn, messageId));
@@ -1230,7 +1119,7 @@ public class H2DatabaseTest extends BriarTestCase {
assertTrue(db.setReadFlag(txn, messageId, false));
assertFalse(db.setReadFlag(txn, messageId, false));
// Unsubscribe from the group
db.removeSubscription(txn, groupId);
db.removeGroup(txn, groupId);
db.commitTransaction(txn);
db.close();
@@ -1242,24 +1131,24 @@ public class H2DatabaseTest extends BriarTestCase {
Connection txn = db.startTransaction();
// Subscribe to a couple of groups
db.addSubscription(txn, group);
db.addGroup(txn, group);
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
Group group1 = new Group(groupId1, "Another group",
new byte[GROUP_SALT_LENGTH]);
db.addSubscription(txn, group1);
new byte[GROUP_SALT_LENGTH], false);
db.addGroup(txn, group1);
// Store two messages in the first group
db.addGroupMessage(txn, message, false);
db.addMessage(txn, message, false);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, author,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, message1, false);
db.addMessage(txn, message1, false);
// Store one message in the second group
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
Message message2 = new TestMessage(messageId2, null, group1, author,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, message2, false);
db.addMessage(txn, message2, false);
// Mark one of the messages in the first group read
assertFalse(db.setReadFlag(txn, messageId, true));
@@ -1299,7 +1188,7 @@ public class H2DatabaseTest extends BriarTestCase {
for(int i = 0; i < 100; i++) {
GroupId id = new GroupId(TestUtils.getRandomId());
String name = "Group " + i;
groups.add(new Group(id, name, new byte[GROUP_SALT_LENGTH]));
groups.add(new Group(id, name, new byte[GROUP_SALT_LENGTH], false));
}
Database<Connection> db = open(false);
@@ -1308,7 +1197,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and subscribe to the groups
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
for(Group g : groups) db.addSubscription(txn, g);
for(Group g : groups) db.addGroup(txn, g);
// Make the groups visible to the contact
Collections.shuffle(groups);
@@ -1319,7 +1208,7 @@ public class H2DatabaseTest extends BriarTestCase {
for(Group g : groups) {
if(Math.random() < 0.5)
db.removeVisibility(txn, contactId, g.getId());
db.removeSubscription(txn, g.getId());
db.removeGroup(txn, g.getId());
}
db.commitTransaction(txn);
@@ -1644,11 +1533,11 @@ public class H2DatabaseTest extends BriarTestCase {
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
assertEquals(contactId1, db.addContact(txn, author1, localAuthorId));
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.setSubscriptions(txn, contactId1, Arrays.asList(group), 1);
db.setGroups(txn, contactId, Arrays.asList(group), 1);
db.setGroups(txn, contactId1, Arrays.asList(group), 1);
// The group should be available, not subscribed, not visible to all
assertEquals(Collections.emptyList(), db.getSubscriptions(txn));
assertEquals(Collections.emptyList(), db.getGroups(txn));
Iterator<GroupStatus> it = db.getAvailableGroups(txn).iterator();
assertTrue(it.hasNext());
GroupStatus status = it.next();
@@ -1659,8 +1548,8 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to the group - it should be available, subscribed,
// not visible to all
db.addSubscription(txn, group);
assertEquals(Arrays.asList(group), db.getSubscriptions(txn));
db.addGroup(txn, group);
assertEquals(Arrays.asList(group), db.getGroups(txn));
it = db.getAvailableGroups(txn).iterator();
assertTrue(it.hasNext());
status = it.next();
@@ -1671,8 +1560,8 @@ public class H2DatabaseTest extends BriarTestCase {
// The first contact unsubscribes - the group should be available,
// subscribed, not visible to all
db.setSubscriptions(txn, contactId, Collections.<Group>emptyList(), 2);
assertEquals(Arrays.asList(group), db.getSubscriptions(txn));
db.setGroups(txn, contactId, Collections.<Group>emptyList(), 2);
assertEquals(Arrays.asList(group), db.getGroups(txn));
it = db.getAvailableGroups(txn).iterator();
assertTrue(it.hasNext());
status = it.next();
@@ -1684,7 +1573,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Make the group visible to all contacts - it should be available,
// subscribed, visible to all
db.setVisibleToAll(txn, groupId, true);
assertEquals(Arrays.asList(group), db.getSubscriptions(txn));
assertEquals(Arrays.asList(group), db.getGroups(txn));
it = db.getAvailableGroups(txn).iterator();
assertTrue(it.hasNext());
status = it.next();
@@ -1695,8 +1584,8 @@ public class H2DatabaseTest extends BriarTestCase {
// Unsubscribe from the group - it should be available, not subscribed,
// not visible to all
db.removeSubscription(txn, groupId);
assertEquals(Collections.emptyList(), db.getSubscriptions(txn));
db.removeGroup(txn, groupId);
assertEquals(Collections.emptyList(), db.getGroups(txn));
it = db.getAvailableGroups(txn).iterator();
assertTrue(it.hasNext());
status = it.next();
@@ -1707,8 +1596,8 @@ public class H2DatabaseTest extends BriarTestCase {
// The second contact unsubscribes - the group should no longer be
// available
db.setSubscriptions(txn, contactId1, Collections.<Group>emptyList(), 2);
assertEquals(Collections.emptyList(), db.getSubscriptions(txn));
db.setGroups(txn, contactId1, Collections.<Group>emptyList(), 2);
assertEquals(Collections.emptyList(), db.getGroups(txn));
assertEquals(Collections.emptyList(), db.getAvailableGroups(txn));
db.commitTransaction(txn);

View File

@@ -121,7 +121,7 @@ public class ConstantsTest extends BriarTestCase {
MessageId parent = new MessageId(TestUtils.getRandomId());
// Create a maximum-length group
String groupName = TestUtils.createRandomString(MAX_GROUP_NAME_LENGTH);
Group group = groupFactory.createGroup(groupName);
Group group = groupFactory.createGroup(groupName, false);
// Create a maximum-length author
String authorName =
TestUtils.createRandomString(MAX_AUTHOR_NAME_LENGTH);
@@ -177,13 +177,13 @@ public class ConstantsTest extends BriarTestCase {
@Test
public void testGroupsFitIntoSubscriptionUpdate() throws Exception {
// Create the maximum number of maximum-length groups
Collection<Group> subs = new ArrayList<Group>();
Collection<Group> groups = new ArrayList<Group>();
for(int i = 0; i < MAX_SUBSCRIPTIONS; i++) {
String name = TestUtils.createRandomString(MAX_GROUP_NAME_LENGTH);
subs.add(groupFactory.createGroup(name));
groups.add(groupFactory.createGroup(name, false));
}
// Create a maximum-length subscription update
SubscriptionUpdate u = new SubscriptionUpdate(subs, Long.MAX_VALUE);
SubscriptionUpdate u = new SubscriptionUpdate(groups, Long.MAX_VALUE);
// Serialise the update
ByteArrayOutputStream out = new ByteArrayOutputStream();
PacketWriter writer = packetWriterFactory.createPacketWriter(out, true);

View File

@@ -1,6 +1,7 @@
package net.sf.briar.messaging.simplex;
import static net.sf.briar.api.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static net.sf.briar.api.messaging.MessagingConstants.GROUP_SALT_LENGTH;
import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import java.io.ByteArrayInputStream;
@@ -21,7 +22,9 @@ import net.sf.briar.api.crypto.KeyManager;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.event.DatabaseEvent;
import net.sf.briar.api.db.event.DatabaseListener;
import net.sf.briar.api.db.event.PrivateMessageAddedEvent;
import net.sf.briar.api.db.event.MessageAddedEvent;
import net.sf.briar.api.messaging.Group;
import net.sf.briar.api.messaging.GroupId;
import net.sf.briar.api.messaging.Message;
import net.sf.briar.api.messaging.MessageFactory;
import net.sf.briar.api.messaging.MessageVerifier;
@@ -57,6 +60,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob");
private final Group group;
private final TransportId transportId;
private final byte[] initialSecret;
private final long epoch;
@@ -64,6 +68,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private Injector alice, bob;
public SimplexMessagingIntegrationTest() throws Exception {
GroupId groupId = new GroupId(TestUtils.getRandomId());
group = new Group(groupId, "Group", new byte[GROUP_SALT_LENGTH], true);
transportId = new TransportId(TestUtils.getRandomId());
// Create matching secrets for Alice and Bob
initialSecret = new byte[32];
@@ -116,6 +122,9 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
Author bobAuthor = new Author(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = db.addContact(bobAuthor, aliceId);
// Add the inbox group
db.addGroup(group);
db.setInboxGroup(contactId, group);
// Add the transport and the endpoint
db.addTransport(transportId, LATENCY);
Endpoint ep = new Endpoint(contactId, transportId, epoch, true);
@@ -126,9 +135,9 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
long timestamp = System.currentTimeMillis();
byte[] body = "Hi Bob!".getBytes("UTF-8");
MessageFactory messageFactory = alice.getInstance(MessageFactory.class);
Message message = messageFactory.createPrivateMessage(null, contentType,
timestamp, body);
db.addLocalPrivateMessage(message, contactId);
Message message = messageFactory.createAnonymousMessage(null, group,
contentType, timestamp, body);
db.addLocalMessage(message);
// Create an outgoing simplex connection
ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionRegistry connRegistry =
@@ -172,6 +181,9 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
Author aliceAuthor = new Author(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = db.addContact(aliceAuthor, bobId);
// Add the inbox group
db.addGroup(group);
db.setInboxGroup(contactId, group);
// Add the transport and the endpoint
db.addTransport(transportId, LATENCY);
Endpoint ep = new Endpoint(contactId, transportId, epoch, false);
@@ -227,7 +239,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private boolean messageAdded = false;
public void eventOccurred(DatabaseEvent e) {
if(e instanceof PrivateMessageAddedEvent) messageAdded = true;
if(e instanceof MessageAddedEvent) messageAdded = true;
}
}
}