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

File MailTest.java

 
testMail: Timed out after 10 seconds waiting for org.xwiki.test.ui....
 

Code metrics

12
84
7
1
338
215
13
0.15
12
7
1.86

Classes

Class Line # Actions
MailTest 54 84 0% 13 96
0.0679611646.8%
 

Contributing tests

This file is covered by 1 test. .

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.test.ui;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.ByteArrayOutputStream;
24    import java.util.ArrayList;
25    import java.util.List;
26   
27    import javax.mail.internet.MimeMessage;
28   
29    import org.apache.commons.httpclient.UsernamePasswordCredentials;
30    import org.junit.After;
31    import org.junit.Assert;
32    import org.junit.Before;
33    import org.junit.Rule;
34    import org.junit.Test;
35    import org.xwiki.administration.test.po.AdministrationPage;
36    import org.xwiki.mail.test.po.MailStatusAdministrationSectionPage;
37    import org.xwiki.mail.test.po.SendMailAdministrationSectionPage;
38    import org.xwiki.test.ui.AbstractTest;
39    import org.xwiki.test.ui.SuperAdminAuthenticationRule;
40    import org.xwiki.test.ui.po.LiveTableElement;
41    import org.xwiki.test.ui.po.ViewPage;
42   
43    import com.icegreen.greenmail.util.GreenMail;
44    import com.icegreen.greenmail.util.ServerSetupTest;
45   
46    import static org.junit.Assert.*;
47   
48    /**
49    * UI tests for the Mail application.
50    *
51    * @version $Id: a82b6035947dd6fc1d4b4e152c9884fe8381daa5 $
52    * @since 6.4M2
53    */
 
