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

File ScriptingIntegrationTest.java

 

Code metrics

0
73
5
1
302
220
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: c54232467870141a570033d768b1100a78ff4497 $
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
111    {
112    @Rule
113    public GreenMailRule mail = new GreenMailRule(ServerSetupTest.SMTP);
114   
115    @Rule
116    public MockitoComponentManagerRule componentManager = new MockitoComponentManagerRule();
117   
118    private MailSenderScriptService scriptService;
119   
 
120  2 toggle @BeforeComponent
121    public void registerConfiguration() throws Exception
122    {
123  2 MailSenderConfiguration configuration =
124    new TestMailSenderConfiguration(this.mail.getSmtp().getPort(), null, null, new Properties());
125  2 this.componentManager.registerComponent(MailSenderConfiguration.class, configuration);
126   
127    // Register a test Permission Checker that allows sending mails
128  2 ScriptServicePermissionChecker checker = mock(ScriptServicePermissionChecker.class);
129  2 this.componentManager.registerComponent(ScriptServicePermissionChecker.class, "test", checker);
130   
131    // Set the current wiki in the Context
132  2 ModelContext modelContext = this.componentManager.registerMockComponent(ModelContext.class);
133  2 Mockito.when(modelContext.getCurrentEntityReference()).thenReturn(new WikiReference("wiki"));
134   
135  2 Provider<XWikiContext> xwikiContextProvider =
136    this.componentManager.registerMockComponent(XWikiContext.TYPE_PROVIDER);
137  2 when(xwikiContextProvider.get()).thenReturn(Mockito.mock(XWikiContext.class));
138   
139  2 this.componentManager.registerMockComponent(ExecutionContextManager.class);
140  2 this.componentManager.registerMockComponent(new DefaultParameterizedType(null, Copier.class,
141    ExecutionContext.class));
142   
143  2 EnvironmentConfiguration environmentConfiguration =
144    this.componentManager.registerMockComponent(EnvironmentConfiguration.class);
145  2 when(environmentConfiguration.getPermanentDirectoryPath()).thenReturn(System.getProperty("java.io.tmpdir"));
146   
147  2 this.componentManager.registerMockComponent(ConverterManager.class);
148    }
149   
 
150  2 toggle @Before
151    public void initialize() throws Exception
152    {
153  2 this.scriptService = this.componentManager.getInstance(ScriptService.class, "mailsender");
154   
155    // Set the EC
156  2 Execution execution = this.componentManager.getInstance(Execution.class);
157  2 ExecutionContext executionContext = new ExecutionContext();
158  2 XWikiContext xContext = new XWikiContext();
159  2 xContext.setWikiId("wiki");
160  2 executionContext.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, xContext);
161  2 execution.setContext(executionContext);
162   
163  2 Copier<ExecutionContext> executionContextCloner =
164    this.componentManager.getInstance(new DefaultParameterizedType(null, Copier.class, ExecutionContext.class));
165    // Just return the same execution context
166  2 when(executionContextCloner.copy(executionContext)).thenReturn(executionContext);
167   
168    // Simulate receiving the Application Ready Event to start the mail threads
169  2 MailSenderInitializerListener listener =
170    this.componentManager.getInstance(EventListener.class, MailSenderInitializerListener.LISTENER_NAME);
171  2 listener.onEvent(new ApplicationReadyEvent(), null, null);
172    }
173   
 
174  2 toggle @After
175    public void cleanUp() throws Exception
176    {
177    // Make sure we stop the Mail Sender thread after each test (since it's started automatically when looking
178    // up the MailSender component.
179  2 Disposable listener =
180    this.componentManager.getInstance(EventListener.class, MailSenderInitializerListener.LISTENER_NAME);
181  2 listener.dispose();
182    }
183   
 
184  1 toggle @Test
185    public void sendTextMail() throws Exception
186    {
187  1 ScriptMimeMessage message1 = this.scriptService.createMessage("john@doe.com", "subject");
188  1 message1.addPart("text/plain", "some text here");
189  1 ScriptMimeMessage message2 = this.scriptService.createMessage("john@doe.com", "subject");
190  1 message2.addPart("text/plain", "some text here");
191  1 ScriptMimeMessage message3 = this.scriptService.createMessage("john@doe.com", "subject");
192  1 message3.addPart("text/plain", "some text here");
193   
194    // Send 3 mails (3 times the same mail) to verify we can send several emails at once.
195  1 List<ScriptMimeMessage> messagesList = Arrays.asList(message1, message2, message3);
196  1 ScriptMailResult result = this.scriptService.sendAsynchronously(messagesList, "memory");
197   
198    // Verify that there are no errors
199  1 assertNull(this.scriptService.getLastError());
200   
201    // Wait for all mails to be sent
202  1 result.getStatusResult().waitTillProcessed(10000L);
203  1 assertTrue(result.getStatusResult().isProcessed());
204   
205    // Verify that all mails have been sent properly
206  1 assertFalse("There should not be any failed result!", result.getStatusResult().getByState(MailState.SEND_ERROR)
207    .hasNext());
208  1 assertFalse("There should not be any failed result!", result.getStatusResult().getByState(MailState.PREPARE_ERROR)
209    .hasNext());
210  1 assertFalse("There should not be any mails in the ready state!",
211    result.getStatusResult().getByState(MailState.PREPARE_SUCCESS).hasNext());
212   
213    // Verify that the mails have been received (wait maximum 10 seconds).
214  1 this.mail.waitForIncomingEmail(10000L, 3);
215  1 MimeMessage[] messages = this.mail.getReceivedMessages();
216   
217  1 assertEquals(3, messages.length);
218  1 assertEquals("subject", messages[0].getHeader("Subject", null));
219  1 assertEquals("john@doe.com", messages[0].getHeader("To", null));
220   
221  1 assertEquals(1, ((MimeMultipart) messages[0].getContent()).getCount());
222   
223  1 BodyPart textBodyPart = ((MimeMultipart) messages[0].getContent()).getBodyPart(0);
224  1 assertEquals("text/plain", textBodyPart.getHeader("Content-Type")[0]);
225  1 assertEquals("some text here", textBodyPart.getContent());
226    }
227   
 
