mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Added support for registering listeners with the database that are
called when new messages are available, and a new method hasSendableMessages(ContactId) that listeners can call to see whether it's worth trying to create a batch.
This commit is contained in:
@@ -12,6 +12,7 @@ import net.sf.briar.api.ContactId;
|
||||
import net.sf.briar.api.Rating;
|
||||
import net.sf.briar.api.db.DatabaseComponent;
|
||||
import net.sf.briar.api.db.DbException;
|
||||
import net.sf.briar.api.db.MessageListener;
|
||||
import net.sf.briar.api.db.NoSuchContactException;
|
||||
import net.sf.briar.api.db.Status;
|
||||
import net.sf.briar.api.protocol.Ack;
|
||||
@@ -80,6 +81,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||
final Group group = context.mock(Group.class);
|
||||
final MessageListener listener = context.mock(MessageListener.class);
|
||||
context.checking(new Expectations() {{
|
||||
allowing(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -117,6 +119,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||
|
||||
db.open(false);
|
||||
db.addListener(listener);
|
||||
assertEquals(Rating.UNRATED, db.getRating(authorId));
|
||||
assertEquals(contactId, db.addContact(transports));
|
||||
assertEquals(Collections.singletonList(contactId), db.getContacts());
|
||||
@@ -125,6 +128,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
assertEquals(Collections.singletonList(groupId), db.getSubscriptions());
|
||||
db.unsubscribe(groupId);
|
||||
db.removeContact(contactId);
|
||||
db.removeListener(listener);
|
||||
db.close();
|
||||
|
||||
context.assertIsSatisfied();
|
||||
@@ -388,7 +392,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddingASendableMessageTriggersBackwardInclusion()
|
||||
public void testAddingSendableMessageTriggersBackwardInclusion()
|
||||
throws DbException {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -446,11 +450,11 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
final Transports transportsUpdate = context.mock(Transports.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the contact is still in the DB - which it's not
|
||||
exactly(11).of(database).startTransaction();
|
||||
exactly(12).of(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
exactly(11).of(database).containsContact(txn, contactId);
|
||||
exactly(12).of(database).containsContact(txn, contactId);
|
||||
will(returnValue(false));
|
||||
exactly(11).of(database).commitTransaction(txn);
|
||||
exactly(12).of(database).commitTransaction(txn);
|
||||
}});
|
||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||
|
||||
@@ -485,6 +489,11 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
assertTrue(false);
|
||||
} catch(NoSuchContactException expected) {}
|
||||
|
||||
try {
|
||||
db.hasSendableMessages(contactId);
|
||||
assertTrue(false);
|
||||
} catch(NoSuchContactException expected) {}
|
||||
|
||||
try {
|
||||
db.receiveAck(contactId, ack);
|
||||
assertTrue(false);
|
||||
@@ -1019,4 +1028,65 @@ public abstract class DatabaseComponentTest extends TestCase {
|
||||
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddingMessageCallsListeners() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||
final MessageListener listener = context.mock(MessageListener.class);
|
||||
context.checking(new Expectations() {{
|
||||
// addLocallyGeneratedMessage(message)
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
oneOf(database).containsSubscription(txn, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).addMessage(txn, message);
|
||||
will(returnValue(true));
|
||||
oneOf(database).getContacts(txn);
|
||||
will(returnValue(Collections.singletonList(contactId)));
|
||||
oneOf(database).setStatus(txn, contactId, messageId, Status.NEW);
|
||||
oneOf(database).getRating(txn, authorId);
|
||||
will(returnValue(Rating.UNRATED));
|
||||
oneOf(database).getNumberOfSendableChildren(txn, messageId);
|
||||
will(returnValue(0));
|
||||
oneOf(database).setSendability(txn, messageId, 0);
|
||||
oneOf(database).commitTransaction(txn);
|
||||
// The message was added, so the listener should be called
|
||||
oneOf(listener).messagesAdded();
|
||||
}});
|
||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||
|
||||
db.addListener(listener);
|
||||
db.addLocallyGeneratedMessage(message);
|
||||
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateMessageDoesNotCallListeners() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||
final MessageListener listener = context.mock(MessageListener.class);
|
||||
context.checking(new Expectations() {{
|
||||
// addLocallyGeneratedMessage(message)
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
oneOf(database).containsSubscription(txn, groupId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).addMessage(txn, message);
|
||||
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.addLocallyGeneratedMessage(message);
|
||||
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,12 +210,14 @@ public class H2DatabaseTest extends TestCase {
|
||||
|
||||
// The message should not be sendable
|
||||
assertEquals(0, db.getSendability(txn, messageId));
|
||||
assertFalse(db.hasSendableMessages(txn, contactId));
|
||||
Iterator<MessageId> it =
|
||||
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertFalse(it.hasNext());
|
||||
|
||||
// Changing the sendability to > 0 should make the message sendable
|
||||
db.setSendability(txn, messageId, 1);
|
||||
assertTrue(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertTrue(it.hasNext());
|
||||
assertEquals(messageId, it.next());
|
||||
@@ -223,6 +225,7 @@ public class H2DatabaseTest extends TestCase {
|
||||
|
||||
// Changing the sendability to 0 should make the message unsendable
|
||||
db.setSendability(txn, messageId, 0);
|
||||
assertFalse(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertFalse(it.hasNext());
|
||||
|
||||
@@ -244,12 +247,14 @@ public class H2DatabaseTest extends TestCase {
|
||||
db.setSendability(txn, messageId, 1);
|
||||
|
||||
// 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());
|
||||
|
||||
// Changing the status to Status.NEW should make the message sendable
|
||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||
assertTrue(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertTrue(it.hasNext());
|
||||
assertEquals(messageId, it.next());
|
||||
@@ -257,6 +262,7 @@ public class H2DatabaseTest extends TestCase {
|
||||
|
||||
// Changing the status to SENT should make the message unsendable
|
||||
db.setStatus(txn, contactId, messageId, Status.SENT);
|
||||
assertFalse(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertFalse(it.hasNext());
|
||||
|
||||
@@ -283,12 +289,14 @@ public class H2DatabaseTest extends TestCase {
|
||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||
|
||||
// The contact is not subscribed, so the message should not be sendable
|
||||
assertFalse(db.hasSendableMessages(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, Collections.singleton(group), 1);
|
||||
assertTrue(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertTrue(it.hasNext());
|
||||
assertEquals(messageId, it.next());
|
||||
@@ -296,6 +304,7 @@ public class H2DatabaseTest extends TestCase {
|
||||
|
||||
// The contact unsubscribing should make the message unsendable
|
||||
db.setSubscriptions(txn, contactId, Collections.<Group>emptySet(), 2);
|
||||
assertFalse(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertFalse(it.hasNext());
|
||||
|
||||
@@ -317,12 +326,14 @@ public class H2DatabaseTest extends TestCase {
|
||||
db.setSendability(txn, messageId, 1);
|
||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||
|
||||
// The message is too large to send
|
||||
// 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(messageId, it.next());
|
||||
@@ -347,12 +358,14 @@ public class H2DatabaseTest extends TestCase {
|
||||
|
||||
// The subscription is not visible to the contact, so the message
|
||||
// should not be sendable
|
||||
assertFalse(db.hasSendableMessages(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.setVisibility(txn, groupId, Collections.singleton(contactId));
|
||||
assertTrue(db.hasSendableMessages(txn, contactId));
|
||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||
assertTrue(it.hasNext());
|
||||
assertEquals(messageId, it.next());
|
||||
|
||||
Reference in New Issue
Block a user