diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumManagerTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..59c88d4d7fe03b492aad603783d4718ee1abf50b --- /dev/null +++ b/briar-android-tests/src/test/java/org/briarproject/ForumManagerTest.java @@ -0,0 +1,121 @@ +package org.briarproject; + +import junit.framework.Assert; + +import org.briarproject.api.db.DatabaseComponent; +import org.briarproject.api.forum.Forum; +import org.briarproject.api.forum.ForumManager; +import org.briarproject.api.forum.ForumPost; +import org.briarproject.api.forum.ForumPostFactory; +import org.briarproject.api.forum.ForumPostHeader; +import org.briarproject.api.sync.GroupId; +import org.briarproject.contact.ContactModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.forum.ForumModule; +import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.properties.PropertiesModule; +import org.briarproject.sync.SyncModule; +import org.briarproject.transport.TransportModule; +import org.briarproject.util.StringUtils; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Collection; + +import javax.inject.Inject; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ForumManagerTest { + + @Inject + protected ForumManager forumManager; + @Inject + protected ForumPostFactory forumPostFactory; + @Inject + protected DatabaseComponent db; + + private final File testDir = TestUtils.getTestDirectory(); + + @Before + public void setUp() throws Exception { + + assertTrue(testDir.mkdirs()); + File tDir = new File(testDir, "db"); + + ForumManagerTestComponent component = + DaggerForumManagerTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(tDir)) + .build(); + + component.inject(new LifecycleModule.EagerSingletons()); + component.inject(new ForumModule.EagerSingletons()); + component.inject(new CryptoModule.EagerSingletons()); + component.inject(new ContactModule.EagerSingletons()); + component.inject(new TransportModule.EagerSingletons()); + component.inject(new SyncModule.EagerSingletons()); + component.inject(new PropertiesModule.EagerSingletons()); + component.inject(this); + } + + ForumPost createForumPost(GroupId groupId, ForumPost parent, String body, + long ms) + throws Exception { + return forumPostFactory.createAnonymousPost(groupId, ms, + parent == null ? null : parent.getMessage().getId(), + "text/plain", StringUtils.toUtf8(body)); + } + + @Test + public void testForumPost() throws Exception { + assertFalse(db.open()); + assertNotNull(forumManager); + Forum forum = forumManager.addForum("TestForum"); + assertEquals(1, forumManager.getForums().size()); + final long ms1 = System.currentTimeMillis() - 1000L; + final String body1 = "some forum text"; + final long ms2 = System.currentTimeMillis(); + final String body2 = "some other forum text"; + ForumPost post1 = + createForumPost(forum.getGroup().getId(), null, body1, ms1); + assertEquals(ms1, post1.getMessage().getTimestamp()); + ForumPost post2 = + createForumPost(forum.getGroup().getId(), post1, body2, ms2); + assertEquals(ms2, post2.getMessage().getTimestamp()); + forumManager.addLocalPost(post1); + forumManager.setReadFlag(post1.getMessage().getId(), true); + forumManager.addLocalPost(post2); + forumManager.setReadFlag(post2.getMessage().getId(), false); + Collection<ForumPostHeader> headers = + forumManager.getPostHeaders(forum.getGroup().getId()); + assertEquals(2, headers.size()); + for (ForumPostHeader h : headers) { + final String hBody = + StringUtils.fromUtf8(forumManager.getPostBody(h.getId())); + + boolean isPost1 = h.getId().equals(post1.getMessage().getId()); + boolean isPost2 = h.getId().equals(post2.getMessage().getId()); + Assert.assertTrue(isPost1 || isPost2); + if (isPost1) { + assertEquals(h.getTimestamp(), ms1); + assertEquals(body1, hBody); + assertNull(h.getParentId()); + assertTrue(h.isRead()); + } + else { + assertEquals(h.getTimestamp(), ms2); + assertEquals(body2, hBody); + assertEquals(h.getParentId(), post2.getParent()); + assertFalse(h.isRead()); + } + } + forumManager.removeForum(forum); + assertEquals(0, forumManager.getForums().size()); + db.close(); + } +} diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java b/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java new file mode 100644 index 0000000000000000000000000000000000000000..cac69fb0df0754b6af1ada181fb29512d27d2e8b --- /dev/null +++ b/briar-android-tests/src/test/java/org/briarproject/ForumManagerTestComponent.java @@ -0,0 +1,58 @@ +package org.briarproject; + +import org.briarproject.clients.ClientsModule; +import org.briarproject.contact.ContactModule; +import org.briarproject.crypto.CryptoModule; +import org.briarproject.data.DataModule; +import org.briarproject.db.DatabaseModule; +import org.briarproject.event.EventModule; +import org.briarproject.forum.ForumModule; +import org.briarproject.identity.IdentityModule; +import org.briarproject.lifecycle.LifecycleModule; +import org.briarproject.properties.PropertiesModule; +import org.briarproject.sync.SyncModule; +import org.briarproject.system.SystemModule; +import org.briarproject.transport.TransportModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + TestDatabaseModule.class, + TestPluginsModule.class, + TestSeedProviderModule.class, + ClientsModule.class, + ContactModule.class, + CryptoModule.class, + DataModule.class, + DatabaseModule.class, + EventModule.class, + ForumModule.class, + IdentityModule.class, + LifecycleModule.class, + PropertiesModule.class, + SyncModule.class, + SystemModule.class, + TransportModule.class +}) +public interface ForumManagerTestComponent { + + void inject(ForumManagerTest testCase); + + void inject(ContactModule.EagerSingletons init); + + void inject(CryptoModule.EagerSingletons init); + + void inject(ForumModule.EagerSingletons init); + + void inject(LifecycleModule.EagerSingletons init); + + void inject(PropertiesModule.EagerSingletons init); + + void inject(SyncModule.EagerSingletons init); + + void inject(TransportModule.EagerSingletons init); + +} diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index 9aa469abbc4e185f3017a0092de993cfa9bf22f3..b2069a6f2d7d94bf04e1b234d9c2049ced398fbc 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -20,7 +20,6 @@ import android.widget.Toast; import org.briarproject.R; import org.briarproject.android.ActivityComponent; -import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.util.ListLoadingProgressBar; diff --git a/briar-api/src/org/briarproject/api/forum/ForumConstants.java b/briar-api/src/org/briarproject/api/forum/ForumConstants.java index dcdee0132b9d1d807ca402c12e5972e3cf85ce09..0bbf8896bc9ac7757d1af47bb1cf28947e902cd7 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumConstants.java +++ b/briar-api/src/org/briarproject/api/forum/ForumConstants.java @@ -49,4 +49,15 @@ public interface ForumConstants { int TASK_UNSHARE_FORUM_SHARED_BY_US = 6; int TASK_UNSHARE_FORUM_SHARED_WITH_US = 7; + // Database keys + String KEY_TIMESTAMP = "timestamp"; + String KEY_PARENT = "parent"; + String KEY_ID = "id"; + String KEY_NAME = "name"; + String KEY_PUBLIC_NAME = "publicKey"; + String KEY_AUTHOR = "author"; + String KEY_CONTENT_TYPE = "contentType"; + String KEY_LOCAL = "local"; + String KEY_READ = "read"; + } diff --git a/briar-api/src/org/briarproject/api/forum/ForumPostHeader.java b/briar-api/src/org/briarproject/api/forum/ForumPostHeader.java index 15030223eeac2888443e2daee453be1bf8bc1150..00924f98ab0834de48700d4f855128f1de6dcb02 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumPostHeader.java +++ b/briar-api/src/org/briarproject/api/forum/ForumPostHeader.java @@ -6,15 +6,18 @@ import org.briarproject.api.sync.MessageId; public class ForumPostHeader { private final MessageId id; + private final MessageId parentId; private final long timestamp; private final Author author; private final Author.Status authorStatus; private final String contentType; private final boolean read; - public ForumPostHeader(MessageId id, long timestamp, Author author, - Author.Status authorStatus, String contentType, boolean read) { + public ForumPostHeader(MessageId id, MessageId parentId, long timestamp, + Author author, Author.Status authorStatus, String contentType, + boolean read) { this.id = id; + this.parentId = parentId; this.timestamp = timestamp; this.author = author; this.authorStatus = authorStatus; @@ -45,4 +48,8 @@ public class ForumPostHeader { public boolean isRead() { return read; } + + public MessageId getParentId() { + return parentId; + } } diff --git a/briar-core/src/org/briarproject/clients/ClientsModule.java b/briar-core/src/org/briarproject/clients/ClientsModule.java index ac193646ad1579e35d0eabdba82bbc459bec1761..302939ff3047143e9828d96f9f6d29e41761bacb 100644 --- a/briar-core/src/org/briarproject/clients/ClientsModule.java +++ b/briar-core/src/org/briarproject/clients/ClientsModule.java @@ -50,4 +50,5 @@ public class ClientsModule { QueueMessageFactory provideQueueMessageFactory(CryptoComponent crypto) { return new QueueMessageFactoryImpl(crypto); } + } diff --git a/briar-core/src/org/briarproject/forum/ForumManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumManagerImpl.java index af3d4164db7d8750ccf70df55f8483851d0d36ca..29bf817aaea53b313f96dec67837a2ce0e1b9bb9 100644 --- a/briar-core/src/org/briarproject/forum/ForumManagerImpl.java +++ b/briar-core/src/org/briarproject/forum/ForumManagerImpl.java @@ -31,15 +31,28 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Logger; import javax.inject.Inject; +import static org.briarproject.api.forum.ForumConstants.KEY_AUTHOR; +import static org.briarproject.api.forum.ForumConstants.KEY_CONTENT_TYPE; +import static org.briarproject.api.forum.ForumConstants.KEY_ID; +import static org.briarproject.api.forum.ForumConstants.KEY_LOCAL; +import static org.briarproject.api.forum.ForumConstants.KEY_NAME; +import static org.briarproject.api.forum.ForumConstants.KEY_PARENT; +import static org.briarproject.api.forum.ForumConstants.KEY_PUBLIC_NAME; +import static org.briarproject.api.forum.ForumConstants.KEY_READ; +import static org.briarproject.api.forum.ForumConstants.KEY_TIMESTAMP; import static org.briarproject.api.identity.Author.Status.ANONYMOUS; import static org.briarproject.api.identity.Author.Status.UNKNOWN; import static org.briarproject.api.identity.Author.Status.VERIFIED; class ForumManagerImpl implements ForumManager { + private static final Logger LOG = + Logger.getLogger(ForumManagerImpl.class.getName()); + static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString( "859a7be50dca035b64bd6902fb797097" + "795af837abbf8c16d750b3c2ccc186ea")); @@ -95,19 +108,19 @@ class ForumManagerImpl implements ForumManager { public void addLocalPost(ForumPost p) throws DbException { try { BdfDictionary meta = new BdfDictionary(); - meta.put("timestamp", p.getMessage().getTimestamp()); - if (p.getParent() != null) meta.put("parent", p.getParent()); + meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp()); + if (p.getParent() != null) meta.put(KEY_PARENT, p.getParent()); if (p.getAuthor() != null) { Author a = p.getAuthor(); BdfDictionary authorMeta = new BdfDictionary(); - authorMeta.put("id", a.getId()); - authorMeta.put("name", a.getName()); - authorMeta.put("publicKey", a.getPublicKey()); - meta.put("author", authorMeta); + authorMeta.put(KEY_ID, a.getId()); + authorMeta.put(KEY_NAME, a.getName()); + authorMeta.put(KEY_PUBLIC_NAME, a.getPublicKey()); + meta.put(KEY_AUTHOR, authorMeta); } - meta.put("contentType", p.getContentType()); - meta.put("local", true); - meta.put("read", true); + meta.put(KEY_CONTENT_TYPE, p.getContentType()); + meta.put(KEY_LOCAL, true); + meta.put(KEY_READ, true); clientHelper.addLocalMessage(p.getMessage(), CLIENT_ID, meta, true); } catch (FormatException e) { throw new RuntimeException(e); @@ -194,14 +207,17 @@ class ForumManagerImpl implements ForumManager { for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) { try { BdfDictionary meta = entry.getValue(); - long timestamp = meta.getLong("timestamp"); + long timestamp = meta.getLong(KEY_TIMESTAMP); Author author = null; Author.Status authorStatus = ANONYMOUS; - BdfDictionary d1 = meta.getDictionary("author", null); + MessageId parentId = null; + if (meta.containsKey(KEY_PARENT)) + parentId = new MessageId(meta.getRaw(KEY_PARENT)); + BdfDictionary d1 = meta.getDictionary(KEY_AUTHOR, null); if (d1 != null) { - AuthorId authorId = new AuthorId(d1.getRaw("id")); - String name = d1.getString("name"); - byte[] publicKey = d1.getRaw("publicKey"); + AuthorId authorId = new AuthorId(d1.getRaw(KEY_ID)); + String name = d1.getString(KEY_NAME); + byte[] publicKey = d1.getRaw(KEY_PUBLIC_NAME); author = new Author(authorId, name, publicKey); if (localAuthorIds.contains(authorId)) authorStatus = VERIFIED; @@ -209,10 +225,10 @@ class ForumManagerImpl implements ForumManager { authorStatus = VERIFIED; else authorStatus = UNKNOWN; } - String contentType = meta.getString("contentType"); - boolean read = meta.getBoolean("read"); - headers.add(new ForumPostHeader(entry.getKey(), timestamp, - author, authorStatus, contentType, read)); + String contentType = meta.getString(KEY_CONTENT_TYPE); + boolean read = meta.getBoolean(KEY_READ); + headers.add(new ForumPostHeader(entry.getKey(), parentId, + timestamp, author, authorStatus, contentType, read)); } catch (FormatException e) { throw new DbException(e); } @@ -224,7 +240,7 @@ class ForumManagerImpl implements ForumManager { public void setReadFlag(MessageId m, boolean read) throws DbException { try { BdfDictionary meta = new BdfDictionary(); - meta.put("read", read); + meta.put(KEY_READ, read); clientHelper.mergeMessageMetadata(m, meta); } catch (FormatException e) { throw new RuntimeException(e);