mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Merge branch 'introduction-ui-messages' into 'master'
Fix introduction response messages in UI and some minor fixes Closes #923 See merge request akwizgran/briar!776
This commit is contained in:
@@ -124,6 +124,9 @@ abstract class ConversationItem {
|
|||||||
text = ctx.getString(
|
text = ctx.getString(
|
||||||
R.string.introduction_response_accepted_sent,
|
R.string.introduction_response_accepted_sent,
|
||||||
ir.getName());
|
ir.getName());
|
||||||
|
text += "\n\n" + ctx.getString(
|
||||||
|
R.string.introduction_response_accepted_sent_info,
|
||||||
|
ir.getName());
|
||||||
} else {
|
} else {
|
||||||
text = ctx.getString(
|
text = ctx.getString(
|
||||||
R.string.introduction_response_declined_sent,
|
R.string.introduction_response_declined_sent,
|
||||||
|
|||||||
@@ -156,6 +156,7 @@
|
|||||||
<string name="introduction_request_exists_received">%1$s has asked to introduce you to %2$s, but %2$s is already in your contact list. Since %1$s might not know that, you can still respond:</string>
|
<string name="introduction_request_exists_received">%1$s has asked to introduce you to %2$s, but %2$s is already in your contact list. Since %1$s might not know that, you can still respond:</string>
|
||||||
<string name="introduction_request_answered_received">%1$s has asked to introduce you to %2$s.</string>
|
<string name="introduction_request_answered_received">%1$s has asked to introduce you to %2$s.</string>
|
||||||
<string name="introduction_response_accepted_sent">You accepted the introduction to %1$s.</string>
|
<string name="introduction_response_accepted_sent">You accepted the introduction to %1$s.</string>
|
||||||
|
<string name="introduction_response_accepted_sent_info">Before %1$s gets added to your contacts, they need to accept the introduction as well. This might take some time.</string>
|
||||||
<string name="introduction_response_declined_sent">You declined the introduction to %1$s.</string>
|
<string name="introduction_response_declined_sent">You declined the introduction to %1$s.</string>
|
||||||
<string name="introduction_response_accepted_received">%1$s accepted the introduction to %2$s.</string>
|
<string name="introduction_response_accepted_received">%1$s accepted the introduction to %2$s.</string>
|
||||||
<string name="introduction_response_declined_received">%1$s declined the introduction to %2$s.</string>
|
<string name="introduction_response_declined_received">%1$s declined the introduction to %2$s.</string>
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ public interface IntroductionManager extends ConversationClient {
|
|||||||
*/
|
*/
|
||||||
int CLIENT_VERSION = 1;
|
int CLIENT_VERSION = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if both contacts can be introduced at this moment.
|
||||||
|
*/
|
||||||
boolean canIntroduce(Contact c1, Contact c2) throws DbException;
|
boolean canIntroduce(Contact c1, Contact c2) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -144,15 +144,15 @@ abstract class AbstractProtocolEngine<S extends Session>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcastIntroductionResponseReceivedEvent(Transaction txn,
|
void broadcastIntroductionResponseReceivedEvent(Transaction txn, Session s,
|
||||||
Session s, AuthorId sender, AbstractIntroductionMessage m)
|
AuthorId sender, Author otherAuthor, AbstractIntroductionMessage m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
AuthorId localAuthorId = identityManager.getLocalAuthor(txn).getId();
|
AuthorId localAuthorId = identityManager.getLocalAuthor(txn).getId();
|
||||||
Contact c = contactManager.getContact(txn, sender, localAuthorId);
|
Contact c = contactManager.getContact(txn, sender, localAuthorId);
|
||||||
IntroductionResponse response =
|
IntroductionResponse response =
|
||||||
new IntroductionResponse(s.getSessionId(), m.getMessageId(),
|
new IntroductionResponse(s.getSessionId(), m.getMessageId(),
|
||||||
m.getGroupId(), s.getRole(), m.getTimestamp(), false,
|
m.getGroupId(), s.getRole(), m.getTimestamp(), false,
|
||||||
false, false, false, c.getAuthor().getName(),
|
false, false, false, otherAuthor.getName(),
|
||||||
m instanceof AcceptMessage);
|
m instanceof AcceptMessage);
|
||||||
IntroductionResponseReceivedEvent e =
|
IntroductionResponseReceivedEvent e =
|
||||||
new IntroductionResponseReceivedEvent(c.getId(), response);
|
new IntroductionResponseReceivedEvent(c.getId(), response);
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ class IntroduceeProtocolEngine
|
|||||||
|
|
||||||
// Broadcast IntroductionResponseReceivedEvent
|
// Broadcast IntroductionResponseReceivedEvent
|
||||||
broadcastIntroductionResponseReceivedEvent(txn, s,
|
broadcastIntroductionResponseReceivedEvent(txn, s,
|
||||||
s.getIntroducer().getId(), m);
|
s.getIntroducer().getId(), s.getRemote().author, m);
|
||||||
|
|
||||||
if (s.getState() == AWAIT_RESPONSES) {
|
if (s.getState() == AWAIT_RESPONSES) {
|
||||||
// Mark the request message unavailable to answer
|
// Mark the request message unavailable to answer
|
||||||
|
|||||||
@@ -261,19 +261,24 @@ class IntroducerProtocolEngine
|
|||||||
// Create the next state
|
// Create the next state
|
||||||
IntroducerState state = AWAIT_AUTHS;
|
IntroducerState state = AWAIT_AUTHS;
|
||||||
Introducee introduceeA, introduceeB;
|
Introducee introduceeA, introduceeB;
|
||||||
|
Author sender, other;
|
||||||
if (senderIsAlice) {
|
if (senderIsAlice) {
|
||||||
if (s.getState() == AWAIT_RESPONSES) state = AWAIT_RESPONSE_B;
|
if (s.getState() == AWAIT_RESPONSES) state = AWAIT_RESPONSE_B;
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
||||||
|
sender = introduceeA.author;
|
||||||
|
other = introduceeB.author;
|
||||||
} else {
|
} else {
|
||||||
if (s.getState() == AWAIT_RESPONSES) state = AWAIT_RESPONSE_A;
|
if (s.getState() == AWAIT_RESPONSES) state = AWAIT_RESPONSE_A;
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
||||||
|
sender = introduceeB.author;
|
||||||
|
other = introduceeA.author;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast IntroductionResponseReceivedEvent
|
// Broadcast IntroductionResponseReceivedEvent
|
||||||
Author sender = senderIsAlice ? introduceeA.author : introduceeB.author;
|
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(),
|
||||||
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(), m);
|
other, m);
|
||||||
|
|
||||||
// Move to the next state
|
// Move to the next state
|
||||||
return new IntroducerSession(s.getSessionId(), state,
|
return new IntroducerSession(s.getSessionId(), state,
|
||||||
@@ -313,17 +318,22 @@ class IntroducerProtocolEngine
|
|||||||
m.getTransportProperties(), false);
|
m.getTransportProperties(), false);
|
||||||
|
|
||||||
Introducee introduceeA, introduceeB;
|
Introducee introduceeA, introduceeB;
|
||||||
|
Author sender, other;
|
||||||
if (senderIsAlice) {
|
if (senderIsAlice) {
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
||||||
|
sender = introduceeA.author;
|
||||||
|
other = introduceeB.author;
|
||||||
} else {
|
} else {
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
||||||
|
sender = introduceeB.author;
|
||||||
|
other = introduceeA.author;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast IntroductionResponseReceivedEvent
|
// Broadcast IntroductionResponseReceivedEvent
|
||||||
Author sender = senderIsAlice ? introduceeA.author : introduceeB.author;
|
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(),
|
||||||
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(), m);
|
other, m);
|
||||||
|
|
||||||
return new IntroducerSession(s.getSessionId(), START,
|
return new IntroducerSession(s.getSessionId(), START,
|
||||||
s.getRequestTimestamp(), introduceeA, introduceeB);
|
s.getRequestTimestamp(), introduceeA, introduceeB);
|
||||||
@@ -360,19 +370,24 @@ class IntroducerProtocolEngine
|
|||||||
// Create the next state
|
// Create the next state
|
||||||
IntroducerState state = START;
|
IntroducerState state = START;
|
||||||
Introducee introduceeA, introduceeB;
|
Introducee introduceeA, introduceeB;
|
||||||
|
Author sender, other;
|
||||||
if (senderIsAlice) {
|
if (senderIsAlice) {
|
||||||
if (s.getState() == AWAIT_RESPONSES) state = A_DECLINED;
|
if (s.getState() == AWAIT_RESPONSES) state = A_DECLINED;
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
||||||
|
sender = introduceeA.author;
|
||||||
|
other = introduceeB.author;
|
||||||
} else {
|
} else {
|
||||||
if (s.getState() == AWAIT_RESPONSES) state = B_DECLINED;
|
if (s.getState() == AWAIT_RESPONSES) state = B_DECLINED;
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
||||||
|
sender = introduceeB.author;
|
||||||
|
other = introduceeA.author;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast IntroductionResponseReceivedEvent
|
// Broadcast IntroductionResponseReceivedEvent
|
||||||
Author sender = senderIsAlice ? introduceeA.author : introduceeB.author;
|
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(),
|
||||||
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(), m);
|
other, m);
|
||||||
|
|
||||||
return new IntroducerSession(s.getSessionId(), state,
|
return new IntroducerSession(s.getSessionId(), state,
|
||||||
s.getRequestTimestamp(), introduceeA, introduceeB);
|
s.getRequestTimestamp(), introduceeA, introduceeB);
|
||||||
@@ -405,17 +420,22 @@ class IntroducerProtocolEngine
|
|||||||
Message sent = sendDeclineMessage(txn, i, timestamp, false);
|
Message sent = sendDeclineMessage(txn, i, timestamp, false);
|
||||||
|
|
||||||
Introducee introduceeA, introduceeB;
|
Introducee introduceeA, introduceeB;
|
||||||
|
Author sender, other;
|
||||||
if (senderIsAlice) {
|
if (senderIsAlice) {
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
introduceeA = new Introducee(s.getIntroduceeA(), m.getMessageId());
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
introduceeB = new Introducee(s.getIntroduceeB(), sent);
|
||||||
|
sender = introduceeA.author;
|
||||||
|
other = introduceeB.author;
|
||||||
} else {
|
} else {
|
||||||
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
introduceeA = new Introducee(s.getIntroduceeA(), sent);
|
||||||
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
introduceeB = new Introducee(s.getIntroduceeB(), m.getMessageId());
|
||||||
|
sender = introduceeB.author;
|
||||||
|
other = introduceeA.author;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast IntroductionResponseReceivedEvent
|
// Broadcast IntroductionResponseReceivedEvent
|
||||||
Author sender = senderIsAlice ? introduceeA.author : introduceeB.author;
|
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(),
|
||||||
broadcastIntroductionResponseReceivedEvent(txn, s, sender.getId(), m);
|
other, m);
|
||||||
|
|
||||||
return new IntroducerSession(s.getSessionId(), START,
|
return new IntroducerSession(s.getSessionId(), START,
|
||||||
s.getRequestTimestamp(), introduceeA, introduceeB);
|
s.getRequestTimestamp(), introduceeA, introduceeB);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.briarproject.briar.api.client.SessionId;
|
|||||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionMessage;
|
import org.briarproject.briar.api.introduction.IntroductionMessage;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
||||||
|
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
||||||
@@ -51,6 +52,7 @@ import static org.briarproject.bramble.test.TestUtils.getTransportProperties;
|
|||||||
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
|
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID;
|
import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID;
|
||||||
import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_VERSION;
|
import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_VERSION;
|
||||||
|
import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_RESPONSES;
|
||||||
import static org.briarproject.briar.introduction.IntroduceeState.LOCAL_DECLINED;
|
import static org.briarproject.briar.introduction.IntroduceeState.LOCAL_DECLINED;
|
||||||
import static org.briarproject.briar.introduction.IntroducerState.A_DECLINED;
|
import static org.briarproject.briar.introduction.IntroducerState.A_DECLINED;
|
||||||
import static org.briarproject.briar.introduction.IntroducerState.B_DECLINED;
|
import static org.briarproject.briar.introduction.IntroducerState.B_DECLINED;
|
||||||
@@ -146,24 +148,32 @@ public class IntroductionIntegrationTest
|
|||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener1.requestReceived);
|
assertTrue(listener1.requestReceived);
|
||||||
|
assertEquals(introducee2.getAuthor().getName(),
|
||||||
|
listener1.getRequest().getName());
|
||||||
assertGroupCount(messageTracker1, g1.getId(), 2, 1);
|
assertGroupCount(messageTracker1, g1.getId(), 2, 1);
|
||||||
|
|
||||||
// sync second REQUEST message
|
// sync second REQUEST message
|
||||||
sync0To2(1, true);
|
sync0To2(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener2.requestReceived);
|
assertTrue(listener2.requestReceived);
|
||||||
|
assertEquals(introducee1.getAuthor().getName(),
|
||||||
|
listener2.getRequest().getName());
|
||||||
assertGroupCount(messageTracker2, g2.getId(), 2, 1);
|
assertGroupCount(messageTracker2, g2.getId(), 2, 1);
|
||||||
|
|
||||||
// sync first ACCEPT message
|
// sync first ACCEPT message
|
||||||
sync1To0(1, true);
|
sync1To0(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener0.response1Received);
|
assertTrue(listener0.response1Received);
|
||||||
|
assertEquals(introducee2.getAuthor().getName(),
|
||||||
|
listener0.getResponse().getName());
|
||||||
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
|
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
|
||||||
|
|
||||||
// sync second ACCEPT message
|
// sync second ACCEPT message
|
||||||
sync2To0(1, true);
|
sync2To0(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener0.response2Received);
|
assertTrue(listener0.response2Received);
|
||||||
|
assertEquals(introducee1.getAuthor().getName(),
|
||||||
|
listener0.getResponse().getName());
|
||||||
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
|
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
|
||||||
|
|
||||||
// sync forwarded ACCEPT messages to introducees
|
// sync forwarded ACCEPT messages to introducees
|
||||||
@@ -259,6 +269,10 @@ public class IntroductionIntegrationTest
|
|||||||
assertEquals(alice ? A_DECLINED : B_DECLINED,
|
assertEquals(alice ? A_DECLINED : B_DECLINED,
|
||||||
introducerSession.getState());
|
introducerSession.getState());
|
||||||
|
|
||||||
|
// assert that the name on the decline event is correct
|
||||||
|
assertEquals(introducee2.getAuthor().getName(),
|
||||||
|
listener0.getResponse().getName());
|
||||||
|
|
||||||
// sync second response
|
// sync second response
|
||||||
sync2To0(1, true);
|
sync2To0(1, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
@@ -271,6 +285,11 @@ public class IntroductionIntegrationTest
|
|||||||
// sync first forwarded response
|
// sync first forwarded response
|
||||||
sync0To2(1, true);
|
sync0To2(1, true);
|
||||||
|
|
||||||
|
// assert that the name on the decline event is correct
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertEquals(introducee1.getAuthor().getName(),
|
||||||
|
listener2.getResponse().getName());
|
||||||
|
|
||||||
// note how the introducer does not forward the second response,
|
// note how the introducer does not forward the second response,
|
||||||
// because after the first decline the protocol finished
|
// because after the first decline the protocol finished
|
||||||
|
|
||||||
@@ -339,6 +358,11 @@ public class IntroductionIntegrationTest
|
|||||||
sync0To2(1, true);
|
sync0To2(1, true);
|
||||||
sync0To1(1, true);
|
sync0To1(1, true);
|
||||||
|
|
||||||
|
// assert that the name on the decline event is correct
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertEquals(contact2From0.getAuthor().getName(),
|
||||||
|
listener1.getResponse().getName());
|
||||||
|
|
||||||
assertFalse(contactManager1
|
assertFalse(contactManager1
|
||||||
.contactExists(author2.getId(), author1.getId()));
|
.contactExists(author2.getId(), author1.getId()));
|
||||||
assertFalse(contactManager2
|
assertFalse(contactManager2
|
||||||
@@ -408,8 +432,6 @@ public class IntroductionIntegrationTest
|
|||||||
assertFalse(contactManager2
|
assertFalse(contactManager2
|
||||||
.contactExists(author1.getId(), author2.getId()));
|
.contactExists(author1.getId(), author2.getId()));
|
||||||
|
|
||||||
// since introducee2 was already in FINISHED state when
|
|
||||||
// introducee1's response arrived, she ignores and deletes it
|
|
||||||
assertDefaultUiMessages();
|
assertDefaultUiMessages();
|
||||||
assertFalse(listener0.aborted);
|
assertFalse(listener0.aborted);
|
||||||
assertFalse(listener1.aborted);
|
assertFalse(listener1.aborted);
|
||||||
@@ -417,7 +439,7 @@ public class IntroductionIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResponseAndAckInOneSession() throws Exception {
|
public void testResponseAndAuthInOneSync() throws Exception {
|
||||||
addListeners(true, true);
|
addListeners(true, true);
|
||||||
|
|
||||||
// make introduction
|
// make introduction
|
||||||
@@ -449,10 +471,125 @@ public class IntroductionIntegrationTest
|
|||||||
.respondToIntroduction(contactId0From2, listener2.sessionId, time,
|
.respondToIntroduction(contactId0From2, listener2.sessionId, time,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
// sync second response and ACK and make sure there is no abort
|
// sync second response and AUTH
|
||||||
sync2To0(2, true);
|
sync2To0(2, true);
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener0.response2Received);
|
assertTrue(listener0.response2Received);
|
||||||
|
|
||||||
|
// Forward AUTH
|
||||||
|
sync0To1(1, true);
|
||||||
|
|
||||||
|
// Second AUTH and ACTIATE and forward them
|
||||||
|
sync1To0(2, true);
|
||||||
|
sync0To2(2, true);
|
||||||
|
|
||||||
|
assertTrue(contactManager1
|
||||||
|
.contactExists(author2.getId(), author1.getId()));
|
||||||
|
assertTrue(contactManager2
|
||||||
|
.contactExists(author1.getId(), author2.getId()));
|
||||||
|
|
||||||
|
assertDefaultUiMessages();
|
||||||
|
assertFalse(listener0.aborted);
|
||||||
|
assertFalse(listener1.aborted);
|
||||||
|
assertFalse(listener2.aborted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an introducee declines an introduction,
|
||||||
|
* the other introducee needs to respond before returning to START state,
|
||||||
|
* otherwise a subsequent attempt at introducing the same contacts will fail
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAutomaticSecondDecline() throws Exception {
|
||||||
|
// introducee1 declines automatically and introducee2 doesn't answer
|
||||||
|
addListeners(false, true);
|
||||||
|
listener2.answerRequests = false;
|
||||||
|
|
||||||
|
// make introduction
|
||||||
|
long time = clock.currentTimeMillis();
|
||||||
|
Contact introducee1 = contact1From0;
|
||||||
|
Contact introducee2 = contact2From0;
|
||||||
|
introductionManager0
|
||||||
|
.makeIntroduction(introducee1, introducee2, null, time);
|
||||||
|
|
||||||
|
// sync request messages
|
||||||
|
sync0To1(1, true);
|
||||||
|
sync0To2(1, true);
|
||||||
|
|
||||||
|
// assert that introducee1 is in correct state
|
||||||
|
IntroduceeSession introduceeSession = getIntroduceeSession(c1);
|
||||||
|
assertEquals(LOCAL_DECLINED, introduceeSession.getState());
|
||||||
|
|
||||||
|
// sync first response
|
||||||
|
sync1To0(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener0.response1Received);
|
||||||
|
|
||||||
|
// assert that introducer is in correct state
|
||||||
|
boolean alice = c0.getIntroductionCrypto()
|
||||||
|
.isAlice(introducee1.getAuthor().getId(),
|
||||||
|
introducee2.getAuthor().getId());
|
||||||
|
IntroducerSession introducerSession = getIntroducerSession();
|
||||||
|
assertEquals(alice ? A_DECLINED : B_DECLINED,
|
||||||
|
introducerSession.getState());
|
||||||
|
|
||||||
|
// assert that introducee2 is in correct state
|
||||||
|
introduceeSession = getIntroduceeSession(c2);
|
||||||
|
assertEquals(AWAIT_RESPONSES, introduceeSession.getState());
|
||||||
|
|
||||||
|
// forward first DECLINE
|
||||||
|
sync0To2(1, true);
|
||||||
|
|
||||||
|
// assert that the name on the decline event is correct
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertEquals(introducee1.getAuthor().getName(),
|
||||||
|
listener2.getResponse().getName());
|
||||||
|
|
||||||
|
// assert that introducee2 is in correct state
|
||||||
|
introduceeSession = getIntroduceeSession(c2);
|
||||||
|
assertEquals(IntroduceeState.START, introduceeSession.getState());
|
||||||
|
|
||||||
|
// second response should be an immediate automatic DECLINE
|
||||||
|
sync2To0(1, true);
|
||||||
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
|
assertTrue(listener0.response2Received);
|
||||||
|
|
||||||
|
// assert that introducer now moved to START state
|
||||||
|
introducerSession = getIntroducerSession();
|
||||||
|
assertEquals(START, introducerSession.getState());
|
||||||
|
|
||||||
|
// introducee1 is still waiting for second response
|
||||||
|
introduceeSession = getIntroduceeSession(c1);
|
||||||
|
assertEquals(LOCAL_DECLINED, introduceeSession.getState());
|
||||||
|
|
||||||
|
// forward automatic decline
|
||||||
|
sync0To1(1, true);
|
||||||
|
|
||||||
|
// introducee1 can finally move to the START
|
||||||
|
introduceeSession = getIntroduceeSession(c1);
|
||||||
|
assertEquals(IntroduceeState.START, introduceeSession.getState());
|
||||||
|
|
||||||
|
Group g1 = introductionManager0.getContactGroup(introducee1);
|
||||||
|
Group g2 = introductionManager0.getContactGroup(introducee2);
|
||||||
|
assertEquals(2,
|
||||||
|
introductionManager0.getIntroductionMessages(contactId1From0)
|
||||||
|
.size());
|
||||||
|
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
|
||||||
|
assertEquals(2,
|
||||||
|
introductionManager0.getIntroductionMessages(contactId2From0)
|
||||||
|
.size());
|
||||||
|
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
|
||||||
|
assertEquals(2,
|
||||||
|
introductionManager1.getIntroductionMessages(contactId0From1)
|
||||||
|
.size());
|
||||||
|
assertGroupCount(messageTracker1, g1.getId(), 2, 1);
|
||||||
|
// the automatic DECLINE is invisible in the UI
|
||||||
|
// so there's just the remote REQUEST and remote DECLINE
|
||||||
|
assertEquals(2,
|
||||||
|
introductionManager2.getIntroductionMessages(contactId0From2)
|
||||||
|
.size());
|
||||||
|
assertGroupCount(messageTracker2, g2.getId(), 2, 2);
|
||||||
|
|
||||||
assertFalse(listener0.aborted);
|
assertFalse(listener0.aborted);
|
||||||
assertFalse(listener1.aborted);
|
assertFalse(listener1.aborted);
|
||||||
assertFalse(listener2.aborted);
|
assertFalse(listener2.aborted);
|
||||||
@@ -1012,11 +1149,25 @@ public class IntroductionIntegrationTest
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
private class IntroduceeListener implements EventListener {
|
private abstract class IntroductionListener implements EventListener {
|
||||||
|
|
||||||
|
protected volatile boolean aborted = false;
|
||||||
|
protected volatile Event latestEvent;
|
||||||
|
|
||||||
|
IntroductionResponse getResponse() {
|
||||||
|
assertTrue(
|
||||||
|
latestEvent instanceof IntroductionResponseReceivedEvent);
|
||||||
|
return ((IntroductionResponseReceivedEvent) latestEvent)
|
||||||
|
.getIntroductionResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
private class IntroduceeListener extends IntroductionListener {
|
||||||
|
|
||||||
private volatile boolean requestReceived = false;
|
private volatile boolean requestReceived = false;
|
||||||
private volatile boolean succeeded = false;
|
private volatile boolean succeeded = false;
|
||||||
private volatile boolean aborted = false;
|
|
||||||
private volatile boolean answerRequests = true;
|
private volatile boolean answerRequests = true;
|
||||||
private volatile SessionId sessionId;
|
private volatile SessionId sessionId;
|
||||||
|
|
||||||
@@ -1031,6 +1182,7 @@ public class IntroductionIntegrationTest
|
|||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof IntroductionRequestReceivedEvent) {
|
if (e instanceof IntroductionRequestReceivedEvent) {
|
||||||
|
latestEvent = e;
|
||||||
IntroductionRequestReceivedEvent introEvent =
|
IntroductionRequestReceivedEvent introEvent =
|
||||||
((IntroductionRequestReceivedEvent) e);
|
((IntroductionRequestReceivedEvent) e);
|
||||||
requestReceived = true;
|
requestReceived = true;
|
||||||
@@ -1053,29 +1205,42 @@ public class IntroductionIntegrationTest
|
|||||||
} finally {
|
} finally {
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
}
|
}
|
||||||
|
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
|
// only broadcast for DECLINE messages in introducee role
|
||||||
|
latestEvent = e;
|
||||||
|
eventWaiter.resume();
|
||||||
} else if (e instanceof IntroductionSucceededEvent) {
|
} else if (e instanceof IntroductionSucceededEvent) {
|
||||||
|
latestEvent = e;
|
||||||
succeeded = true;
|
succeeded = true;
|
||||||
Contact contact = ((IntroductionSucceededEvent) e).getContact();
|
Contact contact = ((IntroductionSucceededEvent) e).getContact();
|
||||||
eventWaiter
|
eventWaiter
|
||||||
.assertFalse(contact.getId().equals(contactId0From1));
|
.assertFalse(contact.getId().equals(contactId0From1));
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
} else if (e instanceof IntroductionAbortedEvent) {
|
} else if (e instanceof IntroductionAbortedEvent) {
|
||||||
|
latestEvent = e;
|
||||||
aborted = true;
|
aborted = true;
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IntroductionRequest getRequest() {
|
||||||
|
assertTrue(
|
||||||
|
latestEvent instanceof IntroductionRequestReceivedEvent);
|
||||||
|
return ((IntroductionRequestReceivedEvent) latestEvent)
|
||||||
|
.getIntroductionRequest();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
private class IntroducerListener implements EventListener {
|
private class IntroducerListener extends IntroductionListener {
|
||||||
|
|
||||||
private volatile boolean response1Received = false;
|
private volatile boolean response1Received = false;
|
||||||
private volatile boolean response2Received = false;
|
private volatile boolean response2Received = false;
|
||||||
private volatile boolean aborted = false;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof IntroductionResponseReceivedEvent) {
|
if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
|
latestEvent = e;
|
||||||
ContactId c =
|
ContactId c =
|
||||||
((IntroductionResponseReceivedEvent) e)
|
((IntroductionResponseReceivedEvent) e)
|
||||||
.getContactId();
|
.getContactId();
|
||||||
@@ -1086,6 +1251,7 @@ public class IntroductionIntegrationTest
|
|||||||
}
|
}
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
} else if (e instanceof IntroductionAbortedEvent) {
|
} else if (e instanceof IntroductionAbortedEvent) {
|
||||||
|
latestEvent = e;
|
||||||
aborted = true;
|
aborted = true;
|
||||||
eventWaiter.resume();
|
eventWaiter.resume();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user