Implemented subscription visibility. If a subscription is not visible

to a contact, do not accept, offer, or send messages belonging to that
group to or from that contact, and do not list that group in
subscription updates sent to that contact.
This commit is contained in:
akwizgran
2011-07-27 16:43:19 +01:00
parent 4311b1a224
commit e93fbe0b20
8 changed files with 398 additions and 36 deletions

View File

@@ -693,8 +693,8 @@ public abstract class DatabaseComponentTest extends TestCase {
allowing(database).commitTransaction(txn);
allowing(database).containsContact(txn, contactId);
will(returnValue(true));
// Get the local subscriptions
oneOf(database).getSubscriptions(txn);
// Get the visible subscriptions
oneOf(database).getVisibleSubscriptions(txn, contactId);
will(returnValue(Collections.singletonList(group)));
// Add the subscriptions to the writer
oneOf(subscriptionWriter).writeSubscriptions(
@@ -776,10 +776,11 @@ public abstract class DatabaseComponentTest extends TestCase {
allowing(database).commitTransaction(txn);
allowing(database).containsContact(txn, contactId);
will(returnValue(true));
// Only store messages belonging to subscribed groups
// Only store messages belonging to visible, subscribed groups
oneOf(batch).getMessages();
will(returnValue(Collections.singletonList(message)));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsVisibleSubscription(txn, groupId,
contactId);
will(returnValue(false));
// The message is not stored but the batch must still be acked
oneOf(batch).getId();
@@ -807,10 +808,11 @@ public abstract class DatabaseComponentTest extends TestCase {
allowing(database).commitTransaction(txn);
allowing(database).containsContact(txn, contactId);
will(returnValue(true));
// Only store messages belonging to subscribed groups
// Only store messages belonging to visible, subscribed groups
oneOf(batch).getMessages();
will(returnValue(Collections.singletonList(message)));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsVisibleSubscription(txn, groupId,
contactId);
will(returnValue(true));
// The message is stored, but it's a duplicate
oneOf(database).addMessage(txn, message);
@@ -841,10 +843,11 @@ public abstract class DatabaseComponentTest extends TestCase {
allowing(database).commitTransaction(txn);
allowing(database).containsContact(txn, contactId);
will(returnValue(true));
// Only store messages belonging to subscribed groups
// Only store messages belonging to visible, subscribed groups
oneOf(batch).getMessages();
will(returnValue(Collections.singletonList(message)));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsVisibleSubscription(txn, groupId,
contactId);
will(returnValue(true));
// The message is stored, and it's not a duplicate
oneOf(database).addMessage(txn, message);
@@ -884,10 +887,11 @@ public abstract class DatabaseComponentTest extends TestCase {
allowing(database).commitTransaction(txn);
allowing(database).containsContact(txn, contactId);
will(returnValue(true));
// Only store messages belonging to subscribed groups
// Only store messages belonging to visible, subscribed groups
oneOf(batch).getMessages();
will(returnValue(Collections.singletonList(message)));
oneOf(database).containsSubscription(txn, groupId);
oneOf(database).containsVisibleSubscription(txn, groupId,
contactId);
will(returnValue(true));
// The message is stored, and it's not a duplicate
oneOf(database).addMessage(txn, message);

View File

@@ -203,6 +203,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
db.setStatus(txn, contactId, messageId, Status.NEW);
@@ -237,6 +238,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
db.setSendability(txn, messageId, 1);
@@ -275,6 +277,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.addMessage(txn, message);
db.setSendability(txn, messageId, 1);
db.setStatus(txn, contactId, messageId, Status.NEW);
@@ -308,6 +311,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
db.setSendability(txn, messageId, 1);
@@ -328,6 +332,36 @@ public class H2DatabaseTest extends TestCase {
db.close();
}
@Test
public void testSendableMessagesMustBeVisible() throws DbException {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
db.setSendability(txn, messageId, 1);
db.setStatus(txn, contactId, messageId, Status.NEW);
// The subscription is not visible to the contact, so the message
// should not be sendable
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));
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
assertTrue(it.hasNext());
assertEquals(messageId, it.next());
assertFalse(it.hasNext());
db.commitTransaction(txn);
db.close();
}
@Test
public void testBatchesToAck() throws DbException {
BatchId batchId1 = new BatchId(TestUtils.getRandomId());
@@ -365,6 +399,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
db.setSendability(txn, messageId, 1);
@@ -401,6 +436,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
db.setSendability(txn, messageId, 1);
@@ -718,13 +754,14 @@ public class H2DatabaseTest extends TestCase {
db.setTransports(txn, contactId, transports, 1);
assertEquals(transports, db.getTransports(txn, contactId));
// Remove the transport details
db.setTransports(txn, contactId, null, 2);
db.setTransports(txn, contactId,
Collections.<String, String>emptyMap(), 2);
assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId));
// Set the local transport details
db.setTransports(txn, transports);
assertEquals(transports, db.getTransports(txn));
// Remove the local transport details
db.setTransports(txn, null);
db.setTransports(txn, Collections.<String, String>emptyMap());
assertEquals(Collections.emptyMap(), db.getTransports(txn));
db.commitTransaction(txn);
@@ -880,6 +917,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
// Set the sendability to > 0
@@ -904,6 +942,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact and subscribe to a group
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
// The message is not in the database
@@ -949,6 +988,26 @@ public class H2DatabaseTest extends TestCase {
db.close();
}
@Test
public void testSetStatusSeenIfVisibleRequiresVisibility()
throws DbException {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.addMessage(txn, message);
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.setStatus(txn, contactId, messageId, Status.NEW);
// The subscription is not visible
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
db.commitTransaction(txn);
db.close();
}
@Test
public void testSetStatusSeenIfVisibleReturnsTrueIfAlreadySeen()
throws DbException {
@@ -958,6 +1017,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
// The message has already been seen by the contact
@@ -978,6 +1038,7 @@ public class H2DatabaseTest extends TestCase {
// Add a contact, subscribe to a group and store a message
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
db.setVisibility(txn, groupId, Collections.singleton(contactId));
db.setSubscriptions(txn, contactId, Collections.singleton(group), 1);
db.addMessage(txn, message);
// The message has not been seen by the contact
@@ -989,6 +1050,28 @@ public class H2DatabaseTest extends TestCase {
db.close();
}
@Test
public void testVisibility() throws DbException {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
assertEquals(contactId, db.addContact(txn, null));
db.addSubscription(txn, group);
// The group should not be visible to the contact
assertEquals(Collections.emptyList(), db.getVisibility(txn, groupId));
// Make the group visible to the contact
db.setVisibility(txn, groupId, Collections.singleton(contactId));
assertEquals(Collections.singletonList(contactId),
db.getVisibility(txn, groupId));
// Make the group invisible again
db.setVisibility(txn, groupId, Collections.<ContactId>emptySet());
assertEquals(Collections.emptyList(), db.getVisibility(txn, groupId));
}
private Database<Connection> open(boolean resume) throws DbException {
Database<Connection> db = new H2Database(testDir, password, MAX_SIZE,
groupFactory);

View File

@@ -211,7 +211,7 @@ public class FileReadWriteTest extends TestCase {
assertFalse(requested.get(2));
assertTrue(requested.get(3));
// If there are any padding bits, they should all be zero
for(int i = 4; i < requested.size(); i++) assertFalse(requested.get(i));
assertEquals(2, requested.cardinality());
// Read the subscriptions update
assertTrue(reader.hasUserDefined(Tags.SUBSCRIPTIONS));