1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.mail.internal.thread

File SendMailRunnableTest.java

 

Code metrics

4
76
3
1
213
138
5
0.07
25.33
3
1.67

Classes

Class Line # Actions
SendMailRunnableTest 66 76 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.jupiter.api.BeforeEach;
32    import org.junit.jupiter.api.Test;
33    import org.mockito.Mockito;
34    import org.xwiki.component.util.DefaultParameterizedType;
35    import org.xwiki.mail.ExtendedMimeMessage;
36    import org.xwiki.mail.MailContentStore;
37    import org.xwiki.mail.MailListener;
38    import org.xwiki.mail.MailState;
39    import org.xwiki.mail.MailStatus;
40    import org.xwiki.mail.MailStoreException;
41    import org.xwiki.mail.internal.MemoryMailListener;
42    import org.xwiki.mail.internal.UpdateableMailStatusResult;
43    import org.xwiki.test.annotation.ComponentList;
44    import org.xwiki.test.junit5.mockito.ComponentTest;
45    import org.xwiki.test.junit5.mockito.InjectComponentManager;
46    import org.xwiki.test.junit5.mockito.InjectMockComponents;
47    import org.xwiki.test.mockito.MockitoComponentManager;
48   
49    import com.xpn.xwiki.XWikiContext;
50   
51    import static org.junit.jupiter.api.Assertions.assertEquals;
52    import static org.junit.jupiter.api.Assertions.assertTrue;
53    import static org.mockito.Mockito.when;
54   
55    /**
56    * Unit tests for {@link SendMailRunnable}.
57    *
58    * @version $Id: e95349000aa51d37df2ade890e762193a27d2405 $
59    * @since 6.4
60    */
61    @ComponentTest
62    @ComponentList({
63    MemoryMailListener.class,
64    SendMailQueueManager.class
65    })
 
