Changing an email needs to be confirmed by receiving an email and responding to an URL send inside it
1.1 --- a/freemarkerdor/pom.xml Tue Mar 02 17:09:06 2010 +0100
1.2 +++ b/freemarkerdor/pom.xml Thu Mar 04 19:37:58 2010 +0100
1.3 @@ -13,6 +13,11 @@
1.4 <url>http://maven.apache.org</url>
1.5 <dependencies>
1.6 <dependency>
1.7 + <groupId>javax.mail</groupId>
1.8 + <artifactId>mail</artifactId>
1.9 + <version>1.4.1</version>
1.10 + </dependency>
1.11 + <dependency>
1.12 <groupId>${project.groupId}</groupId>
1.13 <artifactId>webidor</artifactId>
1.14 <version>${webidorVersion}</version>
1.15 @@ -66,6 +71,12 @@
1.16 <scope>test</scope>
1.17 </dependency>
1.18 <dependency>
1.19 + <groupId>org.netbeans.api</groupId>
1.20 + <artifactId>org-netbeans-modules-nbjunit</artifactId>
1.21 + <version>RELEASE65</version>
1.22 + <scope>test</scope>
1.23 + </dependency>
1.24 + <dependency>
1.25 <groupId>freemarker</groupId>
1.26 <artifactId>freemarker</artifactId>
1.27 <version>2.3.8</version>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/EmailService.java Thu Mar 04 19:37:58 2010 +0100
2.3 @@ -0,0 +1,88 @@
2.4 +/*
2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2.6 + *
2.7 + * The contents of this file are subject to the terms of either the GNU
2.8 + * General Public License Version 2 only ("GPL") or the Common
2.9 + * Development and Distribution License("CDDL") (collectively, the
2.10 + * "License"). You may not use this file except in compliance with the
2.11 + * License. You can obtain a copy of the License at
2.12 + * http://www.netbeans.org/cddl-gplv2.html
2.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
2.14 + * specific language governing permissions and limitations under the
2.15 + * License. When distributing the software, include this License Header
2.16 + * Notice in each file and include the License file at
2.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
2.18 + * particular file as subject to the "Classpath" exception as provided
2.19 + * by Sun in the GPL Version 2 section of the License file that
2.20 + * accompanied this code. If applicable, add the following below the
2.21 + * License Header, with the fields enclosed by brackets [] replaced by
2.22 + * your own identifying information:
2.23 + * "Portions Copyrighted [year] [name of copyright owner]"
2.24 + *
2.25 + * Contributor(s):
2.26 + *
2.27 + * Portions Copyrighted 2009 Jaroslav Tulach
2.28 + */
2.29 +
2.30 +package cz.xelfi.quoridor.freemarkerdor;
2.31 +
2.32 +import java.io.IOException;
2.33 +import java.util.Iterator;
2.34 +import java.util.Properties;
2.35 +import java.util.ServiceLoader;
2.36 +import javax.mail.Message;
2.37 +import javax.mail.MessagingException;
2.38 +import javax.mail.Session;
2.39 +import javax.mail.Transport;
2.40 +import javax.mail.internet.InternetAddress;
2.41 +import javax.mail.internet.MimeMessage;
2.42 +import org.openide.util.Exceptions;
2.43 +
2.44 +/** Send emails.
2.45 + *
2.46 + * @author Jaroslav Tulach <jtulach@netbeans.org>
2.47 + */
2.48 +public abstract class EmailService {
2.49 + private static EmailService DEFAULT;
2.50 +
2.51 + public abstract void sendEmail(
2.52 + String address,
2.53 + String subject,
2.54 + String text
2.55 + ) throws IOException;
2.56 +
2.57 + public static synchronized EmailService getDefault() {
2.58 + if (DEFAULT == null) {
2.59 + Iterator<EmailService> it = ServiceLoader.load(EmailService.class).iterator();
2.60 + DEFAULT = it.hasNext() ? it.next() : new Impl();
2.61 + }
2.62 + return DEFAULT;
2.63 + }
2.64 +
2.65 + private static class Impl extends EmailService {
2.66 + private final Session session;
2.67 + public Impl() {
2.68 + Properties props = System.getProperties();
2.69 + final String host = "mail.smtp.host";
2.70 + if (props.get(host) == null) {
2.71 + props.put(host,"localhost");
2.72 + }
2.73 + session = Session.getDefaultInstance(props, null);
2.74 + }
2.75 +
2.76 + @Override
2.77 + public void sendEmail(String address, String subject, String text) throws IOException {
2.78 + try {
2.79 + MimeMessage message = new MimeMessage(session);
2.80 + message.setFrom(new InternetAddress("quoridor@xelfi.cz"));
2.81 + message.addRecipient(Message.RecipientType.TO, new InternetAddress(address));
2.82 + message.setSubject(subject);
2.83 + message.setText(text);
2.84 + Transport.send(message);
2.85 + } catch (MessagingException ex) {
2.86 + throw new IOException(ex);
2.87 + }
2.88 +
2.89 + }
2.90 + }
2.91 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/Requests.java Thu Mar 04 19:37:58 2010 +0100
3.3 @@ -0,0 +1,81 @@
3.4 +/*
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 + *
3.7 + * The contents of this file are subject to the terms of either the GNU
3.8 + * General Public License Version 2 only ("GPL") or the Common
3.9 + * Development and Distribution License("CDDL") (collectively, the
3.10 + * "License"). You may not use this file except in compliance with the
3.11 + * License. You can obtain a copy of the License at
3.12 + * http://www.netbeans.org/cddl-gplv2.html
3.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.14 + * specific language governing permissions and limitations under the
3.15 + * License. When distributing the software, include this License Header
3.16 + * Notice in each file and include the License file at
3.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
3.18 + * particular file as subject to the "Classpath" exception as provided
3.19 + * by Sun in the GPL Version 2 section of the License file that
3.20 + * accompanied this code. If applicable, add the following below the
3.21 + * License Header, with the fields enclosed by brackets [] replaced by
3.22 + * your own identifying information:
3.23 + * "Portions Copyrighted [year] [name of copyright owner]"
3.24 + *
3.25 + * Contributor(s):
3.26 + *
3.27 + * Portions Copyrighted 2009 Jaroslav Tulach
3.28 + */
3.29 +
3.30 +package cz.xelfi.quoridor.freemarkerdor;
3.31 +
3.32 +import com.sun.jersey.api.client.WebResource;
3.33 +import com.sun.jersey.api.client.WebResource.Builder;
3.34 +import java.net.URI;
3.35 +import java.util.HashMap;
3.36 +import java.util.Map;
3.37 +import java.util.UUID;
3.38 +import javax.ws.rs.GET;
3.39 +import javax.ws.rs.Path;
3.40 +import javax.ws.rs.PathParam;
3.41 +import javax.ws.rs.Produces;
3.42 +import javax.ws.rs.core.Cookie;
3.43 +import javax.ws.rs.core.MediaType;
3.44 +import javax.ws.rs.core.Response;
3.45 +
3.46 +/** Keeps "requests". A request is UUID that maps to a URL which can
3.47 + * be executed later.
3.48 + *
3.49 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.50 + */
3.51 +public final class Requests extends Object {
3.52 + private final Map<UUID,Builder> requests = new HashMap<UUID, Builder>();
3.53 + private final WebResource root;
3.54 +
3.55 + Requests(WebResource path) {
3.56 + root = path;
3.57 + }
3.58 +
3.59 + @GET
3.60 + @Path("{id}")
3.61 + @Produces(MediaType.TEXT_HTML)
3.62 + public Response redirect(@PathParam("id") String uuid) {
3.63 + UUID r = UUID.fromString(uuid);
3.64 + Builder web = requests.get(r);
3.65 + if (web == null) {
3.66 + return Response.status(Response.Status.NOT_FOUND).build();
3.67 + }
3.68 + return Response.ok(web.get(String.class)).build();
3.69 + }
3.70 +
3.71 + boolean isVerified(String uuid) {
3.72 + return uuid != null && requests.containsKey(UUID.fromString(uuid));
3.73 + }
3.74 +
3.75 + URI register(String login, WebResource request) {
3.76 + UUID uuid = UUID.randomUUID();
3.77 + WebResource callback = root.path(uuid.toString());
3.78 + Builder builder = request.queryParam("verified", uuid.toString()).
3.79 + cookie(Cookie.valueOf("login=" + login));
3.80 + requests.put(uuid, builder);
3.81 + return callback.getURI();
3.82 + }
3.83 +
3.84 +}
4.1 --- a/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java Tue Mar 02 17:09:06 2010 +0100
4.2 +++ b/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java Thu Mar 04 19:37:58 2010 +0100
4.3 @@ -40,6 +40,7 @@
4.4 import java.io.InputStream;
4.5 import java.io.StringWriter;
4.6 import java.net.URI;
4.7 +import java.text.MessageFormat;
4.8 import java.util.Date;
4.9 import java.util.HashMap;
4.10 import java.util.List;
4.11 @@ -89,6 +90,8 @@
4.12 }
4.13 private static WebResource base;
4.14 private static WebResource stat;
4.15 + private static WebResource web;
4.16 + private static Requests requests;
4.17
4.18 @Context
4.19 private HttpHeaders headers;
4.20 @@ -98,10 +101,17 @@
4.21 public UI() {
4.22 }
4.23
4.24 - private Viewable checkLogin() {
4.25 + private String login() {
4.26 Cookie cookie = headers.getCookies().get("login");
4.27 if (cookie != null) {
4.28 - String id = cookie.getValue();
4.29 + return cookie.getValue();
4.30 + }
4.31 + return null;
4.32 + }
4.33 +
4.34 + private Viewable checkLogin() {
4.35 + String id = login();
4.36 + if (id != null) {
4.37 UserInfo us;
4.38 try {
4.39 us = base.path("users").queryParam("loginID", id).
4.40 @@ -342,23 +352,45 @@
4.41 return viewable("index.fmt", got, args);
4.42 }
4.43
4.44 + @Path("requests")
4.45 + public Requests getRequests() {
4.46 + if (requests == null) {
4.47 + requests = new Requests(web.path("requests"));
4.48 + }
4.49 + return requests;
4.50 + }
4.51 +
4.52
4.53 @GET
4.54 @Path("options")
4.55 public Response changeOptions(
4.56 @QueryParam("email") String email,
4.57 - @QueryParam("language") String language
4.58 - ) {
4.59 + @QueryParam("language") String language,
4.60 + @QueryParam("verified") String verified
4.61 + ) throws IOException {
4.62 Viewable v = checkLogin();
4.63 if (v != null) {
4.64 return Response.status(Response.Status.FORBIDDEN).entity(v).build();
4.65 }
4.66
4.67 if (email != null) {
4.68 - UserInfo ui = base.path("users/" + user.getId()).
4.69 - queryParam("loginID", uuid).
4.70 - queryParam("name", "email").
4.71 - queryParam("value", email).accept(MediaType.TEXT_XML).post(UserInfo.class);
4.72 + if (getRequests().isVerified(verified)) {
4.73 + UserInfo ui = base.path("users/" + user.getId()).
4.74 + queryParam("loginID", uuid).
4.75 + queryParam("name", "email").
4.76 + queryParam("value", email).accept(MediaType.TEXT_XML).post(UserInfo.class);
4.77 + } else {
4.78 + WebResource request;
4.79 + request = web.path("options").queryParam("name", "email").queryParam("email", email);
4.80 + URI callback = getRequests().register(login(), request);
4.81 +
4.82 + ResourceBundle rb = bundle(null);
4.83 + String subject = rb.getString("MSG_ChangeEmailSubject");
4.84 + String text = MessageFormat.format(rb.getString("MSG_ChangeEmailText"), user.getId(), callback);
4.85 + EmailService.getDefault().sendEmail(email, subject, text);
4.86 + return Response.ok(viewable("email.fmt", null)).build();
4.87 +
4.88 + }
4.89 }
4.90
4.91 if (language != null) {
4.92 @@ -490,6 +522,8 @@
4.93
4.94 final String baseUri = "http://localhost:" + port + "/";
4.95 final HttpServer server = HttpServerFactory.create(baseUri, rc);
4.96 + Client c3 = new Client();
4.97 + web = c3.resource(baseUri);
4.98 server.start();
4.99 System.out.println("Quoridor started at port " + port);
4.100
4.101 @@ -504,24 +538,27 @@
4.102 };
4.103 }
4.104
4.105 - private Viewable viewable(String page, Document doc, Object... more) {
4.106 + private ResourceBundle bundle(Locale[] locale) {
4.107 ResourceBundle rb = null;
4.108 String lng = user == null ? null : user.getProperty("language"); // NOI18N
4.109 - Locale locale = null;
4.110 if (lng != null) {
4.111 - try {
4.112 - Locale l = new Locale(lng);
4.113 - rb = ResourceBundle.getBundle("cz.xelfi.quoridor.freemarkerdor.UI.Bundle", l);
4.114 - locale = l;
4.115 - } catch (MissingResourceException e) {
4.116 - // OK
4.117 + try {
4.118 + Locale l = new Locale(lng);
4.119 + rb = ResourceBundle.getBundle("cz.xelfi.quoridor.freemarkerdor.UI.Bundle", l);
4.120 + if (locale != null) {
4.121 + locale[0] = l;
4.122 }
4.123 + } catch (MissingResourceException e) {
4.124 + // OK
4.125 + }
4.126 }
4.127 if (rb == null) {
4.128 for (Locale l : headers.getAcceptableLanguages()) {
4.129 try {
4.130 rb = ResourceBundle.getBundle("cz.xelfi.quoridor.freemarkerdor.UI.Bundle", l);
4.131 - locale = l;
4.132 + if (locale != null) {
4.133 + locale[0] = l;
4.134 + }
4.135 break;
4.136 } catch (MissingResourceException e) {
4.137 // OK
4.138 @@ -530,8 +567,16 @@
4.139 }
4.140 if (rb == null) {
4.141 rb = ResourceBundle.getBundle("cz.xelfi.quoridor.freemarkerdor.UI.Bundle", Locale.ENGLISH);
4.142 - locale = Locale.ENGLISH;
4.143 + if (locale != null) {
4.144 + locale[0] = Locale.ENGLISH;
4.145 + }
4.146 }
4.147 + return rb;
4.148 + }
4.149 +
4.150 + private Viewable viewable(String page, Document doc, Object... more) {
4.151 + Locale[] locale = new Locale[1];
4.152 + ResourceBundle rb = bundle(locale);
4.153
4.154 Map<String,Object> map = new HashMap<String,Object>();
4.155 class ConvertToDate extends HashMap<Object,Object> {
4.156 @@ -542,7 +587,7 @@
4.157 }
4.158 }
4.159
4.160 - map.put("locale", locale.toString());
4.161 + map.put("locale", locale[0].toString());
4.162 map.put("doc", doc);
4.163 if (user != null) {
4.164 map.put("user", user.getId());
5.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/Bundle.properties Tue Mar 02 17:09:06 2010 +0100
5.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/Bundle.properties Thu Mar 04 19:37:58 2010 +0100
5.3 @@ -85,3 +85,17 @@
5.4 OPENINGS=Openings
5.5 WHITE_WON=White won
5.6 BLACK_WON=Black won
5.7 +
5.8 +MSG_ChangeEmailSubject=Quoridor Email Change
5.9 +# {0} user id
5.10 +# {1} request URL
5.11 +MSG_ChangeEmailText=Dear Quoridor user!\n\
5.12 + User {0} have requested change in email settings.\n\
5.13 + \n\
5.14 + To confirm change of the email address, please visit\n\
5.15 + following link {1}\n\
5.16 + \n\
5.17 + Thank you for playing Quoridor!
5.18 +EMAIL_SENT=Email Sent
5.19 +EMAIL_SENT_TO=Email Sent to {0}
5.20 +EMAIL_BACK=Return to games...
5.21 \ No newline at end of file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/email.fmt Thu Mar 04 19:37:58 2010 +0100
6.3 @@ -0,0 +1,16 @@
6.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
6.5 +<html>
6.6 + <head>
6.7 + <title>${bundle.EMAIL_SENT}</title>
6.8 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6.9 + </head>
6.10 + <body bgcolor="white">
6.11 + <h3><a href="/">${bundle("EMAIL_SENT_TO", user)}</a></h3>
6.12 +
6.13 + <a href="/">${bundle.EMAIL_BACK}</a>
6.14 +
6.15 + <hr/>
6.16 + ${bundle("copyright", version)}
6.17 +
6.18 + </body>
6.19 +</html>
6.20 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/freemarkerdor/src/test/java/cz/xelfi/quoridor/freemarkerdor/ChangeEmailTest.java Thu Mar 04 19:37:58 2010 +0100
7.3 @@ -0,0 +1,176 @@
7.4 +/*
7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7.6 + *
7.7 + * The contents of this file are subject to the terms of either the GNU
7.8 + * General Public License Version 2 only ("GPL") or the Common
7.9 + * Development and Distribution License("CDDL") (collectively, the
7.10 + * "License"). You may not use this file except in compliance with the
7.11 + * License. You can obtain a copy of the License at
7.12 + * http://www.netbeans.org/cddl-gplv2.html
7.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
7.14 + * specific language governing permissions and limitations under the
7.15 + * License. When distributing the software, include this License Header
7.16 + * Notice in each file and include the License file at
7.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
7.18 + * particular file as subject to the "Classpath" exception as provided
7.19 + * by Sun in the GPL Version 2 section of the License file that
7.20 + * accompanied this code. If applicable, add the following below the
7.21 + * License Header, with the fields enclosed by brackets [] replaced by
7.22 + * your own identifying information:
7.23 + * "Portions Copyrighted [year] [name of copyright owner]"
7.24 + *
7.25 + * Contributor(s):
7.26 + *
7.27 + * Portions Copyrighted 2010 Jaroslav Tulach
7.28 + */
7.29 +
7.30 +package cz.xelfi.quoridor.freemarkerdor;
7.31 +
7.32 +import com.sun.jersey.api.client.Client;
7.33 +import com.sun.jersey.api.client.ClientResponse;
7.34 +import com.sun.jersey.api.client.WebResource;
7.35 +import com.sun.jersey.core.header.MediaTypes;
7.36 +import com.sun.jersey.core.util.MultivaluedMapImpl;
7.37 +import com.sun.net.httpserver.HttpServer;
7.38 +import cz.xelfi.quoridor.webidor.resources.Quoridor;
7.39 +import java.io.File;
7.40 +import java.io.FileOutputStream;
7.41 +import java.io.IOException;
7.42 +import java.io.InputStream;
7.43 +import java.net.URI;
7.44 +import java.util.Locale;
7.45 +import java.util.concurrent.Callable;
7.46 +import java.util.regex.Matcher;
7.47 +import java.util.regex.Pattern;
7.48 +import javax.ws.rs.core.Cookie;
7.49 +import javax.ws.rs.core.MediaType;
7.50 +import javax.ws.rs.core.MultivaluedMap;
7.51 +import javax.ws.rs.core.UriBuilder;
7.52 +import org.junit.AfterClass;
7.53 +import org.junit.Before;
7.54 +import org.junit.BeforeClass;
7.55 +import org.junit.Test;
7.56 +import org.netbeans.junit.MockServices;
7.57 +import static org.junit.Assert.*;
7.58 +
7.59 +/**
7.60 + *
7.61 + * @author Jaroslav Tulach <jtulach@netbeans.org>
7.62 + */
7.63 +public class ChangeEmailTest extends Object {
7.64 + private static File dir;
7.65 + private static HttpServer stopAPI;
7.66 + private static HttpServer stopStatistics;
7.67 + private static Callable<Void> stop;
7.68 + private WebResource webResource;
7.69 + private WebResource apiResource;
7.70 + private WebResource statResource;
7.71 + private Client client;
7.72 +
7.73 + public ChangeEmailTest() throws Exception {
7.74 + }
7.75 +
7.76 + @BeforeClass
7.77 + public static void localeEnglish() throws Exception {
7.78 + Locale.setDefault(Locale.ENGLISH);
7.79 + dir = File.createTempFile("quoridor", ".dir");
7.80 + dir.delete();
7.81 + dir.mkdirs();
7.82 + System.setProperty("quoridor.dir", dir.getPath());
7.83 + stopAPI = Quoridor.start(7990);
7.84 + stopStatistics = Quoridor.start(7992);
7.85 + stop = UI.startServers(7991, "http://localhost:7990", "http://localhost:7992");
7.86 +
7.87 + File passwd = new File(dir, "passwd");
7.88 + FileOutputStream os = new FileOutputStream(passwd);
7.89 + os.write("test=pes\nJarda=darda\n".getBytes("UTF-8"));
7.90 + os.close();
7.91 +
7.92 + MockServices.setServices(MockEmailer.class);
7.93 + }
7.94 +
7.95 + @Before
7.96 + public void setUp() throws Exception {
7.97 + MockEmailer.clear();
7.98 +
7.99 + client = new Client();
7.100 + webResource = client.resource(new URI("http://localhost:7991/"));
7.101 + apiResource = client.resource(new URI("http://localhost:7990/"));
7.102 + statResource = client.resource(new URI("http://localhost:7992/"));
7.103 + }
7.104 +
7.105 + @AfterClass
7.106 + public static void cleanUpAll() throws Exception {
7.107 + deleteRec(dir);
7.108 + if (stop != null) {
7.109 + stop.call();
7.110 + }
7.111 + if (stopAPI != null) {
7.112 + stopAPI.stop(0);
7.113 + }
7.114 + MockServices.setServices();
7.115 + }
7.116 +
7.117 + static void deleteRec(File dir) throws IOException {
7.118 + if (dir == null) {
7.119 + return;
7.120 + }
7.121 + File[] arr = dir.listFiles();
7.122 + if (arr != null) {
7.123 + for (File f : arr) {
7.124 + deleteRec(f);
7.125 + }
7.126 + }
7.127 + dir.delete();
7.128 + }
7.129 +
7.130 + @Test public void testChangeEmail() throws Exception {
7.131 + String logTest = apiResource.path("login").
7.132 + queryParam("name", "test").
7.133 + queryParam("password", "pes").
7.134 + accept(MediaType.TEXT_PLAIN).
7.135 + put(String.class);
7.136 + ClientResponse res = webResource.path("options").
7.137 + queryParam("email", "xxx@xxx.cz").
7.138 + cookie(Cookie.valueOf("login=" + logTest)).
7.139 + accept("text/html").
7.140 + get(ClientResponse.class);
7.141 + final String txt = res.getEntity(String.class);
7.142 +
7.143 + assertEquals("Emails sent to", "xxx@xxx.cz", MockEmailer.address);
7.144 +
7.145 + int urlIndex = MockEmailer.text.indexOf(webResource.getURI().toString());
7.146 + assertTrue("Found in " + MockEmailer.text, urlIndex >= 0);
7.147 +
7.148 + int endIndex = urlIndex;
7.149 + while (!Character.isWhitespace(MockEmailer.text.charAt(endIndex))) {
7.150 + endIndex++;
7.151 + }
7.152 + final String url = MockEmailer.text.substring(urlIndex, endIndex);
7.153 + WebResource requestURL = client.resource(url);
7.154 +
7.155 + String response = requestURL.accept("text/html").get(String.class);
7.156 + Pattern p = Pattern.compile("<input *type=\"text\" *name=\"email\" *value='xxx@xxx.cz'");
7.157 + assertTrue("New email found" + response, p.matcher(response).find());
7.158 + }
7.159 +
7.160 + public static final class MockEmailer extends EmailService {
7.161 + static String address;
7.162 + static String subject;
7.163 + static String text;
7.164 +
7.165 + @Override
7.166 + public void sendEmail(String address, String subject, String text) throws IOException {
7.167 + assertNull("No email sent yet", MockEmailer.address);
7.168 + MockEmailer.address = address;
7.169 + MockEmailer.subject = subject;
7.170 + MockEmailer.text = text;
7.171 + }
7.172 +
7.173 + public static void clear() {
7.174 + MockEmailer.address = null;
7.175 + MockEmailer.subject = null;
7.176 + MockEmailer.text = null;
7.177 + }
7.178 + }
7.179 +}
8.1 --- a/pom.xml Tue Mar 02 17:09:06 2010 +0100
8.2 +++ b/pom.xml Thu Mar 04 19:37:58 2010 +0100
8.3 @@ -37,7 +37,7 @@
8.4 <quoridorVersion>1.1</quoridorVersion>
8.5 <webidorVersion>1.15</webidorVersion>
8.6 <visidorVersion>1.0-SNAPSHOT</visidorVersion>
8.7 - <freemarkerVersion>1.58</freemarkerVersion>
8.8 + <freemarkerVersion>1.59</freemarkerVersion>
8.9 <emailerVersion>1.0</emailerVersion>
8.10 <statisticsVersion>1.8</statisticsVersion>
8.11 </properties>