IdServerMailServiceTest.java
/*
* Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package com.io7m.idstore.tests.server.service.mail;
import com.io7m.idstore.model.IdEmail;
import com.io7m.idstore.server.api.IdServerMailConfiguration;
import com.io7m.idstore.server.api.IdServerMailTransportSMTP;
import com.io7m.idstore.server.service.mail.IdServerMailService;
import com.io7m.idstore.server.service.mail.IdServerMailServiceType;
import com.io7m.idstore.server.service.telemetry.api.IdEventService;
import com.io7m.idstore.server.service.telemetry.api.IdEventServiceType;
import com.io7m.idstore.server.service.telemetry.api.IdMetricsService;
import com.io7m.idstore.server.service.telemetry.api.IdServerTelemetryNoOp;
import com.io7m.idstore.tests.server.service.IdServiceContract;
import com.io7m.zelador.test_extension.CloseableResourcesType;
import com.io7m.zelador.test_extension.ZeladorExtension;
import io.opentelemetry.api.trace.Span;
import jakarta.mail.MessagingException;
import jakarta.mail.Session;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.subethamail.smtp.server.SMTPServer;
import java.io.ByteArrayInputStream;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import static com.io7m.idstore.server.service.telemetry.api.IdServerTelemetryNoOp.noop;
import static java.util.Map.entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(ZeladorExtension.class)
public final class IdServerMailServiceTest
extends IdServiceContract<IdServerMailServiceType>
{
private ConcurrentLinkedQueue<MimeMessage> emailsReceived;
private SMTPServer smtp;
private IdServerMailConfiguration configuration;
private IdServerMailServiceType mailService;
private IdServerTelemetryNoOp telemetry;
private IdMetricsService metrics;
private IdEventServiceType events;
@BeforeEach
public void setup(
final CloseableResourcesType closeables)
{
this.telemetry =
noop();
this.metrics =
new IdMetricsService(this.telemetry);
this.events =
IdEventService.create(this.telemetry, this.metrics);
this.emailsReceived = new ConcurrentLinkedQueue<>();
this.smtp =
SMTPServer.port(32025)
.messageHandler((messageContext, source, destination, data) -> {
try {
final var message =
new MimeMessage(
Session.getDefaultInstance(new Properties()),
new ByteArrayInputStream(data)
);
this.emailsReceived.add(message);
} catch (final MessagingException e) {
throw new IllegalStateException(e);
}
})
.build();
closeables.addPerTestResource(this.smtp::stop);
this.smtp.start();
this.configuration =
new IdServerMailConfiguration(
new IdServerMailTransportSMTP("127.0.0.1", 32025),
Optional.empty(),
"examples@localhost.com",
Duration.ofHours(6L)
);
this.mailService =
closeables.addPerTestResource(
IdServerMailService.create(noop(), this.events, this.configuration)
);
}
/**
* Sending mail works.
*
* @throws Exception On errors
*/
@Test
public void testSendMail()
throws Exception
{
this.mailService.sendMail(
Span.current(),
UUID.randomUUID(),
new IdEmail("someone@example.com"),
Map.ofEntries(
entry("X-A", "0"),
entry("X-B", "1"),
entry("X-C", "2")
),
"Example subject.",
"Example text."
).get();
final var mail = this.emailsReceived.poll();
assertEquals("Example subject.", mail.getSubject());
assertEquals("Example text.\r\n", mail.getContent());
assertEquals("0", mail.getHeader("X-A")[0]);
assertEquals("1", mail.getHeader("X-B")[0]);
assertEquals("2", mail.getHeader("X-C")[0]);
}
@Override
protected IdServerMailServiceType createInstanceA()
{
return IdServerMailService.create(noop(), this.events, this.configuration);
}
@Override
protected IdServerMailServiceType createInstanceB()
{
return IdServerMailService.create(noop(), this.events, this.configuration);
}
}