Merge branch '122-forum-manager' into 'master'

added parent id to metadata and a unit test

The parent id, a necessary attribute for nested forums, was not being added to the metadata in the forum manager. Additionally, a simple forum manager unit was created.

See merge request !202
This commit is contained in:
Torsten Grote
2016-05-24 18:13:15 +00:00
7 changed files with 235 additions and 22 deletions

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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";
}

View File

@@ -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;
}
}

View File

@@ -50,4 +50,5 @@ public class ClientsModule {
QueueMessageFactory provideQueueMessageFactory(CryptoComponent crypto) {
return new QueueMessageFactoryImpl(crypto);
}
}

View File

@@ -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);