66    public class SendMailRunnableTest
67    {
68    @InjectMockComponents
69    private SendMailRunnable sendMailRunnable;
70   
71    @InjectComponentManager
72    private MockitoComponentManager componentManager;
73   
 
74  2 toggle @BeforeEach
75    public void setUp() throws Exception
76    {
77  2 Provider<XWikiContext> xwikiContextProvider =
78    this.componentManager.registerMockComponent(XWikiContext.TYPE_PROVIDER);
79  2 when(xwikiContextProvider.get()).thenReturn(Mockito.mock(XWikiContext.class));
80    }
81   
 
82  1 toggle @Test
83    public void sendMailWhenSendingFails() throws Exception
84    {
85    // Create a Session with an invalid host so that it generates an error
86  1 Properties properties = new Properties();
87  1 properties.setProperty("mail.smtp.host", "xwiki-unknown");
88  1 Session session = Session.getDefaultInstance(properties);
89   
90  1 MimeMessage msg1 = new MimeMessage(session);
91  1 msg1.setText("Content1");
92  1 ExtendedMimeMessage message1 = new ExtendedMimeMessage(msg1);
93  1 String id1 = message1.getUniqueMessageId();
94  1 MimeMessage msg2 = new MimeMessage(session);
95  1 msg2.setText("Content2");
96  1 ExtendedMimeMessage message2 = new ExtendedMimeMessage(msg2);
97  1 String id2 = message2.getUniqueMessageId();
98   
99  1 MemoryMailListener listener = this.componentManager.getInstance(MailListener.class, "memory");
100  1 String batchId = UUID.randomUUID().toString();
101  1 listener.onPrepareBegin(batchId, Collections.emptyMap());
102  1 ((UpdateableMailStatusResult) listener.getMailStatusResult()).setTotalSize(2);
103   
104  1 SendMailQueueItem item1 = new SendMailQueueItem(id1, session, listener, batchId, "xwiki");
105  1 SendMailQueueItem item2 = new SendMailQueueItem(id2, session, listener, batchId, "xwiki");
106   
107  1 MailQueueManager mailQueueManager = this.componentManager.getInstance(
108    new DefaultParameterizedType(null, MailQueueManager.class, SendMailQueueItem.class));
109   
110    // Simulate loading the message from the content store
111  1 MailContentStore contentStore = this.componentManager.getInstance(MailContentStore.class, "filesystem");
112  1 when(contentStore.load(session, batchId, id1)).thenReturn(message1);
113  1 when(contentStore.load(session, batchId, id2)).thenReturn(message2);
114   
115    // Send 2 mails. Both will fail but we want to verify that the second one is processed even though the first
116    // one failed.
117  1 mailQueueManager.addToQueue(item1);
118  1 mailQueueManager.addToQueue(item2);
119   
120  1 Thread thread = new Thread(this.sendMailRunnable);
121  1 thread.start();
122   
123    // Wait for the mails to have been processed.
124  1 try {
125  1 listener.getMailStatusResult().waitTillProcessed(10000L);
126    } finally {
127  1 this.sendMailRunnable.stopProcessing();
128  1 thread.interrupt();
129  1 thread.join();
130    }
131   
132    // This is the real test: we verify that there's been an error while sending each email.
133  1 Iterator<MailStatus> statuses = listener.getMailStatusResult().getByState(MailState.SEND_ERROR);
134  1 int errorCount = 0;
135  3 while (statuses.hasNext()) {
136  2 MailStatus status = statuses.next();
137    // Note: I would have liked to assert the exact message but it seems there can be different ones returned.
138    // During my tests I got 2 different ones:
139    // "UnknownHostException: xwiki-unknown"
140    // "ConnectException: Connection refused"
141    // Thus for now I only assert that there's an error set, but not its content.
142  2 assertTrue(status.getErrorSummary() != null);
143  2 errorCount++;
144    }
145  1 assertEquals(2, errorCount);
146    }
147   
 
148  1 toggle @Test
149    public void sendMailWhenMailRetrievalFails() throws Exception
150    {
151    // Create a Session with an invalid host so that it generates an error
152  1 Properties properties = new Properties();
153  1 Session session = Session.getDefaultInstance(properties);
154   
155  1 MimeMessage msg1 = new MimeMessage(session);
156  1 msg1.setText("Content1");
157  1 ExtendedMimeMessage message1 = new ExtendedMimeMessage(msg1);
158  1 String id1 = message1.getUniqueMessageId();
159  1 MimeMessage msg2 = new MimeMessage(session);
160  1 msg2.setText("Content2");
161  1 ExtendedMimeMessage message2 = new ExtendedMimeMessage(msg2);
162  1 String id2 = message2.getUniqueMessageId();
163   
164  1 MemoryMailListener listener = this.componentManager.getInstance(MailListener.class, "memory");
165  1 String batchId = UUID.randomUUID().toString();
166  1 listener.onPrepareBegin(batchId, Collections.emptyMap());
167  1 ((UpdateableMailStatusResult) listener.getMailStatusResult()).setTotalSize(2);
168   
169  1 listener.onPrepareMessageSuccess(message1, Collections.emptyMap());
170  1 SendMailQueueItem item1 = new SendMailQueueItem(id1, session, listener, batchId, "xwiki");
171  1 listener.onPrepareMessageSuccess(message2, Collections.emptyMap());
172  1 SendMailQueueItem item2 = new SendMailQueueItem(id2, session, listener, batchId, "xwiki");
173   
174  1 MailQueueManager mailQueueManager = this.componentManager.getInstance(
175    new DefaultParameterizedType(null, MailQueueManager.class, SendMailQueueItem.class));
176   
177    // Simulate loading the message from the content store
178  1 MailContentStore contentStore = this.componentManager.getInstance(MailContentStore.class, "filesystem");
179  1 when(contentStore.load(session, batchId, id1)).thenThrow(new MailStoreException("Store failure on message 1"));
180  1 when(contentStore.load(session, batchId, id2)).thenThrow(new MailStoreException("Store failure on message 2"));
181   
182    // Send 2 mails. Both will fail but we want to verify that the second one is processed even though the first
183    // one failed.
184  1 mailQueueManager.addToQueue(item1);
185  1 mailQueueManager.addToQueue(item2);
186   
187  1 Thread thread = new Thread(this.sendMailRunnable);
188  1 thread.start();
189   
190    // Wait for the mails to have been processed.
191  1 try {
192  1 listener.getMailStatusResult().waitTillProcessed(10000L);
193    } finally {
194  1 this.sendMailRunnable.stopProcessing();
195  1 thread.interrupt();
196  1 thread.join();
197    }
198   
199    // This is the real test: we verify that there's been an error while sending each email.
200  1 Iterator<MailStatus> statuses = listener.getMailStatusResult().getByState(MailState.SEND_FATAL_ERROR);
201  1 int errorCount = 0;
202  3 while (statuses.hasNext()) {
203  2 MailStatus status = statuses.next();
204    // Note: I would have liked to assert the exact message but it seems there can be different ones returned.
205    // During my tests I got 2 different ones:
206    // "UnknownHostException: xwiki-unknown"
207    // "ConnectException: Connection refused"
208    // Thus for now I only assert that there's an error set, but not its content.
209  2 assertEquals("MailStoreException: Store failure on message " + ++errorCount, status.getErrorSummary());
210    }
211  1 assertEquals(2, errorCount);
212    }
213    }