]> WPIA git - gigi.git/blob - tests/club/wpia/gigi/pages/wot/TestVerification.java
fix: more spontaneous failing test cases
[gigi.git] / tests / club / wpia / gigi / pages / wot / TestVerification.java
1 package club.wpia.gigi.pages.wot;
2
3 import static org.hamcrest.CoreMatchers.*;
4 import static org.junit.Assert.*;
5
6 import java.io.IOException;
7 import java.io.UnsupportedEncodingException;
8 import java.net.HttpURLConnection;
9 import java.net.MalformedURLException;
10 import java.net.URLConnection;
11 import java.net.URLEncoder;
12 import java.sql.SQLException;
13 import java.sql.Timestamp;
14 import java.text.SimpleDateFormat;
15 import java.util.Calendar;
16 import java.util.Date;
17 import java.util.regex.Pattern;
18
19 import org.hamcrest.Matcher;
20 import org.junit.Before;
21 import org.junit.Test;
22
23 import club.wpia.gigi.GigiApiException;
24 import club.wpia.gigi.database.GigiPreparedStatement;
25 import club.wpia.gigi.dbObjects.Country;
26 import club.wpia.gigi.dbObjects.Group;
27 import club.wpia.gigi.dbObjects.User;
28 import club.wpia.gigi.pages.account.MyDetails;
29 import club.wpia.gigi.testUtils.IOUtils;
30 import club.wpia.gigi.testUtils.ManagedTest;
31 import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail;
32 import club.wpia.gigi.util.DayDate;
33 import club.wpia.gigi.util.Notary;
34
35 public class TestVerification extends ManagedTest {
36
37     private String agentM;
38
39     private String applicantM;
40
41     private int applicantName;
42
43     private String cookie;
44
45     @Before
46     public void setup() throws IOException {
47         clearCaches();
48         agentM = createUniqueName() + "@example.org";
49         applicantM = createUniqueName() + "@example.org";
50
51         createVerificationUser("a", "b", agentM, TEST_PASSWORD);
52         int applicantId = createVerifiedUser("a", "c", applicantM, TEST_PASSWORD);
53         applicantName = User.getById(applicantId).getPreferredName().getId();
54
55         cookie = login(agentM, TEST_PASSWORD);
56     }
57
58     private Matcher<String> isVerificationForm() {
59         return containsString("<select name=\"verificationType\">");
60     }
61
62     @Test
63     public void testVerifySearch() throws IOException {
64         String loc = search("email=" + URLEncoder.encode(applicantM, "UTF-8") + "&day=1&month=1&year=1910");
65         assertThat(loc, isVerificationForm());
66     }
67
68     @Test
69     public void testVerifySearchEmail() throws IOException {
70         String loc = search("email=1" + URLEncoder.encode(applicantM, "UTF-8") + "&day=1&month=1&year=1910");
71         assertThat(loc, not(isVerificationForm()));
72     }
73
74     @Test
75     public void testVerifySearchDobInvalid() throws IOException {
76         String loc = search("email=" + URLEncoder.encode(applicantM, "UTF-8") + "&day=1&month=1&year=mal");
77         assertThat(loc, not(isVerificationForm()));
78     }
79
80     @Test
81     public void testVerifySearchDob() throws IOException {
82         String loc = search("email=" + URLEncoder.encode(applicantM, "UTF-8") + "&day=2&month=1&year=1910");
83         assertThat(loc, not(isVerificationForm()));
84         loc = search("email=" + URLEncoder.encode(applicantM, "UTF-8") + "&day=1&month=2&year=1910");
85         assertThat(loc, not(isVerificationForm()));
86         loc = search("email=" + URLEncoder.encode(applicantM, "UTF-8") + "&day=1&month=1&year=1911");
87         assertThat(loc, not(isVerificationForm()));
88     }
89
90     private String search(String query) throws MalformedURLException, IOException, UnsupportedEncodingException {
91         URLConnection uc = get(cookie, VerifyPage.PATH);
92         uc.setDoOutput(true);
93         uc.getOutputStream().write(("search&" + query).getBytes("UTF-8"));
94         uc.getOutputStream().flush();
95
96         return IOUtils.readURL(uc);
97     }
98
99     @Test
100     public void testVerifyForm() throws IOException {
101         String body = executeSuccess("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
102         assertThat(body, containsString("10"));
103         assertThat(body, containsString(applicantM));
104     }
105
106     @Test
107     public void testVerifyFormEmpty() throws IOException {
108         URLConnection uc = buildupVerifyFormConnection(true);
109         uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&rules=1&assertion=1&points=10").getBytes("UTF-8"));
110         uc.getOutputStream().flush();
111         String data = IOUtils.readURL(uc);
112         assertThat(data, hasError());
113     }
114
115     @Test
116     public void testVerifyFormContainsData() throws IOException {
117         URLConnection uc = buildupVerifyFormConnection(true);
118         uc.getOutputStream().write(("verifiedName=" + applicantName + "&date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&rules=1&assertion=1&points=10").getBytes("UTF-8"));
119         uc.getOutputStream().flush();
120         String data = IOUtils.readURL(uc);
121         assertThat(data, containsString(validVerificationDateString()));
122         assertThat(data, containsString("testcase"));
123     }
124
125     @Test
126     public void testVerifyFormNoCSRF() throws IOException {
127         // override csrf
128         HttpURLConnection uc = (HttpURLConnection) buildupVerifyFormConnection(false);
129         uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
130         uc.getOutputStream().flush();
131         assertEquals(500, uc.getResponseCode());
132         uc.getErrorStream().close();
133     }
134
135     @Test
136     public void testVerifyFormWrongCSRF() throws IOException {
137         // override csrf
138         HttpURLConnection uc = (HttpURLConnection) buildupVerifyFormConnection(false);
139         uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10&csrf=aragc").getBytes("UTF-8"));
140         uc.getOutputStream().flush();
141         assertEquals(500, uc.getResponseCode());
142         uc.getErrorStream().close();
143     }
144
145     @Test
146     public void testVerifyFormRaceDoB() throws IOException, SQLException {
147         testVerifyFormRace(false);
148     }
149
150     @Test
151     public void testVerifyFormRaceDoBBlind() throws IOException, SQLException {
152         testVerifyFormRace(true);
153     }
154
155     public void testVerifyFormRace(boolean succeed) throws IOException, SQLException {
156         URLConnection uc = buildupVerifyFormConnection(true);
157
158         String applicantCookie = login(applicantM, TEST_PASSWORD);
159         String newDob = "day=1&month=1&year=" + ( !succeed ? 1911 : 1910);
160
161         assertNull(executeBasicWebInteraction(applicantCookie, MyDetails.PATH, newDob + "&action=updateDoB", 0));
162
163         uc.getOutputStream().write(("verifiedName=" + applicantName + "&date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
164         uc.getOutputStream().flush();
165         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
166         if (succeed) {
167             assertNull(error);
168         } else {
169             assertTrue(error, !error.startsWith("</div>"));
170             assertThat(error, containsString("changed his personal details"));
171         }
172     }
173
174     @Test
175     public void testVerifyFormFuture() throws IOException {
176         SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
177         int year = Integer.parseInt(sdf.format(new Date(System.currentTimeMillis()))) + 2;
178         executeFails("date=" + year + "-01-01&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
179     }
180
181     @Test
182     public void testVerifyFormFutureOK() throws IOException {
183         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
184         Calendar c = Calendar.getInstance();
185         c.setTimeInMillis(System.currentTimeMillis());
186         c.add(Calendar.HOUR_OF_DAY, 12);
187
188         executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
189     }
190
191     @Test
192     public void testVerifyFormPastInRange() throws IOException {
193         executeSuccess("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
194     }
195
196     @Test
197     public void testVerifyFormPastOnLimit() throws IOException {
198         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
199         Calendar c = Calendar.getInstance();
200         c.setTimeInMillis(System.currentTimeMillis());
201         c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION);
202         c.add(Calendar.DAY_OF_MONTH, 1);
203
204         executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
205     }
206
207     @Test
208     public void testVerifyFormPastOutOfRange() throws IOException {
209         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
210         Calendar c = Calendar.getInstance();
211         c.setTimeInMillis(System.currentTimeMillis());
212         c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION);
213
214         executeFails("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
215     }
216
217     @Test
218     public void testVerifyFormNoLoc() throws IOException {
219         executeFails("date=" + validVerificationDateString() + "&location=a&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
220         executeFails("date=" + validVerificationDateString() + "&location=&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
221     }
222
223     @Test
224     public void testVerifyFormInvalDate() throws IOException {
225         executeFails("date=20000101&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
226         executeFails("date=&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
227     }
228
229     @Test
230     public void testVerifyFormBoxes() throws IOException {
231         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=0&rules=1&assertion=1&points=10");
232         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=&assertion=1&points=10");
233         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=z&points=10");
234     }
235
236     @Test
237     public void testVerifyListingValid() throws IOException, GigiApiException {
238         String uniqueLoc = createUniqueName();
239         execute("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
240
241         String cookie = login(applicantM, TEST_PASSWORD);
242         URLConnection url = get(cookie, Points.PATH);
243         String resp = IOUtils.readURL(url);
244         resp = resp.split(Pattern.quote("</table>"))[1];
245         assertThat(resp, containsString(uniqueLoc));
246         assertThat(resp, containsString(Country.getCountryByCode("DE", Country.CountryCodeType.CODE_2_CHARS).getName()));
247     }
248
249     @Test
250     public void testAgentListingValid() throws IOException, GigiApiException {
251         String uniqueLoc = createUniqueName();
252         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
253         String cookie = login(agentM, TEST_PASSWORD);
254         URLConnection url = get(cookie, Points.PATH);
255         String resp = IOUtils.readURL(url);
256         resp = resp.split(Pattern.quote("</table>"))[2];
257         assertThat(resp, containsString(uniqueLoc));
258         assertThat(resp, containsString(Country.getCountryByCode("DE", Country.CountryCodeType.CODE_2_CHARS).getName()));
259     }
260
261     private void executeFails(String query) throws MalformedURLException, IOException {
262         assertThat(execute(query), hasError());
263
264     }
265
266     private String executeSuccess(String query) throws MalformedURLException, IOException {
267         String response = execute(query);
268         assertThat(response, hasNoError());
269         return response;
270     }
271
272     private String execute(String query) throws MalformedURLException, IOException {
273         URLConnection uc = buildupVerifyFormConnection(true);
274         uc.getOutputStream().write(("verifiedName=" + applicantName + "&" + query).getBytes("UTF-8"));
275         uc.getOutputStream().flush();
276         return IOUtils.readURL(uc);
277     }
278
279     private URLConnection buildupVerifyFormConnection(boolean doCSRF) throws MalformedURLException, IOException {
280         return buildupVerifyFormConnection(cookie, applicantM, doCSRF);
281     }
282
283     public static URLConnection buildupVerifyFormConnection(String cookie, String email, boolean doCSRF) throws MalformedURLException, IOException {
284         URLConnection uc = get(cookie, VerifyPage.PATH);
285         uc.setDoOutput(true);
286         uc.getOutputStream().write(("email=" + URLEncoder.encode(email, "UTF-8") + "&day=1&month=1&year=1910&search").getBytes("UTF-8"));
287
288         String csrf = getCSRF(uc);
289         uc = get(cookie, VerifyPage.PATH);
290         uc.setDoOutput(true);
291         if (doCSRF) {
292             uc.getOutputStream().write(("csrf=" + csrf + "&").getBytes("UTF-8"));
293         }
294         return uc;
295     }
296
297     @Test
298     public void testMultipleVerification() throws IOException {
299
300         User users[] = User.findByEmail(agentM);
301         int agentID = users[0].getId();
302
303         users = User.findByEmail(applicantM);
304         int applicantID = users[0].getId();
305
306         // enter first entry 200 days in the past
307         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `when`=? ")) {
308             ps.setInt(1, agentID);
309             ps.setInt(2, applicantID);
310             ps.setInt(3, 10);
311             ps.setString(4, "test-location");
312             ps.setString(5, "2010-01-01");
313             ps.setTimestamp(6, new Timestamp(System.currentTimeMillis() - DayDate.MILLI_DAY * 200));
314             ps.execute();
315         }
316
317         // enter second entry
318         String uniqueLoc = createUniqueName();
319         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
320
321         // enter third entry on the same day
322         URLConnection uc = get(cookie, VerifyPage.PATH);
323         uc.setDoOutput(true);
324         uc.getOutputStream().write(("email=" + URLEncoder.encode(applicantM, "UTF-8") + "&day=1&month=1&year=1910&search").getBytes("UTF-8"));
325         assertThat(IOUtils.readURL(uc), hasError());
326
327     }
328
329     @Test
330     public void testVerifyFormNoCountry() throws IOException {
331         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=&certify=1&rules=1&assertion=1&points=10");
332     }
333
334     @Test
335     public void testRANotificationSet() throws IOException, GigiApiException {
336         getMailReceiver().clearMails();
337
338         User users[] = User.findByEmail(agentM);
339         assertTrue("user RA Agent not found", users != null && users.length > 0);
340
341         User u = users[0];
342         u.grantGroup(u, Group.VERIFY_NOTIFICATION);
343         clearCaches();
344         cookie = login(agentM, TEST_PASSWORD);
345
346         String targetMail = u.getEmail();
347
348         // enter verification
349         String uniqueLoc = createUniqueName();
350         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
351         TestMail tm;
352
353         do {
354             tm = getMailReceiver().receive();
355         } while ( !tm.getTo().equals(targetMail));
356         assertThat(tm.getMessage(), containsString("You entered a verification for the account with email address " + applicantM));
357
358     }
359
360     @Test
361     public void testRANotificationNotSet() throws IOException, GigiApiException {
362         getMailReceiver().clearMails();
363
364         User users[] = User.findByEmail(agentM);
365         assertTrue("user RA Agent not found", users != null && users.length > 0);
366
367         User u = users[0];
368         u.revokeGroup(u, Group.VERIFY_NOTIFICATION);
369         clearCaches();
370         cookie = login(agentM, TEST_PASSWORD);
371
372         // enter verification
373         String uniqueLoc = createUniqueName();
374         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
375
376         TestMail tm;
377
378         tm = getMailReceiver().receive();
379         assertThat(tm.getMessage(), not(containsString("You entered a verification for the account with email address " + applicantM)));
380
381     }
382 }