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

File ScriptingIntegrationTest.java

 

Code metrics

0
73
5
1
304
221
5
0.07
14.6
5
1

Classes

Class Line # Actions
ScriptingIntegrationTest 110 73 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.integration;
21   
22    import java.io.InputStream;
23    import java.util.Arrays;
24    import java.util.Collections;
25    import java.util.List;
26    import java.util.Properties;
27   
28    import javax.inject.Provider;
29    import javax.mail.BodyPart;
30    import javax.mail.internet.MimeMessage;
31    import javax.mail.internet.MimeMultipart;
32   
33    import org.apache.commons.io.IOUtils;
34    import org.junit.After;
35    import org.junit.Before;
36    import org.junit.Rule;
37    import org.junit.Test;
38    import org.mockito.Mockito;
39    import org.xwiki.bridge.event.ApplicationReadyEvent;
40    import org.xwiki.component.internal.ContextComponentManagerProvider;
41    import org.xwiki.component.phase.Disposable;
42    import org.xwiki.component.util.DefaultParameterizedType;
43    import org.xwiki.context.Execution;
44    import org.xwiki.context.ExecutionContext;
45    import org.xwiki.context.ExecutionContextManager;
46    import org.xwiki.context.internal.DefaultExecution;
47    import org.xwiki.environment.internal.EnvironmentConfiguration;
48    import org.xwiki.environment.internal.StandardEnvironment;
49    import org.xwiki.mail.MailSenderConfiguration;
50    import org.xwiki.mail.MailState;
51    import org.xwiki.mail.internal.DefaultMailSender;
52    import org.xwiki.mail.internal.DefaultSessionFactory;
53    import org.xwiki.mail.internal.FileSystemMailContentStore;
54    import org.xwiki.mail.internal.MemoryMailListener;
55    import org.xwiki.mail.internal.factory.text.TextMimeBodyPartFactory;
56    import org.xwiki.mail.internal.thread.MailSenderInitializerListener;
57    import org.xwiki.mail.internal.thread.PrepareMailQueueManager;
58    import org.xwiki.mail.internal.thread.PrepareMailRunnable;
59    import org.xwiki.mail.internal.thread.SendMailQueueManager;
60    import org.xwiki.mail.internal.thread.SendMailRunnable;
61    import org.xwiki.mail.internal.thread.context.Copier;
62    import org.xwiki.mail.script.MailSenderScriptService;
63    import org.xwiki.mail.script.ScriptMailResult;
64    import org.xwiki.mail.script.ScriptMimeMessage;
65    import org.xwiki.mail.script.ScriptServicePermissionChecker;
66    import org.xwiki.model.ModelContext;
67    import org.xwiki.model.reference.WikiReference;
68    import org.xwiki.observation.EventListener;
69    import org.xwiki.properties.ConverterManager;
70    import org.xwiki.script.service.ScriptService;
71    import org.xwiki.test.annotation.BeforeComponent;
72    import org.xwiki.test.annotation.ComponentList;
73    import org.xwiki.test.mockito.MockitoComponentManagerRule;
74   
75    import com.icegreen.greenmail.junit.GreenMailRule;
76    import com.icegreen.greenmail.util.ServerSetupTest;
77    import com.xpn.xwiki.XWikiContext;
78   
79    import static org.junit.Assert.assertEquals;
80    import static org.junit.Assert.assertFalse;
81    import static org.junit.Assert.assertNull;
82    import static org.junit.Assert.assertTrue;
83    import static org.mockito.Mockito.mock;
84    import static org.mockito.Mockito.when;
85   
86    /**
87    * Integration tests to prove that mail sending is working fully end to end with the Scripting API.
88    *
89    * @version $Id: d27474ae6079bdc5488cd3803d49596e389a55f2 $
90    * @since 6.1M2
91    */
92    // @formatter:off
93    @ComponentList({
94    MailSenderInitializerListener.class,
95    MailSenderScriptService.class,
96    StandardEnvironment.class,
97    DefaultMailSender.class,
98    DefaultExecution.class,
99    ContextComponentManagerProvider.class,
100    TextMimeBodyPartFactory.class,
101    MemoryMailListener.class,
102    DefaultSessionFactory.class,
103    SendMailRunnable.class,
104    PrepareMailRunnable.class,
105    PrepareMailQueueManager.class,
106    SendMailQueueManager.class,
107    FileSystemMailContentStore.class
108    })
109    // @formatter:on
 
