1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.mail.internal.thread

File SendMailRunnableTest.java

 

Code metrics

4
78
3
1
209
135
5
0.06
26
3
1.67

Classes

Class Line # Actions
SendMailRunnableTest 63 78 0% 5 0
1.0100%
 

Contributing tests

This file is covered by 2 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.mail.internal.thread;
21   
22    import java.util.Collections;
23    import java.util.Iterator;
24    import java.util.Properties;
25    import java.util.UUID;
26   
27    import javax.inject.Provider;
28    import javax.mail.Session;
29    import javax.mail.internet.MimeMessage;
30   
31    import org.junit.Before;
32    import org.junit.Rule;
33    import org.junit.Test;
34    import org.mockito.Mockito;
35    import org.xwiki.component.util.DefaultParameterizedType;
36    import org.xwiki.mail.ExtendedMimeMessage;
37    import org.xwiki.mail.MailContentStore;
38    import org.xwiki.mail.MailListener;
39    import org.xwiki.mail.MailState;
40    import org.xwiki.mail.MailStatus;
41    import org.xwiki.mail.MailStoreException;
42    import org.xwiki.mail.internal.MemoryMailListener;
43    import org.xwiki.mail.internal.UpdateableMailStatusResult;
44    import org.xwiki.test.annotation.ComponentList;
45    import org.xwiki.test.mockito.MockitoComponentMockingRule;
46   
47    import com.xpn.xwiki.XWikiContext;
48   
49    import static org.junit.Assert.assertEquals;
50    import static org.junit.Assert.assertTrue;
51    import static org.mockito.Mockito.when;
52   
53    /**
54    * Unit tests for {@link SendMailRunnable}.
55    *
56    * @version $Id: 1e33c87757aeb41258a49f97db9fe9c98a2bf187 $
57    * @since 6.4
58    */
59    @ComponentList({
60    MemoryMailListener.class,
61    SendMailQueueManager.class
62    })
 
