This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 61c13426a96388fb1d4cd82e4289ffb48b5900e3 Author: Tran Tien Duc <dt...@linagora.com> AuthorDate: Thu Aug 29 10:18:57 2019 +0700 JAMES-2865 Behavior conditions filtering --- .../james/mock/smtp/server/MockMessageHandler.java | 14 +- .../james/mock/smtp/server/MockSMTPServerTest.java | 188 +++++++++++++++++++++ 2 files changed, 196 insertions(+), 6 deletions(-) diff --git a/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/MockMessageHandler.java b/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/MockMessageHandler.java index bef805f..70b01ee 100644 --- a/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/MockMessageHandler.java +++ b/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/MockMessageHandler.java @@ -98,7 +98,7 @@ public class MockMessageHandler implements MessageHandler { @Override public void from(String from) throws RejectException { - Optional<Behavior<MailAddress>> fromBehavior = firstMatchedBehavior(SMTPCommand.MAIL_FROM); + Optional<Behavior<MailAddress>> fromBehavior = firstMatchedBehavior(SMTPCommand.MAIL_FROM, from); fromBehavior .orElseGet(() -> envelopeBuilder::from) @@ -107,7 +107,7 @@ public class MockMessageHandler implements MessageHandler { @Override public void recipient(String recipient) throws RejectException { - Optional<Behavior<MailAddress>> recipientBehavior = firstMatchedBehavior(SMTPCommand.RCPT_TO); + Optional<Behavior<MailAddress>> recipientBehavior = firstMatchedBehavior(SMTPCommand.RCPT_TO, recipient); recipientBehavior .orElseGet(() -> envelopeBuilder::addRecipient) @@ -116,17 +116,19 @@ public class MockMessageHandler implements MessageHandler { @Override public void data(InputStream data) throws RejectException, TooMuchDataException, IOException { - Optional<Behavior<InputStream>> dataBehavior = firstMatchedBehavior(SMTPCommand.DATA); + String dataString = readData(data); + Optional<Behavior<String>> dataBehavior = firstMatchedBehavior(SMTPCommand.DATA, dataString); dataBehavior - .orElseGet(() -> content -> mailBuilder.message(readData(content))) - .behave(data); + .orElseGet(() -> mailBuilder::message) + .behave(dataString); } - private <T> Optional<Behavior<T>> firstMatchedBehavior(SMTPCommand data) { + private <T> Optional<Behavior<T>> firstMatchedBehavior(SMTPCommand data, String dataLine) { return behaviorRepository.remainingBehaviors() .map(MockSMTPBehaviorInformation::getBehavior) .filter(behavior -> behavior.getCommand().equals(data)) + .filter(behavior -> behavior.getCondition().matches(dataLine)) .findFirst() .map(mockBehavior -> new SMTPBehaviorRepositoryUpdater<>(behaviorRepository, mockBehavior)); } diff --git a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java index bf6fe4b..5e9c873 100644 --- a/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java +++ b/server/mailet/mock-smtp-server/src/test/java/org/apache/james/mock/smtp/server/MockSMTPServerTest.java @@ -23,6 +23,7 @@ import static org.apache.james.mock.smtp.server.Fixture.ALICE; import static org.apache.james.mock.smtp.server.Fixture.BOB; import static org.apache.james.mock.smtp.server.Fixture.DOMAIN; import static org.apache.james.mock.smtp.server.Fixture.JACK; +import static org.apache.james.mock.smtp.server.model.Response.SMTPStatusCode.REQUESTED_MAIL_ACTION_NOT_TAKEN_450; import static org.apache.james.mock.smtp.server.model.Response.SMTPStatusCode.SERVICE_NOT_AVAILABLE_421; import static org.apache.james.mock.smtp.server.model.SMTPCommand.DATA; import static org.apache.james.mock.smtp.server.model.SMTPCommand.MAIL_FROM; @@ -49,6 +50,7 @@ import org.apache.james.mock.smtp.server.model.Response; import org.apache.james.util.MimeMessageUtil; import org.apache.james.util.Port; import org.apache.james.utils.SMTPMessageSender; +import org.apache.james.utils.SMTPSendingException; import org.apache.mailet.base.test.FakeMail; import org.awaitility.Awaitility; import org.awaitility.Duration; @@ -338,6 +340,192 @@ class MockSMTPServerTest { } } + @Nested + class ConditionFilteringTest { + private MockSMTPServer mockServer; + private FakeMail mail1; + private MimeMessage mimeMessage1; + private SMTPMessageSender smtpClient; + private SMTPBehaviorRepository behaviorRepository; + + @BeforeEach + void setUp() throws Exception { + behaviorRepository = new SMTPBehaviorRepository(); + mockServer = new MockSMTPServer(behaviorRepository); + + mimeMessage1 = MimeMessageBuilder.mimeMessageBuilder() + .setSubject("test") + .setText("any text") + .build(); + mail1 = FakeMail.builder() + .name("name") + .sender(BOB) + .recipients(ALICE, JACK) + .mimeMessage(mimeMessage1) + .build(); + + mockServer.start(); + smtpClient = new SMTPMessageSender(DOMAIN) + .connect("localhost", mockServer.getPort()); + } + + @AfterEach + void tearDown() { + mockServer.stop(); + } + + @Test + void serverShouldBehaveOnMatchedFromBehavior() throws Exception { + MockSMTPBehavior matched = new MockSMTPBehavior( + MAIL_FROM, + new Condition.OperatorCondition(Operator.CONTAINS, BOB), + Response.serverReject(SERVICE_NOT_AVAILABLE_421, "sender bob should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.anytime()); + + MockSMTPBehavior nonMatched = new MockSMTPBehavior( + MAIL_FROM, + new Condition.OperatorCondition(Operator.CONTAINS, ALICE), + Response.serverReject(REQUESTED_MAIL_ACTION_NOT_TAKEN_450, "sender alice should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.anytime()); + + behaviorRepository.setBehaviors(matched, nonMatched); + + assertThatThrownBy(() -> smtpClient.sendMessage(mail1)) + .isInstanceOf(SMTPConnectionClosedException.class) + .hasMessageContaining(String.valueOf(SERVICE_NOT_AVAILABLE_421.getRawCode())); + } + + @Test + void serverShouldBehaveOnMatchedRecipientBehavior() throws Exception { + MockSMTPBehavior nonMatched = new MockSMTPBehavior( + RCPT_TO, + new Condition.OperatorCondition(Operator.CONTAINS, BOB), + Response.serverReject(SERVICE_NOT_AVAILABLE_421, "recipient bob should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.anytime()); + + MockSMTPBehavior matched = new MockSMTPBehavior( + RCPT_TO, + new Condition.OperatorCondition(Operator.CONTAINS, ALICE), + Response.serverReject(REQUESTED_MAIL_ACTION_NOT_TAKEN_450, "recipient alice should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.anytime()); + + behaviorRepository.setBehaviors(matched, nonMatched); + + assertThatThrownBy(() -> smtpClient.sendMessage(mail1)) + .isInstanceOf(SMTPSendingException.class) + .hasMessageContaining(String.valueOf(REQUESTED_MAIL_ACTION_NOT_TAKEN_450.getRawCode())); + } + + @Test + void serverShouldBehaveOnMatchedDataBehavior() throws Exception { + MockSMTPBehavior nonMatched = new MockSMTPBehavior( + DATA, + new Condition.OperatorCondition(Operator.CONTAINS, "nonRelatedString"), + Response.serverReject(SERVICE_NOT_AVAILABLE_421, "contains 'nonRelatedString' should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.anytime()); + + MockSMTPBehavior matched = new MockSMTPBehavior( + DATA, + new Condition.OperatorCondition(Operator.CONTAINS, "text"), + Response.serverReject(REQUESTED_MAIL_ACTION_NOT_TAKEN_450, "contains 'text' should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.anytime()); + + behaviorRepository.setBehaviors(matched, nonMatched); + + assertThatThrownBy(() -> smtpClient.sendMessage(mail1)) + .isInstanceOf(SMTPSendingException.class) + .hasMessageContaining(String.valueOf(REQUESTED_MAIL_ACTION_NOT_TAKEN_450.getRawCode())); + } + + @Test + void serverShouldDecreaseAnswerCountOnMatchedBehavior() throws Exception { + int matchedAnswerOriginalCount = 10; + MockSMTPBehavior matched = new MockSMTPBehavior( + MAIL_FROM, + new Condition.OperatorCondition(Operator.CONTAINS, BOB), + Response.serverReject(SERVICE_NOT_AVAILABLE_421, "sender bob should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.times(matchedAnswerOriginalCount)); + + int nonMatchedAnswerOriginalCount = 5; + MockSMTPBehavior nonMatched = new MockSMTPBehavior( + MAIL_FROM, + new Condition.OperatorCondition(Operator.CONTAINS, ALICE), + Response.serverReject(REQUESTED_MAIL_ACTION_NOT_TAKEN_450, "sender alice should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.times(nonMatchedAnswerOriginalCount)); + + behaviorRepository.setBehaviors(matched, nonMatched); + + sendMessageIgnoreError(mail1); + + assertThat(behaviorRepository.getBehaviorInformation(matched) + .remainingAnswersCounter()) + .contains(matchedAnswerOriginalCount - 1); + } + + @Test + void serverShouldNotDecreaseAnswerCountOnMonMatchedBehavior() throws Exception { + int matchedAnswerOriginalCount = 10; + MockSMTPBehavior matched = new MockSMTPBehavior( + MAIL_FROM, + new Condition.OperatorCondition(Operator.CONTAINS, BOB), + Response.serverReject(SERVICE_NOT_AVAILABLE_421, "sender bob should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.times(matchedAnswerOriginalCount)); + + int nonMatchedAnswerOriginalCount = 5; + MockSMTPBehavior nonMatched = new MockSMTPBehavior( + MAIL_FROM, + new Condition.OperatorCondition(Operator.CONTAINS, ALICE), + Response.serverReject(REQUESTED_MAIL_ACTION_NOT_TAKEN_450, "sender alice should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.times(nonMatchedAnswerOriginalCount)); + + behaviorRepository.setBehaviors(matched, nonMatched); + + sendMessageIgnoreError(mail1); + + assertThat(remainedAnswersOf(nonMatched)) + .isEqualTo(nonMatchedAnswerOriginalCount); + } + + @Test + void multipleQualifiedBehaviorsShouldNotOnlyBeingDecreasedOnlyOncePerMessage() throws Exception { + int matchedOriginalCount = 10; + MockSMTPBehavior matched = new MockSMTPBehavior( + RCPT_TO, + new Condition.OperatorCondition(Operator.CONTAINS, ALICE), + Response.serverReject(SERVICE_NOT_AVAILABLE_421, "recipient alice should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.times(matchedOriginalCount)); + + int qualifiedButNotMatchedOriginalCount = 5; + MockSMTPBehavior qualifiedButNotMatched = new MockSMTPBehavior( + RCPT_TO, + new Condition.OperatorCondition(Operator.CONTAINS, JACK), + Response.serverReject(REQUESTED_MAIL_ACTION_NOT_TAKEN_450, "recipient jack should match"), + MockSMTPBehavior.NumberOfAnswersPolicy.times(qualifiedButNotMatchedOriginalCount)); + + behaviorRepository.setBehaviors(matched, qualifiedButNotMatched); + + sendMessageIgnoreError(mail1); + + assertThat(remainedAnswersOf(matched) + remainedAnswersOf(qualifiedButNotMatched)) + .isEqualTo(matchedOriginalCount + qualifiedButNotMatchedOriginalCount - 1); + } + + private void sendMessageIgnoreError(FakeMail mail) { + try { + smtpClient.sendMessage(mail); + } catch (MessagingException | IOException e) { + // ignore error + } + } + + private Integer remainedAnswersOf(MockSMTPBehavior nonMatched) { + return behaviorRepository + .getBehaviorInformation(nonMatched) + .remainingAnswersCounter() + .get(); + } + } + @Test void serverStartShouldOpenASmtpPort() { MockSMTPServer mockServer = new MockSMTPServer(); --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org