54    public class MailTest extends AbstractTest
55    {
56    @Rule
57    public SuperAdminAuthenticationRule authenticationRule = new SuperAdminAuthenticationRule(getUtil());
58   
59    private GreenMail mail;
60   
61    private List<String> alreadyAssertedMessages = new ArrayList<>();
62   
 
63  1 toggle @Before
64    public void startMail()
65    {
66  1 this.mail = new GreenMail(ServerSetupTest.SMTP);
67  1 this.mail.start();
68    }
69   
 
70  1 toggle @After
71    public void stopMail()
72    {
73  1 if (this.mail != null) {
74  1 this.mail.stop();
75    }
76    }
77   
 
78  0 toggle @Test
79    public void testMail() throws Exception
80    {
81    // Step 1: Verify that there are 2 email sections in the Email category
82   
83  0 AdministrationPage wikiAdministrationPage = AdministrationPage.gotoPage();
84   
85  0 Assert.assertTrue(wikiAdministrationPage.hasSection("Email", "General"));
86  0 Assert.assertTrue(wikiAdministrationPage.hasSection("Email", "Mail Sending"));
87   
88    // Verify we can click on Email > General
89  0 wikiAdministrationPage.clickSection("Email", "General");
90   
91    // Step 2: Before validating that we can send email, let's verify that we can report errors when the mail
92    // setup is not correct
93   
94    // Make sure there's an invalid mail server set.
95  0 wikiAdministrationPage.clickSection("Email", "Mail Sending");
96  0 SendMailAdministrationSectionPage sendMailPage = new SendMailAdministrationSectionPage();
97  0 sendMailPage.setHost("invalidmailserver");
98  0 sendMailPage.clickSave();
99   
100    // Send the mail that's supposed to fail and validate that it fails
101  0 sendMailWithInvalidMailSetup();
102   
103    // Step 3: Navigate to each mail section and set the mail sending parameters (SMTP host/port)
104  0 wikiAdministrationPage = AdministrationPage.gotoPage();
105  0 wikiAdministrationPage.clickSection("Email", "Mail Sending");
106  0 sendMailPage = new SendMailAdministrationSectionPage();
107  0 sendMailPage.setHost("localhost");
108  0 sendMailPage.setPort("3025");
109    // Make sure we don't wait between email sending in order to speed up the test (and not incur timeouts when
110    // we wait to receive the mails)
111  0 sendMailPage.setSendWaitTime("0");
112    // Keep all mail statuses including successful ones (so that we verify this works fine)
113  0 sendMailPage.setDiscardSuccessStatuses(false);
114  0 sendMailPage.clickSave();
115   
116    // Step 3: Verify that there are no admin email sections when administering a space
117   
118    // Select XWiki space administration.
119  0 AdministrationPage spaceAdministrationPage = AdministrationPage.gotoSpaceAdministrationPage("XWiki");
120   
121    // All those sections should not be present
122  0 Assert.assertTrue(spaceAdministrationPage.hasNotSection("Email", "General"));
123  0 Assert.assertTrue(spaceAdministrationPage.hasNotSection("Email", "Mail Sending"));
124   
125    // Step 4: Prepare a Template Mail
126  0 getUtil().deletePage(getTestClassName(), "MailTemplate");
127   
128    // Create a Wiki page containing a Mail Template (ie a XWiki.Mail object)
129  0 getUtil().createPage(getTestClassName(), "MailTemplate", "", "");
130    // Note: We use the following bindings in the Template subject and content so that we ensure that they are
131    // provided by default:
132    // - "$xwiki"
133    // - "$xcontext"
134    // - "$escapetool"
135    // - "$services"
136    // - "$request"
137    // Note: We also use the $name and $doc bindings to show that the user can add new bindings ($doc is not bound
138    // by default since there isn't always a notion of current doc in all places where mail sending is done).
139  0 String velocityContent = "Hello $name from $escapetool.xml($services.model.resolveDocument("
140    + "$xcontext.getUser()).getName()) - Served from $request.getRequestURL().toString()";
141  0 getUtil().addObject(getTestClassName(), "MailTemplate", "XWiki.Mail",
142    "subject", "#if ($xwiki.exists($doc.documentReference))Status for $name on $doc.fullName#{else}wrong#end",
143    "language", "en",
144    "html", "<strong>" + velocityContent + "</strong>",
145    "text", velocityContent);
146    // We also add an attachment to the Mail Template page to verify that it is sent in the mail
147  0 ByteArrayInputStream bais = new ByteArrayInputStream("Content of attachment".getBytes());
148  0 getUtil().attachFile(getTestClassName(), "MailTemplate", "something.txt", bais, true,
149    new UsernamePasswordCredentials("superadmin", "pass"));
150   
151    // Step 5: Send a template email (with an attachment) to a single email address
152  0 sendTemplateMailToEmail();
153   
154    // Step 6: Send a template email to all the users in the XWikiAllGroup Group (we'll create 2 users) + to
155    // two other users (however since they're part of the group they'll receive only one mail each, we thus test
156    // deduplicatio!).
157  0 sendTemplateMailToUsersAndGroup();
158   
159    // Step 7: Navigate to the Mail Sending Status Admin page and assert that the Livetable displays the entry for
160    // the sent mails
161  0 wikiAdministrationPage = AdministrationPage.gotoPage();
162  0 wikiAdministrationPage.clickSection("Email", "Mail Sending Status");
163  0 MailStatusAdministrationSectionPage statusPage = new MailStatusAdministrationSectionPage();
164  0 LiveTableElement liveTableElement = statusPage.getLiveTable();
165  0 liveTableElement.filterColumn("xwiki-livetable-sendmailstatus-filter-3", "Test");
166  0 liveTableElement.filterColumn("xwiki-livetable-sendmailstatus-filter-5", "send_success");
167  0 liveTableElement.filterColumn("xwiki-livetable-sendmailstatus-filter-6", "xwiki");
168   
169    // Let's wait till we have at least 3 rows. Note that we wait because we could have received the mails above
170    // but the mail status in the database may not have been updated yet.
171  0 Test failure here liveTableElement.waitUntilRowCountGreaterThan(3);
172   
173  0 liveTableElement.filterColumn("xwiki-livetable-sendmailstatus-filter-4", "john@doe.com");
174  0 assertTrue(liveTableElement.getRowCount() > 0);
175  0 assertTrue(liveTableElement.hasRow("Error", ""));
176    }
177   
 
178  0 toggle private void sendMailWithInvalidMailSetup() throws Exception
179    {
180    // Remove existing pages (for pages that we create below)
181  0 getUtil().deletePage(getTestClassName(), "SendInvalidMail");
182   
183    // Create a page with the Velocity script to send the template email.
184    // Note that we don't set the type and thus this message should not appear in the LiveTable filter at the end
185    // of the test.
186  0 String velocity = "{{velocity}}\n"
187    + "#set ($message = $services.mailsender.createMessage('from@doe.com', 'to@doe.com', 'Subject'))\n"
188    + "#set ($discard = $message.addPart('text/plain', 'text message'))\n"
189    + "#set ($result = $services.mailsender.send([$message], 'database'))\n"
190    + "#foreach ($status in $result.statusResult.getAllErrors())\n"
191    + " MSGID $status.messageId SUMMARY $status.errorSummary DESCRIPTION $status.errorDescription\n"
192    + "#end\n"
193    + "{{/velocity}}";
194    // This will create the page and execute its content and thus send the mail
195  0 ViewPage vp = getUtil().createPage(getTestClassName(), "SendInvalidMail", velocity, "");
196   
197    // Verify that the page is not empty (and thus an error message is displayed). Note that it's difficult to
198    // asssert what is displayed because it could vary from system to system. This is why we only assert that
199    // something is displayed and that it matches the defined pattern.
200  0 assertTrue(vp.getContent().matches("(?s)MSGID.*SUMMARY.*DESCRIPTION.*"));
201    }
202   
 
203  0 toggle private void sendTemplateMailToEmail() throws Exception
204    {
205    // Remove existing pages (for pages that we create below)
206  0 getUtil().deletePage(getTestClassName(), "SendMail");
207   
208    // Create another page with the Velocity script to send the template email
209    // Note that we didn't need to bind the "$doc" velocity variable because the send is done synchronously and
210    // thus the current XWiki Context is cloned before being passed to the template evaluation, and thus it
211    // already contains the "$doc" binding!
212  0 String velocity = "{{velocity}}\n"
213    + "#set ($templateReference = $services.model.createDocumentReference('', '" + getTestClassName()
214    + "', 'MailTemplate'))\n"
215    + "#set ($parameters = {'velocityVariables' : { 'name' : 'John' }, 'language' : 'en', "
216    + "'includeTemplateAttachments' : true})\n"
217    + "#set ($message = $services.mailsender.createMessage('template', $templateReference, $parameters))\n"
218    + "#set ($discard = $message.setFrom('localhost@xwiki.org'))\n"
219    + "#set ($discard = $message.addRecipients('to', 'john@doe.com'))\n"
220    + "#set ($discard = $message.setType('Test'))\n"
221    + "#set ($result = $services.mailsender.send([$message], 'database'))\n"
222    + "#if ($services.mailsender.lastError)\n"
223    + " {{error}}$exceptiontool.getStackTrace($services.mailsender.lastError){{/error}}\n"
224    + "#end\n"
225    + "#foreach ($status in $result.statusResult.getByState('SEND_ERROR'))\n"
226    + " {{error}}\n"
227    + " $status.messageId - $status.errorSummary\n"
228    + " $status.errorDescription\n"
229    + " {{/error}}\n"
230    + "#end\n"
231    + "{{/velocity}}";
232    // This will create the page and execute its content and thus send the mail
233  0 ViewPage vp = getUtil().createPage(getTestClassName(), "SendMail", velocity, "");
234   
235    // Verify that the page doesn't display any content (unless there's an error!)
236  0 assertEquals("", vp.getContent());
237   
238    // Verify that the mail has been received.
239  0 this.mail.waitForIncomingEmail(10000L, 1);
240  0 assertEquals(1, this.mail.getReceivedMessages().length);
241  0 assertReceivedMessages(1,
242    "Subject: Status for John on " + getTestClassName() + ".SendMail",
243    "Hello John from superadmin - Served from http://localhost:8080/xwiki/bin/view/MailTest/SendMail",
244    "<strong>Hello John from superadmin - Served from "
245    + "http://localhost:8080/xwiki/bin/view/MailTest/SendMail</strong>",
246    "X-MailType: Test",
247    "Content-Type: text/plain; name=something.txt",
248    "Content-ID: <something.txt>",
249    "Content-Disposition: attachment; filename=something.txt",
250    "Content of attachment");
251    }
252   
 
253  0 toggle private void sendTemplateMailToUsersAndGroup() throws Exception
254    {
255    // Remove existing pages (for pages that we create below)
256  0 getUtil().deletePage(getTestClassName(), "SendMailGroupAndUsers");
257   
258    // Create 2 users
259  0 getUtil().createUser("user1", "password1", getUtil().getURLToNonExistentPage(), "email", "user1@doe.com");
260  0 getUtil().createUser("user2", "password2", getUtil().getURLToNonExistentPage(), "email", "user2@doe.com");
261   
262    // Create another page with the Velocity script to send the template email
263    // Note: the $xcontext and $request bindings are present and have their values at the moment the call to send
264    // the mail asynchronously was done.
265  0 String velocity = "{{velocity}}\n"
266    + "#set ($templateParameters = "
267    + " {'velocityVariables' : { 'name' : 'John', 'doc' : $doc }, "
268    + " 'language' : 'en', 'from' : 'localhost@xwiki.org'})\n"
269    + "#set ($templateReference = $services.model.createDocumentReference('', '" + getTestClassName()
270    + "', 'MailTemplate'))\n"
271    + "#set ($parameters = {'hint' : 'template', 'source' : $templateReference, "
272    + "'parameters' : $templateParameters, 'type' : 'Test'})\n"
273    + "#set ($groupReference = $services.model.createDocumentReference('', 'XWiki', 'XWikiAllGroup'))\n"
274    + "#set ($user1Reference = $services.model.createDocumentReference('', 'XWiki', 'user1'))\n"
275    + "#set ($user2Reference = $services.model.createDocumentReference('', 'XWiki', 'user2'))\n"
276    + "#set ($source = {'groups' : [$groupReference], 'users' : [$user1Reference, $user2Reference]})\n"
277    + "#set ($messages = $services.mailsender.createMessages('usersandgroups', $source, $parameters))\n"
278    + "#set ($result = $services.mailsender.send($messages, 'database'))\n"
279    + "#if ($services.mailsender.lastError)\n"
280    + " {{error}}$exceptiontool.getStackTrace($services.mailsender.lastError){{/error}}\n"
281    + "#end\n"
282    + "#foreach ($status in $result.statusResult.getByState('SEND_ERROR'))\n"
283    + " {{error}}\n"
284    + " $status.messageId - $status.errorSummary\n"
285    + " $status.errorDescription\n"
286    + " {{/error}}\n"
287    + "#end\n"
288    + "{{/velocity}}";
289    // This will create the page and execute its content and thus send the mail
290  0 ViewPage vp = getUtil().createPage(getTestClassName(), "SendMailGroupAndUsers", velocity, "");
291   
292    // Verify that the page doesn't display any content (unless there's an error!)
293  0 assertEquals("", vp.getContent());
294   
295    // Verify that the mails have been received (first mail above + the 2 mails sent to the group)
296  0 this.mail.waitForIncomingEmail(10000L, 3);
297  0 assertEquals(3, this.mail.getReceivedMessages().length);
298  0 assertReceivedMessages(2,
299    "Subject: Status for John on " + getTestClassName() + ".SendMailGroupAndUsers",
300    "Hello John from superadmin - Served from "
301    + "http://localhost:8080/xwiki/bin/view/MailTest/SendMailGroupAndUsers");
302    }
303   
 
304  0 toggle private void assertReceivedMessages(int expectedMatchingCount, String... expectedLines)
305    throws Exception
306    {
307  0 StringBuilder builder = new StringBuilder();
308  0 int count = 0;
309  0 for (MimeMessage message : this.mail.getReceivedMessages()) {
310  0 if (this.alreadyAssertedMessages.contains(message.getMessageID())) {
311  0 continue;
312    }
313  0 ByteArrayOutputStream baos = new ByteArrayOutputStream();
314  0 message.writeTo(baos);
315  0 String fullContent = baos.toString();
316  0 boolean match = true;
317  0 for (int i = 0; i < expectedLines.length; i++) {
318  0 if (!fullContent.contains(expectedLines[i])) {
319  0 match = false;
320  0 break;
321    }
322    }
323  0 if (!match) {
324  0 builder.append("- Content [" + fullContent + "]").append('\n');
325    } else {
326  0 count++;
327    }
328  0 this.alreadyAssertedMessages.add(message.getMessageID());
329    }
330  0 StringBuilder expected = new StringBuilder();
331  0 for (int i = 0; i < expectedLines.length; i++) {
332  0 expected.append("- '" + expectedLines[i] + "'").append('\n');
333    }
334  0 assertEquals(String.format("We got [%s] mails matching the expected content instead of [%s]. We were expecting "
335    + "the following content:\n%s\nWe got the following:\n%s", count, expectedMatchingCount,
336    expected.toString(), builder.toString()), expectedMatchingCount, count);
337    }
338    }