Add AttachmentHeader to AuthorInfo

This way the UI can retrieve the author's avatar (if it exists).
This commit is contained in:
Torsten Grote
2020-11-24 11:15:34 -03:00
parent d0d2e0ed82
commit c3cea37641
14 changed files with 196 additions and 102 deletions

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.api.avatar;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.briar.api.media.Attachment; import org.briarproject.briar.api.media.Attachment;
@@ -42,13 +43,14 @@ public interface AvatarManager {
* or null if none is known. * or null if none is known.
*/ */
@Nullable @Nullable
AttachmentHeader getAvatarHeader(Contact c) throws DbException; AttachmentHeader getAvatarHeader(Transaction txn, Contact c)
throws DbException;
/** /**
* Returns our current profile image header or null if none has been added. * Returns our current profile image header or null if none has been added.
*/ */
@Nullable @Nullable
AttachmentHeader getMyAvatarHeader() throws DbException; AttachmentHeader getMyAvatarHeader(Transaction txn) throws DbException;
/** /**
* Returns the profile image attachment for the given header. * Returns the profile image attachment for the given header.

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.api.identity; package org.briarproject.briar.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.media.AttachmentHeader;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
@@ -20,14 +21,18 @@ public class AuthorInfo {
private final Status status; private final Status status;
@Nullable @Nullable
private final String alias; private final String alias;
@Nullable
private final AttachmentHeader avatarHeader;
public AuthorInfo(Status status, @Nullable String alias) { public AuthorInfo(Status status, @Nullable String alias,
@Nullable AttachmentHeader avatarHeader) {
this.status = status; this.status = status;
this.alias = alias; this.alias = alias;
this.avatarHeader = avatarHeader;
} }
public AuthorInfo(Status status) { public AuthorInfo(Status status) {
this(status, null); this(status, null, null);
} }
public Status getStatus() { public Status getStatus() {
@@ -39,6 +44,11 @@ public class AuthorInfo {
return alias; return alias;
} }
@Nullable
public AttachmentHeader getAvatarHeader() {
return avatarHeader;
}
@Override @Override
public int hashCode() { public int hashCode() {
int hashCode = status.ordinal(); int hashCode = status.ordinal();
@@ -52,6 +62,11 @@ public class AuthorInfo {
AuthorInfo info = (AuthorInfo) o; AuthorInfo info = (AuthorInfo) o;
//noinspection EqualsReplaceableByObjectsCall //noinspection EqualsReplaceableByObjectsCall
return status == info.status && return status == info.status &&
(alias == null ? info.alias == null : alias.equals(info.alias)); // aliases are equal
(alias == null ? info.alias == null :
alias.equals(info.alias)) &&
// avatars are equal
(avatarHeader == null ? info.avatarHeader == null :
avatarHeader.equals(info.avatarHeader));
} }
} }

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.api.identity;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault @NotNullByDefault
@@ -18,4 +19,8 @@ public interface AuthorManager {
*/ */
AuthorInfo getAuthorInfo(Transaction txn, AuthorId a) throws DbException; AuthorInfo getAuthorInfo(Transaction txn, AuthorId a) throws DbException;
/**
* Returns the {@link AuthorInfo} for the {@link LocalAuthor}.
*/
AuthorInfo getMyAuthorInfo(Transaction txn) throws DbException;
} }

View File

