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

File TestUtils.java

 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
41% of files have more coverage

Code metrics

184
647
225
4
2,682
1,662
337
0.52
2.88
56.25
1.5

Classes

Class Line # Actions
TestUtils 104 396 0% 223 96
0.854545585.5%
TestUtils.Session 1133 5 0% 4 0
1.0100%
TestUtils.RestTestUtils 1890 244 0% 109 52
0.864583386.5%
TestUtils.RestTestUtils.ResourceAPI 1898 2 0% 1 0
1.0100%
 

Contributing tests

This file is covered by 229 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.test.ui;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.ByteArrayOutputStream;
24    import java.io.File;
25    import java.io.FileInputStream;
26    import java.io.IOException;
27    import java.io.InputStream;
28    import java.net.URI;
29    import java.net.URLEncoder;
30    import java.util.ArrayList;
31    import java.util.Arrays;
32    import java.util.Collections;
33    import java.util.HashMap;
34    import java.util.HashSet;
35    import java.util.IdentityHashMap;
36    import java.util.List;
37    import java.util.Locale;
38    import java.util.Map;
39    import java.util.Set;
40    import java.util.regex.Matcher;
41    import java.util.regex.Pattern;
42   
43    import javax.ws.rs.core.MediaType;
44    import javax.ws.rs.core.Response.Status;
45    import javax.ws.rs.core.UriBuilder;
46    import javax.xml.bind.JAXBContext;
47    import javax.xml.bind.JAXBException;
48    import javax.xml.bind.Marshaller;
49    import javax.xml.bind.Unmarshaller;
50   
51    import org.apache.commons.httpclient.HttpClient;
52    import org.apache.commons.httpclient.HttpMethod;
53    import org.apache.commons.httpclient.UsernamePasswordCredentials;
54    import org.apache.commons.httpclient.auth.AuthScope;
55    import org.apache.commons.httpclient.methods.DeleteMethod;
56    import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
57    import org.apache.commons.httpclient.methods.GetMethod;
58    import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
59    import org.apache.commons.httpclient.methods.PostMethod;
60    import org.apache.commons.httpclient.methods.PutMethod;
61    import org.apache.commons.httpclient.methods.RequestEntity;
62    import org.apache.commons.io.IOUtils;
63    import org.apache.commons.lang3.ArrayUtils;
64    import org.apache.commons.lang3.StringUtils;
65    import org.openqa.selenium.By;
66    import org.openqa.selenium.Cookie;
67    import org.openqa.selenium.NoSuchElementException;
68    import org.openqa.selenium.WebDriver;
69    import org.openqa.selenium.WebElement;
70    import org.openqa.selenium.support.ui.ExpectedCondition;
71    import org.xwiki.component.manager.ComponentManager;
72    import org.xwiki.model.EntityType;
73    import org.xwiki.model.reference.AttachmentReference;
74    import org.xwiki.model.reference.DocumentReference;
75    import org.xwiki.model.reference.EntityReference;
76    import org.xwiki.model.reference.EntityReferenceResolver;
77    import org.xwiki.model.reference.EntityReferenceSerializer;
78    import org.xwiki.model.reference.LocalDocumentReference;
79    import org.xwiki.model.reference.ObjectPropertyReference;
80    import org.xwiki.model.reference.ObjectReference;
81    import org.xwiki.rest.model.jaxb.Page;
82    import org.xwiki.rest.model.jaxb.Property;
83    import org.xwiki.rest.model.jaxb.Xwiki;
84    import org.xwiki.rest.resources.attachments.AttachmentResource;
85    import org.xwiki.rest.resources.classes.ClassPropertyResource;
86    import org.xwiki.rest.resources.objects.ObjectPropertyResource;
87    import org.xwiki.rest.resources.objects.ObjectResource;
88    import org.xwiki.rest.resources.objects.ObjectsResource;
89    import org.xwiki.rest.resources.pages.PageResource;
90    import org.xwiki.rest.resources.pages.PageTranslationResource;
91    import org.xwiki.test.integration.XWikiExecutor;
92    import org.xwiki.test.ui.po.ViewPage;
93    import org.xwiki.test.ui.po.editor.ClassEditPage;
94    import org.xwiki.test.ui.po.editor.ObjectEditPage;
95   
96    import static org.junit.Assert.fail;
97   
98    /**
99    * Helper methods for testing, not related to a specific Page Object. Also made available to tests classes.
100    *
101    * @version $Id: c2f2258561b547fb88b6f121a0b9b3023a2610f1 $
102    * @since 3.2M3
103    */
 
