/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.launchpad.webapp.integrationtest.servlets.post;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.testing.integration.HttpTestBase;
import org.apache.sling.commons.testing.integration.NameValuePairList;
import org.apache.sling.servlets.post.SlingPostConstants;
/** Test content import via the MicrojaxPostServlet */
public class PostServletImportTest extends HttpTestBase {
public static final String TEST_BASE_PATH = "/sling-import-tests";
static Random random = new Random();
File testFile;
/* (non-Javadoc)
* @see org.apache.sling.commons.testing.integration.HttpTestBase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
if (testFile != null) {
//cleanup temp file
testFile.delete();
}
super.tearDown();
}
static String getStreamAsString(InputStream is) throws IOException {
final StringBuilder content = new StringBuilder();
final byte [] buffer = new byte[16384];
int n = 0;
while( (n = is.read(buffer, 0, buffer.length)) > 0) {
content.append(new String(buffer, 0, n));
}
return content.toString();
}
static String getStreamAsString(InputStream is, String charset) throws IOException {
InputStreamReader reader = new InputStreamReader(is, charset);
final StringBuilder content = new StringBuilder();
final char [] buffer = new char[16384];
int n = 0;
while( (n = reader.read(buffer)) > 0) {
content.append(buffer, 0, n);
}
return content.toString();
}
private File getTestFile(InputStream inputStream) throws IOException {
File tempFile = File.createTempFile("file-to-upload", null, new File("target"));
FileOutputStream outputStream = new FileOutputStream(tempFile);
byte[] bbuf = new byte[16384]; //16k
int len;
while ((len = inputStream.read(bbuf)) != -1) {
outputStream.write(bbuf, 0, len);
}
outputStream.flush();
outputStream.close();
return tempFile;
}
protected void assertExpectedJSON(JSONObject expectedJson, JSONObject actualJson) throws JSONException {
Iterator<String> keys = expectedJson.keys();
while (keys.hasNext()) {
String key = keys.next();
Object object = expectedJson.get(key);
Object object2 = actualJson.get(key);
if (object instanceof JSONObject) {
assertTrue(object instanceof JSONObject);
assertExpectedJSON((JSONObject)object, (JSONObject)object2);
} else if (object instanceof JSONArray) {
//compare the array
assertTrue(object2 instanceof JSONArray);
JSONArray actualArray = (JSONArray)object2;
Set<Object> actualValuesSet = new HashSet<Object>();
for (int i=0; i < actualArray.length(); i++) {
actualValuesSet.add(actualArray.get(i));
}
JSONArray expectedArray = (JSONArray)object;
for (int i=0; i < expectedArray.length(); i++) {
assertTrue(actualValuesSet.contains(expectedArray.get(i)));
}
} else {
assertEquals("Value of key: " + key, object, object2);
}
}
}
/**
* Test import operation which replaces existing content
*/
public void testImportReplace() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
//add node that will get replaced
props.put("propTest", "propTestValue");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath + "/nodeName", props);
//import with the replace option to replace the existing node.
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport2.json"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
props.put(SlingPostConstants.RP_REPLACE, "true");
String importedNodeUrl2 = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
//the new node should have the same path as the replaced node
assertEquals(importedNodeUrl, importedNodeUrl2);
// assert content at new location
String content = getContent(importedNodeUrl2 + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
assertNull(jsonObj.optString("propTest", null)); //test property should be gone.
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
/**
* SLING-1627: test import of content over existing content with the ':replaceProperties"
* parameter set and the ":replace" property not set.
*/
public void testImportReplaceProperties() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
//1. First import some initial content
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
String jsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.json"));
props.put(SlingPostConstants.RP_CONTENT, jsonContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, props);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
//2. Second, import on top of the node from #1 to replace some properties.
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String jsonContent2 = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport_replaceProps.json"));
props.put(SlingPostConstants.RP_CONTENT, jsonContent2);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, importedNodeUrl);
props.put(SlingPostConstants.RP_REPLACE, "false");
props.put(SlingPostConstants.RP_REPLACE_PROPERTIES, "true");
String importedNodeUrl2 = testClient.createNode(importedNodeUrl, props);
assertEquals(importedNodeUrl, importedNodeUrl2);
// assert content at new location
String content2 = getContent(importedNodeUrl2 + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj2 = new JSONObject(content2);
assertNotNull(jsonObj2);
//assert the imported content is there.
String expectedJsonContent2 = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport_replaceProps.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent2), jsonObj2);
}
/**
* Test import operation which checks in versionable nodes.
*/
public void testImportCheckinNodes() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport3.json"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
props.put(SlingPostConstants.RP_CHECKIN, "true");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert that the versionable node is checked in.
assertFalse(jsonObj.getBoolean("jcr:isCheckedOut"));
//now try with the checkin value set to false
testFile.delete();
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName2 = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName2);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport3.json"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
props.put(SlingPostConstants.RP_CHECKIN, "false");
String importedNodeUrl2 = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content2 = getContent(importedNodeUrl2 + ".json", CONTENT_TYPE_JSON);
JSONObject jsonObj2 = new JSONObject(content2);
assertNotNull(jsonObj2);
//assert that the versionable node is checked in.
assertTrue(jsonObj2.getBoolean("jcr:isCheckedOut"));
}
/**
* SLING-2108 Test import operation which auto checks out versionable nodes.
*/
public void testImportAutoCheckoutNodes() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
//1. first create some content to update.
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport3.json"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
props.put(SlingPostConstants.RP_CHECKIN, "true");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert that the versionable node is checked in.
assertFalse(jsonObj.getBoolean("jcr:isCheckedOut"));
//2. try an update with the :autoCheckout value set to false
List<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT));
postParams.add(new NameValuePair(SlingPostConstants.RP_CONTENT_TYPE, "json"));
postParams.add(new NameValuePair(SlingPostConstants.RP_CHECKIN, "true"));
postParams.add(new NameValuePair(SlingPostConstants.RP_REPLACE_PROPERTIES, "true"));
postParams.add(new NameValuePair(SlingPostConstants.RP_AUTO_CHECKOUT, "false"));
postParams.add(new NameValuePair(SlingPostConstants.RP_CONTENT, "{ \"abc\": \"def2\" }"));
assertPostStatus(importedNodeUrl, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, "Expected error from VersionException");
//3. now try an update with the :autoCheckout value set to true
postParams.clear();
postParams.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT));
postParams.add(new NameValuePair(SlingPostConstants.RP_CONTENT_TYPE, "json"));
postParams.add(new NameValuePair(SlingPostConstants.RP_CHECKIN, "true"));
postParams.add(new NameValuePair(SlingPostConstants.RP_REPLACE_PROPERTIES, "true"));
postParams.add(new NameValuePair(SlingPostConstants.RP_AUTO_CHECKOUT, "true"));
postParams.add(new NameValuePair(SlingPostConstants.RP_CONTENT, "{ \"abc\": \"def2\" }"));
postParams.add(new NameValuePair(":http-equiv-accept", "application/json,*/*;q=0.9"));
HttpMethod post = assertPostStatus(importedNodeUrl, HttpServletResponse.SC_CREATED, postParams, "Expected 201 status");
String responseBodyAsString = post.getResponseBodyAsString();
JSONObject responseJSON = new JSONObject(responseBodyAsString);
JSONArray changes = responseJSON.getJSONArray("changes");
JSONObject checkoutChange = changes.getJSONObject(0);
assertEquals("checkout", checkoutChange.getString("type"));
// assert content at new location
String content2 = getContent(importedNodeUrl + ".json", CONTENT_TYPE_JSON);
JSONObject jsonObj2 = new JSONObject(content2);
assertNotNull(jsonObj2);
//make sure it was really updated
assertEquals("def2", jsonObj2.getString("abc"));
//assert that the versionable node is checked back in.
assertFalse(jsonObj.getBoolean("jcr:isCheckedOut"));
}
/**
* Test import operation for a posted json file
*/
public void testImportJSONFromFile() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.json"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
/**
* Test import operation for a posted json file without the optional name
*/
public void testImportJSONFromFileWithoutOptionalName() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport2.json"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
//make sure the name is what was inside the file.
assertTrue(importedNodeUrl.endsWith("/nodeName"));
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
/**
* Test import operation for a posted json string
*/
public void testImportJSONFromRequestParam() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
String jsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.json"));
props.put(SlingPostConstants.RP_CONTENT, jsonContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, props);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
/**
* Test import operation for a posted json string without the optional name
*/
public void testImportJSONFromRequestParamWithoutOptionalName() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String jsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport2.json"));
props.put(SlingPostConstants.RP_CONTENT, jsonContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, props);
//make sure the name is what was inside the file.
assertTrue(importedNodeUrl.endsWith("/nodeName"));
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportXMLFromFile() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.xml"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "xml");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportXMLFromFileWithoutOptionalName() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport2.xml"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "xml");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
//make sure the name is what was inside the file.
assertTrue(importedNodeUrl.endsWith("/nodeName"));
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportXMLFromRequestParam() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
String xmlContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.xml"));
props.put(SlingPostConstants.RP_CONTENT, xmlContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "xml");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, props);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportXMLFromRequestParamWithoutOptionalName() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String xmlContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport2.xml"));
props.put(SlingPostConstants.RP_CONTENT, xmlContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "xml");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, props);
//make sure the name is what was inside the file.
assertTrue(importedNodeUrl.endsWith("/nodeName"));
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportZipFromFile() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.zip"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "zip");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimportzip.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportJarFromFile() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.jar"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "jar");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimportzip.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
public void testImportJCRXMLFromFile() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testnode_1287021810";
props.put(SlingPostConstants.RP_NODE_NAME, testNodeName);
testFile = getTestFile(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.jcr.xml"));
props.put(SlingPostConstants.RP_CONTENT_TYPE, "jcr.xml");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, new NameValuePairList(props), null, true,
testFile, SlingPostConstants.RP_CONTENT_FILE, null);
// assert content at new location
String content = getContent(importedNodeUrl + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
}
protected String importNodeWithExactName(String testNodeName) throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
props.put(SlingPostConstants.RP_NODE_NAME, testNodeName);
String jsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.json"));
props.put(SlingPostConstants.RP_CONTENT, jsonContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String location = testClient.createNode(HTTP_BASE_URL + testPath, props);
// assert content at new location
String content = getContent(location + ".3.json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
String expectedJsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/importresults.json"));
assertExpectedJSON(new JSONObject(expectedJsonContent), jsonObj);
assertHttpStatus(location + DEFAULT_EXT, HttpServletResponse.SC_OK,
"POST must redirect to created resource (" + location + ")");
assertTrue("Node (" + location + ") must have exact name",
!location.endsWith("/*"));
assertTrue("Node (" + location + ") must created be under POST URL (" + testNode + ")",
location.contains(testNode + "/"));
assertTrue("Node (" + location + ") must have exact name '" + testNodeName + "'",
location.endsWith("/" + testNodeName));
return location;
}
/**
* SLING-1091: test create node with an exact node name (no filtering)
*/
public void testImportNodeWithExactName() throws IOException, JSONException {
importNodeWithExactName("exactNodeName");
}
/**
* SLING-1091: test error reporting when attempting to create a node with an
* invalid exact node name.
*/
public void testImportNodeWithInvalidExactName() throws IOException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
List<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new NameValuePair(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_IMPORT));
postParams.add(new NameValuePair(SlingPostConstants.RP_NODE_NAME, "exactNodeName*"));
String jsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport.json"));
postParams.add(new NameValuePair(SlingPostConstants.RP_CONTENT, jsonContent));
postParams.add(new NameValuePair(SlingPostConstants.RP_CONTENT_TYPE, "json"));
postParams.add(new NameValuePair(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*"));
//expect a 500 status since the name is invalid
String location = HTTP_BASE_URL + testPath;
assertPostStatus(location, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
}
/**
* SLING-1091: test error reporting when attempting to import a node with an
* already used node name.
*/
public void testImportNodeWithAlreadyUsedExactName() throws IOException, JSONException {
String testNodeName = "alreadyUsedExactNodeName";
String location = importNodeWithExactName(testNodeName);
//try to create the same node again, since same name siblings are not allowed an error should be
// thrown
List<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new NameValuePair(SlingPostConstants.RP_NODE_NAME, testNodeName));
//expect a 500 status since the name is not unique
String postUrl = location.substring(0, location.lastIndexOf('/'));
assertPostStatus(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
}
/**
* SLING-2143: test import where json is in a UTF-8 charset
*/
public void testImportJSONWithUTF8Content() throws IOException, JSONException {
final String testPath = TEST_BASE_PATH;
Map<String, String> props = new HashMap<String, String>();
String testNode = testClient.createNode(HTTP_BASE_URL + testPath, props);
urlsToDelete.add(testNode);
props.clear();
props.put(SlingPostConstants.RP_OPERATION,
SlingPostConstants.OPERATION_IMPORT);
String testNodeName = "testNode_" + String.valueOf(random.nextInt());
props.put(SlingPostConstants.RP_NODE_NAME_HINT, testNodeName);
final String jsonContent = getStreamAsString(getClass().getResourceAsStream("/integration-test/servlets/post/testimport_utf8.json"), "UTF-8");
props.put(SlingPostConstants.RP_CONTENT, jsonContent);
props.put(SlingPostConstants.RP_CONTENT_TYPE, "json");
props.put(SlingPostConstants.RP_REDIRECT_TO, SERVLET_CONTEXT + testPath + "/*");
String importedNodeUrl = testClient.createNode(HTTP_BASE_URL + testPath, props);
// assert content at new location
String content = getContent(importedNodeUrl + ".json", CONTENT_TYPE_JSON);
JSONObject jsonObj = new JSONObject(content);
assertNotNull(jsonObj);
//assert the imported content is there.
assertExpectedJSON(new JSONObject(jsonContent), jsonObj);
}
}