Merge branch '766-unit-tests-for-group-validators' into 'master'

Add unit tests for group validators

Part of #766

See merge request !436
This commit is contained in:
akwizgran
2016-11-29 18:13:43 +00:00
4 changed files with 1245 additions and 15 deletions

View File

@@ -9,7 +9,6 @@ import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.privategroup.MessageType;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.invitation.GroupInvitationFactory;
@@ -79,17 +78,14 @@ class GroupMessageValidator extends BdfMessageValidator {
Author member = authorFactory.createAuthor(memberName, memberPublicKey);
BdfMessageContext c;
switch (MessageType.valueOf(type)) {
case JOIN:
c = validateJoin(m, g, body, member);
addMessageMetadata(c, member, m.getTimestamp());
break;
case POST:
c = validatePost(m, g, body, member);
addMessageMetadata(c, member, m.getTimestamp());
break;
default:
throw new InvalidMessageException("Unknown Message Type");
if (type == JOIN.getInt()) {
c = validateJoin(m, g, body, member);
addMessageMetadata(c, member, m.getTimestamp());
} else if (type == POST.getInt()) {
c = validatePost(m, g, body, member);
addMessageMetadata(c, member, m.getTimestamp());
} else {
throw new InvalidMessageException("Unknown Message Type");
}
c.getDictionary().put(KEY_TYPE, type);
return c;
@@ -133,8 +129,9 @@ class GroupMessageValidator extends BdfMessageValidator {
.createInviteToken(creator.getId(), member.getId(),
pg.getId(), inviteTimestamp);
try {
clientHelper.verifySignature(SIGNING_LABEL_INVITE, creatorSignature,
creator.getPublicKey(), token);
clientHelper
.verifySignature(SIGNING_LABEL_INVITE, creatorSignature,
creator.getPublicKey(), token);
} catch (GeneralSecurityException e) {
throw new InvalidMessageException(e);
}
@@ -180,7 +177,7 @@ class GroupMessageValidator extends BdfMessageValidator {
// content (string)
String content = body.getString(5);
checkLength(content, 0, MAX_GROUP_POST_BODY_LENGTH);
checkLength(content, 1, MAX_GROUP_POST_BODY_LENGTH);
// signature (raw)
// a signature with the member's private key over a list with 7 elements

View File

@@ -2,6 +2,7 @@ package org.briarproject;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
@@ -16,6 +17,8 @@ public abstract class ValidatorTestCase extends BriarMockTestCase {
protected final MetadataEncoder metadataEncoder =
context.mock(MetadataEncoder.class);
protected final Clock clock = context.mock(Clock.class);
protected final AuthorFactory authorFactory =
context.mock(AuthorFactory.class);
protected final MessageId messageId =
new MessageId(TestUtils.getRandomId());

View File

@@ -0,0 +1,648 @@
package org.briarproject.privategroup;
import org.briarproject.ValidatorTestCase;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.BdfMessageContext;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.privategroup.MessageType;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.invitation.GroupInvitationFactory;
import org.briarproject.api.sync.InvalidMessageException;
import org.briarproject.api.sync.MessageId;
import org.jmock.Expectations;
import org.junit.Test;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.briarproject.TestUtils.getRandomBytes;
import static org.briarproject.TestUtils.getRandomId;
import static org.briarproject.TestUtils.getRandomString;
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.api.privategroup.GroupMessageFactory.SIGNING_LABEL_JOIN;
import static org.briarproject.api.privategroup.GroupMessageFactory.SIGNING_LABEL_POST;
import static org.briarproject.api.privategroup.MessageType.JOIN;
import static org.briarproject.api.privategroup.MessageType.POST;
import static org.briarproject.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
import static org.briarproject.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
import static org.briarproject.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
import static org.briarproject.privategroup.GroupConstants.KEY_MEMBER_ID;
import static org.briarproject.privategroup.GroupConstants.KEY_MEMBER_NAME;
import static org.briarproject.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
import static org.briarproject.privategroup.GroupConstants.KEY_PARENT_MSG_ID;
import static org.briarproject.privategroup.GroupConstants.KEY_PREVIOUS_MSG_ID;
import static org.briarproject.privategroup.GroupConstants.KEY_READ;
import static org.briarproject.privategroup.GroupConstants.KEY_TIMESTAMP;
import static org.briarproject.privategroup.GroupConstants.KEY_TYPE;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class GroupMessageValidatorTest extends ValidatorTestCase {
private final PrivateGroupFactory privateGroupFactory =
context.mock(PrivateGroupFactory.class);
private final GroupInvitationFactory groupInvitationFactory =
context.mock(GroupInvitationFactory.class);
private final String creatorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final String memberName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final byte[] creatorKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final byte[] memberKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final byte[] creatorSignature =
getRandomBytes(MAX_SIGNATURE_LENGTH);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final Author member =
new Author(new AuthorId(getRandomId()), memberName, memberKey);
private final Author creator =
new Author(new AuthorId(getRandomId()), creatorName, creatorKey);
private final long inviteTimestamp = 42L;
private final PrivateGroup privateGroup = new PrivateGroup(group,
getRandomString(MAX_GROUP_NAME_LENGTH), creator,
getRandomBytes(GROUP_SALT_LENGTH));
private final BdfList token = BdfList.of("token");
private final MessageId parentId = new MessageId(getRandomId());
private final MessageId previousMsgId = new MessageId(getRandomId());
private final String postContent =
getRandomString(MAX_GROUP_POST_BODY_LENGTH);
private final GroupMessageValidator validator =
new GroupMessageValidator(privateGroupFactory, clientHelper,
metadataEncoder, clock, authorFactory,
groupInvitationFactory);
// JOIN message
@Test(expected = FormatException.class)
public void testRejectsTooShortJoinMessage() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey, null);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongJoinMessage() throws Exception {
expectCreateAuthor(creator);
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey, null,
signature, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooShortMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), "", memberKey, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithTooLongMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(),
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), memberKey, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNullMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), null, memberKey, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNonStringMemberName() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), getRandomBytes(5), memberKey,
null, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooShortMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName, new byte[0], null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooLongMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), null, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithNoullMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName, null, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithNonRawMemberKey() throws Exception {
BdfList body = BdfList.of(JOIN.getInt(), memberName, "not raw", null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithNonListInvitation() throws Exception {
expectCreateAuthor(creator);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey,
"not a list", signature);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsCreatorJoin() throws Exception {
expectJoinMessage(creator, null, true, true);
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey,
null, signature);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, JOIN, creator,
Collections.<MessageId>emptyList());
assertTrue(messageContext.getDictionary()
.getBoolean(KEY_INITIAL_JOIN_MSG));
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithNullInvitation() throws Exception {
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, null,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooShortInvitation() throws Exception {
BdfList invite = BdfList.of(inviteTimestamp);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooLongInvitation() throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature, "");
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithEqualInvitationTime()
throws Exception {
BdfList invite = BdfList.of(message.getTimestamp(), creatorSignature);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithLaterInvitationTime()
throws Exception {
BdfList invite = BdfList.of(message.getTimestamp() + 1,
creatorSignature);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullInvitationTime()
throws Exception {
BdfList invite = BdfList.of(null, creatorSignature);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNonLongInvitationTime()
throws Exception {
BdfList invite = BdfList.of("not long", creatorSignature);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithTooShortCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, new byte[0]);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinWithTooLongCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNullCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, null);
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsMemberJoinWithNonRawCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, "not raw");
expectCreateAuthor(member);
expectParsePrivateGroup();
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithInvalidCreatorSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
expectJoinMessage(member, invite, false, true);
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMemberJoinWithInvalidMemberSignature()
throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
expectJoinMessage(member, invite, true, false);
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsMemberJoin() throws Exception {
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
expectJoinMessage(member, invite, true, true);
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
signature);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, JOIN, member,
Collections.<MessageId>emptyList());
assertFalse(messageContext.getDictionary()
.getBoolean(KEY_INITIAL_JOIN_MSG));
}
private void expectCreateAuthor(final Author member) {
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(member.getName(),
member.getPublicKey());
will(returnValue(member));
}});
}
private void expectParsePrivateGroup() throws Exception {
context.checking(new Expectations() {{
oneOf(privateGroupFactory).parsePrivateGroup(group);
will(returnValue(privateGroup));
}});
}
private void expectJoinMessage(final Author member, final BdfList invite,
final boolean creatorSigValid, final boolean memberSigValid)
throws Exception {
final BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
JOIN.getInt(), member.getName(), member.getPublicKey(), invite);
expectCreateAuthor(member);
expectParsePrivateGroup();
context.checking(new Expectations() {{
if (invite != null) {
oneOf(groupInvitationFactory).createInviteToken(creator.getId(),
member.getId(), privateGroup.getId(), inviteTimestamp);
will(returnValue(token));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE,
creatorSignature, creatorKey, token);
if (!memberSigValid)
will(throwException(new GeneralSecurityException()));
}
if (memberSigValid) {
oneOf(clientHelper).verifySignature(SIGNING_LABEL_JOIN,
signature, member.getPublicKey(), signed);
if (!creatorSigValid)
will(throwException(new GeneralSecurityException()));
}
}});
}
// POST Message
@Test(expected = FormatException.class)
public void testRejectsTooShortPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, signature, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(), "", memberKey, parentId,
previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(),
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), memberKey,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(), null, memberKey,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonStringMemberName() throws Exception {
BdfList body = BdfList.of(POST.getInt(), getRandomBytes(5), memberKey,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, new byte[0],
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), parentId,
previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, null,
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawMemberKey() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, "not raw",
parentId, previousMsgId, postContent, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortParentId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
getRandomBytes(MessageId.LENGTH - 1), previousMsgId,
postContent, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongParentId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
getRandomBytes(MessageId.LENGTH + 1), previousMsgId,
postContent, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawParentId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
"not raw", previousMsgId, postContent, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, getRandomBytes(MessageId.LENGTH - 1), postContent,
signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, getRandomBytes(MessageId.LENGTH + 1), postContent,
signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, null, postContent, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawPreviousMsgId() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, "not raw", postContent, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, "", signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId,
getRandomString(MAX_GROUP_POST_BODY_LENGTH + 1), signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, null, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonStringContent() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, getRandomBytes(5), signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooShortSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, new byte[0]);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithTooLongSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNullSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent,null);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsPostWithNonRawSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, "not raw");
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
@Test(expected = InvalidMessageException.class)
public void testRejectsPostWithInvalidSignature() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, signature);
expectPostMessage(member, parentId, false);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
parentId, previousMsgId, postContent, signature);
expectPostMessage(member, parentId, true);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, POST, member,
Arrays.asList(parentId, previousMsgId));
assertArrayEquals(previousMsgId.getBytes(),
messageContext.getDictionary().getRaw(KEY_PREVIOUS_MSG_ID));
assertArrayEquals(parentId.getBytes(),
messageContext.getDictionary().getRaw(KEY_PARENT_MSG_ID));
}
@Test
public void testAcceptsTopLevelPost() throws Exception {
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey, null,
previousMsgId, postContent, signature);
expectPostMessage(member, null, true);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertExpectedMessageContext(messageContext, POST, member,
Collections.singletonList(previousMsgId));
assertArrayEquals(previousMsgId.getBytes(),
messageContext.getDictionary().getRaw(KEY_PREVIOUS_MSG_ID));
assertFalse(
messageContext.getDictionary().containsKey(KEY_PARENT_MSG_ID));
}
private void expectPostMessage(final Author member,
final MessageId parentId, final boolean sigValid) throws Exception {
final BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
POST.getInt(), member.getName(), member.getPublicKey(),
parentId == null ? null : parentId.getBytes(),
previousMsgId.getBytes(), postContent);
expectCreateAuthor(member);
context.checking(new Expectations() {{
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
member.getPublicKey(), signed);
if (!sigValid) will(throwException(new GeneralSecurityException()));
}});
}
private void assertExpectedMessageContext(BdfMessageContext c,
MessageType type, Author member,
Collection<MessageId> dependencies) throws FormatException {
BdfDictionary d = c.getDictionary();
assertEquals(type.getInt(), d.getLong(KEY_TYPE).intValue());
assertEquals(message.getTimestamp(),
d.getLong(KEY_TIMESTAMP).longValue());
assertFalse(d.getBoolean(KEY_READ));
assertEquals(member.getId().getBytes(), d.getRaw(KEY_MEMBER_ID));
assertEquals(member.getName(), d.getString(KEY_MEMBER_NAME));
assertEquals(member.getPublicKey(), d.getRaw(KEY_MEMBER_PUBLIC_KEY));
assertEquals(dependencies, c.getDependencies());
}
@Test(expected = InvalidMessageException.class)
public void testRejectsMessageWithUnknownType() throws Exception {
BdfList body = BdfList.of(POST.getInt() + 1, memberName, memberKey,
parentId, previousMsgId, postContent, signature);
expectCreateAuthor(member);
validator.validateMessage(message, group, body);
}
}