104    public class TestUtils
105    {
106    /**
107    * @since 5.0M2
108    */
109    public static final UsernamePasswordCredentials ADMIN_CREDENTIALS =
110    new UsernamePasswordCredentials("Admin", "admin");
111   
112    /**
113    * @since 5.1M1
114    */
115    public static final UsernamePasswordCredentials SUPER_ADMIN_CREDENTIALS =
116    new UsernamePasswordCredentials("superadmin", "pass");
117   
118    /**
119    * @since 5.0M2
120    * @deprecated since 7.3M1, use {@link #getBaseURL()} instead
121    */
122    @Deprecated
123    public static final String BASE_URL = XWikiExecutor.URL + ":" + XWikiExecutor.DEFAULT_PORT
124    + XWikiExecutor.DEFAULT_CONTEXT + "/";
125   
126    /**
127    * @since 5.0M2
128    * @deprecated since 7.3M1, use {@link #getBaseBinURL()} instead
129    */
130    @Deprecated
131    public static final String BASE_BIN_URL = BASE_URL + "bin/";
132   
133    /**
134    * @since 5.0M2
135    * @deprecated since 7.3M1, use {@link #getBaseURL()} instead
136    */
137    @Deprecated
138    public static final String BASE_REST_URL = BASE_URL + "rest/";
139   
140    /**
141    * @since 7.3M1
142    */
143    public static final int[] STATUS_OK_NOT_FOUND =
144    new int[] { Status.OK.getStatusCode(), Status.NOT_FOUND.getStatusCode() };
145   
146    /**
147    * @since 7.3M1
148    */
149    public static final int[] STATUS_OK = new int[] { Status.OK.getStatusCode() };
150   
151    /**
152    * @since 7.3M1
153    */
154    public static final int[] STATUS_NO_CONTENT = new int[] { Status.NO_CONTENT.getStatusCode() };
155   
156    /**
157    * @since 8.3RC1
158    */
159    public static final int[] STATUS_NO_CONTENT_NOT_FOUND =
160    new int[] { Status.NO_CONTENT.getStatusCode(), Status.NOT_FOUND.getStatusCode() };
161   
162    /**
163    * @since 7.3M1
164    */
165    public static final int[] STATUS_CREATED_ACCEPTED =
166    new int[] { Status.CREATED.getStatusCode(), Status.ACCEPTED.getStatusCode() };
167   
168    /**
169    * @since 7.3M1
170    */
171    public static final int[] STATUS_CREATED = new int[] { Status.CREATED.getStatusCode() };
172   
173    /**
174    * @since 9.5RC1
175    */
176    public static final int[] STATUS_ACCEPTED = new int[] { Status.ACCEPTED.getStatusCode() };
177   
178    private static PersistentTestContext context;
179   
180    private static ComponentManager componentManager;
181   
182    private static EntityReferenceResolver<String> relativeReferenceResolver;
183   
184    private static EntityReferenceSerializer<String> referenceSerializer;
185   
186    private static EntityReferenceResolver<String> referenceResolver;
187   
188    /**
189    * Used to convert Java object into its REST XML representation.
190    */
191    private static Marshaller marshaller;
192   
193    /**
194    * Used to convert REST request XML result into its Java representation.
195    */
196    private static Unmarshaller unmarshaller;
197   
198    private static String urlPrefix = XWikiExecutor.URL;
199   
200    /** Cached secret token. TODO cache for each user. */
201    private String secretToken = null;
202   
203    private HttpClient httpClient;
204   
205    /**
206    * @since 8.0M1
207    */
208    private List<XWikiExecutor> executors;
209   
210    /**
211    * @since 7.3M1
212    */
213    private int currentExecutorIndex = 0;
214   
215    /**
216    * @since 7.3M1
217    */
218    private String currentWiki = "xwiki";
219   
220    private RestTestUtils rest;
221   
 
222  103 toggle public TestUtils()
223    {
224  103 this.httpClient = new HttpClient();
225  103 this.httpClient.getState().setCredentials(AuthScope.ANY, SUPER_ADMIN_CREDENTIALS);
226  103 this.httpClient.getParams().setAuthenticationPreemptive(true);
227   
228  103 this.rest = new RestTestUtils(this);
229    }
230   
231    /**
232    * @since 8.0M1
233    */
 
234  11744 toggle public XWikiExecutor getCurrentExecutor()
235    {
236  11744 return this.executors != null && this.executors.size() > this.currentExecutorIndex
237    ? this.executors.get(this.currentExecutorIndex) : null;
238    }
239   
240    /**
241    * @since 8.0M1
242    */
 
243  316 toggle public void switchExecutor(int index)
244    {
245  316 this.currentExecutorIndex = index;
246    }
247   
248    /**
249    * @since 8.0M1
250    */
 
251  33 toggle public void setExecutors(List<XWikiExecutor> executors)
252    {
253  33 this.executors = executors;
254    }
255   
256    /** Used so that AllTests can set the persistent test context. */
 
257  33 toggle public static void setContext(PersistentTestContext context)
258    {
259  33 TestUtils.context = context;
260    }
261   
 
262  34 toggle public static void initializeComponent(ComponentManager componentManager) throws Exception
263    {
264  34 TestUtils.componentManager = componentManager;
265  34 TestUtils.relativeReferenceResolver =
266    TestUtils.componentManager.getInstance(EntityReferenceResolver.TYPE_STRING, "relative");
267  34 TestUtils.referenceResolver = TestUtils.componentManager.getInstance(EntityReferenceResolver.TYPE_STRING);
268  34 TestUtils.referenceSerializer = TestUtils.componentManager.getInstance(EntityReferenceSerializer.TYPE_STRING);
269    }
270   
 
271  4232 toggle public XWikiWebDriver getDriver()
272    {
273  4232 return TestUtils.context.getDriver();
274    }
275   
 
276  32 toggle public Session getSession()
277    {
278  32 return this.new Session(getDriver().manage().getCookies(), getSecretToken());
279    }
280   
 
281  111 toggle public void setSession(Session session)
282    {
283  111 WebDriver.Options options = getDriver().manage();
284  111 options.deleteAllCookies();
285  111 if (session != null) {
286  38 for (Cookie cookie : session.getCookies()) {
287  153 options.addCookie(cookie);
288    }
289    }
290  111 if (session != null && !StringUtils.isEmpty(session.getSecretToken())) {
291  38 this.secretToken = session.getSecretToken();
292    } else {
293  73 recacheSecretToken();
294    }
295    }
296   
297    /**
298    * @since 7.0RC1
299    */
 
300  135 toggle public void setDefaultCredentials(String username, String password)
301    {
302  135 setDefaultCredentials(new UsernamePasswordCredentials(username, password));
303    }
304   
305    /**
306    * @since 7.0RC1
307    */
 
308  213 toggle public UsernamePasswordCredentials setDefaultCredentials(UsernamePasswordCredentials defaultCredentials)
309    {
310  213 UsernamePasswordCredentials currentCredentials = getDefaultCredentials();
311   
312  213 this.httpClient.getState().setCredentials(AuthScope.ANY, defaultCredentials);
313   
314  213 return currentCredentials;
315    }
316   
 
317  218 toggle public UsernamePasswordCredentials getDefaultCredentials()
318    {
319  218 return (UsernamePasswordCredentials) this.httpClient.getState().getCredentials(AuthScope.ANY);
320    }
321   
 
322  20 toggle public void loginAsSuperAdmin()
323    {
324  20 login(SUPER_ADMIN_CREDENTIALS.getUserName(), SUPER_ADMIN_CREDENTIALS.getPassword());
325    }
326   
 
327  3 toggle public void loginAsSuperAdminAndGotoPage(String pageURL)
328    {
329  3 loginAndGotoPage(SUPER_ADMIN_CREDENTIALS.getUserName(), SUPER_ADMIN_CREDENTIALS.getPassword(), pageURL);
330    }
331   
 
332  4 toggle public void loginAsAdmin()
333    {
334  4 login(ADMIN_CREDENTIALS.getUserName(), ADMIN_CREDENTIALS.getPassword());
335    }
336   
 
337  0 toggle public void loginAsAdminAndGotoPage(String pageURL)
338    {
339  0 loginAndGotoPage(ADMIN_CREDENTIALS.getUserName(), ADMIN_CREDENTIALS.getPassword(), pageURL);
340    }
341   
 
342  239 toggle public void login(String username, String password)
343    {
344  239 loginAndGotoPage(username, password, null);
345    }
346   
 
347  244 toggle public void loginAndGotoPage(String username, String password, String pageURL)
348    {
349  244 if (!username.equals(getLoggedInUserName())) {
350    // Log in and direct to a non existent page so that it loads very fast and we don't incur the time cost of
351    // going to the home page for example.
352    // Also recache the CSRF token
353  101 getDriver().get(getURLToLoginAndGotoPage(username, password, getURL("XWiki", "Register", "register")));
354  101 recacheSecretTokenWhenOnRegisterPage();
355  101 if (pageURL != null) {
356    // Go to the page asked
357  5 getDriver().get(pageURL);
358    } else {
359  96 getDriver().get(getURLToNonExistentPage());
360    }
361   
362  101 setDefaultCredentials(username, password);
363    }
364    }
365   
366    /**
367    * Consider using setSession(null) because it will drop the cookies which is faster than invoking a logout action.
368    */
 
369  0 toggle public String getURLToLogout()
370    {
371  0 return getURL("XWiki", "XWikiLogin", "logout");
372    }
373   
 
374  7 toggle public String getURLToLoginAsAdmin()
375    {
376  7 return getURLToLoginAs(ADMIN_CREDENTIALS.getUserName(), ADMIN_CREDENTIALS.getPassword());
377    }
378   
 
379  0 toggle public String getURLToLoginAsSuperAdmin()
380    {
381  0 return getURLToLoginAs(SUPER_ADMIN_CREDENTIALS.getUserName(), SUPER_ADMIN_CREDENTIALS.getPassword());
382    }
383   
 
384  12 toggle public String getURLToLoginAs(final String username, final String password)
385    {
386  12 return getURLToLoginAndGotoPage(username, password, null);
387    }
388   
389    /**
390    * @param pageURL the URL of the page to go to after logging in.
391    * @return URL to accomplish login and goto.
392    */
 
393  36 toggle public String getURLToLoginAsAdminAndGotoPage(final String pageURL)
394    {
395  36 return getURLToLoginAndGotoPage(ADMIN_CREDENTIALS.getUserName(), ADMIN_CREDENTIALS.getPassword(), pageURL);
396    }
397   
398    /**
399    * @param pageURL the URL of the page to go to after logging in.
400    * @return URL to accomplish login and goto.
401    */
 
402  0 toggle public String getURLToLoginAsSuperAdminAndGotoPage(final String pageURL)
403    {
404  0 return getURLToLoginAndGotoPage(SUPER_ADMIN_CREDENTIALS.getUserName(), SUPER_ADMIN_CREDENTIALS.getPassword(),
405    pageURL);
406    }
407   
408    /**
409    * @param username the name of the user to log in as.
410    * @param password the password for the user to log in.
411    * @param pageURL the URL of the page to go to after logging in.
412    * @return URL to accomplish login and goto.
413    */
 
414  180 toggle public String getURLToLoginAndGotoPage(final String username, final String password, final String pageURL)
415    {
416  180 Map<String, String> parameters = new HashMap<String, String>()
417    {
 
418  180 toggle {
419  180 put("j_username", username);
420  180 put("j_password", password);
421  180 if (pageURL != null && pageURL.length() > 0) {
422  168 put("xredirect", pageURL);
423    }
424    }
425    };
426  180 return getURL("XWiki", "XWikiLogin", "loginsubmit", parameters);
427    }
428   
429    /**
430    * @return URL to a non existent page that loads very fast (we are using plain mode so that we don't even have to
431    * display the skin ;))
432    */
 
433  162 toggle public String getURLToNonExistentPage()
434    {
435  162 return getURL("NonExistentSpace", "NonExistentPage", "view", "xpage=plain");
436    }
437   
438    /**
439    * After successful completion of this function, you are guaranteed to be logged in as the given user and on the
440    * page passed in pageURL.
441    */
 
442  4 toggle public void assertOnPage(final String pageURL)
443    {
444  4 final String pageURI = pageURL.replaceAll("\\?.*", "");
445  4 getDriver().waitUntilCondition(new ExpectedCondition<Boolean>()
446    {
 
447  4 toggle @Override
448    public Boolean apply(WebDriver driver)
449    {
450  4 return getDriver().getCurrentUrl().contains(pageURI);
451    }
452    });
453    }
454   
 
455  245 toggle public String getLoggedInUserName()
456    {
457  245 By userAvatarInDrawer = By.id("tmUser");
458  245 if (!getDriver().hasElementWithoutWaiting(userAvatarInDrawer)) {
459    // Guest
460  48 return null;
461    }
462   
463  197 WebElement element = getDriver().findElementWithoutWaiting(userAvatarInDrawer);
464  197 String href = element.getAttribute("href");
465  197 String loggedInUserName = href.substring(href.lastIndexOf("/") + 1);
466   
467    // Return
468  197 return loggedInUserName;
469    }
470   
 
471  31 toggle public void createUserAndLogin(final String username, final String password, Object... properties)
472    {
473  31 createUserAndLoginWithRedirect(username, password, getURLToNonExistentPage(), properties);
474    }
475   
 
476  31 toggle public void createUserAndLoginWithRedirect(final String username, final String password, String url,
477    Object... properties)
478    {
479  31 createUser(username, password, getURLToLoginAndGotoPage(username, password, url), properties);
480   
481  31 setDefaultCredentials(username, password);
482    }
483   
 
484  55 toggle public void createUser(final String username, final String password, String redirectURL, Object... properties)
485    {
486  55 Map<String, String> parameters = new HashMap<String, String>();
487  55 parameters.put("register", "1");
488  55 parameters.put("xwikiname", username);
489  55 parameters.put("register_password", password);
490  55 parameters.put("register2_password", password);
491  55 parameters.put("register_email", "");
492  55 parameters.put("xredirect", redirectURL);
493  55 parameters.put("form_token", getSecretToken());
494  55 getDriver().get(getURL("XWiki", "Register", "register", parameters));
495  55 recacheSecretToken();
496  55 if (properties.length > 0) {
497  26 updateObject("XWiki", username, "XWiki.XWikiUsers", 0, properties);
498    }
499    }
500   
 
501  148 toggle public ViewPage gotoPage(String space, String page)
502    {
503  148 gotoPage(space, page, "view");
504  148 return new ViewPage();
505    }
506   
507    /**
508    * @since 7.2M2
509    */
 
510  25 toggle public ViewPage gotoPage(EntityReference reference)
511    {
512  25 gotoPage(reference, "view");
513  25 return new ViewPage();
514    }
515   
 
516  512 toggle public void gotoPage(String space, String page, String action)
517    {
518  512 gotoPage(space, page, action, "");
519    }
520   
521    /**
522    * @since 7.2M2
523    */
 
524  30 toggle public void gotoPage(EntityReference reference, String action)
525    {
526  30 gotoPage(reference, action, "");
527    }
528   
529    /**
530    * @since 3.5M1
531    */
 
532  32 toggle public void gotoPage(String space, String page, String action, Object... queryParameters)
533    {
534  32 gotoPage(space, page, action, toQueryString(queryParameters));
535    }
536   
 
537  13 toggle public void gotoPage(String space, String page, String action, Map<String, ?> queryParameters)
538    {
539  13 gotoPage(Collections.singletonList(space), page, action, queryParameters);
540    }
541   
542    /**
543    * @since 7.2M2
544    */
 
545  310 toggle public void gotoPage(List<String> spaces, String page, String action, Map<String, ?> queryParameters)
546    {
547  310 gotoPage(spaces, page, action, toQueryString(queryParameters));
548    }
549   
550    /**
551    * @since 7.2M2
552    */
 
553  25 toggle public void gotoPage(EntityReference reference, String action, Map<String, ?> queryParameters)
554    {
555  25 gotoPage(reference, action, toQueryString(queryParameters));
556    }
557   
 
558  716 toggle public void gotoPage(String space, String page, String action, String queryString)
559    {
560  716 gotoPage(Collections.singletonList(space), page, action, queryString);
561    }
562   
563    /**
564    * @since 7.2M2
565    */
 
566  1030 toggle public void gotoPage(List<String> spaces, String page, String action, String queryString)
567    {
568  1030 gotoPage(getURL(spaces, page, action, queryString));
569    }
570   
571    /**
572    * @since 7.2M2
573    */
 
574  57 toggle public void gotoPage(EntityReference reference, String action, String queryString)
575    {
576  57 gotoPage(reference, action, queryString, null);
577    }
578   
579    /**
580    * @since 10.9
581    */
 
582  61 toggle public void gotoPage(EntityReference reference, String action, String queryString, String fragment)
583    {
584  61 gotoPage(getURL(reference, action, queryString, fragment));
585   
586    // Update current wiki
587  61 EntityReference wikiReference = reference.extractReference(EntityType.WIKI);
588  61 if (wikiReference != null) {
589  35 this.currentWiki = wikiReference.getName();
590    }
591    }
592   
 
593  1152 toggle public void gotoPage(String url)
594    {
595    // Only navigate if the current URL is different from the one to go to, in order to improve performances.
596  1152 if (!getDriver().getCurrentUrl().equals(url)) {
597  1142 getDriver().get(url);
598    }
599    }
600   
 
601  29 toggle public String getURLToDeletePage(String space, String page)
602    {
603  29 return getURL(space, page, "delete", "confirm=1");
604    }
605   
606    /**
607    * @since 7.2M2
608    */
 
609  9 toggle public String getURLToDeletePage(EntityReference reference)
610    {
611  9 return getURL(reference, "delete", "confirm=1");
612    }
613   
614    /**
615    * @param space the name of the space to delete
616    * @return the URL that can be used to delete the specified pace
617    * @since 4.5
618    */
 
619  40 toggle public String getURLToDeleteSpace(String space)
620    {
621  40 return getURL(space, "WebHome", "deletespace", "confirm=1&async=false&affectChidlren=on");
622    }
623   
 
624  101 toggle public ViewPage createPage(String space, String page, String content, String title)
625    {
626  101 return createPage(Collections.singletonList(space), page, content, title);
627    }
628   
629    /**
630    * @since 7.2M2
631    */
 
632  12 toggle public ViewPage createPage(EntityReference reference, String content, String title)
633    {
634  12 return createPage(reference, content, title, null);
635    }
636   
637    /**
638    * @since 7.2M2
639    */
 
640  112 toggle public ViewPage createPage(List<String> spaces, String page, String content, String title)
641    {
642  112 return createPage(spaces, page, content, title, null);
643    }
644   
 
645  9 toggle public ViewPage createPage(String space, String page, String content, String title, String syntaxId)
646    {
647  9 return createPage(Collections.singletonList(space), page, content, title, syntaxId);
648    }
649   
650    /**
651    * @since 7.2M2
652    */
 
653  12 toggle public ViewPage createPage(EntityReference reference, String content, String title, String syntaxId)
654    {
655  12 return createPage(reference, content, title, syntaxId, null);
656    }
657   
658    /**
659    * @since 7.2M2
660    */
 
661  121 toggle public ViewPage createPage(List<String> spaces, String page, String content, String title, String syntaxId)
662    {
663  121 return createPage(spaces, page, content, title, syntaxId, null);
664    }
665   
 
666  2 toggle public ViewPage createPage(String space, String page, String content, String title, String syntaxId,
667    String parentFullPageName)
668    {
669  2 return createPage(Collections.singletonList(space), page, content, title, syntaxId, parentFullPageName);
670    }
671   
672    /**
673    * @since 7.2M2
674    */
 
675  125 toggle public ViewPage createPage(List<String> spaces, String page, String content, String title, String syntaxId,
676    String parentFullPageName)
677    {
678  125 Map<String, String> queryMap = new HashMap<String, String>();
679  125 if (content != null) {
680  102 queryMap.put("content", content);
681    }
682  125