110    public class ScriptingIntegrationTest extends AbstractMailIntegrationTest
111    {
112    private static final String PERMDIR = "target/" + ScriptingIntegrationTest.class.getSimpleName();
113   
114    @Rule
115    public GreenMailRule mail = new GreenMailRule(getCustomServerSetup(ServerSetupTest.SMTP));
116   
117    @Rule
118    public MockitoComponentManagerRule componentManager = new MockitoComponentManagerRule();
119   
120    private MailSenderScriptService scriptService;
121   
 
122  2 toggle @BeforeComponent
123    public void registerConfiguration() throws Exception
124    {
125  2 MailSenderConfiguration configuration =
126    new TestMailSenderConfiguration(this.mail.getSmtp().getPort(), null, null, new Properties());
127  2 this.componentManager.registerComponent(MailSenderConfiguration.class, configuration);
128   
129    // Register a test Permission Checker that allows sending mails
130  2 ScriptServicePermissionChecker checker = mock(ScriptServicePermissionChecker.class);
131  2 this.componentManager.registerComponent(ScriptServicePermissionChecker.class, "test", checker);
132   
133    // Set the current wiki in the Context
134  2 ModelContext modelContext = this.componentManager.registerMockComponent(ModelContext.class);
135  2 Mockito.when(modelContext.getCurrentEntityReference()).thenReturn(new WikiReference("wiki"));
136   
137  2 Provider<XWikiContext> xwikiContextProvider =
138    this.componentManager.registerMockComponent(XWikiContext.TYPE_PROVIDER);
139  2 when(xwikiContextProvider.get()).thenReturn(Mockito.mock(XWikiContext.class));
140   
141  2 this.componentManager.registerMockComponent(ExecutionContextManager.class);
142  2 this.componentManager.registerMockComponent(new DefaultParameterizedType(null, Copier.class,
143    ExecutionContext.class));
144   
145  2 EnvironmentConfiguration environmentConfiguration =
146    this.componentManager.registerMockComponent(EnvironmentConfiguration.class);
147  2 when(environmentConfiguration.getPermanentDirectoryPath()).thenReturn(PERMDIR);
148   
149  2 this.componentManager.registerMockComponent(ConverterManager.class);
150    }
151   
 
152  2 toggle @Before
153    public void initialize() throws Exception
154    {
155  2 this.scriptService = this.componentManager.getInstance(ScriptService.class, "mailsender");
156   
157    // Set the EC
158  2 Execution execution = this.componentManager.getInstance(Execution.class);
159  2 ExecutionContext executionContext = new ExecutionContext();
160  2 XWikiContext xContext = new XWikiContext();
161  2 xContext.setWikiId("wiki");
162  2 executionContext.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, xContext);
163  2 execution.setContext(executionContext);
164   
165  2 Copier<ExecutionContext> executionContextCloner =
166    this.componentManager.getInstance(new DefaultParameterizedType(null, Copier.class, ExecutionContext.class));
167    // Just return the same execution context
168  2 when(executionContextCloner.copy(executionContext)).thenReturn(executionContext);
169   
170    // Simulate receiving the Application Ready Event to start the mail threads
171  2 MailSenderInitializerListener listener =
172    this.componentManager.getInstance(EventListener.class, MailSenderInitializerListener.LISTENER_NAME);
173  2 listener.onEvent(new ApplicationReadyEvent(), null, null);
174    }
175   
 
176  2 toggle @After
177    public void cleanUp() throws Exception
178    {
179    // Make sure we stop the Mail Sender thread after each test (since it's started automatically when looking
180    // up the MailSender component.
181  2 Disposable listener =
182    this.componentManager.getInstance(EventListener.class, MailSenderInitializerListener.LISTENER_NAME);
183  2 listener.dispose();
184    }
185   
 
186  1 toggle @Test
187    public void sendTextMail() throws Exception
188    {
189  1 ScriptMimeMessage message1 = this.scriptService.createMessage("john@doe.com", "subject");
190  1 message1.addPart("text/plain", "some text here");
191  1 ScriptMimeMessage message2 = this.scriptService.createMessage("john@doe.com", "subject");
192  1 message2.addPart("text/plain", "some text here");
193  1 ScriptMimeMessage message3 = this.scriptService.createMessage("john@doe.com", "subject");
194  1 message3.addPart("text/plain", "some text here");
195   
196    // Send 3 mails (3 times the same mail) to verify we can send several emails at once.
197  1 List<ScriptMimeMessage> messagesList = Arrays.asList(message1, message2, message3);
198  1 ScriptMailResult result = this.scriptService.sendAsynchronously(messagesList, "memory");
199   
200    // Verify that there are no errors
201  1 assertNull(this.scriptService.getLastError());
202   
203    // Wait for all mails to be sent
204  1 result.getStatusResult().waitTillProcessed(30000L);
205  1 assertTrue(result.getStatusResult().isProcessed());
206   
207    // Verify that all mails have been sent properly
208  1 assertFalse("There should not be any failed result!", result.getStatusResult().getByState(MailState.SEND_ERROR)
209    .hasNext());
210  1 assertFalse("There should not be any failed result!", result.getStatusResult().getByState(MailState.PREPARE_ERROR)
211    .hasNext());
212  1 assertFalse("There should not be any mails in the ready state!",
213    result.getStatusResult().getByState(MailState.PREPARE_SUCCESS).hasNext());
214   
215    // Verify that the mails have been received (wait maximum 30 seconds).
216  1 this.mail.waitForIncomingEmail(30000L, 3);
217  1 MimeMessage[] messages = this.mail.getReceivedMessages();
218   
219  1 assertEquals(3, messages.length);
220  1 assertEquals("subject", messages[0].getHeader("Subject", null));
221  1 assertEquals("john@doe.com", messages[0].getHeader("To", null));
222   
223  1 assertEquals(1, ((MimeMultipart) messages[0].getContent()).getCount());
224   
225  1 BodyPart textBodyPart = ((MimeMultipart) messages[0].getContent()).getBodyPart(0);
226  1 assertEquals("text/plain", textBodyPart.getHeader("Content-Type")[0]);
227  1 assertEquals("some text here", textBodyPart.getContent());
228    }
229   
 
