/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.test.rest.framework;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.restlet.data.MediaType;
import org.xwiki.component.annotation.ComponentAnnotationLoader;
import org.xwiki.component.annotation.ComponentDeclaration;
import org.xwiki.component.embed.EmbeddableComponentManager;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.model.internal.DefaultModelConfiguration;
import org.xwiki.model.internal.reference.DefaultEntityReferenceProvider;
import org.xwiki.model.internal.reference.DefaultStringEntityReferenceResolver;
import org.xwiki.model.internal.reference.DefaultStringEntityReferenceSerializer;
import org.xwiki.model.internal.reference.DefaultSymbolScheme;
import org.xwiki.model.internal.reference.RelativeStringEntityReferenceResolver;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.repository.test.SolrTestUtils;
import org.xwiki.rest.internal.Utils;
import org.xwiki.rest.model.jaxb.Attachment;
import org.xwiki.rest.model.jaxb.Attachments;
import org.xwiki.rest.model.jaxb.Link;
import org.xwiki.rest.model.jaxb.LinkCollection;
import org.xwiki.rest.model.jaxb.ObjectFactory;
import org.xwiki.rest.model.jaxb.Objects;
import org.xwiki.rest.model.jaxb.Page;
import org.xwiki.rest.model.jaxb.PageSummary;
import org.xwiki.rest.model.jaxb.Pages;
import org.xwiki.rest.model.jaxb.Wikis;
import org.xwiki.rest.resources.pages.PageResource;
import org.xwiki.rest.resources.wikis.WikisResource;
import org.xwiki.test.ui.AbstractTest;
import org.xwiki.test.ui.TestUtils;
public abstract class AbstractHttpTest
{
/**
* The object used to access the name of the current test.
*/
@Rule
public final TestName testName = new TestName();
protected Random random;
protected Marshaller marshaller;
protected Unmarshaller unmarshaller;
protected ObjectFactory objectFactory;
// TODO: Refactor TestUtils to move REST tools to xwiki-platform-test-integration
protected TestUtils testUtils = new TestUtils();
protected SolrTestUtils solrUtils;
static {
try {
initializeSystem();
} catch (Exception e) {
}
}
@Before
public void setUp() throws Exception
{
random = new Random();
JAXBContext context = JAXBContext.newInstance("org.xwiki.rest.model.jaxb");
marshaller = context.createMarshaller();
unmarshaller = context.createUnmarshaller();
objectFactory = new ObjectFactory();
// Make sure guest does not have edit right
Page page = this.testUtils.rest().page(new DocumentReference("xwiki", "XWiki", "XWikiPreferences"));
org.xwiki.rest.model.jaxb.Object rightObject = this.testUtils.rest().object("XWiki.XWikiGlobalRights");
rightObject.withProperties(this.testUtils.rest().property("users", "XWiki.XWikiGuest"),
this.testUtils.rest().property("levels", "edit"), this.testUtils.rest().property("allow", "0"));
Objects objects = new Objects();
objects.withObjectSummaries(rightObject);
page.setObjects(objects);
this.testUtils.rest().save(page);
// Init solr utils
this.solrUtils = new SolrTestUtils(this.testUtils);
}
public static void initializeSystem() throws Exception
{
ComponentManager componentManager = new EmbeddableComponentManager();
// Only load the minimal number of components required for the test framework, for both performance reasons
// and for avoiding having to declare dependencies such as HttpServletRequest.
ComponentAnnotationLoader loader = new ComponentAnnotationLoader();
List<ComponentDeclaration> componentDeclarations = new ArrayList<>();
componentDeclarations.add(new ComponentDeclaration(DefaultStringEntityReferenceResolver.class.getName()));
componentDeclarations.add(new ComponentDeclaration(DefaultStringEntityReferenceSerializer.class.getName()));
componentDeclarations.add(new ComponentDeclaration(RelativeStringEntityReferenceResolver.class.getName()));
componentDeclarations.add(new ComponentDeclaration(DefaultEntityReferenceProvider.class.getName()));
componentDeclarations.add(new ComponentDeclaration(DefaultModelConfiguration.class.getName()));
componentDeclarations.add(new ComponentDeclaration(DefaultSymbolScheme.class.getName()));
loader.initialize(componentManager, AbstractTest.class.getClassLoader(), componentDeclarations);
TestUtils.initializeComponent(componentManager);
}
protected Link getFirstLinkByRelation(LinkCollection linkCollection, String relation)
{
if (linkCollection.getLinks() == null) {
return null;
}
for (Link link : linkCollection.getLinks()) {
if (link.getRel().equals(relation)) {
return link;
}
}
return null;
}
protected List<Link> getLinksByRelation(LinkCollection linkCollection, String relation)
{
List<Link> result = new ArrayList<Link>();
if (linkCollection.getLinks() == null) {
return result;
}
for (Link link : linkCollection.getLinks()) {
if (link.getRel().equals(relation)) {
result.add(link);
}
}
return result;
}
protected String getBaseURL()
{
return this.testUtils.rest().getBaseURL();
}
protected String getFullUri(Class<?> resourceClass)
{
return this.testUtils.rest().createUri(resourceClass, null).toString();
}
public abstract void testRepresentation() throws Exception;
protected GetMethod executeGet(String uri) throws Exception
{
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(uri);
getMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
httpClient.executeMethod(getMethod);
return getMethod;
}
protected GetMethod executeGet(String uri, String userName, String password) throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
GetMethod getMethod = new GetMethod(uri);
getMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
httpClient.executeMethod(getMethod);
return getMethod;
}
protected PostMethod executePostXml(String uri, Object object) throws Exception
{
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(uri);
postMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
StringWriter writer = new StringWriter();
marshaller.marshal(object, writer);
RequestEntity entity =
new StringRequestEntity(writer.toString(), MediaType.APPLICATION_XML.toString(), "UTF-8");
postMethod.setRequestEntity(entity);
httpClient.executeMethod(postMethod);
return postMethod;
}
protected PostMethod executePostXml(String uri, Object object, String userName, String password) throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
PostMethod postMethod = new PostMethod(uri);
postMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
StringWriter writer = new StringWriter();
marshaller.marshal(object, writer);
RequestEntity entity =
new StringRequestEntity(writer.toString(), MediaType.APPLICATION_XML.toString(), "UTF-8");
postMethod.setRequestEntity(entity);
httpClient.executeMethod(postMethod);
return postMethod;
}
protected PostMethod executePost(String uri, InputStream is, String userName, String password) throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
PostMethod postMethod = new PostMethod(uri);
postMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
RequestEntity entity = new InputStreamRequestEntity(is);
postMethod.setRequestEntity(entity);
httpClient.executeMethod(postMethod);
return postMethod;
}
protected PostMethod executePost(String uri, String string, String mediaType, String userName, String password)
throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
PostMethod postMethod = new PostMethod(uri);
postMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
RequestEntity entity = new StringRequestEntity(string, mediaType, "UTF-8");
postMethod.setRequestEntity(entity);
httpClient.executeMethod(postMethod);
return postMethod;
}
protected PostMethod executePostForm(String uri, NameValuePair[] nameValuePairs, String userName, String password)
throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
PostMethod postMethod = new PostMethod(uri);
postMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
postMethod.addRequestHeader("Content-type", MediaType.APPLICATION_WWW_FORM.toString());
postMethod.setRequestBody(nameValuePairs);
httpClient.executeMethod(postMethod);
return postMethod;
}
protected PutMethod executePutXml(String uri, Object object) throws Exception
{
HttpClient httpClient = new HttpClient();
PutMethod putMethod = new PutMethod(uri);
putMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
StringWriter writer = new StringWriter();
marshaller.marshal(object, writer);
RequestEntity entity =
new StringRequestEntity(writer.toString(), MediaType.APPLICATION_XML.toString(), "UTF-8");
putMethod.setRequestEntity(entity);
httpClient.executeMethod(putMethod);
return putMethod;
}
protected PutMethod executePutXml(String uri, Object object, String userName, String password) throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
PutMethod putMethod = new PutMethod(uri);
putMethod.addRequestHeader("Accept", MediaType.APPLICATION_XML.toString());
StringWriter writer = new StringWriter();
marshaller.marshal(object, writer);
RequestEntity entity =
new StringRequestEntity(writer.toString(), MediaType.APPLICATION_XML.toString(), "UTF-8");
putMethod.setRequestEntity(entity);
httpClient.executeMethod(putMethod);
return putMethod;
}
protected PutMethod executePut(String uri, String string, String mediaType) throws Exception
{
HttpClient httpClient = new HttpClient();
PutMethod putMethod = new PutMethod(uri);
RequestEntity entity = new StringRequestEntity(string, mediaType, "UTF-8");
putMethod.setRequestEntity(entity);
httpClient.executeMethod(putMethod);
return putMethod;
}
protected PutMethod executePut(String uri, String string, String mediaType, String userName, String password)
throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
PutMethod putMethod = new PutMethod(uri);
RequestEntity entity = new StringRequestEntity(string, mediaType, "UTF-8");
putMethod.setRequestEntity(entity);
httpClient.executeMethod(putMethod);
return putMethod;
}
protected DeleteMethod executeDelete(String uri) throws Exception
{
HttpClient httpClient = new HttpClient();
DeleteMethod deleteMethod = new DeleteMethod(uri);
httpClient.executeMethod(deleteMethod);
return deleteMethod;
}
protected DeleteMethod executeDelete(String uri, String userName, String password) throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
httpClient.getParams().setAuthenticationPreemptive(true);
DeleteMethod deleteMethod = new DeleteMethod(uri);
httpClient.executeMethod(deleteMethod);
return deleteMethod;
}
protected String getWiki() throws Exception
{
GetMethod getMethod = executeGet(getFullUri(WikisResource.class));
Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_OK, getMethod.getStatusCode());
Wikis wikis = (Wikis) unmarshaller.unmarshal(getMethod.getResponseBodyAsStream());
Assert.assertTrue(wikis.getWikis().size() > 0);
return wikis.getWikis().get(0).getName();
}
protected String getContentFromURI(String uri) throws Exception
{
GetMethod getMethod = executeGet(uri);
Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_OK, getMethod.getStatusCode());
return getMethod.getResponseBodyAsString();
}
protected void checkLinks(LinkCollection linkCollection) throws Exception
{
if (linkCollection.getLinks() != null) {
for (Link link : linkCollection.getLinks()) {
GetMethod getMethod = executeGet(link.getHref());
if (getMethod.getStatusCode() != HttpStatus.SC_UNAUTHORIZED) {
Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_OK, getMethod.getStatusCode());
}
}
}
}
protected String buildURI(Class<?> resource, Object... pathParameters) throws Exception
{
return Utils.createURI(new URI(getBaseURL()), resource, pathParameters).toString();
}
private Page getPage(String wikiName, List<String> spaceName, String pageName) throws Exception
{
String uri = buildURI(PageResource.class, wikiName, spaceName, pageName).toString();
GetMethod getMethod = executeGet(uri);
return (Page) unmarshaller.unmarshal(getMethod.getResponseBodyAsStream());
}
protected String getPageContent(String wikiName, List<String> spaceName, String pageName) throws Exception
{
Page page = getPage(wikiName, spaceName, pageName);
return page.getContent();
}
protected int setPageContent(String wikiName, List<String> spaceName, String pageName, String content)
throws Exception
{
String uri = buildURI(PageResource.class, wikiName, spaceName, pageName).toString();
PutMethod putMethod = executePut(uri, content, javax.ws.rs.core.MediaType.TEXT_PLAIN,
TestUtils.SUPER_ADMIN_CREDENTIALS.getUserName(), TestUtils.SUPER_ADMIN_CREDENTIALS.getPassword());
int code = putMethod.getStatusCode();
Assert.assertTrue(String.format("Failed to set page content, %s", getHttpMethodInfo(putMethod)),
code == HttpStatus.SC_ACCEPTED || code == HttpStatus.SC_CREATED);
return code;
}
protected String getHttpMethodInfo(HttpMethod method) throws Exception
{
return String.format("\nName: %s\nURI: %s\nStatus code: %d\nStatus text: %s", method.getName(), method.getURI(),
method.getStatusCode(), method.getStatusText());
}
protected String getAttachmentsInfo(Attachments attachments)
{
StringBuffer sb = new StringBuffer();
sb.append(String.format("Attachments: %d\n", attachments.getAttachments().size()));
for (Attachment attachment : attachments.getAttachments()) {
sb.append(String.format("* %s\n", attachment.getName()));
}
return sb.toString();
}
protected String getPagesInfo(Pages pages)
{
StringBuffer sb = new StringBuffer();
sb.append(String.format("Pages: %d\n", pages.getPageSummaries().size()));
for (PageSummary pageSummary : pages.getPageSummaries()) {
sb.append(String.format("* %s\n", pageSummary.getFullName()));
}
return sb.toString();
}
protected void createPage(List<String> spaces, String pageName, String content) throws Exception
{
String uri = buildURI(PageResource.class, getWiki(), spaces, pageName);
Page page = this.objectFactory.createPage();
page.setContent(content);
PutMethod putMethod = executePutXml(uri, page, TestUtils.SUPER_ADMIN_CREDENTIALS.getUserName(),
TestUtils.SUPER_ADMIN_CREDENTIALS.getPassword());
Assert.assertEquals(getHttpMethodInfo(putMethod), HttpStatus.SC_CREATED, putMethod.getStatusCode());
}
protected boolean createPageIfDoesntExist(List<String> spaces, String pageName, String content) throws Exception
{
String uri = buildURI(PageResource.class, getWiki(), spaces, pageName);
GetMethod getMethod = executeGet(uri);
if (getMethod.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
createPage(spaces, pageName, content);
getMethod = executeGet(uri);
Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_OK, getMethod.getStatusCode());
return true;
}
return false;
}
protected String getTestMethodName()
{
return this.testName.getMethodName();
}
protected String getTestClassName()
{
return getClass().getSimpleName();
}
}