63    public class SendMailRunnableTest
64    {
65    @Rule
66    public MockitoComponentMockingRule<SendMailRunnable> mocker =
67    new MockitoComponentMockingRule<>(SendMailRunnable.class);
68   
 
69  2 toggle @Before
70    public void setUp() throws Exception
71    {
72  2 Provider<XWikiContext> xwikiContextProvider = this.mocker.registerMockComponent(XWikiContext.TYPE_PROVIDER);
73  2 when(xwikiContextProvider.get()).thenReturn(Mockito.mock(XWikiContext.class));
74    }
75   
 
76  1 toggle @Test
77    public void sendMailWhenSendingFails() throws Exception
78    {
79    // Create a Session with an invalid host so that it generates an error
80  1 Properties properties = new Properties();
81  1 properties.setProperty("mail.smtp.host", "xwiki-unknown");
82  1 Session session = Session.getDefaultInstance(properties);
83   
84  1 MimeMessage msg1 = new MimeMessage(session);
85  1 msg1.setText("Content1");
86  1 ExtendedMimeMessage message1 = new ExtendedMimeMessage(msg1);
87  1 String id1 = message1.getUniqueMessageId();
88  1 MimeMessage msg2 = new MimeMessage(session);
89  1 msg2.setText("Content2");
90  1 ExtendedMimeMessage message2 = new ExtendedMimeMessage(msg2);
91  1 String id2 = message2.getUniqueMessageId();
92   
93  1 MemoryMailListener listener = this.mocker.getInstance(MailListener.class, "memory");
94  1 String batchId = UUID.randomUUID().toString();
95  1 listener.onPrepareBegin(batchId, Collections.<String, Object>emptyMap());
96  1 ((UpdateableMailStatusResult) listener.getMailStatusResult()).setTotalSize(2);
97   
98  1 SendMailQueueItem item1 = new SendMailQueueItem(id1, session, listener, batchId, "xwiki");
99  1 SendMailQueueItem item2 = new SendMailQueueItem(id2, session, listener, batchId, "xwiki");
100   
101  1 MailQueueManager mailQueueManager = this.mocker.getInstance(
102    new DefaultParameterizedType(null, MailQueueManager.class, SendMailQueueItem.class));
103   
104    // Simulate loading the message from the content store
105  1 MailContentStore contentStore = this.mocker.getInstance(MailContentStore.class, "filesystem");
106  1 when(contentStore.load(session, batchId, id1)).thenReturn(message1);
107  1 when(contentStore.load(session, batchId, id2)).thenReturn(message2);
108   
109    // Send 2 mails. Both will fail but we want to verify that the second one is processed even though the first
110    // one failed.
111  1 mailQueueManager.addToQueue(item1);
112  1 mailQueueManager.addToQueue(item2);
113   
114  1 MailRunnable runnable = this.mocker.getComponentUnderTest();
115  1 Thread thread = new Thread(runnable);
116  1 thread.start();
117   
118    // Wait for the mails to have been processed.
119  1 try {
120  1 listener.getMailStatusResult().waitTillProcessed(10000L);
121    } finally {
122  1 runnable.stopProcessing();
123  1 thread.interrupt();
124  1 thread.join();
125    }
126   
127    // This is the real test: we verify that there's been an error while sending each email.
128  1 Iterator<MailStatus> statuses = listener.getMailStatusResult().getByState(MailState.SEND_ERROR);
129  1 int errorCount = 0;
130  3 while (statuses.hasNext()) {
131  2 MailStatus status = statuses.next();
132    // Note: I would have liked to assert the exact message but it seems there can be different ones returned.
133    // During my tests I got 2 different ones:
134    // "UnknownHostException: xwiki-unknown"
135    // "ConnectException: Connection refused"
136    // Thus for now I only assert that there's an error set, but not its content.
137  2 assertTrue(status.getErrorSummary() != null);
138  2 errorCount++;
139    }
140  1 assertEquals(2, errorCount);
141    }
142   
 
143  1 toggle @Test
144    public void sendMailWhenMailRetrievalFails() throws Exception
145    {
146    // Create a Session with an invalid host so that it generates an error
147  1 Properties properties = new Properties();
148  1 Session session = Session.getDefaultInstance(properties);
149   
150  1 MimeMessage msg1 = new MimeMessage(session);
151  1 msg1.setText("Content1");
152  1 ExtendedMimeMessage message1 = new ExtendedMimeMessage(msg1);
153  1 String id1 = message1.getUniqueMessageId();
154  1 MimeMessage msg2 = new MimeMessage(session);
155  1 msg2.setText("Content2");
156  1 ExtendedMimeMessage message2 = new ExtendedMimeMessage(msg2);
157  1 String id2 = message2.getUniqueMessageId();
158   
159  1 MemoryMailListener listener = this.mocker.getInstance(MailListener.class, "memory");
160  1 String batchId = UUID.randomUUID().toString();
161  1 listener.onPrepareBegin(batchId, Collections.<String, Object>emptyMap());
162  1 ((UpdateableMailStatusResult) listener.getMailStatusResult()).setTotalSize(2);
163   
164  1 listener.onPrepareMessageSuccess(message1, Collections.<String, Object>emptyMap());
165  1 SendMailQueueItem item1 = new SendMailQueueItem(id1, session, listener, batchId, "xwiki");
166  1 listener.onPrepareMessageSuccess(message2, Collections.<String, Object>emptyMap());
167  1 SendMailQueueItem item2 = new SendMailQueueItem(id2, session, listener, batchId, "xwiki");
168   
169  1 MailQueueManager mailQueueManager = this.mocker.getInstance(
170    new DefaultParameterizedType(null, MailQueueManager.class, SendMailQueueItem.class));
171   
172    // Simulate loading the message from the content store
173  1 MailContentStore contentStore = this.mocker.getInstance(MailContentStore.class, "filesystem");
174  1 when(contentStore.load(session, batchId, id1)).thenThrow(new MailStoreException("Store failure on message 1"));
175  1 when(contentStore.load(session, batchId, id2)).thenThrow(new MailStoreException("Store failure on message 2"));
176   
177    // Send 2 mails. Both will fail but we want to verify that the second one is processed even though the first
178    // one failed.
179  1 mailQueueManager.addToQueue(item1);
180  1 mailQueueManager.addToQueue(item2);
181   
182  1 MailRunnable runnable = this.mocker.getComponentUnderTest();
183  1 Thread thread = new Thread(runnable);
184  1 thread.start();
185   
186    // Wait for the mails to have been processed.
187  1 try {
188  1 listener.getMailStatusResult().waitTillProcessed(10000L);
189    } finally {
190  1 runnable.stopProcessing();
191  1 thread.interrupt();
192  1 thread.join();
193    }
194   
195    // This is the real test: we verify that there's been an error while sending each email.
196  1 Iterator<MailStatus> statuses = listener.getMailStatusResult().getByState(MailState.SEND_FATAL_ERROR);
197  1 int errorCount = 0;
198  3 while (statuses.hasNext()) {
199  2 MailStatus status = statuses.next();
200    // Note: I would have liked to assert the exact message but it seems there can be different ones returned.
201    // During my tests I got 2 different ones:
202    // "UnknownHostException: xwiki-unknown"
203    // "ConnectException: Connection refused"
204    // Thus for now I only assert that there's an error set, but not its content.
205  2 assertEquals("MailStoreException: Store failure on message " + ++errorCount, status.getErrorSummary());
206    }
207  1 assertEquals(2, errorCount);
208    }
209    }