mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Merge branch '1567-remove-pending-contact-state-from-db' into 'master'
Remove pending contact state from DB See merge request briar/briar!1102
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.api.contact;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
@@ -76,9 +77,11 @@ public interface ContactManager {
|
||||
throws DbException, FormatException;
|
||||
|
||||
/**
|
||||
* Returns a list of {@link PendingContact}s.
|
||||
* Returns a list of {@link PendingContact PendingContacts} and their
|
||||
* {@link PendingContactState states}.
|
||||
*/
|
||||
Collection<PendingContact> getPendingContacts() throws DbException;
|
||||
Collection<Pair<PendingContact, PendingContactState>> getPendingContacts()
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Removes a {@link PendingContact}.
|
||||
|
||||
@@ -12,15 +12,13 @@ public class PendingContact {
|
||||
private final PendingContactId id;
|
||||
private final PublicKey publicKey;
|
||||
private final String alias;
|
||||
private final PendingContactState state;
|
||||
private final long timestamp;
|
||||
|
||||
public PendingContact(PendingContactId id, PublicKey publicKey,
|
||||
String alias, PendingContactState state, long timestamp) {
|
||||
String alias, long timestamp) {
|
||||
this.id = id;
|
||||
this.publicKey = publicKey;
|
||||
this.alias = alias;
|
||||
this.state = state;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
@@ -36,10 +34,6 @@ public class PendingContact {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public PendingContactState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,9 @@
|
||||
package org.briarproject.bramble.api.contact;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public enum PendingContactState {
|
||||
|
||||
WAITING_FOR_CONNECTION(0),
|
||||
CONNECTED(1),
|
||||
ADDING_CONTACT(2),
|
||||
FAILED(3);
|
||||
|
||||
private final int value;
|
||||
|
||||
PendingContactState(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static PendingContactState fromValue(int value) {
|
||||
for (PendingContactState s : values()) if (s.value == value) return s;
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
WAITING_FOR_CONNECTION,
|
||||
CONNECTED,
|
||||
ADDING_CONTACT,
|
||||
FAILED
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.bramble.api.contact.event;
|
||||
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when a pending contact is added.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class PendingContactAddedEvent extends Event {
|
||||
|
||||
private final PendingContact pendingContact;
|
||||
|
||||
public PendingContactAddedEvent(PendingContact pendingContact) {
|
||||
this.pendingContact = pendingContact;
|
||||
}
|
||||
|
||||
public PendingContact getPendingContact() {
|
||||
return pendingContact;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
@@ -181,10 +180,7 @@ public class TestUtils {
|
||||
PendingContactId id = new PendingContactId(getRandomId());
|
||||
PublicKey publicKey = getAgreementPublicKey();
|
||||
String alias = getRandomString(nameLength);
|
||||
int stateIndex =
|
||||
random.nextInt(PendingContactState.values().length - 1);
|
||||
PendingContactState state = PendingContactState.values()[stateIndex];
|
||||
return new PendingContact(id, publicKey, alias, state, timestamp);
|
||||
return new PendingContact(id, publicKey, alias, timestamp);
|
||||
}
|
||||
|
||||
public static ContactId getContactId() {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package org.briarproject.bramble.contact;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
@@ -19,6 +21,7 @@ import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.transport.KeyManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@@ -28,6 +31,7 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32_LINK_BYTES;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
||||
@@ -111,8 +115,16 @@ class ContactManagerImpl implements ContactManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PendingContact> getPendingContacts() throws DbException {
|
||||
return db.transactionWithResult(true, db::getPendingContacts);
|
||||
public Collection<Pair<PendingContact, PendingContactState>> getPendingContacts()
|
||||
throws DbException {
|
||||
Collection<PendingContact> pendingContacts =
|
||||
db.transactionWithResult(true, db::getPendingContacts);
|
||||
List<Pair<PendingContact, PendingContactState>> pairs =
|
||||
new ArrayList<>(pendingContacts.size());
|
||||
for (PendingContact p : pendingContacts) {
|
||||
pairs.add(new Pair<>(p, WAITING_FOR_CONNECTION)); // TODO
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
|
||||
class PendingContactFactoryImpl implements PendingContactFactory {
|
||||
|
||||
@@ -39,8 +38,7 @@ class PendingContactFactoryImpl implements PendingContactFactory {
|
||||
PublicKey publicKey = parseHandshakeLink(link);
|
||||
PendingContactId id = getPendingContactId(publicKey);
|
||||
long timestamp = clock.currentTimeMillis();
|
||||
return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION,
|
||||
timestamp);
|
||||
return new PendingContact(id, publicKey, alias, timestamp);
|
||||
}
|
||||
|
||||
private PublicKey parseHandshakeLink(String link) throws FormatException {
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
@@ -674,12 +673,6 @@ interface Database<T> {
|
||||
void setMessageState(T txn, MessageId m, MessageState state)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the state of the given pending contact.
|
||||
*/
|
||||
void setPendingContactState(T txn, PendingContactId p,
|
||||
PendingContactState state) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the reordering window for the given transport keys in the given
|
||||
* time period.
|
||||
|
||||
@@ -7,8 +7,8 @@ import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
@@ -295,8 +295,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
if (db.containsPendingContact(txn, p.getId()))
|
||||
throw new PendingContactExistsException();
|
||||
db.addPendingContact(txn, p);
|
||||
transaction.attach(new PendingContactStateChangedEvent(p.getId(),
|
||||
p.getState()));
|
||||
transaction.attach(new PendingContactAddedEvent(p));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
@@ -98,7 +97,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
||||
abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
// Package access for testing
|
||||
static final int CODE_SCHEMA_VERSION = 44;
|
||||
static final int CODE_SCHEMA_VERSION = 45;
|
||||
|
||||
// Time period offsets for incoming transport keys
|
||||
private static final int OFFSET_PREV = -1;
|
||||
@@ -264,7 +263,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " (pendingContactId _HASH NOT NULL,"
|
||||
+ " publicKey _BINARY NOT NULL,"
|
||||
+ " alias _STRING NOT NULL,"
|
||||
+ " state INT NOT NULL,"
|
||||
+ " timestamp BIGINT NOT NULL,"
|
||||
+ " PRIMARY KEY (pendingContactId))";
|
||||
|
||||
@@ -457,7 +455,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
new Migration40_41(dbTypes),
|
||||
new Migration41_42(dbTypes),
|
||||
new Migration42_43(dbTypes),
|
||||
new Migration43_44(dbTypes)
|
||||
new Migration43_44(dbTypes),
|
||||
new Migration44_45()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -933,14 +932,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "INSERT INTO pendingContacts (pendingContactId,"
|
||||
+ " publicKey, alias, state, timestamp)"
|
||||
+ " VALUES (?, ?, ?, ?, ?)";
|
||||
+ " publicKey, alias, timestamp)"
|
||||
+ " VALUES (?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, p.getId().getBytes());
|
||||
ps.setBytes(2, p.getPublicKey().getEncoded());
|
||||
ps.setString(3, p.getAlias());
|
||||
ps.setInt(4, p.getState().getValue());
|
||||
ps.setLong(5, p.getTimestamp());
|
||||
ps.setLong(4, p.getTimestamp());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected != 1) throw new DbStateException();
|
||||
ps.close();
|
||||
@@ -2213,8 +2211,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
Statement s = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT pendingContactId, publicKey, alias, state,"
|
||||
+ " timestamp"
|
||||
String sql = "SELECT pendingContactId, publicKey, alias, timestamp"
|
||||
+ " FROM pendingContacts";
|
||||
s = txn.createStatement();
|
||||
rs = s.executeQuery(sql);
|
||||
@@ -2223,11 +2220,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PendingContactId id = new PendingContactId(rs.getBytes(1));
|
||||
PublicKey publicKey = new AgreementPublicKey(rs.getBytes(2));
|
||||
String alias = rs.getString(3);
|
||||
PendingContactState state =
|
||||
PendingContactState.fromValue(rs.getInt(4));
|
||||
long timestamp = rs.getLong(5);
|
||||
long timestamp = rs.getLong(4);
|
||||
pendingContacts.add(new PendingContact(id, publicKey, alias,
|
||||
state, timestamp));
|
||||
timestamp));
|
||||
}
|
||||
rs.close();
|
||||
s.close();
|
||||
@@ -3077,25 +3072,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPendingContactState(Connection txn, PendingContactId p,
|
||||
PendingContactState state) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE pendingContacts SET state = ?"
|
||||
+ " WHERE pendingContactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, state.getValue());
|
||||
ps.setBytes(2, p.getBytes());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
tryToClose(ps, LOG, WARNING);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReorderingWindow(Connection txn, KeySetId k,
|
||||
TransportId t, long timePeriod, long base, byte[] bitmap)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.briarproject.bramble.db;
|
||||
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||
|
||||
class Migration44_45 implements Migration<Connection> {
|
||||
|
||||
private static final Logger LOG = getLogger(Migration44_45.class.getName());
|
||||
|
||||
@Override
|
||||
public int getStartVersion() {
|
||||
return 44;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndVersion() {
|
||||
return 45;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrate(Connection txn) throws DbException {
|
||||
Statement s = null;
|
||||
try {
|
||||
s = txn.createStatement();
|
||||
s.execute("ALTER TABLE pendingContacts DROP COLUMN state");
|
||||
} catch (SQLException e) {
|
||||
tryToClose(s, LOG, WARNING);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
|
||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
@@ -108,7 +107,6 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
|
||||
assertArrayEquals(publicKey.getEncoded(),
|
||||
p.getPublicKey().getEncoded());
|
||||
assertEquals(alias, p.getAlias());
|
||||
assertEquals(WAITING_FOR_CONNECTION, p.getState());
|
||||
assertEquals(timestamp, p.getTimestamp());
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
||||
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||
@@ -2211,16 +2210,6 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
PendingContact retrieved = pendingContacts.iterator().next();
|
||||
assertEquals(pendingContact.getId(), retrieved.getId());
|
||||
assertEquals(pendingContact.getAlias(), retrieved.getAlias());
|
||||
assertEquals(pendingContact.getState(), retrieved.getState());
|
||||
assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp());
|
||||
|
||||
db.setPendingContactState(txn, pendingContact.getId(), FAILED);
|
||||
pendingContacts = db.getPendingContacts(txn);
|
||||
assertEquals(1, pendingContacts.size());
|
||||
retrieved = pendingContacts.iterator().next();
|
||||
assertEquals(pendingContact.getId(), retrieved.getId());
|
||||
assertEquals(pendingContact.getAlias(), retrieved.getAlias());
|
||||
assertEquals(FAILED, retrieved.getState());
|
||||
assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp());
|
||||
|
||||
db.removePendingContact(txn, pendingContact.getId());
|
||||
@@ -2232,8 +2221,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testSetHandshakeKeyPair() throws Exception {
|
||||
Identity withoutKeys =
|
||||
new Identity(localAuthor, null, null, identity.getTimeCreated());
|
||||
Identity withoutKeys = new Identity(localAuthor, null, null,
|
||||
identity.getTimeCreated());
|
||||
assertFalse(withoutKeys.hasHandshakeKeyPair());
|
||||
PublicKey publicKey = getAgreementPublicKey();
|
||||
PrivateKey privateKey = getAgreementPrivateKey();
|
||||
|
||||
@@ -18,10 +18,9 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
|
||||
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
@@ -65,7 +64,6 @@ import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAn
|
||||
import static android.support.v4.view.ViewCompat.getTransitionName;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
@@ -293,15 +291,8 @@ public class ContactListFragment extends BaseFragment implements EventListener,
|
||||
(ConversationMessageReceivedEvent) e;
|
||||
ConversationMessageHeader h = p.getMessageHeader();
|
||||
updateItem(p.getContactId(), h);
|
||||
} else if (e instanceof PendingContactStateChangedEvent) {
|
||||
PendingContactStateChangedEvent pe =
|
||||
(PendingContactStateChangedEvent) e;
|
||||
// only re-check pending contacts for initial state
|
||||
if (pe.getPendingContactState() == WAITING_FOR_CONNECTION) {
|
||||
checkForPendingContacts();
|
||||
}
|
||||
} else if (e instanceof PendingContactRemovedEvent ||
|
||||
e instanceof ContactAddedRemotelyEvent) {
|
||||
} else if (e instanceof PendingContactAddedEvent ||
|
||||
e instanceof PendingContactRemovedEvent) {
|
||||
checkForPendingContacts();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.app.Application;
|
||||
import android.arch.lifecycle.AndroidViewModel;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
@@ -45,7 +44,7 @@ public class AddContactViewModel extends AndroidViewModel {
|
||||
private String remoteHandshakeLink;
|
||||
|
||||
@Inject
|
||||
public AddContactViewModel(@NonNull Application application,
|
||||
AddContactViewModel(Application application,
|
||||
ContactManager contactManager,
|
||||
@DatabaseExecutor Executor dbExecutor) {
|
||||
super(application);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.briar.android.contact.add.remote;
|
||||
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class PendingContactItem {
|
||||
|
||||
private final PendingContact pendingContact;
|
||||
private final PendingContactState state;
|
||||
|
||||
PendingContactItem(PendingContact pendingContact,
|
||||
PendingContactState state) {
|
||||
this.pendingContact = pendingContact;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
PendingContact getPendingContact() {
|
||||
return pendingContact;
|
||||
}
|
||||
|
||||
PendingContactState getState() {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,8 @@ public class PendingContactListActivity extends BriarActivity
|
||||
viewModel.getPendingContacts()
|
||||
.observe(this, this::onPendingContactsChanged);
|
||||
|
||||
adapter = new PendingContactListAdapter(this, this, PendingContact.class);
|
||||
adapter = new PendingContactListAdapter(this, this,
|
||||
PendingContactItem.class);
|
||||
list = findViewById(R.id.list);
|
||||
list.setEmptyText(R.string.no_pending_contacts);
|
||||
list.setLayoutManager(new LinearLayoutManager(this));
|
||||
@@ -75,13 +76,11 @@ public class PendingContactListActivity extends BriarActivity
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,8 +88,9 @@ public class PendingContactListActivity extends BriarActivity
|
||||
viewModel.removePendingContact(pendingContact.getId());
|
||||
}
|
||||
|
||||
private void onPendingContactsChanged(Collection<PendingContact> contacts) {
|
||||
if (contacts.isEmpty()) {
|
||||
private void onPendingContactsChanged(
|
||||
Collection<PendingContactItem> items) {
|
||||
if (items.isEmpty()) {
|
||||
if (adapter.isEmpty()) {
|
||||
list.showData(); // hides progress bar, shows empty text
|
||||
} else {
|
||||
@@ -98,7 +98,7 @@ public class PendingContactListActivity extends BriarActivity
|
||||
supportFinishAfterTransition();
|
||||
}
|
||||
} else {
|
||||
adapter.setItems(contacts);
|
||||
adapter.setItems(items);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ import org.briarproject.briar.android.util.BriarAdapter;
|
||||
|
||||
@NotNullByDefault
|
||||
class PendingContactListAdapter extends
|
||||
BriarAdapter<PendingContact, PendingContactViewHolder> {
|
||||
BriarAdapter<PendingContactItem, PendingContactViewHolder> {
|
||||
|
||||
private final PendingContactListener listener;
|
||||
|
||||
PendingContactListAdapter(Context ctx, PendingContactListener listener,
|
||||
Class<PendingContact> c) {
|
||||
Class<PendingContactItem> c) {
|
||||
super(ctx, c);
|
||||
this.listener = listener;
|
||||
}
|
||||
@@ -37,23 +37,29 @@ class PendingContactListAdapter extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(PendingContact item1, PendingContact item2) {
|
||||
return (int) (item1.getTimestamp() - item2.getTimestamp());
|
||||
public int compare(PendingContactItem item1, PendingContactItem item2) {
|
||||
long timestamp1 = item1.getPendingContact().getTimestamp();
|
||||
long timestamp2 = item2.getPendingContact().getTimestamp();
|
||||
return Long.compare(timestamp1, timestamp2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(PendingContact item1,
|
||||
PendingContact item2) {
|
||||
return item1.getId().equals(item2.getId()) &&
|
||||
item1.getAlias().equals(item2.getAlias()) &&
|
||||
item1.getTimestamp() == item2.getTimestamp() &&
|
||||
public boolean areContentsTheSame(PendingContactItem item1,
|
||||
PendingContactItem item2) {
|
||||
PendingContact p1 = item1.getPendingContact();
|
||||
PendingContact p2 = item2.getPendingContact();
|
||||
return p1.getId().equals(p2.getId()) &&
|
||||
p1.getAlias().equals(p2.getAlias()) &&
|
||||
p1.getTimestamp() == p2.getTimestamp() &&
|
||||
item1.getState() == item2.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(PendingContact item1,
|
||||
PendingContact item2) {
|
||||
return item1.getId().equals(item2.getId());
|
||||
public boolean areItemsTheSame(PendingContactItem item1,
|
||||
PendingContactItem item2) {
|
||||
PendingContact p1 = item1.getPendingContact();
|
||||
PendingContact p2 = item2.getPendingContact();
|
||||
return p1.getId().equals(p2.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@ import android.arch.lifecycle.AndroidViewModel;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
@@ -18,7 +19,9 @@ import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -40,11 +43,11 @@ public class PendingContactListViewModel extends AndroidViewModel
|
||||
private final ContactManager contactManager;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private final MutableLiveData<Collection<PendingContact>> pendingContacts =
|
||||
new MutableLiveData<>();
|
||||
private final MutableLiveData<Collection<PendingContactItem>>
|
||||
pendingContacts = new MutableLiveData<>();
|
||||
|
||||
@Inject
|
||||
public PendingContactListViewModel(Application application,
|
||||
PendingContactListViewModel(Application application,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
ContactManager contactManager, EventBus eventBus) {
|
||||
super(application);
|
||||
@@ -63,8 +66,7 @@ public class PendingContactListViewModel extends AndroidViewModel
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactAddedRemotelyEvent ||
|
||||
e instanceof PendingContactStateChangedEvent ||
|
||||
if (e instanceof PendingContactStateChangedEvent ||
|
||||
e instanceof PendingContactRemovedEvent) {
|
||||
loadPendingContacts();
|
||||
}
|
||||
@@ -73,14 +75,21 @@ public class PendingContactListViewModel extends AndroidViewModel
|
||||
private void loadPendingContacts() {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
pendingContacts.postValue(contactManager.getPendingContacts());
|
||||
Collection<Pair<PendingContact, PendingContactState>> pairs =
|
||||
contactManager.getPendingContacts();
|
||||
List<PendingContactItem> items = new ArrayList<>(pairs.size());
|
||||
for (Pair<PendingContact, PendingContactState> p : pairs) {
|
||||
items.add(new PendingContactItem(p.getFirst(),
|
||||
p.getSecond()));
|
||||
}
|
||||
pendingContacts.setValue(items);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
LiveData<Collection<PendingContact>> getPendingContacts() {
|
||||
LiveData<Collection<PendingContactItem>> getPendingContacts() {
|
||||
return pendingContacts;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,14 @@ class PendingContactViewHolder extends ViewHolder {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void bind(PendingContact item) {
|
||||
avatar.setText(item.getAlias());
|
||||
avatar.setBackgroundBytes(item.getId().getBytes());
|
||||
name.setText(item.getAlias());
|
||||
time.setText(formatDate(time.getContext(), item.getTimestamp()));
|
||||
public void bind(PendingContactItem item) {
|
||||
PendingContact p = item.getPendingContact();
|
||||
avatar.setText(p.getAlias());
|
||||
avatar.setBackgroundBytes(p.getId().getBytes());
|
||||
name.setText(p.getAlias());
|
||||
time.setText(formatDate(time.getContext(), p.getTimestamp()));
|
||||
removeButton.setOnClickListener(v -> {
|
||||
listener.onFailedPendingContactRemoved(item);
|
||||
listener.onFailedPendingContactRemoved(p);
|
||||
removeButton.setEnabled(false);
|
||||
});
|
||||
|
||||
|
||||
@@ -107,11 +107,27 @@ Until it is completed, a pending contact is returned as JSON:
|
||||
{
|
||||
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
||||
"state": "adding_contact",
|
||||
"timestamp": 1557838312175
|
||||
}
|
||||
```
|
||||
|
||||
It is possible to get a list of all pending contacts:
|
||||
|
||||
`GET /v1/contacts/add/pending`
|
||||
|
||||
This will return a JSON array of pending contacts and their states:
|
||||
|
||||
```json
|
||||
{
|
||||
"pendingContact": {
|
||||
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
||||
"timestamp": 1557838312175
|
||||
},
|
||||
"state": "adding_contact"
|
||||
}
|
||||
```
|
||||
|
||||
The state can be one of these values:
|
||||
|
||||
* `waiting_for_connection`
|
||||
@@ -119,21 +135,16 @@ The state can be one of these values:
|
||||
* `adding_contact`
|
||||
* `failed`
|
||||
|
||||
If you want to get informed about state changes,
|
||||
If you want to be informed about state changes,
|
||||
you can use the Websocket API (below) to listen for events.
|
||||
|
||||
The following events are relevant here:
|
||||
|
||||
* `PendingContactAddedEvent`
|
||||
* `PendingContactStateChangedEvent`
|
||||
* `PendingContactRemovedEvent`
|
||||
* `ContactAddedRemotelyEvent` (when the pending contact becomes an actual contact)
|
||||
|
||||
It is possible to get a list of all pending contacts:
|
||||
|
||||
`GET /v1/contacts/add/pending`
|
||||
|
||||
This will return a JSON array of pending contacts formatted as shown above.
|
||||
|
||||
To remove a pending contact and abort the process of adding it:
|
||||
|
||||
`DELETE /v1/contacts/add/pending`
|
||||
@@ -302,6 +313,22 @@ it will send a JSON object representing the new contact to connected websocket c
|
||||
}
|
||||
```
|
||||
|
||||
### A pending contact was added
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"pendingContact": {
|
||||
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
||||
"timestamp": 1557838312175
|
||||
}
|
||||
},
|
||||
"name": "PendingContactAddedEvent",
|
||||
"type": "event"
|
||||
}
|
||||
|
||||
```
|
||||
### A pending contact changed its state
|
||||
|
||||
```json
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.contact.ContactManager
|
||||
import org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX
|
||||
import org.briarproject.bramble.api.contact.PendingContactId
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||
@@ -28,6 +29,7 @@ import javax.inject.Singleton
|
||||
|
||||
internal const val EVENT_CONTACT_ADDED_REMOTELY = "ContactAddedRemotelyEvent"
|
||||
internal const val EVENT_PENDING_CONTACT_STATE_CHANGED = "PendingContactStateChangedEvent"
|
||||
internal const val EVENT_PENDING_CONTACT_ADDED = "PendingContactAddedEvent"
|
||||
internal const val EVENT_PENDING_CONTACT_REMOVED = "PendingContactRemovedEvent"
|
||||
|
||||
@Immutable
|
||||
@@ -47,6 +49,9 @@ constructor(
|
||||
is PendingContactStateChangedEvent -> {
|
||||
webSocket.sendEvent(EVENT_PENDING_CONTACT_STATE_CHANGED, e.output())
|
||||
}
|
||||
is PendingContactAddedEvent -> {
|
||||
webSocket.sendEvent(EVENT_PENDING_CONTACT_ADDED, e.output())
|
||||
}
|
||||
is PendingContactRemovedEvent -> {
|
||||
webSocket.sendEvent(EVENT_PENDING_CONTACT_REMOVED, e.output())
|
||||
}
|
||||
@@ -78,8 +83,8 @@ constructor(
|
||||
}
|
||||
|
||||
override fun listPendingContacts(ctx: Context): Context {
|
||||
val pendingContacts = contactManager.pendingContacts.map { pendingContact ->
|
||||
pendingContact.output()
|
||||
val pendingContacts = contactManager.pendingContacts.map { pair ->
|
||||
JsonDict("pendingContact" to pair.first.output(), "state" to pair.second.output())
|
||||
}
|
||||
return ctx.json(pendingContacts)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.briar.headless.contact
|
||||
import org.briarproject.bramble.api.contact.PendingContact
|
||||
import org.briarproject.bramble.api.contact.PendingContactState
|
||||
import org.briarproject.bramble.api.contact.PendingContactState.*
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||
import org.briarproject.briar.headless.json.JsonDict
|
||||
@@ -10,7 +11,6 @@ import org.briarproject.briar.headless.json.JsonDict
|
||||
internal fun PendingContact.output() = JsonDict(
|
||||
"pendingContactId" to id.bytes,
|
||||
"alias" to alias,
|
||||
"state" to state.output(),
|
||||
"timestamp" to timestamp
|
||||
)
|
||||
|
||||
@@ -22,6 +22,10 @@ internal fun PendingContactState.output() = when(this) {
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
|
||||
internal fun PendingContactAddedEvent.output() = JsonDict(
|
||||
"pendingContact" to pendingContact.output()
|
||||
)
|
||||
|
||||
internal fun PendingContactStateChangedEvent.output() = JsonDict(
|
||||
"pendingContactId" to id.bytes,
|
||||
"state" to pendingContactState.output()
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test
|
||||
class ContactControllerIntegrationTest: IntegrationTest() {
|
||||
|
||||
@Test
|
||||
fun `list of contacts need authentication token`() {
|
||||
fun `returning list of contacts needs authentication token`() {
|
||||
val response = getWithWrongToken("$url/contacts")
|
||||
assertEquals(401, response.statusCode)
|
||||
}
|
||||
@@ -72,11 +72,10 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
||||
assertEquals(200, response.statusCode)
|
||||
assertEquals(1, response.jsonArray.length())
|
||||
val jsonObject = response.jsonArray.getJSONObject(0)
|
||||
assertEquals(alias, jsonObject.getString("alias"))
|
||||
assertEquals("waiting_for_connection", jsonObject.getString("state"))
|
||||
assertEquals(alias, jsonObject.getJSONObject("pendingContact").getString("alias"))
|
||||
|
||||
// remove pending contact again
|
||||
val idString = jsonObject.getString("pendingContactId")
|
||||
val idString = jsonObject.getJSONObject("pendingContact").getString("pendingContactId")
|
||||
val deleteJson = """{"pendingContactId": "$idString"}"""
|
||||
response = delete("$url/contacts/add/pending", deleteJson)
|
||||
assertEquals(200, response.statusCode)
|
||||
@@ -94,7 +93,7 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `adding pending contacts needs authentication token`() {
|
||||
fun `adding a pending contact needs authentication token`() {
|
||||
val response = postWithWrongToken("$url/contacts/add/pending")
|
||||
assertEquals(401, response.statusCode)
|
||||
}
|
||||
@@ -106,7 +105,7 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `deleting contact need authentication token`() {
|
||||
fun `deleting a contact needs authentication token`() {
|
||||
val response = deleteWithWrongToken("$url/contacts/1")
|
||||
assertEquals(401, response.statusCode)
|
||||
}
|
||||
|
||||
@@ -7,11 +7,14 @@ import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.runs
|
||||
import org.briarproject.bramble.api.Pair
|
||||
import org.briarproject.bramble.api.contact.Contact
|
||||
import org.briarproject.bramble.api.contact.ContactId
|
||||
import org.briarproject.bramble.api.contact.PendingContactId
|
||||
import org.briarproject.bramble.api.contact.PendingContactState.FAILED
|
||||
import org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||
@@ -124,8 +127,14 @@ internal class ContactControllerTest : ControllerTest() {
|
||||
|
||||
@Test
|
||||
fun testListPendingContacts() {
|
||||
every { contactManager.pendingContacts } returns listOf(pendingContact)
|
||||
every { ctx.json(listOf(pendingContact.output())) } returns ctx
|
||||
every { contactManager.pendingContacts } returns listOf(
|
||||
Pair(pendingContact, WAITING_FOR_CONNECTION)
|
||||
)
|
||||
val dict = JsonDict(
|
||||
"pendingContact" to pendingContact.output(),
|
||||
"state" to WAITING_FOR_CONNECTION.output()
|
||||
)
|
||||
every { ctx.json(listOf(dict)) } returns ctx
|
||||
controller.listPendingContacts(ctx)
|
||||
}
|
||||
|
||||
@@ -225,6 +234,20 @@ internal class ContactControllerTest : ControllerTest() {
|
||||
controller.eventOccurred(event)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPendingContactAddedEvent() {
|
||||
val event = PendingContactAddedEvent(pendingContact)
|
||||
|
||||
every {
|
||||
webSocketController.sendEvent(
|
||||
EVENT_PENDING_CONTACT_ADDED,
|
||||
event.output()
|
||||
)
|
||||
} just runs
|
||||
|
||||
controller.eventOccurred(event)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPendingContactRemovedEvent() {
|
||||
val event = PendingContactRemovedEvent(pendingContact.id)
|
||||
@@ -284,13 +307,27 @@ internal class ContactControllerTest : ControllerTest() {
|
||||
{
|
||||
"pendingContactId": ${toJson(pendingContact.id.bytes)},
|
||||
"alias": "${pendingContact.alias}",
|
||||
"state": "${pendingContact.state.name.toLowerCase()}",
|
||||
"timestamp": ${pendingContact.timestamp}
|
||||
}
|
||||
"""
|
||||
assertJsonEquals(json, pendingContact.output())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOutputPendingContactAddedEvent() {
|
||||
val event = PendingContactAddedEvent(pendingContact)
|
||||
val json = """
|
||||
{
|
||||
"pendingContact": {
|
||||
"pendingContactId": ${toJson(pendingContact.id.bytes)},
|
||||
"alias": "${pendingContact.alias}",
|
||||
"timestamp": ${pendingContact.timestamp}
|
||||
}
|
||||
}
|
||||
"""
|
||||
assertJsonEquals(json, event.output())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOutputPendingContactStateChangedEvent() {
|
||||
val event = PendingContactStateChangedEvent(pendingContact.id, FAILED)
|
||||
|
||||
Reference in New Issue
Block a user