@@ -1,24 +1,37 @@
package org.briarproject.briar.api.identity; package org.briarproject.briar.api.identity;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.briar.api.media.AttachmentHeader;
import org.junit.Test; import org.junit.Test;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.NONE; import static org.briarproject.briar.api.identity.AuthorInfo.Status.NONE;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED; import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED;
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_BYTES;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
public class AuthorInfoTest extends BrambleTestCase { public class AuthorInfoTest extends BrambleTestCase {
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
private final AttachmentHeader avatarHeader =
new AttachmentHeader(new MessageId(getRandomId()), contentType);
@Test @Test
public void testEquals() { public void testEquals() {
assertEquals( assertEquals(
new AuthorInfo(NONE), new AuthorInfo(NONE),
new AuthorInfo(NONE, null) new AuthorInfo(NONE, null, null)
); );
assertEquals( assertEquals(
new AuthorInfo(NONE, "test"), new AuthorInfo(NONE, "test", null),
new AuthorInfo(NONE, "test") new AuthorInfo(NONE, "test", null)
);
assertEquals(
new AuthorInfo(NONE, "test", avatarHeader),
new AuthorInfo(NONE, "test", avatarHeader)
); );
assertNotEquals( assertNotEquals(
@@ -26,16 +39,20 @@ public class AuthorInfoTest extends BrambleTestCase {
new AuthorInfo(VERIFIED) new AuthorInfo(VERIFIED)
); );
assertNotEquals( assertNotEquals(
new AuthorInfo(NONE, "test"), new AuthorInfo(NONE, "test", null),
new AuthorInfo(NONE) new AuthorInfo(NONE)
); );
assertNotEquals( assertNotEquals(
new AuthorInfo(NONE), new AuthorInfo(NONE),
new AuthorInfo(NONE, "test") new AuthorInfo(NONE, "test", null)
); );
assertNotEquals( assertNotEquals(
new AuthorInfo(NONE, "a"), new AuthorInfo(NONE, "a", null),
new AuthorInfo(NONE, "b") new AuthorInfo(NONE, "b", null)
);
assertNotEquals(
new AuthorInfo(NONE, "a", null),
new AuthorInfo(NONE, "a", avatarHeader)
); );
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar; package org.briarproject.briar;
import org.briarproject.briar.avatar.AvatarModule;
import org.briarproject.briar.blog.BlogModule; import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.feed.FeedModule; import org.briarproject.briar.feed.FeedModule;
import org.briarproject.briar.forum.ForumModule; import org.briarproject.briar.forum.ForumModule;
@@ -12,6 +13,8 @@ import org.briarproject.briar.sharing.SharingModule;
public interface BriarCoreEagerSingletons { public interface BriarCoreEagerSingletons {
void inject(AvatarModule.EagerSingletons init);
void inject(BlogModule.EagerSingletons init); void inject(BlogModule.EagerSingletons init);
void inject(FeedModule.EagerSingletons init); void inject(FeedModule.EagerSingletons init);
@@ -33,6 +36,7 @@ public interface BriarCoreEagerSingletons {
class Helper { class Helper {
public static void injectEagerSingletons(BriarCoreEagerSingletons c) { public static void injectEagerSingletons(BriarCoreEagerSingletons c) {
c.inject(new AvatarModule.EagerSingletons());
c.inject(new BlogModule.EagerSingletons()); c.inject(new BlogModule.EagerSingletons());
c.inject(new FeedModule.EagerSingletons()); c.inject(new FeedModule.EagerSingletons());
c.inject(new ForumModule.EagerSingletons()); c.inject(new ForumModule.EagerSingletons());

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar; package org.briarproject.briar;
import org.briarproject.briar.avatar.AvatarModule;
import org.briarproject.briar.blog.BlogModule; import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.client.BriarClientModule; import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.feed.DnsModule; import org.briarproject.briar.feed.DnsModule;
@@ -16,6 +17,7 @@ import org.briarproject.briar.test.TestModule;
import dagger.Module; import dagger.Module;
@Module(includes = { @Module(includes = {
AvatarModule.class,
BlogModule.class, BlogModule.class,
BriarClientModule.class, BriarClientModule.class,
FeedModule.class, FeedModule.class,

View File

@@ -219,12 +219,11 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
@Nullable @Nullable
@Override @Override
public AttachmentHeader getAvatarHeader(Contact c) throws DbException { public AttachmentHeader getAvatarHeader(Transaction txn, Contact c)
throws DbException {
try { try {
Group g = getGroup(c.getAuthor().getId()); Group g = getGroup(c.getAuthor().getId());
return db.transactionWithNullableResult(true, txn -> return getAvatarHeader(txn, g.getId());
getAvatarHeader(txn, g.getId())
);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }
@@ -232,12 +231,11 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
@Nullable @Nullable
@Override @Override
public AttachmentHeader getMyAvatarHeader() throws DbException { public AttachmentHeader getMyAvatarHeader(Transaction txn)
throws DbException {
try { try {
return db.transactionWithNullableResult(true, txn -> {
Group g = getOurGroup(txn); Group g = getOurGroup(txn);
return getAvatarHeader(txn, g.getId()); return getAvatarHeader(txn, g.getId());
});
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -49,7 +49,6 @@ import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_LOCAL; import static org.briarproject.briar.api.forum.ForumConstants.KEY_LOCAL;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT; import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP; import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ; import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
@ThreadSafe @ThreadSafe
@@ -127,8 +126,17 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
@Override @Override
public ForumPostHeader addLocalPost(ForumPost p) throws DbException { public ForumPostHeader addLocalPost(ForumPost p) throws DbException {
db.transaction(false, txn -> { return db.transactionWithResult(false, txn -> {
try { try {
return addLocalPost(txn, p);
} catch (FormatException e) {
throw new AssertionError(e);
}
});
}
private ForumPostHeader addLocalPost(Transaction txn, ForumPost p)
throws DbException, FormatException {
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp()); meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp());
if (p.getParent() != null) meta.put(KEY_PARENT, p.getParent()); if (p.getParent() != null) meta.put(KEY_PARENT, p.getParent());
@@ -136,14 +144,9 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
meta.put(KEY_AUTHOR, clientHelper.toList(a)); meta.put(KEY_AUTHOR, clientHelper.toList(a));
meta.put(KEY_LOCAL, true); meta.put(KEY_LOCAL, true);
meta.put(MSG_KEY_READ, true); meta.put(MSG_KEY_READ, true);
clientHelper.addLocalMessage(txn, p.getMessage(), meta, true, clientHelper.addLocalMessage(txn, p.getMessage(), meta, true, false);
false);
messageTracker.trackOutgoingMessage(txn, p.getMessage()); messageTracker.trackOutgoingMessage(txn, p.getMessage());
} catch (FormatException e) { AuthorInfo authorInfo = authorManager.getMyAuthorInfo(txn);
throw new AssertionError(e);
}
});
AuthorInfo authorInfo = new AuthorInfo(OURSELVES);
return new ForumPostHeader(p.getMessage().getId(), p.getParent(), return new ForumPostHeader(p.getMessage().getId(), p.getParent(),
p.getMessage().getTimestamp(), p.getAuthor(), authorInfo, true); p.getMessage().getTimestamp(), p.getAuthor(), authorInfo, true);
} }

View File

@@ -8,8 +8,10 @@ import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.avatar.AvatarManager;
import org.briarproject.briar.api.identity.AuthorInfo; import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorManager; import org.briarproject.briar.api.identity.AuthorManager;
import org.briarproject.briar.api.media.AttachmentHeader;
import java.util.Collection; import java.util.Collection;
@@ -27,11 +29,14 @@ class AuthorManagerImpl implements AuthorManager {
private final DatabaseComponent db; private final DatabaseComponent db;
private final IdentityManager identityManager; private final IdentityManager identityManager;
private final AvatarManager avatarManager;
@Inject @Inject
AuthorManagerImpl(DatabaseComponent db, IdentityManager identityManager) { AuthorManagerImpl(DatabaseComponent db, IdentityManager identityManager,
AvatarManager avatarManager) {
this.db = db; this.db = db;
this.identityManager = identityManager; this.identityManager = identityManager;
this.avatarManager = avatarManager;
} }
@Override @Override
@@ -43,14 +48,21 @@ class AuthorManagerImpl implements AuthorManager {
public AuthorInfo getAuthorInfo(Transaction txn, AuthorId authorId) public AuthorInfo getAuthorInfo(Transaction txn, AuthorId authorId)
throws DbException { throws DbException {
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
if (localAuthor.getId().equals(authorId)) if (localAuthor.getId().equals(authorId)) return getMyAuthorInfo(txn);
return new AuthorInfo(OURSELVES);
Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId); Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId);
if (contacts.isEmpty()) return new AuthorInfo(UNKNOWN); if (contacts.isEmpty()) return new AuthorInfo(UNKNOWN);
if (contacts.size() > 1) throw new AssertionError(); if (contacts.size() > 1) throw new AssertionError();
Contact c = contacts.iterator().next(); Contact c = contacts.iterator().next();
if (c.isVerified()) return new AuthorInfo(VERIFIED, c.getAlias()); AttachmentHeader avatar = avatarManager.getAvatarHeader(txn, c);
else return new AuthorInfo(UNVERIFIED, c.getAlias()); if (c.isVerified())
return new AuthorInfo(VERIFIED, c.getAlias(), avatar);
else return new AuthorInfo(UNVERIFIED, c.getAlias(), avatar);
}
@Override
public AuthorInfo getMyAuthorInfo(Transaction txn) throws DbException {
AttachmentHeader avatar = avatarManager.getMyAvatarHeader(txn);
return new AuthorInfo(OURSELVES, null, avatar);
} }
} }

View File

@@ -55,7 +55,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.UNVERIFIED; import static org.briarproject.briar.api.identity.AuthorInfo.Status.UNVERIFIED;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED; import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED;
import static org.briarproject.briar.api.privategroup.MessageType.JOIN; import static org.briarproject.briar.api.privategroup.MessageType.JOIN;
@@ -211,8 +210,17 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
@Override @Override
public GroupMessageHeader addLocalMessage(GroupMessage m) public GroupMessageHeader addLocalMessage(GroupMessage m)
throws DbException { throws DbException {
Transaction txn = db.startTransaction(false); return db.transactionWithResult(false, txn -> {
try { try {
return addLocalMessage(txn, m);
} catch (FormatException e) {
throw new DbException(e);
}
});
}
private GroupMessageHeader addLocalMessage(Transaction txn, GroupMessage m)
throws DbException, FormatException {
// store message and metadata // store message and metadata
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TYPE, POST.getInt()); meta.put(KEY_TYPE, POST.getInt());
@@ -222,21 +230,12 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
GroupId g = m.getMessage().getGroupId(); GroupId g = m.getMessage().getGroupId();
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true, clientHelper.addLocalMessage(txn, m.getMessage(), meta, true,
false); false);
// track message // track message
setPreviousMsgId(txn, g, m.getMessage().getId()); setPreviousMsgId(txn, g, m.getMessage().getId());
messageTracker.trackOutgoingMessage(txn, m.getMessage()); messageTracker.trackOutgoingMessage(txn, m.getMessage());
// broadcast event // broadcast event
attachGroupMessageAddedEvent(txn, m.getMessage(), meta, true); attachGroupMessageAddedEvent(txn, m.getMessage(), meta, true);
AuthorInfo authorInfo = authorManager.getMyAuthorInfo(txn);
db.commitTransaction(txn);
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
AuthorInfo authorInfo = new AuthorInfo(OURSELVES);
return new GroupMessageHeader(m.getMessage().getGroupId(), return new GroupMessageHeader(m.getMessage().getGroupId(),
m.getMessage().getId(), m.getParent(), m.getMessage().getId(), m.getParent(),
m.getMessage().getTimestamp(), m.getMember(), authorInfo, true); m.getMessage().getTimestamp(), m.getMember(), authorInfo, true);

View File

@@ -64,12 +64,16 @@ public class AvatarManagerIntegrationTest
@Test @Test
public void testAddingAndSyncAvatars() throws Exception { public void testAddingAndSyncAvatars() throws Exception {
// Both contacts don't have avatars // Both contacts don't have avatars
assertNull(avatarManager0.getMyAvatarHeader()); assertNull(db0.transactionWithNullableResult(true,
assertNull(avatarManager1.getMyAvatarHeader()); txn -> avatarManager0.getMyAvatarHeader(txn)));
assertNull(db1.transactionWithNullableResult(true,
txn -> avatarManager1.getMyAvatarHeader(txn)));
// Both contacts don't see avatars for each other // Both contacts don't see avatars for each other
assertNull(avatarManager0.getAvatarHeader(contact1From0)); assertNull(db0.transactionWithNullableResult(true,
assertNull(avatarManager1.getAvatarHeader(contact0From1)); txn -> avatarManager0.getAvatarHeader(txn, contact1From0)));
assertNull(db1.transactionWithNullableResult(true,
txn -> avatarManager1.getAvatarHeader(txn, contact0From1)));
// 0 adds avatar // 0 adds avatar
byte[] avatar0bytes = getRandomBytes(42); byte[] avatar0bytes = getRandomBytes(42);
@@ -79,7 +83,8 @@ public class AvatarManagerIntegrationTest
assertEquals(contentType, header0.getContentType()); assertEquals(contentType, header0.getContentType());
// 0 sees their own avatar // 0 sees their own avatar
header0 = avatarManager0.getMyAvatarHeader(); header0 = db0.transactionWithResult(true,
txn -> avatarManager0.getMyAvatarHeader(txn));
assertNotNull(header0); assertNotNull(header0);
assertEquals(contentType, header0.getContentType()); assertEquals(contentType, header0.getContentType());
assertNotNull(header0.getMessageId()); assertNotNull(header0.getMessageId());
@@ -93,8 +98,8 @@ public class AvatarManagerIntegrationTest
sync0To1(1, true); sync0To1(1, true);
// 1 also sees 0's avatar now // 1 also sees 0's avatar now
AttachmentHeader header0From1 = AttachmentHeader header0From1 = db1.transactionWithResult(true,
avatarManager1.getAvatarHeader(contact0From1); txn -> avatarManager1.getAvatarHeader(txn, contact0From1));
assertNotNull(header0From1); assertNotNull(header0From1);
assertEquals(contentType, header0From1.getContentType()); assertEquals(contentType, header0From1.getContentType());
assertNotNull(header0From1.getMessageId()); assertNotNull(header0From1.getMessageId());
@@ -115,8 +120,8 @@ public class AvatarManagerIntegrationTest
sync1To0(1, true); sync1To0(1, true);
// 0 sees 1's avatar now // 0 sees 1's avatar now
AttachmentHeader header1From0 = AttachmentHeader header1From0 = db0.transactionWithResult(true,
avatarManager0.getAvatarHeader(contact1From0); txn -> avatarManager0.getAvatarHeader(txn, contact1From0));
assertNotNull(header1From0); assertNotNull(header1From0);
assertEquals(contentType1, header1From0.getContentType()); assertEquals(contentType1, header1From0.getContentType());
assertNotNull(header1From0.getMessageId()); assertNotNull(header1From0.getMessageId());
@@ -136,7 +141,8 @@ public class AvatarManagerIntegrationTest
avatarManager0.addAvatar(contentType, avatar0inputStream); avatarManager0.addAvatar(contentType, avatar0inputStream);
// 0 can retrieve their own avatar // 0 can retrieve their own avatar
AttachmentHeader header0 = avatarManager0.getMyAvatarHeader(); AttachmentHeader header0 = db0.transactionWithResult(true,
txn -> avatarManager0.getMyAvatarHeader(txn));
assertNotNull(header0); assertNotNull(header0);
Attachment attachment0 = avatarManager0.getAvatar(header0); Attachment attachment0 = avatarManager0.getAvatar(header0);
assertStreamMatches(avatar0bytes, attachment0.getStream()); assertStreamMatches(avatar0bytes, attachment0.getStream());
@@ -145,8 +151,8 @@ public class AvatarManagerIntegrationTest
sync0To1(1, true); sync0To1(1, true);
// 1 only sees 0's avatar // 1 only sees 0's avatar
AttachmentHeader header0From1 = AttachmentHeader header0From1 = db1.transactionWithNullableResult(true,
avatarManager1.getAvatarHeader(contact0From1); txn -> avatarManager1.getAvatarHeader(txn, contact0From1));
assertNotNull(header0From1); assertNotNull(header0From1);
Attachment attachment0From1 = avatarManager1.getAvatar(header0From1); Attachment attachment0From1 = avatarManager1.getAvatar(header0From1);
assertStreamMatches(avatar0bytes, attachment0From1.getStream()); assertStreamMatches(avatar0bytes, attachment0From1.getStream());
@@ -158,7 +164,8 @@ public class AvatarManagerIntegrationTest
avatarManager0.addAvatar(contentType, avatar0inputStream2); avatarManager0.addAvatar(contentType, avatar0inputStream2);
// 0 now only sees their new avatar // 0 now only sees their new avatar
header0 = avatarManager0.getMyAvatarHeader(); header0 = db0.transactionWithResult(true,
txn -> avatarManager0.getMyAvatarHeader(txn));
assertNotNull(header0); assertNotNull(header0);
attachment0 = avatarManager0.getAvatar(header0); attachment0 = avatarManager0.getAvatar(header0);
assertStreamMatches(avatar0bytes2, attachment0.getStream()); assertStreamMatches(avatar0bytes2, attachment0.getStream());
@@ -167,8 +174,8 @@ public class AvatarManagerIntegrationTest
sync0To1(1, true); sync0To1(1, true);
// 1 only sees 0's new avatar // 1 only sees 0's new avatar
header0From1 = header0From1 = db1.transactionWithNullableResult(true,
avatarManager1.getAvatarHeader(contact0From1); txn -> avatarManager1.getAvatarHeader(txn, contact0From1));
assertNotNull(header0From1); assertNotNull(header0From1);
attachment0From1 = avatarManager1.getAvatar(header0From1); attachment0From1 = avatarManager1.getAvatar(header0From1);
assertStreamMatches(avatar0bytes2, attachment0From1.getStream()); assertStreamMatches(avatar0bytes2, attachment0From1.getStream());

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
import org.briarproject.bramble.test.TestSocksModule; import org.briarproject.bramble.test.TestSocksModule;
import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.feed.FeedManager; import org.briarproject.briar.api.feed.FeedManager;
import org.briarproject.briar.avatar.AvatarModule;
import org.briarproject.briar.blog.BlogModule; import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.client.BriarClientModule; import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.identity.IdentityModule; import org.briarproject.briar.identity.IdentityModule;
@@ -21,6 +22,7 @@ import dagger.Component;
@Component(modules = { @Component(modules = {
BrambleCoreIntegrationTestModule.class, BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class, BrambleCoreModule.class,
AvatarModule.class,
BlogModule.class, BlogModule.class,
BriarClientModule.class, BriarClientModule.class,
FeedModule.class, FeedModule.class,
@@ -33,6 +35,8 @@ interface FeedManagerIntegrationTestComponent
void inject(FeedManagerIntegrationTest testCase); void inject(FeedManagerIntegrationTest testCase);
void inject(AvatarModule.EagerSingletons init);
void inject(BlogModule.EagerSingletons init); void inject(BlogModule.EagerSingletons init);
void inject(FeedModule.EagerSingletons init); void inject(FeedModule.EagerSingletons init);
@@ -51,6 +55,7 @@ interface FeedManagerIntegrationTestComponent
FeedManagerIntegrationTestComponent c) { FeedManagerIntegrationTestComponent c) {
BrambleCoreIntegrationTestEagerSingletons.Helper BrambleCoreIntegrationTestEagerSingletons.Helper
.injectEagerSingletons(c); .injectEagerSingletons(c);
c.inject(new AvatarModule.EagerSingletons());
c.inject(new BlogModule.EagerSingletons()); c.inject(new BlogModule.EagerSingletons());
c.inject(new FeedModule.EagerSingletons()); c.inject(new FeedModule.EagerSingletons());
} }

View File

@@ -8,9 +8,12 @@ import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.DbExpectations; import org.briarproject.bramble.test.DbExpectations;
import org.briarproject.briar.api.avatar.AvatarManager;
import org.briarproject.briar.api.identity.AuthorInfo; import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.briar.api.media.AttachmentHeader;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
@@ -21,10 +24,13 @@ import static java.util.Collections.singletonList;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES; import static org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.UNKNOWN; import static org.briarproject.briar.api.identity.AuthorInfo.Status.UNKNOWN;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.UNVERIFIED; import static org.briarproject.briar.api.identity.AuthorInfo.Status.UNVERIFIED;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED; import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED;
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_BYTES;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
@@ -33,73 +39,87 @@ public class AuthorManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class); private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final IdentityManager identityManager = private final IdentityManager identityManager =
context.mock(IdentityManager.class); context.mock(IdentityManager.class);
private final AvatarManager avatarManager =
context.mock(AvatarManager.class);
private final Author remote = getAuthor(); private final Author remote = getAuthor();
private final LocalAuthor localAuthor = getLocalAuthor(); private final LocalAuthor localAuthor = getLocalAuthor();
private final AuthorId local = localAuthor.getId(); private final AuthorId local = localAuthor.getId();
private final boolean verified = false; private final boolean verified = false;
private final Contact contact = getContact(remote, local, verified); private final Contact contact = getContact(remote, local, verified);
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
private final AttachmentHeader avatarHeader =
new AttachmentHeader(new MessageId(getRandomId()), contentType);
private final AuthorManagerImpl authorManager = private final AuthorManagerImpl authorManager =
new AuthorManagerImpl(db, identityManager); new AuthorManagerImpl(db, identityManager, avatarManager);
@Test @Test
public void testGetAuthorInfo() throws Exception { public void testGetAuthorInfoUnverified() throws Exception {
Transaction txn = new Transaction(null, true); Transaction txn = new Transaction(null, true);
checkAuthorInfoContext(txn, remote.getId(), singletonList(contact));
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(identityManager).getLocalAuthor(txn); oneOf(avatarManager).getAvatarHeader(txn, contact);
will(returnValue(localAuthor)); will(returnValue(avatarHeader));
oneOf(db).getContactsByAuthorId(txn, remote.getId());
will(returnValue(singletonList(contact)));
}}); }});
AuthorInfo authorInfo = AuthorInfo authorInfo =
authorManager.getAuthorInfo(txn, remote.getId()); authorManager.getAuthorInfo(txn, remote.getId());
assertEquals(UNVERIFIED, authorInfo.getStatus()); assertEquals(UNVERIFIED, authorInfo.getStatus());
assertEquals(contact.getAlias(), authorInfo.getAlias()); assertEquals(contact.getAlias(), authorInfo.getAlias());
assertEquals(avatarHeader, authorInfo.getAvatarHeader());
} }
@Test @Test
public void testGetAuthorInfoTransaction() throws DbException { public void testGetAuthorInfoUnknown() throws DbException {
Transaction txn = new Transaction(null, true); Transaction txn = new Transaction(null, true);
// check unknown author checkAuthorInfoContext(txn, remote.getId(), emptyList());
context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContactsByAuthorId(txn, remote.getId());
will(returnValue(emptyList()));
}});
AuthorInfo authorInfo = AuthorInfo authorInfo =
authorManager.getAuthorInfo(txn, remote.getId()); authorManager.getAuthorInfo(txn, remote.getId());
assertEquals(UNKNOWN, authorInfo.getStatus()); assertEquals(UNKNOWN, authorInfo.getStatus());
assertNull(authorInfo.getAlias()); assertNull(authorInfo.getAlias());
assertNull(authorInfo.getAvatarHeader());
}
// check unverified contact @Test
checkAuthorInfoContext(txn, remote.getId(), singletonList(contact)); public void testGetAuthorInfoVerified() throws DbException {
authorInfo = authorManager.getAuthorInfo(txn, remote.getId()); Transaction txn = new Transaction(null, true);
assertEquals(UNVERIFIED, authorInfo.getStatus());
assertEquals(contact.getAlias(), authorInfo.getAlias());
// check verified contact
Contact verified = getContact(remote, local, true); Contact verified = getContact(remote, local, true);
checkAuthorInfoContext(txn, remote.getId(), singletonList(verified)); checkAuthorInfoContext(txn, remote.getId(), singletonList(verified));
authorInfo = authorManager.getAuthorInfo(txn, remote.getId()); context.checking(new DbExpectations() {{
oneOf(avatarManager).getAvatarHeader(txn, verified);
will(returnValue(avatarHeader));
}});
AuthorInfo authorInfo =
authorManager.getAuthorInfo(txn, remote.getId());
assertEquals(VERIFIED, authorInfo.getStatus()); assertEquals(VERIFIED, authorInfo.getStatus());
assertEquals(verified.getAlias(), authorInfo.getAlias()); assertEquals(verified.getAlias(), authorInfo.getAlias());
assertEquals(avatarHeader, authorInfo.getAvatarHeader());
}
@Test
public void testGetAuthorInfoOurselves() throws DbException {
Transaction txn = new Transaction(null, true);
// check ourselves // check ourselves
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn); oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor)); will(returnValue(localAuthor));
never(db).getContactsByAuthorId(txn, remote.getId()); never(db).getContactsByAuthorId(txn, remote.getId());
oneOf(avatarManager).getMyAvatarHeader(txn);
will(returnValue(avatarHeader));
}}); }});
authorInfo = authorManager.getAuthorInfo(txn, localAuthor.getId()); AuthorInfo authorInfo =
authorManager.getAuthorInfo(txn, localAuthor.getId());
assertEquals(OURSELVES, authorInfo.getStatus()); assertEquals(OURSELVES, authorInfo.getStatus());
assertNull(authorInfo.getAlias()); assertNull(authorInfo.getAlias());
assertEquals(avatarHeader, authorInfo.getAvatarHeader());
} }
private void checkAuthorInfoContext(Transaction txn, AuthorId authorId, private void checkAuthorInfoContext(Transaction txn, AuthorId authorId,

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.messaging;
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons; import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.BrambleCoreModule;
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
import org.briarproject.briar.avatar.AvatarModule;
import org.briarproject.briar.client.BriarClientModule; import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.forum.ForumModule; import org.briarproject.briar.forum.ForumModule;
import org.briarproject.briar.identity.IdentityModule; import org.briarproject.briar.identity.IdentityModule;
@@ -16,6 +17,7 @@ import dagger.Component;
BrambleCoreIntegrationTestModule.class, BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class, BrambleCoreModule.class,
BriarClientModule.class, BriarClientModule.class,
AvatarModule.class,
ForumModule.class, ForumModule.class,
IdentityModule.class, IdentityModule.class,
MessagingModule.class MessagingModule.class
@@ -25,6 +27,8 @@ interface MessageSizeIntegrationTestComponent
void inject(MessageSizeIntegrationTest testCase); void inject(MessageSizeIntegrationTest testCase);
void inject(AvatarModule.EagerSingletons init);
void inject(ForumModule.EagerSingletons init); void inject(ForumModule.EagerSingletons init);
void inject(MessagingModule.EagerSingletons init); void inject(MessagingModule.EagerSingletons init);
@@ -35,6 +39,7 @@ interface MessageSizeIntegrationTestComponent
MessageSizeIntegrationTestComponent c) { MessageSizeIntegrationTestComponent c) {
BrambleCoreIntegrationTestEagerSingletons.Helper BrambleCoreIntegrationTestEagerSingletons.Helper
.injectEagerSingletons(c); .injectEagerSingletons(c);
c.inject(new AvatarModule.EagerSingletons());
c.inject(new ForumModule.EagerSingletons()); c.inject(new ForumModule.EagerSingletons());
c.inject(new MessagingModule.EagerSingletons()); c.inject(new MessagingModule.EagerSingletons());
} }