228  1 toggle @Test
229    public void sendHTMLAndCalendarInvitationMail() throws Exception
230    {
231  1 ScriptMimeMessage message = this.scriptService.createMessage("john@doe.com", "subject");
232  1 message.addPart("text/html", "<font size=\"\\\"2\\\"\">simple meeting invitation</font>");
233    // @formatter:off
234  1 String calendarContent = "BEGIN:VCALENDAR\r\n"
235    + "METHOD:REQUEST\r\n"
236    + "PRODID: Meeting\r\n"
237    + "VERSION:2.0\r\n"
238    + "BEGIN:VEVENT\r\n"
239    + "DTSTAMP:20140616T164100\r\n"
240    + "DTSTART:20140616T164100\r\n"
241    + "DTEND:20140616T194100\r\n"
242    + "SUMMARY:test request\r\n"
243    + "UID:324\r\n"
244    + "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:MAILTO:john@doe.com\r\n"
245    + "ORGANIZER:MAILTO:john@doe.com\r\n"
246    + "LOCATION:on the net\r\n"
247    + "DESCRIPTION:learn some stuff\r\n"
248    + "SEQUENCE:0\r\n"
249    + "PRIORITY:5\r\n"
250    + "CLASS:PUBLIC\r\n"
251    + "STATUS:CONFIRMED\r\n"
252    + "TRANSP:OPAQUE\r\n"
253    + "BEGIN:VALARM\r\n"
254    + "ACTION:DISPLAY\r\n"
255    + "DESCRIPTION:REMINDER\r\n"
256    + "TRIGGER;RELATED=START:-PT00H15M00S\r\n"
257    + "END:VALARM\r\n"
258    + "END:VEVENT\r\n"
259    + "END:VCALENDAR";
260    // @formatter:on
261  1 message.addPart(
262    "text/calendar;method=CANCEL",
263    calendarContent,
264    Collections.<String, Object>singletonMap("headers",
265    Collections.singletonMap("Content-Class", "urn:content-classes:calendarmessage")));
266   
267  1 ScriptMailResult result = this.scriptService.send(Arrays.asList(message));
268   
269    // Verify that there are no errors and that 1 mail was sent
270  1 assertNull(this.scriptService.getLastError());
271  1 assertTrue(result.getStatusResult().isProcessed());
272  1 assertEquals(1, result.getStatusResult().getProcessedMailCount());
273   
274    // Verify that all mails have been sent properly
275  1 assertFalse("There should not be any failed result!", result.getStatusResult().getByState(MailState.SEND_ERROR)
276    .hasNext());
277  1 assertFalse("There should not be any failed result!",
278    result.getStatusResult().getByState(MailState.PREPARE_ERROR)
279    .hasNext());
280  1 assertFalse("There should not be any mails in the ready state!",
281    result.getStatusResult().getByState(MailState.PREPARE_SUCCESS).hasNext());
282   
283    // Verify that the mail has been received (wait maximum 10 seconds).
284  1 this.mail.waitForIncomingEmail(10000L, 1);
285  1 MimeMessage[] messages = this.mail.getReceivedMessages();
286   
287  1 assertEquals(1, messages.length);
288  1 assertEquals("subject", messages[0].getHeader("Subject", null));
289  1 assertEquals("john@doe.com", messages[0].getHeader("To", null));
290   
291  1 assertEquals(2, ((MimeMultipart) messages[0].getContent()).getCount());
292   
293  1 BodyPart htmlBodyPart = ((MimeMultipart) messages[0].getContent()).getBodyPart(0);
294  1 assertEquals("text/html", htmlBodyPart.getHeader("Content-Type")[0]);
295  1 assertEquals("<font size=\"\\\"2\\\"\">simple meeting invitation</font>", htmlBodyPart.getContent());
296   
297  1 BodyPart calendarBodyPart = ((MimeMultipart) messages[0].getContent()).getBodyPart(1);
298  1 assertEquals("text/calendar;method=CANCEL", calendarBodyPart.getHeader("Content-Type")[0]);
299  1 InputStream is = (InputStream) calendarBodyPart.getContent();
300  1 assertEquals(calendarContent, IOUtils.toString(is));
301    }
302    }