/* * (C) Copyright 2016 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Vladimir Pasquier <vpasquier@nuxeo.com> */ package org.nuxeo.ftest.server; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.codehaus.jackson.JsonNode; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.nuxeo.ecm.automation.client.Constants; import org.nuxeo.ecm.automation.client.Session; import org.nuxeo.ecm.automation.client.jaxrs.impl.HttpAutomationClient; import org.nuxeo.ecm.automation.client.model.Document; import org.nuxeo.ecm.automation.client.model.Documents; import org.nuxeo.ecm.automation.client.model.FileBlob; import org.nuxeo.ecm.automation.client.model.PaginableDocuments; import org.nuxeo.ecm.automation.client.model.PathRef; import org.nuxeo.ecm.automation.client.model.PropertyList; import org.nuxeo.ecm.automation.client.model.PropertyMap; import org.nuxeo.ecm.automation.core.operations.document.CreateDocument; import org.nuxeo.ecm.automation.core.operations.services.DocumentPageProviderOperation; import org.nuxeo.ecm.automation.core.operations.services.query.DocumentPaginatedQuery; import org.nuxeo.ecm.automation.server.test.business.client.BusinessBean; import org.nuxeo.ecm.automation.test.RemoteAutomationServerFeature; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.test.runner.Features; import org.nuxeo.runtime.test.runner.FeaturesRunner; /** * @since 5.7.2 Automation TCK Tests Suite */ @RunWith(FeaturesRunner.class) @Features(RemoteAutomationServerFeature.class) public class ITRemoteAutomationClientTCK { protected static String[] attachments = { "att1", "att2", "att3" }; @Inject Session session; @Inject HttpAutomationClient client; private Document folder1; private Document folder2; private Document folder3; private Document file; @Test public void testSuite() throws Exception { testCRUDSuite(); testBlobSuite(); testPaginationSuite(); // TODO: NXP-17000 (reactivate when NXBT-902 is resolved) // testComplexPropertiesWithJSON(); // testAutomationBusinessObjects(); } public void testCRUDSuite() throws Exception { testCreateRoot(); testCreateChild1(); testCreateChild2(); testUpdateChild2(); testGetChildren(); testGetChildrenWithWebAdapter(); } public void testBlobSuite() throws Exception { testCreateBlobText(); testAttachBlob(); testGetBlob(); } public void testPaginationSuite() throws Exception { testCreateAnotherRoot(); testCreateChild("1"); testCreateChild("2"); testCreateChild("3"); testQueryPage1(); testQueryPage2(); } /** * Create Read Update Delete */ public void testCreateRoot() throws Exception { folder1 = (Document) session.newRequest("Document.Create") .setInput("/") .set("type", "Folder") .set("name", "TestFolder1") .set("properties", "dc:title=Test Folder2\ndc:description=Simple container") .execute(); assertNotNull(folder1); assertEquals("/TestFolder1", folder1.getPath()); assertEquals("Test Folder2", folder1.getTitle()); } public void testCreateChild1() throws Exception { Document aFile = (Document) session.newRequest("Document.Create") .setInput("/TestFolder1") .set("type", "File") .set("name", "TestFile1") .execute(); assertNotNull(aFile); assertEquals("/TestFolder1/TestFile1", aFile.getPath()); } public void testCreateChild2() throws Exception { Document aFile = (Document) session.newRequest("Document.Create") .setInput("/TestFolder1") .set("type", "File") .set("name", "TestFile2") .execute(); assertNotNull(aFile); assertEquals("/TestFolder1/TestFile2", aFile.getPath()); } public void testUpdateChild2() throws Exception { Document aFile = (Document) session.newRequest("Document.Update") .setHeader(Constants.HEADER_NX_SCHEMAS, "*") .setInput("/TestFolder1/TestFile2") .set("save", "true") .set("properties", "dc:description=Simple File\ndc:subjects=art,sciences") .execute(); assertNotNull(aFile); assertEquals("Simple File", aFile.getProperties().get("dc:description")); assertEquals(2, ((PropertyList) aFile.getProperties().get("dc:subjects")).size()); } public void testGetChildren() throws Exception { Document root = (Document) session.newRequest("Document.Fetch").set("value", "/TestFolder1").execute(); assertNotNull(root); Documents children = (Documents) session.newRequest("Document.GetChildren").setInput(root.getPath()).execute(); assertEquals(2, children.size()); } public void testGetChildrenWithWebAdapter() throws Exception { JsonNode node = client.getRestClient().newRequest("/path/TestFolder1/@children").execute().asJson(); assertEquals(2, node.get("resultsCount").getIntValue()); } /** * Managing Pagination */ public void testCreateAnotherRoot() throws Exception { folder2 = (Document) session.newRequest("Document.Create") .setInput("/") .set("type", "Folder") .set("name", "TestFolder2") .set("properties", "dc:title=Test Folder3\ndc:description=Simple container") .execute(); assertNotNull(folder2); } public void testCreateChild(String id) throws Exception { String name = "TestFile" + id; Document aFile = (Document) session.newRequest("Document.Create") .setInput("/TestFolder2") .set("type", "File") .set("name", name) .execute(); assertNotNull(aFile); } public void testQueryPage1() throws Exception { Document root = (Document) session.newRequest("Document.Fetch").set("value", "/TestFolder2").execute(); PaginableDocuments docs = (PaginableDocuments) session.newRequest(DocumentPageProviderOperation.ID) .set("query", "select * from Document where ecm:parentId = ?") .set("queryParams", root.getId()) .set("pageSize", "2") .set("page", "0") .execute(); assertEquals(2, docs.size()); assertEquals(2, docs.getPageSize()); assertEquals(2, docs.getNumberOfPages()); assertEquals(3, docs.getResultsCount()); } public void testQueryPage2() throws Exception { Document root = (Document) session.newRequest("Document.Fetch").set("value", "/TestFolder2").execute(); PaginableDocuments docs = (PaginableDocuments) session.newRequest(DocumentPageProviderOperation.ID) .set("query", "select * from Document where ecm:parentId = ?") .set("queryParams", root.getId()) .set("pageSize", "2") .set("page", "1") .execute(); assertEquals(1, docs.size()); assertEquals(2, docs.getPageSize()); assertEquals(2, docs.getNumberOfPages()); assertEquals(3, docs.getResultsCount()); } /** * Managing Blobs */ protected File newFile(String content) throws IOException { File aFile = Framework.createTempFile("automation-test-", ".xml"); FileUtils.writeStringToFile(aFile, content); return aFile; } // Create documents from Blob using muti-part encoding public void testCreateBlobText() throws Exception { folder3 = (Document) session.newRequest("Document.Create") .setInput("/") .set("type", "Folder") .set("name", "FolderBlob") .execute(); assertNotNull(folder3); assertEquals("/FolderBlob", folder3.getPath()); File aFile = newFile("<doc>mydoc</doc>"); FileBlob blob = new FileBlob(aFile); blob.setMimeType("text/xml"); session.newRequest("FileManager.Import") .setInput(blob) .setContextProperty("currentDocument", folder3.getPath()) .execute(); Documents docs = (Documents) session.newRequest(DocumentPaginatedQuery.ID) .setHeader(Constants.HEADER_NX_SCHEMAS, "*") .set("query", "SELECT * from Document WHERE ecm:path STARTSWITH '/FolderBlob/'") .execute(); assertEquals(1, docs.size()); Document document = docs.get(0); // get the file content property PropertyMap map = document.getProperties().getMap("file:content"); // get the data URL String path = map.getString("data"); // download the file from its remote location blob = (FileBlob) session.getFile(path); assertNotNull(blob); assertEquals("text/xml", blob.getMimeType()); assertEquals("<doc>mydoc</doc>", IOUtils.toString(blob.getStream(), "utf-8")); } // Test attaching blob public void testAttachBlob() throws Exception { // get the root Document root = (Document) session.newRequest("Document.Fetch").set("value", "/").execute(); // create a file document file = (Document) session.newRequest("Document.Create") .setInput(root) .set("type", "File") .set("name", "myfile") .set("properties", "dc:title=My File") .execute(); // upload file blob File fieldAsJsonFile = org.nuxeo.common.utils.FileUtils.getResourceFileFromContext("creationFields.json"); FileBlob fb = new FileBlob(fieldAsJsonFile); fb.setMimeType("image/jpeg"); session.newRequest("Blob.Attach") .setHeader("X-NXVoidOperation", "true") .setInput(fb) .set("document", "/myfile") .execute(); } // Test attaching blob public void testGetBlob() throws Exception { // get the file document where blob was attached Document doc = (Document) session.newRequest("Document.Fetch") .setHeader(Constants.HEADER_NX_SCHEMAS, "*") .set("value", "/myfile") .execute(); // get the file content property PropertyMap map = doc.getProperties().getMap("file:content"); // get the data URL String path = map.getString("data"); // download the file from its remote location FileBlob blob = (FileBlob) session.getFile(path); // ... do something with the file // at the end delete the temporary file blob.getFile().delete(); } /** * Managing Complex Properties */ public void testComplexPropertiesWithJSON() throws Exception { // get the root Document root = (Document) session.newRequest("Document.Fetch").set("value", "/").execute(); // Fill the document properties Map<String, Object> creationProps = new HashMap<>(); creationProps.put("ds:tableName", "MyTable"); creationProps.put("ds:attachments", attachments); // send the fields representation as json File fieldAsJsonFile = org.nuxeo.common.utils.FileUtils.getResourceFileFromContext("creationFields.json"); assertNotNull(fieldAsJsonFile); String fieldsDataAsJSon = org.apache.commons.io.FileUtils.readFileToString(fieldAsJsonFile); fieldsDataAsJSon = fieldsDataAsJSon.replaceAll("\n", ""); fieldsDataAsJSon = fieldsDataAsJSon.replaceAll("\r", ""); creationProps.put("ds:fields", fieldsDataAsJSon); creationProps.put("dc:title", "testDoc"); // Document creation session.newRequest(CreateDocument.ID) .setInput(root) .set("type", "DataSet") .set("name", "testDoc") .set("properties", new PropertyMap(creationProps).toString()) .execute(); // Fetch the document Document document = (Document) session.newRequest("Document.GetChild") .setInput(new PathRef("/")) .set("name", "testDoc") .execute(); // Send the fields representation as json // Read the json file fieldAsJsonFile = org.nuxeo.common.utils.FileUtils.getResourceFileFromContext("updateFields.json"); fieldsDataAsJSon = org.apache.commons.io.FileUtils.readFileToString(fieldAsJsonFile); // Don't forget to replace CRLF or LF fieldsDataAsJSon = fieldsDataAsJSon.replaceAll("\n", ""); fieldsDataAsJSon = fieldsDataAsJSon.replaceAll("\r", ""); // Set the json values to the related metadata document.set("ds:fields", fieldsDataAsJSon); // Document Update session.newRequest("Document.Update").setInput(document).set("properties", document).execute(); } /** * Managing Business Objects */ public void testAutomationBusinessObjects() throws Exception { // Test for pojo <-> adapter automation creation BusinessBean note = new BusinessBean("Note", "File description", "Note Content", "Note", new String("object")); // Marshaller for bean 'note' registration client.registerPojoMarshaller(note.getClass()); note = (BusinessBean) session.newRequest("Business.BusinessCreateOperation") .setInput(note) .set("name", note.getTitle()) .set("parentPath", "/") .execute(); assertNotNull(note); // Test for pojo <-> adapter automation update note.setTitle("Update"); note = (BusinessBean) session.newRequest("Business.BusinessUpdateOperation").setInput(note).execute(); assertEquals("Update", note.getTitle()); } @After public void teardown() throws IOException { Documents list = new Documents(); list.add(folder1); list.add(folder2); list.add(folder3); list.add(file); session.newRequest("Document.Delete").setInput(list).execute(); } }