http://git-wip-us.apache.org/repos/asf/james-project/blob/8c089562/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMoveTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMoveTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMoveTest.java deleted file mode 100644 index 2089cdd..0000000 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMoveTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.mailbox.store.mail.model; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Date; - -import javax.mail.Flags; -import javax.mail.util.SharedByteArrayInputStream; - -import org.apache.james.mailbox.exception.MailboxException; -import org.apache.james.mailbox.model.MailboxPath; -import org.apache.james.mailbox.model.MessageMetaData; -import org.apache.james.mailbox.model.MessageRange; -import org.apache.james.mailbox.store.mail.MessageMapper; -import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; -import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; -import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; -import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public abstract class AbstractMessageMoveTest { - - private final static char DELIMITER = ':'; - private static final int LIMIT = 10; - private static final int BODY_START = 16; - public static final int UID_VALIDITY = 42; - - private MapperProvider mapperProvider; - private MessageMapper messageMapper; - - private SimpleMailbox benwaInboxMailbox; - private SimpleMailbox benwaWorkMailbox; - - private SimpleMailboxMessage message1; - - public AbstractMessageMoveTest(MapperProvider mapperProvider) { - this.mapperProvider = mapperProvider; - } - - @Before - public void setUp() throws MailboxException { - mapperProvider.ensureMapperPrepared(); - messageMapper = mapperProvider.createMessageMapper(); - benwaInboxMailbox = createMailbox(new MailboxPath("#private", "benwa", "INBOX")); - benwaWorkMailbox = createMailbox( new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work")); - message1 = createMessage(benwaInboxMailbox, "Subject: Test1 \n\nBody1\n.\n", BODY_START, new PropertyBuilder()); - } - - @After - public void tearDown() throws MailboxException { - mapperProvider.clearMapper(); - } - - @Test - public void movingAMessageShouldWork() throws Exception { - messageMapper.add(benwaInboxMailbox, message1); - message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); - - messageMapper.move(benwaWorkMailbox, message1); - - assertThat(retrieveMessageFromStorage(benwaWorkMailbox, message1)).isEqualTo(message1); - } - - @Test - public void movingAMessageShouldReturnCorrectMetadata() throws Exception { - messageMapper.add(benwaInboxMailbox, message1); - message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); - - MessageMetaData messageMetaData = messageMapper.move(benwaWorkMailbox, message1); - - Flags expectedFlags = message1.createFlags(); - expectedFlags.add(Flags.Flag.RECENT); - assertThat(messageMetaData.getFlags()).isEqualTo(expectedFlags); - assertThat(messageMetaData.getUid()).isEqualTo(messageMapper.getLastUid(benwaWorkMailbox)); - assertThat(messageMetaData.getModSeq()).isEqualTo(messageMapper.getHighestModSeq(benwaWorkMailbox)); - } - - @Test - public void movingAMessageShouldNotViolateMessageCount() throws Exception { - messageMapper.add(benwaInboxMailbox, message1); - message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); - - messageMapper.move(benwaWorkMailbox, message1); - - assertThat(messageMapper.countMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); - assertThat(messageMapper.countMessagesInMailbox(benwaWorkMailbox)).isEqualTo(1); - } - - @Test - public void movingAMessageShouldNotViolateUnseenMessageCount() throws Exception { - messageMapper.add(benwaInboxMailbox, message1); - message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); - - messageMapper.move(benwaWorkMailbox, message1); - - assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); - assertThat(messageMapper.countUnseenMessagesInMailbox(benwaWorkMailbox)).isEqualTo(1); - } - - @Test - public void movingASeenMessageShouldNotIncrementUnseenMessageCount() throws Exception { - message1.setFlags(new Flags(Flags.Flag.SEEN)); - messageMapper.add(benwaInboxMailbox, message1); - message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); - - messageMapper.move(benwaWorkMailbox, message1); - - assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); - assertThat(messageMapper.countUnseenMessagesInMailbox(benwaWorkMailbox)).isEqualTo(0); - } - - private SimpleMailbox createMailbox(MailboxPath mailboxPath) { - SimpleMailbox mailbox = new SimpleMailbox(mailboxPath, UID_VALIDITY); - MailboxId id = mapperProvider.generateId(); - mailbox.setMailboxId(id); - return mailbox; - } - - private MailboxMessage retrieveMessageFromStorage(Mailbox mailbox, MailboxMessage message) throws MailboxException { - return messageMapper.findInMailbox(mailbox, MessageRange.one(message.getUid()), FetchType.Metadata, LIMIT).next(); - } - - private SimpleMailboxMessage createMessage(Mailbox mailbox, String content, int bodyStart, PropertyBuilder propertyBuilder) { - return new SimpleMailboxMessage(new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, mailbox.getMailboxId()); - } -}
http://git-wip-us.apache.org/repos/asf/james-project/blob/8c089562/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java new file mode 100644 index 0000000..0fbfe1a --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java @@ -0,0 +1,95 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.james.mailbox.exception.AttachmentNotFoundException; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.store.mail.AttachmentMapper; +import org.junit.After; +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import org.xenei.junit.contract.Contract; +import org.xenei.junit.contract.ContractTest; +import org.xenei.junit.contract.IProducer; + +import com.google.common.collect.ImmutableList; + +@Contract(MapperProvider.class) +public class AttachmentMapperTest<T extends MapperProvider> { + + private IProducer<T> producer; + private AttachmentMapper attachmentMapper; + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Contract.Inject + public final void setProducer(IProducer<T> producer) throws MailboxException { + this.producer = producer; + this.attachmentMapper = producer.newInstance().createAttachmentMapper(); + } + + @After + public void tearDown() { + producer.cleanUp(); + } + + @ContractTest + public void getAttachmentShouldThrowWhenNullAttachmentId() throws Exception { + expected.expect(IllegalArgumentException.class); + attachmentMapper.getAttachment(null); + } + + @ContractTest + public void getAttachmentShouldThrowWhenNonReferencedAttachmentId() throws Exception { + expected.expect(AttachmentNotFoundException.class); + attachmentMapper.getAttachment(AttachmentId.forPayload("unknown".getBytes())); + } + + @ContractTest + public void getAttachmentShouldReturnTheAttachmentWhenReferenced() throws Exception { + //Given + Attachment expected = Attachment.from("payload".getBytes(), "content"); + AttachmentId attachmentId = expected.getAttachmentId(); + attachmentMapper.storeAttachment(expected); + //When + Attachment attachment = attachmentMapper.getAttachment(attachmentId); + //Then + assertThat(attachment).isEqualTo(expected); + } + + @ContractTest + public void getAttachmentShouldReturnTheAttachmentsWhenMultipleStored() throws Exception { + //Given + Attachment expected1 = Attachment.from("payload1".getBytes(), "content1"); + Attachment expected2 = Attachment.from("payload2".getBytes(), "content2"); + AttachmentId attachmentId1 = expected1.getAttachmentId(); + AttachmentId attachmentId2 = expected2.getAttachmentId(); + //When + attachmentMapper.storeAttachments(ImmutableList.of(expected1, expected2)); + //Then + Attachment attachment1 = attachmentMapper.getAttachment(attachmentId1); + Attachment attachment2 = attachmentMapper.getAttachment(attachmentId2); + assertThat(attachment1).isEqualTo(expected1); + assertThat(attachment2).isEqualTo(expected2); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/8c089562/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java new file mode 100644 index 0000000..a7964b9 --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java @@ -0,0 +1,278 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import java.util.List; + +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.exception.MailboxNotFoundException; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.store.mail.AttachmentMapper; +import org.apache.james.mailbox.store.mail.MailboxMapper; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.xenei.junit.contract.Contract; +import org.xenei.junit.contract.ContractTest; +import org.xenei.junit.contract.IProducer; + +/** + * Generic purpose tests for your implementation MailboxMapper. + * + * You then just need to instantiate your mailbox mapper and an IdGenerator. + */ +@Contract(MapperProvider.class) +public class MailboxMapperTest<T extends MapperProvider> { + + private final static char DELIMITER = ':'; + private final static char WILDCARD = '%'; + private final static long UID_VALIDITY = 42; + + private IProducer<T> producer; + private MailboxMapper mailboxMapper; + + private MailboxPath benwaInboxPath; + private SimpleMailbox benwaInboxMailbox; + private MailboxPath benwaWorkPath; + private SimpleMailbox benwaWorkMailbox; + private MailboxPath benwaWorkTodoPath; + private SimpleMailbox benwaWorkTodoMailbox; + private MailboxPath benwaPersoPath; + private SimpleMailbox benwaPersoMailbox; + private MailboxPath benwaWorkDonePath; + private SimpleMailbox benwaWorkDoneMailbox; + private MailboxPath bobInboxPath; + private SimpleMailbox bobyMailbox; + private MailboxPath bobyMailboxPath; + private SimpleMailbox bobInboxMailbox; + private MailboxPath esnDevGroupInboxPath; + private SimpleMailbox esnDevGroupInboxMailbox; + private MailboxPath esnDevGroupHublinPath; + private SimpleMailbox esnDevGroupHublinMailbox; + private MailboxPath esnDevGroupJamesPath; + private SimpleMailbox esnDevGroupJamesMailbox; + private MailboxPath obmTeamGroupInboxPath; + private SimpleMailbox obmTeamGroupInboxMailbox; + private MailboxPath obmTeamGroupOPushPath; + private SimpleMailbox obmTeamGroupOPushMailbox; + private MailboxPath obmTeamGroupRoundCubePath; + private SimpleMailbox obmTeamGroupRoundCubeMailbox; + private MailboxPath bobDifferentNamespacePath; + private SimpleMailbox bobDifferentNamespaceMailbox; + + @Rule + public ExpectedException expected = ExpectedException.none(); + private T mapperProvider; + + @Contract.Inject + public final void setProducer(IProducer<T> producer) throws MailboxException { + this.producer = producer; + this.mapperProvider = producer.newInstance(); + this.mapperProvider.ensureMapperPrepared(); + this.mailboxMapper = mapperProvider.createMailboxMapper(); + + benwaInboxPath = new MailboxPath("#private", "benwa", "INBOX"); + benwaWorkPath = new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work"); + benwaWorkTodoPath = new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work"+DELIMITER+"todo"); + benwaPersoPath = new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"perso"); + benwaWorkDonePath = new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work"+DELIMITER+"done"); + bobInboxPath = new MailboxPath("#private", "bob", "INBOX"); + bobyMailboxPath = new MailboxPath("#private", "boby", "INBOX.that.is.a.trick"); + bobDifferentNamespacePath = new MailboxPath("#private_bob", "bob", "INBOX.bob"); + esnDevGroupInboxPath = new MailboxPath("#community_ESN_DEV", null, "INBOX"); + esnDevGroupHublinPath = new MailboxPath("#community_ESN_DEV", null, "INBOX"+DELIMITER+"hublin"); + esnDevGroupJamesPath = new MailboxPath("#community_ESN_DEV", null, "INBOX"+DELIMITER+"james"); + obmTeamGroupInboxPath = new MailboxPath("#community_OBM_Core_Team", null, "INBOX"); + obmTeamGroupOPushPath = new MailboxPath("#community_OBM_Core_Team", null, "INBOX"+DELIMITER+"OPush"); + obmTeamGroupRoundCubePath = new MailboxPath("#community_OBM_Core_Team", null, "INBOX"+DELIMITER+"roundCube"); + + benwaInboxMailbox = createMailbox(benwaInboxPath); + benwaWorkMailbox = createMailbox(benwaWorkPath); + benwaWorkTodoMailbox = createMailbox(benwaWorkTodoPath); + benwaPersoMailbox = createMailbox(benwaPersoPath); + benwaWorkDoneMailbox = createMailbox(benwaWorkDonePath); + bobInboxMailbox = createMailbox(bobInboxPath); + esnDevGroupInboxMailbox = createMailbox(esnDevGroupInboxPath); + esnDevGroupHublinMailbox = createMailbox(esnDevGroupHublinPath); + esnDevGroupJamesMailbox = createMailbox(esnDevGroupJamesPath); + obmTeamGroupInboxMailbox = createMailbox(obmTeamGroupInboxPath); + obmTeamGroupOPushMailbox = createMailbox(obmTeamGroupOPushPath); + obmTeamGroupRoundCubeMailbox = createMailbox(obmTeamGroupRoundCubePath); + bobyMailbox = createMailbox(bobyMailboxPath); + bobDifferentNamespaceMailbox = createMailbox(bobDifferentNamespacePath); + } + + @After + public void tearDown() throws MailboxException { + producer.cleanUp(); + } + + @ContractTest + public void findMailboxByPathWhenAbsentShouldFail() throws MailboxException { + expected.expect(MailboxNotFoundException.class); + mailboxMapper.findMailboxByPath(new MailboxPath("#private", "benwa", "INBOX")); + } + + @ContractTest + public void saveShouldPersistTheMailbox() throws MailboxException{ + mailboxMapper.save(benwaInboxMailbox); + MailboxAssert.assertThat(mailboxMapper.findMailboxByPath(benwaInboxPath)).isEqualTo(benwaInboxMailbox); + } + + @ContractTest + public void saveWithNullUserShouldPersistTheMailbox() throws MailboxException{ + mailboxMapper.save(esnDevGroupInboxMailbox); + MailboxAssert.assertThat(mailboxMapper.findMailboxByPath(esnDevGroupInboxPath)).isEqualTo(esnDevGroupInboxMailbox); + } + + @ContractTest + public void listShouldRetrieveAllMailbox() throws MailboxException { + saveAll(); + List<Mailbox> mailboxes = mailboxMapper.list(); + assertThat(mailboxes).contains(benwaInboxMailbox, benwaWorkMailbox, benwaWorkTodoMailbox, benwaPersoMailbox, benwaWorkDoneMailbox, bobInboxMailbox, esnDevGroupInboxMailbox, esnDevGroupHublinMailbox, + esnDevGroupJamesMailbox, obmTeamGroupInboxMailbox, obmTeamGroupOPushMailbox, obmTeamGroupRoundCubeMailbox); + } + + @ContractTest + public void hasChildrenShouldReturnFalseWhenNoChildrenExists() throws MailboxException { + saveAll(); + assertThat(mailboxMapper.hasChildren(benwaWorkTodoMailbox, DELIMITER)).isFalse(); + } + + @ContractTest + public void hasChildrenShouldReturnTrueWhenChildrenExists() throws MailboxException { + saveAll(); + assertThat(mailboxMapper.hasChildren(benwaInboxMailbox, DELIMITER)).isTrue(); + } + + @ContractTest + public void hasChildrenWithNullUserShouldReturnFalseWhenNoChildrenExists() throws MailboxException { + saveAll(); + assertThat(mailboxMapper.hasChildren(esnDevGroupHublinMailbox, DELIMITER)).isFalse(); + } + + @ContractTest + public void hasChildrenWithNullUserShouldReturnTrueWhenChildrenExists() throws MailboxException { + saveAll(); + assertThat(mailboxMapper.hasChildren(esnDevGroupInboxMailbox, DELIMITER)).isTrue(); + } + + @ContractTest + public void hasChildrenShouldNotBeAcrossUsersAndNamespace() throws MailboxException { + saveAll(); + assertThat(mailboxMapper.hasChildren(bobInboxMailbox, '.')).isFalse(); + } + + @ContractTest + public void findMailboxWithPathLikeShouldBeLimitedToUserAndNamespace() throws MailboxException { + saveAll(); + MailboxPath mailboxPathQuery = new MailboxPath(bobInboxMailbox.getNamespace(), bobInboxMailbox.getUser(), "IN" + WILDCARD); + assertThat(mailboxMapper.findMailboxWithPathLike(mailboxPathQuery)).containsOnly(bobInboxMailbox); + } + + @ContractTest + public void deleteShouldEraseTheGivenMailbox() throws MailboxException { + expected.expect(MailboxNotFoundException.class); + try { + saveAll(); + mailboxMapper.delete(benwaInboxMailbox); + } catch(MailboxException exception) { + fail("Error was not thrown by the appropriate method", exception); + } + mailboxMapper.findMailboxByPath(benwaInboxPath); + } + + @ContractTest + public void deleteWithNullUserShouldEraseTheGivenMailbox() throws MailboxException { + expected.expect(MailboxNotFoundException.class); + try { + saveAll(); + mailboxMapper.delete(esnDevGroupJamesMailbox); + } catch(MailboxException exception) { + fail("Error was not thrown by the appropriate method", exception); + } + mailboxMapper.findMailboxByPath(esnDevGroupJamesPath); + } + + @ContractTest + public void findMailboxWithPathLikeWithChildRegexShouldRetrieveChildren() throws MailboxException { + saveAll(); + MailboxPath regexPath = new MailboxPath(benwaWorkPath.getNamespace(), benwaWorkPath.getUser(), benwaWorkPath.getName() + WILDCARD); + assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).containsOnly(benwaWorkMailbox, benwaWorkTodoMailbox, benwaWorkDoneMailbox); + } + + @ContractTest + public void findMailboxWithPathLikeWithNullUserWithChildRegexShouldRetrieveChildren() throws MailboxException { + saveAll(); + MailboxPath regexPath = new MailboxPath(obmTeamGroupInboxPath.getNamespace(), obmTeamGroupInboxPath.getUser(), obmTeamGroupInboxPath.getName() + WILDCARD); + assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).contains(obmTeamGroupInboxMailbox, obmTeamGroupOPushMailbox, obmTeamGroupRoundCubeMailbox); + } + + @ContractTest + public void findMailboxWithPathLikeWithRegexShouldRetrieveCorrespondingMailbox() throws MailboxException { + saveAll(); + MailboxPath regexPath = new MailboxPath(benwaInboxPath.getNamespace(), benwaInboxPath.getUser(), WILDCARD + "X"); + assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).containsOnly(benwaInboxMailbox); + } + + @ContractTest + public void findMailboxWithPathLikeWithNullUserWithRegexShouldRetrieveCorrespondingMailbox() throws MailboxException { + saveAll(); + MailboxPath regexPath = new MailboxPath(esnDevGroupInboxPath.getNamespace(), esnDevGroupInboxPath.getUser(), WILDCARD + "X"); + assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).contains(esnDevGroupInboxMailbox); + } + + @ContractTest + public void findMailboxWithPathLikeShouldEscapeMailboxName() throws MailboxException { + saveAll(); + MailboxPath regexPath = new MailboxPath(benwaInboxPath.getNamespace(), benwaInboxPath.getUser(), "INB?X"); + assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).isEmpty(); + } + + private void saveAll() throws MailboxException{ + mailboxMapper.save(benwaInboxMailbox); + mailboxMapper.save(benwaWorkMailbox); + mailboxMapper.save(benwaWorkTodoMailbox); + mailboxMapper.save(benwaPersoMailbox); + mailboxMapper.save(benwaWorkDoneMailbox); + mailboxMapper.save(esnDevGroupInboxMailbox); + mailboxMapper.save(esnDevGroupHublinMailbox); + mailboxMapper.save(esnDevGroupJamesMailbox); + mailboxMapper.save(obmTeamGroupInboxMailbox); + mailboxMapper.save(obmTeamGroupOPushMailbox); + mailboxMapper.save(obmTeamGroupRoundCubeMailbox); + mailboxMapper.save(bobyMailbox); + mailboxMapper.save(bobDifferentNamespaceMailbox); + mailboxMapper.save(bobInboxMailbox); + } + + private SimpleMailbox createMailbox(MailboxPath mailboxPath) { + SimpleMailbox mailbox = new SimpleMailbox(mailboxPath, UID_VALIDITY); + mailbox.setMailboxId(mapperProvider.generateId()); + return mailbox; + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/8c089562/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java index 4a8314a..bf47904 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java @@ -36,4 +36,6 @@ public interface MapperProvider { void clearMapper() throws MailboxException; void ensureMapperPrepared() throws MailboxException; + + boolean supportPartialAttachmentFetch(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/8c089562/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java new file mode 100644 index 0000000..4354830 --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java @@ -0,0 +1,755 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.mail.Flags; +import javax.mail.util.SharedByteArrayInputStream; + +import org.apache.james.mailbox.FlagsBuilder; +import org.apache.james.mailbox.MessageManager.FlagsUpdateMode; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.MessageMetaData; +import org.apache.james.mailbox.model.MessageRange; +import org.apache.james.mailbox.model.UpdatedFlags; +import org.apache.james.mailbox.store.FlagsUpdateCalculator; +import org.apache.james.mailbox.store.mail.AttachmentMapper; +import org.apache.james.mailbox.store.mail.MessageMapper; +import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; +import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage; +import org.junit.After; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.xenei.junit.contract.Contract; +import org.xenei.junit.contract.ContractTest; +import org.xenei.junit.contract.IProducer; + +import com.google.common.collect.ImmutableList; + +@Contract(MapperProvider.class) +public class MessageMapperTest<T extends MapperProvider> { + + private final static char DELIMITER = ':'; + private static final int LIMIT = 10; + private static final int BODY_START = 16; + public static final int UID_VALIDITY = 42; + public static final String USER_FLAG = "userFlag"; + + private IProducer<T> producer; + private MapperProvider mapperProvider; + private MessageMapper messageMapper; + + private SimpleMailbox benwaInboxMailbox; + private SimpleMailbox benwaWorkMailbox; + private SimpleMailbox attachmentsMailbox; + + private SimpleMailboxMessage message1; + private SimpleMailboxMessage message2; + private SimpleMailboxMessage message3; + private SimpleMailboxMessage message4; + private SimpleMailboxMessage message5; + private SimpleMailboxMessage message6; + private SimpleMailboxMessage message7With1Attachment; + private SimpleMailboxMessage message8With2Attachments; + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Contract.Inject + public final void setProducer(IProducer<T> producer) throws MailboxException { + this.producer = producer; + this.mapperProvider = producer.newInstance(); + this.mapperProvider.ensureMapperPrepared(); + this. messageMapper = mapperProvider.createMessageMapper(); + + benwaInboxMailbox = createMailbox(new MailboxPath("#private", "benwa", "INBOX")); + benwaWorkMailbox = createMailbox( new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work")); + attachmentsMailbox = createMailbox( new MailboxPath("#private", "benwa", "Attachments")); + + message1 = createMessage(benwaInboxMailbox, "Subject: Test1 \n\nBody1\n.\n", BODY_START, new PropertyBuilder()); + message2 = createMessage(benwaInboxMailbox, "Subject: Test2 \n\nBody2\n.\n", BODY_START, new PropertyBuilder()); + message3 = createMessage(benwaInboxMailbox, "Subject: Test3 \n\nBody3\n.\n", BODY_START, new PropertyBuilder()); + message4 = createMessage(benwaInboxMailbox, "Subject: Test4 \n\nBody4\n.\n", BODY_START, new PropertyBuilder()); + message5 = createMessage(benwaInboxMailbox, "Subject: Test5 \n\nBody5\n.\n", BODY_START, new PropertyBuilder()); + message6 = createMessage(benwaWorkMailbox, "Subject: Test6 \n\nBody6\n.\n", BODY_START, new PropertyBuilder()); + message7With1Attachment = createMessage(attachmentsMailbox, "Subject: Test7 \n\nBody7\n.\n", BODY_START, new PropertyBuilder(), ImmutableList.of(AttachmentId.from("123"))); + message8With2Attachments = createMessage(attachmentsMailbox, "Subject: Test8 \n\nBody8\n.\n", BODY_START, new PropertyBuilder(), ImmutableList.of(AttachmentId.from("123"), AttachmentId.from("456"))); + + } + + @After + public void tearDown() throws MailboxException { + producer.cleanUp(); + } + + @ContractTest + public void emptyMailboxShouldHaveZeroMessageCount() throws MailboxException { + assertThat(messageMapper.countMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); + } + + @ContractTest + public void mailboxContainingMessagesShouldHaveTheGoodMessageCount() throws MailboxException { + saveMessages(); + assertThat(messageMapper.countMessagesInMailbox(benwaInboxMailbox)).isEqualTo(5); + } + + @ContractTest + public void mailboxCountShouldBeDecrementedAfterAMessageDelete() throws MailboxException { + saveMessages(); + messageMapper.delete(benwaInboxMailbox, message1); + assertThat(messageMapper.countMessagesInMailbox(benwaInboxMailbox)).isEqualTo(4); + } + + @ContractTest + public void emptyMailboxShouldNotHaveUnseenMessages() throws MailboxException { + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); + } + + @ContractTest + public void mailboxContainingMessagesShouldHaveTheGoodUnseenMessageCount() throws MailboxException { + saveMessages(); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(5); + } + + @ContractTest + public void mailboxUnSeenCountShouldBeDecrementedAfterAMessageIsMarkedSeen() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())).hasNext(); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(4); + } + + @ContractTest + public void mailboxUnSeenCountShouldBeDecrementedAfterAMessageIsMarkedUnSeen() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(5); + } + + @ContractTest + public void mailboxUnSeenCountShouldBeDecrementedAfterAMessageDelete() throws MailboxException { + saveMessages(); + messageMapper.delete(benwaInboxMailbox, message1); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(4); + } + + @ContractTest + public void deletedMessagesShouldBeRemovedFromStorage() throws MailboxException { + saveMessages(); + messageMapper.delete(benwaInboxMailbox, message1); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), MessageMapper.FetchType.Metadata, LIMIT)).isEmpty(); + } + + @ContractTest + public void deletingUnExistingMessageShouldHaveNoSideEffect() throws MailboxException, IOException { + saveMessages(); + message6.setUid(messageMapper.getLastUid(benwaInboxMailbox) + 1); + messageMapper.delete(benwaInboxMailbox, message6); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message1, message2, message3, message4, message5); + } + + @ContractTest + public void noMessageShouldBeRetrievedInEmptyMailbox() throws MailboxException { + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), MessageMapper.FetchType.Metadata, LIMIT)).isEmpty(); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeOne() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Full; + int limit =10; + MessageAssert.assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), fetchType, limit).next()) + .isEqualTo(message1, fetchType); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeRange() throws MailboxException, IOException{ + saveMessages(); + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper + .findInMailbox(benwaInboxMailbox, MessageRange.range(message1.getUid(), message4.getUid()), MessageMapper.FetchType.Full, LIMIT); + assertThat(retrievedMessageIterator).containsOnly(message1, message2, message3, message4); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeRangeContainingAHole() throws MailboxException, IOException { + saveMessages(); + messageMapper.delete(benwaInboxMailbox, message3); + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper + .findInMailbox(benwaInboxMailbox, MessageRange.range(message1.getUid(), message4.getUid()), MessageMapper.FetchType.Full, LIMIT); + assertThat(retrievedMessageIterator).containsOnly(message1, message2, message4); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeFrom() throws MailboxException, IOException { + saveMessages(); + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper + .findInMailbox(benwaInboxMailbox, MessageRange.from(message3.getUid()), MessageMapper.FetchType.Full, LIMIT); + assertThat(retrievedMessageIterator).containsOnly(message3, message4, message5); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeFromContainingAHole() throws MailboxException, IOException { + saveMessages(); + messageMapper.delete(benwaInboxMailbox, message4); + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper + .findInMailbox(benwaInboxMailbox, MessageRange.from(message3.getUid()), MessageMapper.FetchType.Full, LIMIT); + assertThat(retrievedMessageIterator).containsOnly(message3, message5); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeAll() throws MailboxException, IOException { + saveMessages(); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message1, message2, message3, message4, message5); + } + + @ContractTest + public void messagesCanBeRetrievedInMailboxWithRangeTypeAllContainingHole() throws MailboxException, IOException { + saveMessages(); + messageMapper.delete(benwaInboxMailbox, message1); + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper + .findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT); + assertThat(retrievedMessageIterator).containsOnly(message2, message3, message4, message5); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeMetadataShouldHaveAtLastMetadataDataLoaded() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Metadata; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), fetchType, LIMIT); + MessageAssert.assertThat(retrievedMessageIterator.next()).isEqualTo(message1, fetchType); + assertThat(retrievedMessageIterator).isEmpty(); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeHeaderShouldHaveHeaderDataLoaded() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Headers; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), fetchType, LIMIT); + MessageAssert.assertThat(retrievedMessageIterator.next()).isEqualTo(message1, fetchType); + assertThat(retrievedMessageIterator).isEmpty(); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeBodyShouldHaveBodyDataLoaded() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Body; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), fetchType, LIMIT); + MessageAssert.assertThat(retrievedMessageIterator.next()).isEqualTo(message1, fetchType); + assertThat(retrievedMessageIterator).isEmpty(); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeFullShouldHaveAttachmentsIdsEmptyWhenNoAttachment() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Full; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message1.getUid()), fetchType, LIMIT); + assertThat(retrievedMessageIterator.next().getAttachmentsIds()).isEmpty(); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeFullShouldHaveAttachmentsIdsLoadedWhenOneAttachment() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Full; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(attachmentsMailbox, MessageRange.one(message7With1Attachment.getUid()), fetchType, LIMIT); + assertThat(retrievedMessageIterator.next().getAttachmentsIds()).isEqualTo(message7With1Attachment.getAttachmentsIds()); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeFullShouldHaveAttachmentsIdsLoadedWhenTwoAttachments() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Full; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(attachmentsMailbox, MessageRange.one(message8With2Attachments.getUid()), fetchType, LIMIT); + assertThat(retrievedMessageIterator.next().getAttachmentsIds()).isEqualTo(message8With2Attachments.getAttachmentsIds()); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeBodyShouldHaveAttachmentsIdsLoadedWhenOneAttachment() throws MailboxException, IOException{ + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Body; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(attachmentsMailbox, MessageRange.one(message7With1Attachment.getUid()), fetchType, LIMIT); + assertThat(retrievedMessageIterator.next().getAttachmentsIds()).isEqualTo(message7With1Attachment.getAttachmentsIds()); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeHeadersShouldHaveAttachmentsIdsEmptyWhenOneAttachment() throws MailboxException, IOException{ + Assume.assumeTrue(mapperProvider.supportPartialAttachmentFetch()); + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Headers; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(attachmentsMailbox, MessageRange.one(message7With1Attachment.getUid()), fetchType, LIMIT); + assertThat(retrievedMessageIterator.next().getAttachmentsIds()).isEmpty(); + } + + @ContractTest + public void messagesRetrievedUsingFetchTypeMetadataShouldHaveAttachmentsIdsEmptyWhenOneAttachment() throws MailboxException, IOException{ + Assume.assumeTrue(mapperProvider.supportPartialAttachmentFetch()); + saveMessages(); + MessageMapper.FetchType fetchType = MessageMapper.FetchType.Metadata; + Iterator<MailboxMessage> retrievedMessageIterator = messageMapper.findInMailbox(attachmentsMailbox, MessageRange.one(message7With1Attachment.getUid()), fetchType, LIMIT); + assertThat(retrievedMessageIterator.next().getAttachmentsIds()).isEmpty(); + } + + @ContractTest + public void retrievingMessagesWithALimitShouldLimitTheNumberOfMessages() throws MailboxException { + int limit = 2; + saveMessages(); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, limit)).hasSize(2); + } + + @ContractTest + public void findRecentUidsInMailboxShouldReturnEmptyListWhenNoMessagesMarkedAsRecentArePresentInMailbox() throws MailboxException { + assertThat(messageMapper.findRecentMessageUidsInMailbox(benwaInboxMailbox)).isEmpty(); + } + + @ContractTest + public void findRecentUidsInMailboxShouldReturnListOfMessagesHoldingFlagsRecent() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.RECENT), FlagsUpdateMode.REPLACE), MessageRange.one(message2.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.RECENT), FlagsUpdateMode.REPLACE), MessageRange.one(message4.getUid())); + messageMapper.updateFlags(benwaWorkMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.RECENT), FlagsUpdateMode.REPLACE), MessageRange.one(message6.getUid())); + assertThat(messageMapper.findRecentMessageUidsInMailbox(benwaInboxMailbox)).containsOnly(message2.getUid(), message4.getUid()); + } + + @ContractTest + public void findFirstUnseenMessageUidShouldReturnNullWhenNoUnseenMessagesCanBeFound() throws MailboxException { + assertThat(messageMapper.findFirstUnseenMessageUid(benwaInboxMailbox)).isNull(); + } + + @ContractTest + public void findFirstUnseenMessageUidShouldReturnUid1WhenUid1isNotSeen() throws MailboxException { + saveMessages(); + assertThat(messageMapper.findFirstUnseenMessageUid(benwaInboxMailbox)).isEqualTo(message1.getUid()); + } + + @ContractTest + public void findFirstUnseenMessageUidShouldReturnUid2WhenUid2isSeen() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.one(message3.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.one(message5.getUid())); + assertThat(messageMapper.findFirstUnseenMessageUid(benwaInboxMailbox)).isEqualTo(message2.getUid()); + } + + @ContractTest + public void expungeMarkedForDeletionInMailboxShouldReturnEmptyResultOnEmptyMailbox() throws MailboxException, IOException { + assertThat(messageMapper.expungeMarkedForDeletionInMailbox(benwaInboxMailbox, MessageRange.all())).isEmpty(); + } + + @ContractTest + public void expungeMarkedForDeletionInMailboxShouldReturnEmptyResultWhenNoMessageInMailboxIsDeleted() throws MailboxException, IOException { + saveMessages(); + assertThat(messageMapper.expungeMarkedForDeletionInMailbox(benwaInboxMailbox, MessageRange.all())).isEmpty(); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message1, message2, message3, message4, message5); + } + + @ContractTest + public void expungeShouldReturnCorrectMetadataWithRangeAll() throws MailboxException, IOException { + saveMessages(); + MetadataMapAssert.assertThat(markThenPerformExpunge(MessageRange.all())) + .hasSize(2) + .containsMetadataForMessages(message1, message4); + } + + @ContractTest + public void expungeShouldModifyUnderlyingStorageWithRangeAll() throws MailboxException, IOException { + saveMessages(); + markThenPerformExpunge(MessageRange.all()); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message2, message3, message5); + } + + @ContractTest + public void expungeShouldReturnCorrectMetadataWithRangeOne() throws MailboxException, IOException { + saveMessages(); + MetadataMapAssert.assertThat(markThenPerformExpunge(MessageRange.one(message1.getUid()))) + .hasSize(1) + .containsMetadataForMessages(message1); + } + + @ContractTest + public void expungeShouldModifyUnderlyingStorageWithRangeOne() throws MailboxException, IOException { + saveMessages(); + markThenPerformExpunge(MessageRange.one(message1.getUid())); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message4, message2, message3, message5); + } + + @ContractTest + public void expungeShouldReturnCorrectMetadataWithRangeFrom() throws MailboxException, IOException { + saveMessages(); + MetadataMapAssert.assertThat(markThenPerformExpunge(MessageRange.from(message3.getUid()))) + .hasSize(1) + .containsMetadataForMessages(message4); + } + + @ContractTest + public void expungeShouldModifyUnderlyingStorageWithRangeFrom() throws MailboxException, IOException { + saveMessages(); + markThenPerformExpunge(MessageRange.from(message3.getUid())); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message1, message2, message3, message5); + } + + @ContractTest + public void expungeShouldReturnCorrectMetadataWithRange() throws MailboxException, IOException { + saveMessages(); + MetadataMapAssert.assertThat(markThenPerformExpunge(MessageRange.range(message3.getUid(), message5.getUid()))) + .hasSize(1) + .containsMetadataForMessages(message4); + } + + @ContractTest + public void expungeShouldModifyUnderlyingStorageWithRange() throws MailboxException, IOException { + saveMessages(); + markThenPerformExpunge(MessageRange.range(message3.getUid(), message5.getUid())); + assertThat(messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.all(), MessageMapper.FetchType.Full, LIMIT)) + .containsOnly(message1, message2, message3, message5); + } + + @ContractTest + public void getHighestMoseqShouldBeEqualToZeroOnEmptyMailbox() throws MailboxException { + assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isEqualTo(0); + } + + @ContractTest + public void insertingAMessageShouldIncrementModSeq() throws MailboxException { + messageMapper.add(benwaInboxMailbox, message1); + long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox); + assertThat(modSeq).isGreaterThan(0); + messageMapper.add(benwaInboxMailbox, message2); + assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isGreaterThan(modSeq); + } + + @ContractTest + public void getLastUidShouldReturn0OnEmptyMailbox() throws MailboxException { + assertThat(messageMapper.getLastUid(benwaInboxMailbox)).isEqualTo(0); + } + + @ContractTest + public void insertingAMessageShouldIncrementLastUid() throws MailboxException { + messageMapper.add(benwaInboxMailbox, message1); + long uid = messageMapper.getLastUid(benwaInboxMailbox); + assertThat(uid).isGreaterThan(0); + messageMapper.add(benwaInboxMailbox, message2); + assertThat(messageMapper.getLastUid(benwaInboxMailbox)).isGreaterThan(uid); + } + + @ContractTest + public void copyShouldIncrementUid() throws MailboxException, IOException { + saveMessages(); + long uid = messageMapper.getLastUid(benwaInboxMailbox); + messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat(messageMapper.getLastUid(benwaInboxMailbox)).isGreaterThan(uid); + } + + @ContractTest + public void copyShouldIncrementMessageCount() throws MailboxException, IOException { + saveMessages(); + messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat(messageMapper.countMessagesInMailbox(benwaInboxMailbox)).isEqualTo(6); + } + + @ContractTest + public void copyOfUnSeenMessageShouldIncrementUnSeenMessageCount() throws MailboxException, IOException { + saveMessages(); + messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(6); + } + + @ContractTest + public void copyShouldIncrementModSeq() throws MailboxException, IOException { + saveMessages(); + long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox); + messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isGreaterThan(modSeq); + } + + @ContractTest + public void copyShouldCreateAMessageInDestination() throws MailboxException, IOException { + saveMessages(); + MailboxMessage message7 = SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6); + messageMapper.copy(benwaInboxMailbox, message7); + message7.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + assertThat(messageMapper.getLastUid(benwaInboxMailbox)).isGreaterThan(message6.getUid()); + + MailboxMessage result = messageMapper.findInMailbox(benwaInboxMailbox, + MessageRange.one(messageMapper.getLastUid(benwaInboxMailbox)), + MessageMapper.FetchType.Full, + LIMIT) + .next(); + + MessageAssert.assertThat(result).isEqualToWithoutUid(message7, MessageMapper.FetchType.Full); + assertThat(result.getUid()).isEqualTo(messageMapper.getLastUid(benwaInboxMailbox)); + } + + @ContractTest + public void copyOfSeenMessageShouldNotIncrementUnSeenMessageCount() throws MailboxException { + message6.setFlags(new Flags(Flags.Flag.SEEN)); + messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); + } + + @ContractTest + public void copiedMessageShouldBeMarkedAsRecent() throws MailboxException { + MessageMetaData metaData = messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat( + messageMapper.findInMailbox(benwaInboxMailbox, + MessageRange.one(metaData.getUid()), + MessageMapper.FetchType.Metadata, + LIMIT + ).next() + .isRecent() + ).isTrue(); + } + + @ContractTest + public void copiedRecentMessageShouldBeMarkedAsRecent() throws MailboxException { + message6.setFlags(new Flags(Flags.Flag.RECENT)); + MessageMetaData metaData = messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6)); + assertThat( + messageMapper.findInMailbox(benwaInboxMailbox, + MessageRange.one(metaData.getUid()), + MessageMapper.FetchType.Metadata, + LIMIT + ).next() + .isRecent() + ).isTrue(); + } + + @ContractTest + public void flagsReplacementShouldReplaceStoredMessageFlags() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new Flags(Flags.Flag.FLAGGED)); + } + + @ContractTest + public void flagsReplacementShouldReturnAnUpdatedFlagHighlightingTheReplacement() throws MailboxException { + saveMessages(); + long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid()))) + .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new Flags(), new Flags(Flags.Flag.FLAGGED))); + } + + @ContractTest + public void flagsAdditionShouldReturnAnUpdatedFlagHighlightingTheAddition() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.ADD), MessageRange.one(message1.getUid()))) + .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new Flags(Flags.Flag.FLAGGED), new FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build())); + } + + @ContractTest + public void flagsAdditionShouldUpdateStoredMessageFlags() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.ADD), MessageRange.one(message1.getUid())); + MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build()); + } + + @ContractTest + public void flagsRemovalShouldReturnAnUpdatedFlagHighlightingTheRemoval() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new FlagsBuilder().add(Flags.Flag.FLAGGED, Flags.Flag.SEEN).build(), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REMOVE), MessageRange.one(message1.getUid()))) + .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build(), new Flags(Flags.Flag.FLAGGED))); + } + + @ContractTest + public void flagsRemovalShouldUpdateStoredMessageFlags() throws MailboxException { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new FlagsBuilder().add(Flags.Flag.FLAGGED, Flags.Flag.SEEN).build(), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REMOVE), MessageRange.one(message1.getUid())); + MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new Flags(Flags.Flag.FLAGGED)); + } + + @ContractTest + public void updateFlagsOnRangeShouldAffectMessagesContainedInThisRange() throws MailboxException { + saveMessages(); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.range(message1.getUid(), message3.getUid()))) + .hasSize(3); + } + + @ContractTest + public void updateFlagsWithRangeFromShouldAffectMessagesContainedInThisRange() throws MailboxException { + saveMessages(); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.from(message3.getUid()))).hasSize(3); + } + + @ContractTest + public void updateFlagsWithRangeAllRangeShouldAffectAllMessages() throws MailboxException { + saveMessages(); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), MessageRange.all())).hasSize(5); + } + + @ContractTest + public void messagePropertiesShouldBeStored() throws Exception { + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setMediaType("text"); + propBuilder.setSubType("html"); + propBuilder.setTextualLineCount(2L); + propBuilder.setProperty(StandardNames.NAMESPACE_RFC_2045, StandardNames.MIME_CONTENT_TRANSFER_ENCODING_NAME, "7bit"); + propBuilder.setProperty(StandardNames.MIME_CONTENT_TYPE_PARAMETER_SPACE, StandardNames.MIME_CONTENT_TYPE_PARAMETER_CHARSET_NAME, "US-ASCII"); + + SimpleMailboxMessage messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStored \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + MailboxMessage message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getProperties()).containsOnlyElementsOf(propBuilder.toProperties()); + } + + @ContractTest + public void messagePropertiesShouldBeStoredWhenDuplicateEntries() throws Exception { + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setProperty(StandardNames.MIME_CONTENT_LANGUAGE_SPACE, StandardNames.MIME_CONTENT_LANGUAGE_NAME, "us"); + propBuilder.setProperty(StandardNames.MIME_CONTENT_LANGUAGE_SPACE, StandardNames.MIME_CONTENT_LANGUAGE_NAME, "fr"); + + SimpleMailboxMessage messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + MailboxMessage message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getProperties()).containsOnlyElementsOf(propBuilder.toProperties()); + } + + @ContractTest + public void messagePropertiesShouldBeStoredWhenNoProperty() throws Exception { + SimpleMailboxMessage messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenNoProperty \n\nBody\n.\n", BODY_START, new PropertyBuilder()); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + MailboxMessage message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getProperties()).isEmpty(); + } + + @ContractTest + public void textualLineCountShouldBeWellStored() throws Exception { + long textualLineCount = 48L; + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setTextualLineCount(textualLineCount); + + SimpleMailboxMessage messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + MailboxMessage message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getTextualLineCount()).isEqualTo(textualLineCount); + } + + @ContractTest + public void mediaTypeShouldBeWellStored() throws Exception { + String mediaType = "plain"; + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setMediaType(mediaType); + + SimpleMailboxMessage messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + MailboxMessage message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getMediaType()).isEqualTo(mediaType); + } + + @ContractTest + public void subTypeShouldBeWellStored() throws Exception { + String subType = "text"; + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setSubType(subType); + + SimpleMailboxMessage messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + MailboxMessage message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getSubType()).isEqualTo(subType); + } + + @ContractTest + public void userFlagsShouldBeSupported() throws Exception { + saveMessages(); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(USER_FLAG), FlagsUpdateMode.ADD), MessageRange.one(message1.getUid())); + MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new Flags(USER_FLAG)); + } + + @ContractTest + public void userFlagsUpdateShouldReturnCorrectUpdatedFlags() throws Exception { + saveMessages(); + long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox); + assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(USER_FLAG), FlagsUpdateMode.ADD), MessageRange.one(message1.getUid()))) + .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new Flags(), new Flags(USER_FLAG))); + } + + @ContractTest + public void messagesShouldBeSavedWithTheirUserFlags() throws Exception { + MailboxMessage message = SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message1); + messageMapper.add(benwaInboxMailbox, message); + MessageAssert.assertThat(retrieveMessageFromStorage(message)).hasFlags(new Flags(USER_FLAG)); + } + + private Map<Long, MessageMetaData> markThenPerformExpunge(MessageRange range) throws MailboxException { + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.DELETED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid())); + messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.DELETED), FlagsUpdateMode.REPLACE), MessageRange.one(message4.getUid())); + return messageMapper.expungeMarkedForDeletionInMailbox(benwaInboxMailbox, range); + } + + private SimpleMailbox createMailbox(MailboxPath mailboxPath) { + SimpleMailbox mailbox = new SimpleMailbox(mailboxPath, UID_VALIDITY); + MailboxId id = mapperProvider.generateId(); + mailbox.setMailboxId(id); + return mailbox; + } + + private void saveMessages() throws MailboxException { + messageMapper.add(benwaInboxMailbox, message1); + message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + messageMapper.add(benwaInboxMailbox, message2); + message2.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + messageMapper.add(benwaInboxMailbox, message3); + message3.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + messageMapper.add(benwaInboxMailbox, message4); + message4.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + messageMapper.add(benwaInboxMailbox, message5); + message5.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + messageMapper.add(benwaWorkMailbox, message6); + message6.setModSeq(messageMapper.getHighestModSeq(benwaWorkMailbox)); + messageMapper.add(attachmentsMailbox, message7With1Attachment); + message7With1Attachment.setModSeq(messageMapper.getHighestModSeq(attachmentsMailbox)); + messageMapper.add(attachmentsMailbox, message8With2Attachments); + message8With2Attachments.setModSeq(messageMapper.getHighestModSeq(attachmentsMailbox)); + } + + private MailboxMessage retrieveMessageFromStorage(MailboxMessage message) throws MailboxException { + return messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message.getUid()), MessageMapper.FetchType.Metadata, LIMIT).next(); + } + + private SimpleMailboxMessage createMessage(Mailbox mailbox, String content, int bodyStart, PropertyBuilder propertyBuilder, List<AttachmentId> attachmentsIds) { + return new SimpleMailboxMessage(new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, mailbox.getMailboxId(), attachmentsIds); + } + + private SimpleMailboxMessage createMessage(Mailbox mailbox, String content, int bodyStart, PropertyBuilder propertyBuilder) { + return new SimpleMailboxMessage(new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, mailbox.getMailboxId()); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/8c089562/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMoveTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMoveTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMoveTest.java new file mode 100644 index 0000000..86e81f1 --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMoveTest.java @@ -0,0 +1,157 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Date; + +import javax.mail.Flags; +import javax.mail.util.SharedByteArrayInputStream; + +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.MessageMetaData; +import org.apache.james.mailbox.model.MessageRange; +import org.apache.james.mailbox.store.mail.AttachmentMapper; +import org.apache.james.mailbox.store.mail.MessageMapper; +import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; +import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; +import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.xenei.junit.contract.Contract; +import org.xenei.junit.contract.ContractTest; +import org.xenei.junit.contract.IProducer; + +@Contract(MapperProvider.class) +public class MessageMoveTest<T extends MapperProvider> { + + private final static char DELIMITER = ':'; + private static final int LIMIT = 10; + private static final int BODY_START = 16; + public static final int UID_VALIDITY = 42; + + private MapperProvider mapperProvider; + private MessageMapper messageMapper; + private IProducer<T> producer; + + private SimpleMailbox benwaInboxMailbox; + private SimpleMailbox benwaWorkMailbox; + + private SimpleMailboxMessage message1; + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Contract.Inject + public final void setProducer(IProducer<T> producer) throws MailboxException { + this.producer = producer; + this.mapperProvider = producer.newInstance(); + this.mapperProvider.ensureMapperPrepared(); + this.messageMapper = mapperProvider.createMessageMapper(); + + benwaInboxMailbox = createMailbox(new MailboxPath("#private", "benwa", "INBOX")); + benwaWorkMailbox = createMailbox( new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work")); + message1 = createMessage(benwaInboxMailbox, "Subject: Test1 \n\nBody1\n.\n", BODY_START, new PropertyBuilder()); + } + + @After + public void tearDown() { + producer.cleanUp(); + } + + @ContractTest + public void movingAMessageShouldWork() throws Exception { + messageMapper.add(benwaInboxMailbox, message1); + message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + + messageMapper.move(benwaWorkMailbox, message1); + + assertThat(retrieveMessageFromStorage(benwaWorkMailbox, message1)).isEqualTo(message1); + } + + @ContractTest + public void movingAMessageShouldReturnCorrectMetadata() throws Exception { + messageMapper.add(benwaInboxMailbox, message1); + message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + + MessageMetaData messageMetaData = messageMapper.move(benwaWorkMailbox, message1); + + Flags expectedFlags = message1.createFlags(); + expectedFlags.add(Flags.Flag.RECENT); + assertThat(messageMetaData.getFlags()).isEqualTo(expectedFlags); + assertThat(messageMetaData.getUid()).isEqualTo(messageMapper.getLastUid(benwaWorkMailbox)); + assertThat(messageMetaData.getModSeq()).isEqualTo(messageMapper.getHighestModSeq(benwaWorkMailbox)); + } + + @ContractTest + public void movingAMessageShouldNotViolateMessageCount() throws Exception { + messageMapper.add(benwaInboxMailbox, message1); + message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + + messageMapper.move(benwaWorkMailbox, message1); + + assertThat(messageMapper.countMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); + assertThat(messageMapper.countMessagesInMailbox(benwaWorkMailbox)).isEqualTo(1); + } + + @ContractTest + public void movingAMessageShouldNotViolateUnseenMessageCount() throws Exception { + messageMapper.add(benwaInboxMailbox, message1); + message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + + messageMapper.move(benwaWorkMailbox, message1); + + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaWorkMailbox)).isEqualTo(1); + } + + @ContractTest + public void movingASeenMessageShouldNotIncrementUnseenMessageCount() throws Exception { + message1.setFlags(new Flags(Flags.Flag.SEEN)); + messageMapper.add(benwaInboxMailbox, message1); + message1.setModSeq(messageMapper.getHighestModSeq(benwaInboxMailbox)); + + messageMapper.move(benwaWorkMailbox, message1); + + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(0); + assertThat(messageMapper.countUnseenMessagesInMailbox(benwaWorkMailbox)).isEqualTo(0); + } + + private SimpleMailbox createMailbox(MailboxPath mailboxPath) { + SimpleMailbox mailbox = new SimpleMailbox(mailboxPath, UID_VALIDITY); + MailboxId id = mapperProvider.generateId(); + mailbox.setMailboxId(id); + return mailbox; + } + + private MailboxMessage retrieveMessageFromStorage(Mailbox mailbox, MailboxMessage message) throws MailboxException { + return messageMapper.findInMailbox(mailbox, MessageRange.one(message.getUid()), FetchType.Metadata, LIMIT).next(); + } + + private SimpleMailboxMessage createMessage(Mailbox mailbox, String content, int bodyStart, PropertyBuilder propertyBuilder) { + return new SimpleMailboxMessage(new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, mailbox.getMailboxId()); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org