230  1 toggle @Test
231    public void sendHTMLAndCalendarInvitationMail() throws Exception
232    {
233  1 ScriptMimeMessage message = this.scriptService.createMessage("john@doe.com", "subject");
234  1 message.addPart("text/html", "<font size=\"\\\"2\\\"\">simple meeting invitation</font>");
235    // @formatter:off
236  1 String calendarContent = "BEGIN:VCALENDAR\r\n"
237    + "METHOD:REQUEST\r\n"
238    + "PRODID: Meeting\r\n"
239    + "VERSION:2.0\r\n"
240    + "BEGIN:VEVENT\r\n"
241    + "DTSTAMP:20140616T164100\r\n"
242    + "DTSTART:20140616T164100\r\n"
243    + "DTEND:20140616T194100\r\n"
244    + "SUMMARY:test request\r\n"
245    + "UID:324\r\n"
246    + "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:MAILTO:john@doe.com\r\n"
247    + "ORGANIZER:MAILTO:john@doe.com\r\n"
248    + "LOCATION:on the net\r\n"
249    + "DESCRIPTION:learn some stuff\r\n"
250    + "SEQUENCE:0\r\n"
251    + "PRIORITY:5\r\n"
252    + "CLASS:PUBLIC\r\n"
253    + "STATUS:CONFIRMED\r\n"
254    + "TRANSP:OPAQUE\r\n"
255    + "BEGIN:VALARM\r\n"
256    + "ACTION:DISPLAY\r\n"
257    + "DESCRIPTION:REMINDER\r\n"
258    + "TRIGGER;RELATED=START:-PT00H15M00S\r\n"
259    + "END:VALARM\r\n"
260    + "END:VEVENT\r\n"
261    + "END:VCALENDAR";
262    // @formatter:on
263  1 message.addPart(
264    "text/calendar;method=CANCEL",
265    calendarContent,
266    Collections.<String, Object>singletonMap("headers",
267    Collections.singletonMap("Content-Class", "urn:content-classes:calendarmessage")));
268   
269  1 ScriptMailResult result = this.scriptService.send(Arrays.asList(message));
270   
271    // Verify that there are no errors and that 1 mail was sent
272  1 assertNull(this.scriptService.getLastError());
273  1 assertTrue(result.getStatusResult().isProcessed());
274  1 assertEquals(1, result.getStatusResult().getProcessedMailCount());
275   
276    // Verify that all mails have been sent properly
277  1 assertFalse("There should not be any failed result!", result.getStatusResult().getByState(MailState.SEND_ERROR)
278    .hasNext());
279  1 assertFalse("There should not be any failed result!",
280    result.getStatusResult().getByState(MailState.PREPARE_ERROR)
281    .hasNext());
282  1 assertFalse("There should not be any mails in the ready state!",
283    result.getStatusResult().getByState(MailState.PREPARE_SUCCESS).hasNext());
284   
285    // Verify that the mail has been received (wait maximum 30 seconds).
286  1 this.mail.waitForIncomingEmail(30000L, 1);
287  1 MimeMessage[] messages = this.mail.getReceivedMessages();
288   
289  1 assertEquals(1, messages.length);
290  1 assertEquals("subject", messages[0].getHeader("Subject", null));
291  1 assertEquals("john@doe.com", messages[0].getHeader("To", null));
292   
293  1 assertEquals(2, ((MimeMultipart) messages[0].getContent()).getCount());
294   
295  1 BodyPart htmlBodyPart = ((MimeMultipart) messages[0].getContent()).getBodyPart(0);
296  1 assertEquals("text/html", htmlBodyPart.getHeader("Content-Type")[0]);
297  1 assertEquals("<font size=\"\\\"2\\\"\">simple meeting invitation</font>", htmlBodyPart.getContent());
298   
299  1 BodyPart calendarBodyPart = ((MimeMultipart) messages[0].getContent()).getBodyPart(1);
300  1 assertEquals("text/calendar;method=CANCEL", calendarBodyPart.getHeader("Content-Type")[0]);
301  1 InputStream is = (InputStream) calendarBodyPart.getContent();
302  1 assertEquals(calendarContent, IOUtils.toString(is));
303    }
304    }