google-nomulus/javatests/google/registry/reporting/spec11/Spec11EmailUtilsTest.java
jianglai 476759e861 Update Spec 11 emails body and add a bcc address.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=217150650
2018-10-17 11:51:28 -04:00

211 lines
7.9 KiB
Java

// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed 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 google.registry.reporting.spec11;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.testing.JUnitBackports.assertThrows;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import google.registry.gcs.GcsUtils;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper;
import google.registry.testing.TestDataHelper;
import google.registry.util.Retrier;
import google.registry.util.SendEmailService;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;
import javax.annotation.Nullable;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.joda.time.YearMonth;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
/** Unit tests for {@link Spec11EmailUtils}. */
@RunWith(JUnit4.class)
public class Spec11EmailUtilsTest {
private static final int RETRY_COUNT = 2;
private SendEmailService emailService;
private Spec11EmailUtils emailUtils;
private GcsUtils gcsUtils;
private ArgumentCaptor<Message> gotMessage;
@Before
public void setUp() {
emailService = mock(SendEmailService.class);
when(emailService.createMessage())
.thenAnswer((args) -> new MimeMessage(Session.getInstance(new Properties(), null)));
gcsUtils = mock(GcsUtils.class);
when(gcsUtils.openInputStream(
new GcsFilename("test-bucket", "icann/spec11/2018-06/SPEC11_MONTHLY_REPORT")))
.thenAnswer(
(args) ->
new ByteArrayInputStream(
loadFile("spec11_fake_report").getBytes(StandardCharsets.UTF_8)));
gotMessage = ArgumentCaptor.forClass(Message.class);
emailUtils =
new Spec11EmailUtils(
emailService,
new YearMonth(2018, 6),
"my-sender@test.com",
"my-receiver@test.com",
"my-reply-to@test.com",
"{LIST_OF_THREATS}\n{REPLY_TO_EMAIL}",
"test-bucket",
"icann/spec11/2018-06/SPEC11_MONTHLY_REPORT",
gcsUtils,
new Retrier(new FakeSleeper(new FakeClock()), RETRY_COUNT));
}
@Test
public void testSuccess_emailSpec11Reports() throws MessagingException, IOException {
emailUtils.emailSpec11Reports();
// We inspect individual parameters because Message doesn't implement equals().
verify(emailService, times(3)).sendMessage(gotMessage.capture());
List<Message> capturedMessages = gotMessage.getAllValues();
validateMessage(
capturedMessages.get(0),
"my-sender@test.com",
"a@fake.com",
"my-reply-to@test.com",
"Google Registry Monthly Threat Detector [2018-06]",
"a.com - MALWARE\n\nmy-reply-to@test.com");
validateMessage(
capturedMessages.get(1),
"my-sender@test.com",
"b@fake.com",
"my-reply-to@test.com",
"Google Registry Monthly Threat Detector [2018-06]",
"b.com - MALWARE\nc.com - MALWARE\n\nmy-reply-to@test.com");
validateMessage(
capturedMessages.get(2),
"my-sender@test.com",
"my-receiver@test.com",
null,
"Spec11 Pipeline Success 2018-06",
"Spec11 reporting completed successfully.");
}
@Test
public void testFailure_tooManyRetries_emailsAlert() throws MessagingException, IOException {
Message throwingMessage = mock(Message.class);
doThrow(new MessagingException("expected")).when(throwingMessage).setSubject(any(String.class));
// Only return the throwingMessage enough times to force failure. The last invocation will
// be for the alert e-mail we're looking to verify.
when(emailService.createMessage())
.thenAnswer(
new Answer<Message>() {
private int count = 0;
@Override
public Message answer(InvocationOnMock invocation) {
if (count < RETRY_COUNT) {
count++;
return throwingMessage;
} else if (count == RETRY_COUNT) {
return new MimeMessage(Session.getDefaultInstance(new Properties(), null));
} else {
assertWithMessage("Attempted to generate too many messages!").fail();
return null;
}
}
});
RuntimeException thrown =
assertThrows(RuntimeException.class, () -> emailUtils.emailSpec11Reports());
assertThat(thrown).hasMessageThat().isEqualTo("Emailing spec11 report failed");
assertThat(thrown)
.hasCauseThat()
.hasMessageThat()
.isEqualTo("javax.mail.MessagingException: expected");
// We should have created RETRY_COUNT failing messages and one final alert message
verify(emailService, times(RETRY_COUNT + 1)).createMessage();
// Verify we sent an e-mail alert
verify(emailService).sendMessage(gotMessage.capture());
validateMessage(
gotMessage.getValue(),
"my-sender@test.com",
"my-receiver@test.com",
null,
"Spec11 Emailing Failure 2018-06",
"Emailing spec11 reports failed due to expected");
}
@Test
public void testSuccess_sendAlertEmail() throws MessagingException, IOException {
emailUtils.sendAlertEmail("Spec11 Pipeline Alert: 2018-06", "Alert!");
verify(emailService).sendMessage(gotMessage.capture());
validateMessage(
gotMessage.getValue(),
"my-sender@test.com",
"my-receiver@test.com",
null,
"Spec11 Pipeline Alert: 2018-06",
"Alert!");
}
private void validateMessage(
Message message,
String from,
String recipient,
@Nullable String replyTo,
String subject,
String body)
throws MessagingException, IOException {
assertThat(message.getFrom()).asList().containsExactly(new InternetAddress(from));
assertThat(message.getRecipients(RecipientType.TO))
.asList()
.containsExactly(new InternetAddress(recipient));
if (replyTo == null) {
assertThat(message.getRecipients(RecipientType.BCC)).isNull();
} else {
assertThat(message.getRecipients(RecipientType.BCC))
.asList()
.containsExactly(new InternetAddress(replyTo));
}
assertThat(message.getRecipients(RecipientType.CC)).isNull();
assertThat(message.getSubject()).isEqualTo(subject);
assertThat(message.getContentType()).isEqualTo("text/plain");
assertThat(message.getContent().toString()).isEqualTo(body);
}
/** Returns a {@link String} from a file in the {@code spec11/testdata/} directory. */
public static String loadFile(String filename) {
return TestDataHelper.loadFile(Spec11EmailUtils.class, filename);
}
}