This is an automated email from the ASF dual-hosted git repository. olli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-messaging-mail.git
commit 735b0a2588166f9a83c623042eb7d144c4c084d9 Author: Oliver Lietz <[email protected]> AuthorDate: Fri Sep 10 21:57:28 2021 +0200 check for required configuration and services, test component lifecycle --- pom.xml | 1 + .../messaging/mail/internal/SimpleMailService.java | 6 ++ .../mail/internal/SimpleMailServiceTest.java | 111 +++++++++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + 4 files changed, 119 insertions(+) diff --git a/pom.xml b/pom.xml index 703e49d..7e3d2d0 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,7 @@ <configuration> <excludes combine.children="append"> <exclude>**/*.txt</exclude> + <exclude>src/test/resources/mockito-extensions/*</exclude> <exclude>src/test/resources/password</exclude> </excludes> </configuration> diff --git a/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java b/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java index 6822c6e..f90cd5d 100644 --- a/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java +++ b/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java @@ -174,10 +174,16 @@ public final class SimpleMailService implements MailService { @Override public @NotNull CompletableFuture<Void> sendMessage(@NotNull final MimeMessage message) { + final var threadPool = this.threadPool; + Objects.requireNonNull(threadPool, "Thread pool must not be null"); return CompletableFuture.runAsync(() -> send(message), runnable -> threadPool.submit(runnable)); } private void send(@NotNull final MimeMessage message) { + final var configuration = this.configuration; + Objects.requireNonNull(configuration, "Configuration must not be null"); + final var cryptoService = this.cryptoService; + Objects.requireNonNull(cryptoService, "Crypto service must not be null"); try { final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); diff --git a/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceTest.java b/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceTest.java new file mode 100644 index 0000000..d11d10e --- /dev/null +++ b/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceTest.java @@ -0,0 +1,111 @@ +/* + * 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.sling.commons.messaging.mail.internal; + +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.Future; + +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.MimeMessage; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.apache.sling.commons.crypto.CryptoService; +import org.apache.sling.commons.threads.ThreadPool; +import org.apache.sling.commons.threads.ThreadPoolConfig; +import org.apache.sling.commons.threads.ThreadPoolManager; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class SimpleMailServiceTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void testComponentLifecycle() throws Exception { + final MimeMessage message = mock(MimeMessage.class); + final ThreadPoolManager threadPoolManager = mock(ThreadPoolManager.class); + when(threadPoolManager.get("default")).thenReturn(new DefaultThreadPool()); + final CryptoService cryptoService = mock(CryptoService.class); + final Transport transport = mock(Transport.class); + final Session session = mock(Session.class); + when(session.getTransport("smtps")).thenReturn(transport); + final SimpleMailService service = new SimpleMailService(); + FieldUtils.writeDeclaredField(service, "threadPoolManager", threadPoolManager, true); + FieldUtils.writeDeclaredField(service, "cryptoService", cryptoService, true); + FieldUtils.writeDeclaredField(service, "connectionListeners", Collections.emptyList(), true); + FieldUtils.writeDeclaredField(service, "transportListeners", Collections.emptyList(), true); + { // activate + final SimpleMailServiceConfiguration configuration = mock(SimpleMailServiceConfiguration.class); + when(configuration.threadpool_name()).thenReturn("default"); + MethodUtils.invokeMethod(service, true, "activate", configuration); + FieldUtils.writeDeclaredField(service, "session", session, true); + service.sendMessage(message); + } + { // modified + final SimpleMailServiceConfiguration configuration = mock(SimpleMailServiceConfiguration.class); + when(configuration.threadpool_name()).thenReturn("default"); + MethodUtils.invokeMethod(service, true, "modified", configuration); + service.sendMessage(message); + } + { // deactivate + MethodUtils.invokeMethod(service, true, "deactivate"); + exception.expect(NullPointerException.class); + exception.expectMessage("Thread pool must not be null"); + service.sendMessage(message); + } + } + + private static final class DefaultThreadPool implements ThreadPool { + + @Override + public void execute(Runnable runnable) { + ForkJoinPool.commonPool().execute(runnable); + } + + @Override + public <T> Future<T> submit(Callable<T> callable) { + return ForkJoinPool.commonPool().submit(callable); + } + + @Override + public Future<?> submit(Runnable runnable) { + return ForkJoinPool.commonPool().submit(runnable); + } + + @Override + public String getName() { + return "default"; + } + + @Override + public ThreadPoolConfig getConfiguration() { + return null; + } + + } + +} diff --git a/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..1f0955d --- /dev/null +++ b/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline
