mirror of
https://github.com/Alfresco/SearchServices.git
synced 2026-09-16 18:12:56 +00:00
Merge branch 'master' of https://git.alfresco.com/tas/alfresco-tas-restapi-test into tas-rest-api-search
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
package org.alfresco.rest.actions;
|
||||
|
||||
import static junit.framework.Assert.fail;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import org.alfresco.dataprep.CMISUtil;
|
||||
import org.alfresco.rest.RestTest;
|
||||
import org.alfresco.rest.exception.EmptyJsonResponseException;
|
||||
import org.alfresco.rest.model.RestActionDefinitionModel;
|
||||
import org.alfresco.rest.model.RestActionDefinitionModelsCollection;
|
||||
import org.alfresco.rest.model.RestNodeModel;
|
||||
@@ -105,6 +103,30 @@ public class ActionsTests extends RestTest
|
||||
});
|
||||
}
|
||||
|
||||
@TestRail (section = { TestGroup.REST_API, TestGroup.ACTIONS }, executionType = ExecutionType.SANITY,
|
||||
description = "Sanity test for POST /action-executions")
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.ACTIONS, TestGroup.SANITY })
|
||||
public void executeActionWithoutParam() throws Exception
|
||||
{
|
||||
JSONObject response = restClient.authenticateUser(adminUser).withCoreAPI().usingActions().executeAction
|
||||
("check-out", document);
|
||||
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
|
||||
|
||||
assertFalse(response.getString("id").isEmpty());
|
||||
|
||||
/*
|
||||
* Get all node properties and check that action was executed and
|
||||
* cm:checkedOut aspect was added
|
||||
*/
|
||||
Utility.sleep(500, 20000, () -> {
|
||||
RestNodeModel fileModel = restClient.authenticateUser(adminUser).withCoreAPI().usingNode(document)
|
||||
.getNode();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
fileModel.assertThat().field("aspectNames").contains("cm:checkedOut");
|
||||
});
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API,TestGroup.ACTIONS }, executionType = ExecutionType.SANITY,
|
||||
description = "Sanity test for ACTIONS endpoint GET action-definitions/{actionDefinitionId}")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.ACTIONS, TestGroup.SANITY})
|
||||
|
||||
@@ -74,13 +74,12 @@ public class DiscoveryTests extends RestTest
|
||||
assertTrue(modules.contains("alfresco-share-services"));
|
||||
assertTrue(modules.contains("alfresco-saml-repo"));
|
||||
assertTrue(modules.contains("org_alfresco_device_sync_repo"));
|
||||
// The MM does not support new RenditionService2
|
||||
// assertTrue(modules.contains("org_alfresco_mm_repo"));
|
||||
assertTrue(modules.contains("org_alfresco_mm_repo"));
|
||||
assertTrue(modules.contains("org.alfresco.module.TransformationServer"));
|
||||
|
||||
// Check that all installed modules are in INSTALLED state
|
||||
List<String> modulesStates = restClient.onResponse().getResponse().jsonPath().getList("entry.repository.modules.installState", String.class);
|
||||
assertEquals(Collections.frequency(modulesStates, "INSTALLED"), 10);
|
||||
assertEquals(Collections.frequency(modulesStates, "INSTALLED"), 11);
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.DISCOVERY, TestGroup.SANITY, TestGroup.CORE })
|
||||
|
||||
@@ -10,6 +10,8 @@ import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import org.alfresco.dataprep.CMISUtil.DocumentType;
|
||||
import org.alfresco.rest.RestTest;
|
||||
@@ -19,6 +21,7 @@ import org.alfresco.rest.model.RestNodeModel;
|
||||
import org.alfresco.rest.model.RestVersionModel;
|
||||
import org.alfresco.rest.model.RestVersionModelsCollection;
|
||||
import org.alfresco.rest.model.body.RestNodeLockBodyModel;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.alfresco.utility.Utility;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FileType;
|
||||
@@ -30,6 +33,7 @@ import org.alfresco.utility.report.Bug;
|
||||
import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Ignore;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
@@ -112,6 +116,37 @@ public class NodesContentAndVersioningTests extends RestTest
|
||||
restClient.withCoreAPI().usingNode(iso8859File).getNodeContent().assertThat().contentType(iso8859Type);
|
||||
}
|
||||
|
||||
|
||||
// This test takes around 30 minutes to complete so it will be ignored by default
|
||||
@Test(enabled=false, groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.REGRESSION })
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.NODES },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify that the node content is streamed directly to the client and not buffered in memory.")
|
||||
public void verifyUploadDownloadLargeFileUsingRestAPI() throws Exception
|
||||
{
|
||||
Integer largeFileSizeBytes = Integer.MAX_VALUE;
|
||||
String largeFileName = "largeFile.tmp";
|
||||
String tempFolderPath = TempFileProvider.getTempDir().getAbsolutePath();
|
||||
|
||||
STEP("1. Create a folder and a large file");
|
||||
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
|
||||
createRandomFileInDirectory(tempFolderPath, largeFileName, largeFileSizeBytes);
|
||||
|
||||
STEP("2. Using multipart data upload for the large file (POST nodes/{nodeId}/children).");
|
||||
File largeFile = new File(tempFolderPath, largeFileName);
|
||||
FileModel largeFileModel = new FileModel(largeFileName, FileType.UNDEFINED);
|
||||
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", largeFile);
|
||||
RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
largeFileModel.setNodeRef(fileNode.getId());
|
||||
|
||||
STEP("3. Retrieve the content of the node without running out of memory (GET nodes/{nodeId}/content).");
|
||||
RestResponse nodeContent = restClient.withCoreAPI().usingNode(largeFileModel).getNodeContent();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
assertEquals(Integer.valueOf(nodeContent.getResponse().getHeader("Content-Length")), largeFileSizeBytes);
|
||||
|
||||
largeFile.delete();
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.NODES }, executionType = ExecutionType.SANITY, description = "Verify updating a node content.")
|
||||
public void testUpdateNodeContent() throws Exception
|
||||
@@ -262,4 +297,13 @@ public class NodesContentAndVersioningTests extends RestTest
|
||||
restClient.assertHeaderValueContains("content-range", "bytes 1-10");
|
||||
restClient.assertHeaderValueContains("content-length", String.valueOf(10));
|
||||
}
|
||||
|
||||
|
||||
private void createRandomFileInDirectory(String path, String fileName, int size) throws IOException {
|
||||
String fullPath = new File(path, fileName).getPath();
|
||||
|
||||
RandomAccessFile file = new RandomAccessFile(fullPath,"rw");
|
||||
file.setLength(size);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class AvatarPeopleSanityTest extends RestTest
|
||||
ValidatableResponse response = restClient.withCoreAPI().usingAuthUser()
|
||||
.uploadAvatarContent(restProperties.envProperty().getFullServerUrl(), avatarFile).statusCode(200);
|
||||
// Renditions are async
|
||||
Utility.sleep(200, 2000, () ->
|
||||
Utility.sleep(500, 60000, () ->
|
||||
{
|
||||
restClient.authenticateUser(userModel).withCoreAPI().usingAuthUser().downloadAvatarContent();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package org.alfresco.rest.renditions;
|
||||
|
||||
import org.alfresco.rest.model.RestNodeModel;
|
||||
import org.alfresco.rest.model.RestRenditionInfoModel;
|
||||
import org.alfresco.rest.model.RestRenditionInfoModelCollection;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* Sanity check for renditions through REST API.<br>
|
||||
* Tests upload files and then request renditions for those files. <br>
|
||||
* Renditions are requested based on supported renditions according to GET '/nodes/{nodeId}/renditions'. <br>
|
||||
*/
|
||||
@Test(groups = {TestGroup.REQUIRE_TRANSFORMATION, TestGroup.RENDITIONS_REGRESSION})
|
||||
public class AvailableRenditionTests extends RenditionIntegrationTests
|
||||
{
|
||||
/** List of parameters used as an input to supportedRenditionTest - fileName, nodeId, renditionId, expectedMimeType **/
|
||||
private List<Object[]> renditionsToTest;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void dataPreparation() throws Exception
|
||||
{
|
||||
super.dataPreparation();
|
||||
|
||||
// Upload files and get available renditions for each file
|
||||
List<String> toTest = Arrays.asList("doc", "xls", "ppt", "docx", "xlsx", "pptx", "msg", "pdf", "png", "gif", "jpg");
|
||||
List<Object[]> renditionsForFiles = new LinkedList<>();
|
||||
for (String extensions : toTest)
|
||||
{
|
||||
String sourceFile = "quick/quick." + extensions;
|
||||
renditionsForFiles.addAll(uploadFileAndGetAvailableRenditions(sourceFile));
|
||||
}
|
||||
|
||||
renditionsToTest = Collections.unmodifiableList(renditionsForFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a source file and get all supported renditions for it.
|
||||
*/
|
||||
private List<Object[]> uploadFileAndGetAvailableRenditions(String sourceFile) throws Exception
|
||||
{
|
||||
|
||||
// Create folder & upload file
|
||||
RestNodeModel fileNode = uploadFile(sourceFile);
|
||||
FileModel file = new FileModel();
|
||||
file.setNodeRef(fileNode.getId());
|
||||
|
||||
List<Object[]> renditionsForFile = new LinkedList<>();
|
||||
|
||||
// Get supported renditions
|
||||
RestRenditionInfoModelCollection renditionsInfo = restClient.withCoreAPI().usingNode(file).getNodeRenditionsInfo();
|
||||
for (RestRenditionInfoModel m : renditionsInfo.getEntries())
|
||||
{
|
||||
RestRenditionInfoModel renditionInfo = m.onModel();
|
||||
String renditionId = renditionInfo.getId();
|
||||
String targetMimeType = renditionInfo.getContent().getMimeType();
|
||||
|
||||
renditionsForFile.add(new Object[]{sourceFile, fileNode.getId(), renditionId, targetMimeType});
|
||||
|
||||
}
|
||||
|
||||
return renditionsForFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a particular rendition can be created for the file and that it has the expected Mime type
|
||||
*/
|
||||
@Test(dataProvider = "RenditionTestDataProvider", groups = {TestGroup.REST_API, TestGroup.RENDITIONS, TestGroup.SANITY})
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.RENDITIONS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify renditions created for a selection of test files via POST nodes/{nodeId}/renditions")
|
||||
public void supportedRenditionTest(String fileName, String nodeId, String renditionId, String expectedMimeType) throws Exception
|
||||
{
|
||||
checkRendition(fileName, nodeId, renditionId, expectedMimeType);
|
||||
}
|
||||
|
||||
@DataProvider(name = "RenditionTestDataProvider")
|
||||
protected Iterator<Object[]> renditionTestDataProvider() throws Exception
|
||||
{
|
||||
return renditionsToTest.iterator();
|
||||
}
|
||||
|
||||
@Test(groups = {TestGroup.REST_API, TestGroup.RENDITIONS, TestGroup.SANITY})
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.RENDITIONS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify that there are some available renditions.")
|
||||
public void renditionsAvailableTest()
|
||||
{
|
||||
Assert.assertFalse(renditionsToTest.isEmpty(), "No available renditions were reported for any of the test files.");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "UnsupportedRenditionTestDataProvider",groups = {TestGroup.REST_API, TestGroup.RENDITIONS, TestGroup.SANITY})
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.RENDITIONS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify that requests for unsupported renditions return 400 ")
|
||||
public void unsupportedRenditionTest(String sourceFile, String renditionId) throws Exception
|
||||
{
|
||||
RestNodeModel fileNode = uploadFile(sourceFile);
|
||||
|
||||
// 2. Request rendition of the file using RESTAPI
|
||||
FileModel file = new FileModel(sourceFile);
|
||||
file.setNodeRef(fileNode.getId());
|
||||
restClient.withCoreAPI().usingNode(file).createNodeRendition(renditionId);
|
||||
|
||||
Assert.assertEquals(restClient.getStatusCode(), HttpStatus.BAD_REQUEST.toString(),
|
||||
"Expected to see the rendition rejected. [" + sourceFile + ", " + renditionId + "] [source file, rendition ID] ");
|
||||
}
|
||||
|
||||
@DataProvider(name = "UnsupportedRenditionTestDataProvider")
|
||||
protected Iterator<Object[]> unsupportedRenditionTestDataProvider() throws Exception
|
||||
{
|
||||
String renditionId = "pdf";
|
||||
|
||||
List<Object[]> toTest = new LinkedList<>();
|
||||
toTest.add(new Object[]{"quick/quick.png", renditionId});
|
||||
toTest.add(new Object[]{"quick/quick.gif", renditionId});
|
||||
toTest.add(new Object[]{"quick/quick.jpg", renditionId});
|
||||
toTest.add(new Object[]{"quick/quick.pdf", renditionId});
|
||||
|
||||
return toTest.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +90,12 @@ public class CreateRenditionTests extends RestTest
|
||||
|
||||
restClient.authenticateUser(user).withCoreAPI().usingNode(document).createNodeRendition("doclib");
|
||||
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
|
||||
|
||||
restClient.withCoreAPI().usingNode(document).getNodeRenditionUntilIsCreated("doclib")
|
||||
.assertThat().field("status").is("CREATED");
|
||||
|
||||
// Renditions are async
|
||||
Utility.sleep(500, 60000, () ->
|
||||
{
|
||||
restClient.withCoreAPI().usingNode(document).getNodeRenditionUntilIsCreated("doclib")
|
||||
.assertThat().field("status").is("CREATED");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.alfresco.rest.renditions;
|
||||
|
||||
import org.alfresco.rest.RestTest;
|
||||
import org.alfresco.rest.core.RestResponse;
|
||||
import org.alfresco.rest.model.RestNodeModel;
|
||||
import org.alfresco.utility.Utility;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.SiteModel;
|
||||
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
||||
public abstract class RenditionIntegrationTests extends RestTest
|
||||
{
|
||||
|
||||
protected UserModel user;
|
||||
protected SiteModel site;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void dataPreparation() throws Exception
|
||||
{
|
||||
user = dataUser.createRandomTestUser();
|
||||
site = dataSite.usingUser(user).createPublicRandomSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a rendition can be created for the specified node id
|
||||
* @param fileName
|
||||
* @param nodeId
|
||||
* @param renditionId
|
||||
* @param expectedMimeType
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void checkRendition(String fileName, String nodeId, String renditionId, String expectedMimeType) throws Exception
|
||||
{
|
||||
FileModel file = new FileModel();
|
||||
file.setNodeRef(nodeId);
|
||||
|
||||
// 1. Create a rendition of the file using RESTAPI
|
||||
restClient.withCoreAPI().usingNode(file).createNodeRendition(renditionId);
|
||||
Assert.assertEquals(restClient.getStatusCode(), HttpStatus.ACCEPTED.toString(),
|
||||
"Failed to submit a request for rendition. [" + fileName+ ", " + renditionId+"] [source file, rendition ID]. ");
|
||||
|
||||
// 2. Verify that a rendition of the file is created and has content using RESTAPI
|
||||
RestResponse restResponse = restClient.withCoreAPI().usingNode(file).getNodeRenditionContentUntilIsCreated(renditionId);
|
||||
Assert.assertEquals(restClient.getStatusCode(), HttpStatus.OK.toString(),
|
||||
"Failed to produce rendition. [" + fileName+ ", " + renditionId+"] [source file, rendition ID] ");
|
||||
|
||||
// 3. Check the returned content type
|
||||
Assert.assertEquals(restClient.getResponseHeaders().getValue("Content-Type"), expectedMimeType+";charset=UTF-8",
|
||||
"Rendition was created but it has the wrong Content-Type. [" + fileName+ ", " + renditionId + "] [source file, rendition ID]");
|
||||
|
||||
|
||||
Assert.assertTrue((restResponse.getResponse().body().asInputStream().available() > 0),
|
||||
"Rendition was created but its content is empty. [" + fileName+ ", " + renditionId+"] [source file, rendition ID] ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a file and return its node id
|
||||
* @param sourceFile
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected RestNodeModel uploadFile(String sourceFile) throws Exception
|
||||
{
|
||||
FolderModel folder = FolderModel.getRandomFolderModel();
|
||||
folder = dataContent.usingUser(user).usingSite(site).createFolder(folder);
|
||||
restClient.authenticateUser(user).configureRequestSpec()
|
||||
.addMultiPart("filedata", Utility.getResourceTestDataFile(sourceFile));
|
||||
RestNodeModel fileNode = restClient.authenticateUser(user).withCoreAPI().usingNode(folder).createNode();
|
||||
|
||||
Assert.assertEquals(restClient.getStatusCode(), HttpStatus.CREATED.toString(),
|
||||
"Failed to created a node for rendition tests using file " + sourceFile);
|
||||
|
||||
return fileNode;
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.search;
|
||||
|
||||
import javax.naming.AuthenticationException;
|
||||
|
||||
import org.alfresco.dataprep.SiteService.Visibility;
|
||||
import org.alfresco.rest.RestTest;
|
||||
import org.alfresco.rest.core.RestResponse;
|
||||
@@ -33,6 +31,8 @@ import org.alfresco.utility.model.UserModel;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
||||
import javax.naming.AuthenticationException;
|
||||
|
||||
/**
|
||||
* Abstract Search test class that contains useful methods
|
||||
* such as:
|
||||
@@ -129,15 +129,23 @@ public class AbstractSearchTest extends RestTest
|
||||
return restClient.authenticateUser(userModel).withSearchAPI().search(query);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Helper method which create an http post request to Search API end point.
|
||||
* @param term String search term
|
||||
* Executes the given search request without throwing checked exceptions (a {@link RuntimeException} will be thrown in case).
|
||||
* @param query the search request.
|
||||
* @return {@link SearchResponse} response.
|
||||
* @throws Exception if error
|
||||
*
|
||||
*/
|
||||
protected SearchResponse query(SearchRequest query) throws Exception
|
||||
{
|
||||
return restClient.authenticateUser(userModel).withSearchAPI().search(query);
|
||||
try
|
||||
{
|
||||
return restClient.authenticateUser(userModel).withSearchAPI().search(query);
|
||||
}
|
||||
catch (final Exception exception)
|
||||
{
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
protected SearchRequest createQuery(String term)
|
||||
@@ -148,6 +156,7 @@ public class AbstractSearchTest extends RestTest
|
||||
query.setQuery(queryReq);
|
||||
return query;
|
||||
}
|
||||
|
||||
protected SearchRequest carsQuery()
|
||||
{
|
||||
return createQuery("cars");
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
*/
|
||||
package org.alfresco.rest.search;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests the search functionality using an ancestor path.
|
||||
* Using the category as an example, it is a node that is located
|
||||
@@ -32,7 +33,7 @@ import java.util.List;
|
||||
* so that we can return all the child elements of our target path.
|
||||
* A search on root/rootCategory/classifiable should return Regions, Languages
|
||||
* as they are the child elements of the given path.
|
||||
*
|
||||
*
|
||||
* @author Michael Suzuki
|
||||
*
|
||||
*/
|
||||
@@ -77,94 +78,108 @@ public class SearchAPATHTest extends AbstractSearchTest
|
||||
* "consistency": {"lastTxId": 89}
|
||||
* }
|
||||
*}}
|
||||
*
|
||||
*
|
||||
*/
|
||||
public void searchLevel0() throws Exception
|
||||
{
|
||||
SearchRequest searchQuery = new SearchRequest();
|
||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
||||
queryReq.setQuery("name:*");
|
||||
searchQuery.setQuery(queryReq);
|
||||
|
||||
RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel();
|
||||
List<RestRequestFacetFieldModel> list = new ArrayList<>();
|
||||
list.add(new RestRequestFacetFieldModel("APATH","0"));
|
||||
facetFields.setFacets(list);
|
||||
searchQuery.setFacetFields(facetFields);
|
||||
SearchRequest searchQuery = searchRequestWithAPATHFacet("name:*", "0");
|
||||
SearchResponse response = query(searchQuery);
|
||||
RestResultBucketsModel fresponse = response.getContext().getFacetsFields().get(0);
|
||||
fresponse.assertThat().field("buckets").isNotEmpty();
|
||||
Assert.assertEquals(2,fresponse.getBuckets().size());
|
||||
fresponse.getBuckets().get(0).assertThat().field("label").contains("0/");
|
||||
fresponse.getBuckets().get(1).assertThat().field("label").is("0/");
|
||||
|
||||
List<FacetFieldBucket> buckets = getBuckets(response);
|
||||
Assert.assertEquals(2, buckets.size());
|
||||
|
||||
buckets.forEach(bucket -> bucket.assertThat().field("label").contains("0/"));
|
||||
}
|
||||
|
||||
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
|
||||
public void searchLevel0andIncludeSubLevel1() throws Exception
|
||||
{
|
||||
SearchRequest searchQuery = new SearchRequest();
|
||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
||||
queryReq.setQuery("name:*");
|
||||
searchQuery.setQuery(queryReq);
|
||||
|
||||
RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel();
|
||||
List<RestRequestFacetFieldModel> list = new ArrayList<>();
|
||||
list.add(new RestRequestFacetFieldModel("APATH","1"));
|
||||
facetFields.setFacets(list);
|
||||
searchQuery.setFacetFields(facetFields);
|
||||
SearchRequest searchQuery = searchRequestWithAPATHFacet("name:*", "1/");
|
||||
SearchResponse response = query(searchQuery);
|
||||
RestResultBucketsModel fresponse = response.getContext().getFacetsFields().get(0);
|
||||
Assert.assertEquals(4,fresponse.getBuckets().size());
|
||||
fresponse.getBuckets().get(0).assertThat().field("label").contains("1/");
|
||||
|
||||
List<FacetFieldBucket> buckets = getBuckets(response);
|
||||
Assert.assertEquals(4, buckets.size());
|
||||
|
||||
getFirstBucket(response).assertThat().field("label").contains("1/");
|
||||
}
|
||||
|
||||
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
|
||||
public void searchLevel2() throws Exception
|
||||
{
|
||||
String queryString = "name:"+ "cars";
|
||||
|
||||
SearchRequest searchQuery = new SearchRequest();
|
||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
||||
queryReq.setQuery(queryString);
|
||||
searchQuery.setQuery(queryReq);
|
||||
|
||||
RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel();
|
||||
List<RestRequestFacetFieldModel> list = new ArrayList<>();
|
||||
list.add(new RestRequestFacetFieldModel("APATH","1/"));
|
||||
facetFields.setFacets(list);
|
||||
searchQuery.setFacetFields(facetFields);
|
||||
|
||||
SearchResponse response = query(searchQuery);
|
||||
|
||||
RestResultBucketsModel fresponse = response.getContext().getFacetsFields().get(0);
|
||||
String path = fresponse.getBuckets().get(0).getLabel().replace("1/", "2/");
|
||||
list.remove(0);
|
||||
list.add(new RestRequestFacetFieldModel("APATH", path));
|
||||
|
||||
facetFields.setFacets(list);
|
||||
searchQuery.setFacetFields(facetFields);
|
||||
response = query(searchQuery);
|
||||
fresponse = response.getContext().getFacetsFields().get(0);
|
||||
Assert.assertTrue(fresponse.getBuckets().size() >= 1);
|
||||
fresponse.getBuckets().get(0).assertThat().field("label").contains("2/");
|
||||
fresponse.getBuckets().get(0).assertThat().field("label").contains(path);
|
||||
/**
|
||||
* To return the contents of the path and its sub directory change the prefix
|
||||
* Below 2/path/path -> will return whats in path/path only
|
||||
* if 3/path/path -> will return contents from path/path/path
|
||||
* @throws Exception
|
||||
*/
|
||||
searchQuery = new SearchRequest();
|
||||
queryReq = new RestRequestQueryModel();
|
||||
queryReq.setQuery(queryString);
|
||||
searchQuery.setQuery(queryReq);
|
||||
facetFields = new RestRequestFacetFieldsModel();
|
||||
list.remove(0);
|
||||
list.add(new RestRequestFacetFieldModel("APATH",path.replace("2/", "3/")));
|
||||
facetFields.setFacets(list);
|
||||
searchQuery.setFacetFields(facetFields);
|
||||
response = query(searchQuery);
|
||||
fresponse = response.getContext().getFacetsFields().get(0);
|
||||
Assert.assertTrue(fresponse.getBuckets().size() >= 1);
|
||||
fresponse.getBuckets().get(0).assertThat().field("label").contains("3/");
|
||||
String queryString = "name:cars";
|
||||
|
||||
SearchRequest l1Request = searchRequestWithAPATHFacet(queryString, "1/");
|
||||
SearchResponse l1Response = query(l1Request);
|
||||
|
||||
String l2Prefix = getFirstBucket(l1Response).getLabel().replaceFirst("^1/", "2/");
|
||||
|
||||
SearchRequest l2Request = searchRequestWithAPATHFacet(queryString, l2Prefix);
|
||||
SearchResponse l2Response = query(l2Request);
|
||||
|
||||
FacetFieldBucket bucket = getFirstBucket(l2Response);
|
||||
bucket.assertThat().field("label").contains(l2Prefix);
|
||||
|
||||
String l3Prefix = bucket.getLabel().replaceFirst("^2/", "3/");
|
||||
|
||||
SearchRequest l3Request = searchRequestWithAPATHFacet(queryString, l3Prefix);
|
||||
SearchResponse l3response = query(l3Request);
|
||||
|
||||
List<FacetFieldBucket> buckets = getBuckets(l3response);
|
||||
Assert.assertEquals(1, buckets.size());
|
||||
|
||||
getFirstBucket(l3response).assertThat().field("label").contains(l3Prefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SearchRequest} for this test case.
|
||||
*
|
||||
* @param queryString the query string.
|
||||
* @param facetPrefix the facet prefix.
|
||||
* @return a new {@link SearchRequest} for this test case.
|
||||
*/
|
||||
private SearchRequest searchRequestWithAPATHFacet(String queryString, String facetPrefix)
|
||||
{
|
||||
SearchRequest searchRequest = new SearchRequest();
|
||||
|
||||
RestRequestQueryModel query = new RestRequestQueryModel();
|
||||
query.setQuery(queryString);
|
||||
searchRequest.setQuery(query);
|
||||
|
||||
RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel();
|
||||
facetFields.setFacets(Collections.singletonList(new RestRequestFacetFieldModel("APATH", facetPrefix)));
|
||||
searchRequest.setFacetFields(facetFields);
|
||||
|
||||
return searchRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the first bucket from the given response.
|
||||
*
|
||||
* @param response the results of a query execution.
|
||||
* @return the first bucket included in the search response.
|
||||
*/
|
||||
private FacetFieldBucket getFirstBucket(SearchResponse response)
|
||||
{
|
||||
return getBuckets(response).iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the buckets from the given response.
|
||||
* The method also makes sure the buckets list is not empty in the input response.
|
||||
*
|
||||
* @param response the results of a query execution.
|
||||
* @return the getBuckets included in the search response.
|
||||
*/
|
||||
private List<FacetFieldBucket> getBuckets(SearchResponse response)
|
||||
{
|
||||
List<RestResultBucketsModel> facetFields = response.getContext().getFacetsFields();
|
||||
Assert.assertNotNull(facetFields);
|
||||
Assert.assertFalse(facetFields.isEmpty());
|
||||
|
||||
List<FacetFieldBucket> buckets = facetFields.iterator().next().getBuckets();
|
||||
Assert.assertNotNull(buckets);
|
||||
Assert.assertFalse(buckets.isEmpty());
|
||||
|
||||
return buckets;
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,23 @@
|
||||
*/
|
||||
package org.alfresco.rest.search;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.alfresco.rest.model.body.RestNodeLockBodyModel;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.codehaus.groovy.runtime.InvokerHelper.asList;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
* Search end point Public API test.
|
||||
@@ -71,4 +81,103 @@ public class SearchTest extends AbstractSearchTest
|
||||
response.getContext().assertThat().field("request").isNotEmpty();
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ACS_61n }) @TestRail(section = {
|
||||
TestGroup.REST_API, TestGroup.SEARCH,
|
||||
TestGroup.ACS_61n }, executionType = ExecutionType.REGRESSION, description = "Checks the \"include\" request parameter support the 'permissions' option") public void searchQuery_includePermissions_shouldReturnNodeWithPermissionsInformation()
|
||||
throws Exception
|
||||
{
|
||||
String query = "fox";
|
||||
String include = "permissions";
|
||||
|
||||
SearchRequest retrievalQueryIncludingPermissionsInformation = createQuery(query);
|
||||
retrievalQueryIncludingPermissionsInformation.setInclude(asList(include));
|
||||
|
||||
query(retrievalQueryIncludingPermissionsInformation);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
restClient.onResponse().assertThat().body("list.entries[0].entry.permissions", notNullValue());
|
||||
|
||||
SearchRequest retrievalQueryNotIncludingLockInformation = createQuery(query);
|
||||
|
||||
query(retrievalQueryNotIncludingLockInformation);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
restClient.onResponse().assertThat().body("list.entries[0].entry.permissions", nullValue());
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ACS_61n })
|
||||
@TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ACS_61n }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Checks the \"include\" request parameter support the 'isLocked' option")
|
||||
public void searchQuery_includeIsLocked_shouldReturnNodeWithLockInformation() throws Exception {
|
||||
String query = "fox";
|
||||
String include = "isLocked";
|
||||
|
||||
SearchRequest retrievalQueryIncludingLockInformation = createQuery(query);
|
||||
retrievalQueryIncludingLockInformation.setInclude(asList(include));
|
||||
|
||||
query(retrievalQueryIncludingLockInformation);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
restClient.onResponse().assertThat().body("list.entries[0].entry.isLocked", equalTo(false));
|
||||
|
||||
RestNodeLockBodyModel lockBodyModel = new RestNodeLockBodyModel();
|
||||
lockBodyModel.setLifetime("EPHEMERAL");
|
||||
lockBodyModel.setTimeToExpire(20);
|
||||
lockBodyModel.setType("FULL");
|
||||
restClient.authenticateUser(userModel).withCoreAPI().usingNode(file).usingParams("include=isLocked").lockNode(lockBodyModel);
|
||||
|
||||
query(retrievalQueryIncludingLockInformation);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
restClient.onResponse().assertThat().body("list.entries[0].entry.isLocked", equalTo(true));
|
||||
|
||||
SearchRequest retrievalQueryNotIncludingLockInformation = createQuery(query);
|
||||
|
||||
query(retrievalQueryNotIncludingLockInformation);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
restClient.onResponse().assertThat().body("list.entries[0].entry.isLocked", nullValue());
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ACS_61n })
|
||||
@TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ACS_61n }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Checks the \"include\" request parameter does not support the 'notValid' option")
|
||||
public void searchQuery_includeInvalid_shouldReturnBadResponse() throws Exception
|
||||
{
|
||||
String query = "fox";
|
||||
String notValidInclude = "notValid";
|
||||
SearchRequest permissionsRetrieval = createQuery(query);
|
||||
permissionsRetrieval.setInclude(asList(notValidInclude));
|
||||
|
||||
query(permissionsRetrieval);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
|
||||
restClient.onResponse()
|
||||
.assertThat()
|
||||
.body("error.briefSummary", containsString("An invalid argument was received "+notValidInclude));
|
||||
}
|
||||
|
||||
// Test that when fields parameter is set, only restricted fields appear in the response
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ASS_1 })
|
||||
public void searchWithFields() throws Exception
|
||||
{
|
||||
SearchRequest query = new SearchRequest();
|
||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
||||
queryReq.setQuery("alfresco");
|
||||
query.setQuery(queryReq);
|
||||
|
||||
// Restrict to fields: parentId
|
||||
List<String> fields = new ArrayList<String>();
|
||||
fields.add("parentId");
|
||||
query.setFields(fields);
|
||||
|
||||
query(query);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
// Only Field parentId is included in the response
|
||||
restClient.onResponse().assertThat().body("list.entries.entry[0].parentId", Matchers.notNullValue());
|
||||
// Usual Fields such as 'name, id' aren't included in the response
|
||||
restClient.onResponse().assertThat().body("list.entries.entry[0].name", Matchers.nullValue());
|
||||
restClient.onResponse().assertThat().body("list.entries.entry[0].id", Matchers.nullValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Alfresco Software Limited.
|
||||
* This file is part of Alfresco
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.rest.search.solr;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import javax.json.JsonArrayBuilder;
|
||||
|
||||
import org.alfresco.rest.core.JsonBodyGenerator;
|
||||
import org.alfresco.rest.model.RestTextResponse;
|
||||
import org.alfresco.rest.search.AbstractSearchTest;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* Tests for solr/alfresco Solr API.
|
||||
*
|
||||
* @author Meenal Bhave
|
||||
*/
|
||||
public class SearchSolrAPITest extends AbstractSearchTest
|
||||
{
|
||||
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_112 }, priority = 01)
|
||||
public void testGetSolrConfig() throws Exception
|
||||
{
|
||||
RestTextResponse response = restClient.authenticateUser(adminUserModel).withSolrAPI().getConfig();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
restClient.onResponse().assertThat().content(Matchers.containsString("config"));
|
||||
Assert.assertNotNull(response.getJsonValueByPath("config.requestHandler"));
|
||||
Assert.assertNotNull(response.getJsonObjectByPath("config.requestHandler"));
|
||||
|
||||
// TODO: Following asserts fail with error:
|
||||
/*
|
||||
* java.lang.IllegalStateException: Expected response body to be verified as JSON, HTML or XML but content-type 'text/plain' is not supported out of the box.
|
||||
* Try registering a custom parser using: RestAssured.registerParser("text/plain", <parser type>);
|
||||
*/
|
||||
|
||||
// response.assertThat().body("config.requestHandler", Matchers.notNullValue());
|
||||
// restClient.onResponse().assertThat().body("config.requestHandler",Matchers.notNullValue());
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_112 }, priority = 02)
|
||||
public void testEditSolrConfig() throws Exception
|
||||
{
|
||||
String expectedError = "solrconfig editing is not enabled due to disable.configEdit";
|
||||
|
||||
JsonArrayBuilder argsArray = JsonBodyGenerator.defineJSONArray();
|
||||
argsArray.add("ANYARGS");
|
||||
|
||||
String postBody = JsonBodyGenerator.defineJSON()
|
||||
.add("add-listener", JsonBodyGenerator.defineJSON()
|
||||
.add("event", "postCommit")
|
||||
.add("name", "newlistener")
|
||||
.add("class", "solr.RunExecutableListener")
|
||||
.add("exe", "ANYCOMMAND")
|
||||
.add("dir", "/usr/bin/")
|
||||
.add("args", argsArray)).build().toString();
|
||||
|
||||
// RestTextResponse response =
|
||||
restClient.authenticateUser(adminUserModel).withSolrAPI().postConfig(postBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.FORBIDDEN);
|
||||
|
||||
restClient.onResponse().assertThat().content(Matchers.containsString(expectedError));
|
||||
|
||||
// TODO: Following asserts fail with error:
|
||||
/*
|
||||
* java.lang.IllegalStateException: Expected response body to be verified as JSON, HTML or XML but content-type 'text/plain' is not supported out of the box.
|
||||
* Try registering a custom parser using: RestAssured.registerParser("text/plain", <parser type>);
|
||||
*/
|
||||
|
||||
// response.assertThat().body("error.msg", Matchers.contains(expectedError));
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_112 }, priority = 03)
|
||||
public void testGetSolrConfigOverlay() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel).withSolrAPI().getConfigOverlay();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
restClient.onResponse().assertThat().content(Matchers.containsString("overlay"));
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_112 }, priority = 04)
|
||||
public void testGetSolrConfigParams() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel).withSolrAPI().getConfigParams();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
restClient.onResponse().assertThat().content(Matchers.containsString("response"));
|
||||
}
|
||||
|
||||
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_112 }, priority = 05)
|
||||
public void testGetSolrSelect() throws Exception
|
||||
{
|
||||
String queryParams = "{!xmlparser v='<!DOCTYPE a SYSTEM \"http://localhost:4444/executed\"><a></a>'}";
|
||||
|
||||
String encodedQueryParams = URLEncoder.encode(queryParams, "UTF-8");
|
||||
|
||||
restClient.authenticateUser(dataContent.getAdminUser()).withParams(encodedQueryParams).withSolrAPI().getSelectQuery();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
|
||||
String errorMsg = "No QueryObjectBuilder defined for node a in {q={!xmlparser";
|
||||
Assert.assertTrue(restClient.onResponse().getResponse().body().xmlPath().getString("response").contains(errorMsg));
|
||||
}
|
||||
}
|
||||
@@ -32,4 +32,18 @@
|
||||
<class name="org.alfresco.rest.search.ShardInfoTest"/>
|
||||
</classes>
|
||||
</test>
|
||||
|
||||
<test name="SolrAPIs">
|
||||
<classes>
|
||||
<class name="org.alfresco.rest.search.solr.SearchSolrAPITest" />
|
||||
</classes>
|
||||
</test>
|
||||
|
||||
<test name="InsightEngine">
|
||||
<classes>
|
||||
<class name="org.alfresco.rest.search.sql.SearchSQLAPITest"/>
|
||||
<class name="org.alfresco.rest.search.sql.SearchSQLPhraseTest"/>
|
||||
<class name="org.alfresco.rest.search.sql.SearchSQLViaJDBCTest"/>
|
||||
</classes>
|
||||
</test>
|
||||
</suite>
|
||||
|
||||
@@ -8,6 +8,11 @@ sync.scheme=http
|
||||
sync.server=localhost
|
||||
sync.port=9090
|
||||
|
||||
# Solr Server Settings
|
||||
solr.scheme=http
|
||||
solr.server=localhost
|
||||
solr.port=8083
|
||||
|
||||
#Solr Indexing Time
|
||||
solrWaitTimeInSeconds=20
|
||||
|
||||
|
||||
Reference in New Issue
Block a user