View File

@@ -0,0 +1,582 @@
package org.briarproject.privategroup.invitation;
import org.briarproject.ValidatorTestCase;
import org.briarproject.api.FormatException;
import org.briarproject.api.UniqueId;
import org.briarproject.api.clients.BdfMessageContext;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jmock.Expectations;
import org.junit.Test;
import java.security.GeneralSecurityException;
import static org.briarproject.TestUtils.getRandomBytes;
import static org.briarproject.TestUtils.getRandomId;
import static org.briarproject.TestUtils.getRandomString;
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
import static org.briarproject.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
import static org.briarproject.privategroup.invitation.MessageType.ABORT;
import static org.briarproject.privategroup.invitation.MessageType.INVITE;
import static org.briarproject.privategroup.invitation.MessageType.JOIN;
import static org.briarproject.privategroup.invitation.MessageType.LEAVE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class GroupInvitationValidatorTest extends ValidatorTestCase {
private final PrivateGroupFactory privateGroupFactory =
context.mock(PrivateGroupFactory.class);
private final MessageEncoder messageEncoder =
context.mock(MessageEncoder.class);
private final String groupName = getRandomString(MAX_GROUP_NAME_LENGTH);
private final String creatorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final byte[] creatorKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final Author creator =
new Author(new AuthorId(getRandomId()), creatorName, creatorKey);
private final byte[] salt = getRandomBytes(GROUP_SALT_LENGTH);
private final PrivateGroup privateGroup =
new PrivateGroup(group, groupName, creator, salt);
private final String inviteText =
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final BdfDictionary meta =
BdfDictionary.of(new BdfEntry("meta", "data"));
private final MessageId previousMessageId = new MessageId(getRandomId());
private final GroupInvitationValidator validator =
new GroupInvitationValidator(clientHelper, metadataEncoder,
clock, authorFactory, privateGroupFactory, messageEncoder);
// INVITE Message
@Test(expected = FormatException.class)
public void testRejectsTooShortInviteMessage() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongInviteMessage() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, signature, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), "", creatorName,
creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(),
getRandomString(MAX_GROUP_NAME_LENGTH + 1), creatorName,
creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), null, creatorName,
creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonStringGroupName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), getRandomBytes(5),
creatorName, creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, "", creatorKey,
salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName,
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), creatorKey, salt,
inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, null,
creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonStringCreatorName()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName,
getRandomBytes(5), creatorKey, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
new byte[0], salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), salt, inviteText,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
null, salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonRawCreatorKey()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
"not raw", salt, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, getRandomBytes(GROUP_SALT_LENGTH - 1), inviteText,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, getRandomBytes(GROUP_SALT_LENGTH + 1), inviteText,
signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, null, inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonRawGroupSalt()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, "not raw", inviteText, signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortContent() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, "", signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongContent() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt,
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH + 1),
signature);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsInviteMessageWithNullContent() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, null, signature);
expectInviteMessage(false);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonStringContent()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, getRandomBytes(5), signature);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooShortSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, new byte[0]);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithTooLongSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText,
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNullSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, null);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithNonRawSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, "not raw");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsInviteMessageWithInvalidSignature()
throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, null, signature);
expectInviteMessage(true);
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsValidInviteMessage() throws Exception {
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
creatorKey, salt, inviteText, signature);
expectInviteMessage(false);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertTrue(messageContext.getDependencies().isEmpty());
assertEquals(meta, messageContext.getDictionary());
}
private void expectInviteMessage(final boolean exception) throws Exception {
final BdfList signed = BdfList.of(message.getTimestamp(),
message.getGroupId(), privateGroup.getId());
context.checking(new Expectations() {{
oneOf(authorFactory).createAuthor(creatorName, creatorKey);
will(returnValue(creator));
oneOf(privateGroupFactory).createPrivateGroup(groupName, creator,
salt);
will(returnValue(privateGroup));
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE, signature,
creatorKey, signed);
if (exception) {
will(throwException(new GeneralSecurityException()));
} else {
oneOf(messageEncoder).encodeMetadata(INVITE,
message.getGroupId(), message.getTimestamp(), false,
false, false, false);
will(returnValue(meta));
}
}});
}
// JOIN Message
@Test(expected = FormatException.class)
public void testRejectsTooShortJoinMessage() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId());
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongJoinMessage() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId(),
previousMessageId, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithTooShortGroupId() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(),
getRandomBytes(GroupId.LENGTH - 1), previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithTooLongGroupId() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(),
getRandomBytes(GroupId.LENGTH + 1), previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNullGroupId() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), null, previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNonRawGroupId() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), "not raw",
previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithTooShortPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId(),
getRandomBytes(UniqueId.LENGTH - 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithTooLongPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId(),
getRandomBytes(UniqueId.LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsJoinMessageWithNonRawPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId(),
"not raw");
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsJoinMessageWithNullPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId(), null);
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(JOIN, message.getGroupId(),
message.getTimestamp(), false, false, false, false);
will(returnValue(meta));
}});
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertEquals(0, messageContext.getDependencies().size());
assertEquals(meta, messageContext.getDictionary());
}
@Test
public void testAcceptsValidJoinMessage() throws Exception {
BdfList body = BdfList.of(JOIN.getValue(), privateGroup.getId(),
previousMessageId);
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(JOIN, message.getGroupId(),
message.getTimestamp(), false, false, false, false);
will(returnValue(meta));
}});
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertEquals(1, messageContext.getDependencies().size());
assertEquals(previousMessageId,
messageContext.getDependencies().iterator().next());
assertEquals(meta, messageContext.getDictionary());
}
// LEAVE message
@Test(expected = FormatException.class)
public void testRejectsTooShortLeaveMessage() throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId());
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongLeaveMessage() throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId(),
previousMessageId, "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithTooShortGroupId() throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(),
getRandomBytes(GroupId.LENGTH - 1), previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithTooLongGroupId() throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(),
getRandomBytes(GroupId.LENGTH + 1), previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithNullGroupId() throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), null, previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithNonRawGroupId() throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), "not raw",
previousMessageId);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithTooShortPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId(),
getRandomBytes(UniqueId.LENGTH - 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithTooLongPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId(),
getRandomBytes(UniqueId.LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsLeaveMessageWithNonRawPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId(),
"not raw");
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsLeaveMessageWithNullPreviousMessageId()
throws Exception {
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId(), null);
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(LEAVE, message.getGroupId(),
message.getTimestamp(), false, false, false, false);
will(returnValue(meta));
}});
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertEquals(0, messageContext.getDependencies().size());
assertEquals(meta, messageContext.getDictionary());
}
@Test
public void testAcceptsValidLeaveMessage() throws Exception {
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(LEAVE, message.getGroupId(),
message.getTimestamp(), false, false, false, false);
will(returnValue(meta));
}});
BdfList body = BdfList.of(LEAVE.getValue(), privateGroup.getId(),
previousMessageId);
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertEquals(1, messageContext.getDependencies().size());
assertEquals(previousMessageId,
messageContext.getDependencies().iterator().next());
assertEquals(meta, messageContext.getDictionary());
}
// ABORT message
@Test(expected = FormatException.class)
public void testRejectsTooShortAbortMessage() throws Exception {
BdfList body = BdfList.of(ABORT.getValue());
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooLongAbortMessage() throws Exception {
BdfList body = BdfList.of(ABORT.getValue(), privateGroup.getId(), "");
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsAbortMessageWithTooShortGroupId() throws Exception {
BdfList body = BdfList.of(ABORT.getValue(),
getRandomBytes(GroupId.LENGTH - 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsAbortMessageWithTooLongGroupId() throws Exception {
BdfList body = BdfList.of(ABORT.getValue(),
getRandomBytes(GroupId.LENGTH + 1));
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsAbortMessageWithNullGroupId() throws Exception {
BdfList body = BdfList.of(ABORT.getValue(), null);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsAbortMessageWithNonRawGroupId() throws Exception {
BdfList body = BdfList.of(ABORT.getValue(), "not raw");
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsValidAbortMessage() throws Exception {
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(ABORT, message.getGroupId(),
message.getTimestamp(), false, false, false, false);
will(returnValue(meta));
}});
BdfList body = BdfList.of(ABORT.getValue(), privateGroup.getId());
BdfMessageContext messageContext =
validator.validateMessage(message, group, body);
assertEquals(0, messageContext.getDependencies().size());
assertEquals(meta, messageContext.getDictionary());
}
@Test(expected = FormatException.class)
public void testRejectsMessageWithUnknownType() throws Exception {
BdfList body = BdfList.of(ABORT.getValue() + 1);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsEmptyMessage() throws Exception {
BdfList body = new BdfList();
validator.validateMessage(message, group, body);
}
}