ACS-3531 Replace content tests using TAS. (#1582)

* ACS-3531 Output the list of TAS tests that ran.

* ACS-3531 Update content and versioning REST tests. [tas]

* ACS-3531 Replace download/caching IT tests with TAS tests.
This commit is contained in:
Tom Page
2022-12-06 09:14:34 +00:00
committed by GitHub
parent b8994d990e
commit 7426a2eaa2
2 changed files with 155 additions and 145 deletions

View File

@@ -3,16 +3,22 @@ package org.alfresco.rest.nodes;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNotSame;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import javax.json.Json;
import javax.json.JsonObject;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Paths;
import io.restassured.http.Headers;
import org.alfresco.dataprep.CMISUtil.DocumentType;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.core.JsonBodyGenerator;
@@ -31,6 +37,7 @@ import org.alfresco.utility.model.UserModel;
import org.alfresco.utility.report.Bug;
import org.alfresco.utility.testrail.ExecutionType;
import org.alfresco.utility.testrail.annotation.TestRail;
import org.hamcrest.Matchers;
import org.json.JSONObject;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
@@ -48,7 +55,7 @@ public class NodesContentAndVersioningTests extends RestTest
private FileModel file1, file2;
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception
public void dataPreparation()
{
user1 = dataUser.createRandomTestUser();
user2 = dataUser.createRandomTestUser();
@@ -60,21 +67,18 @@ public class NodesContentAndVersioningTests extends RestTest
@TestRail(section = { TestGroup.REST_API, TestGroup.NODES }, executionType = ExecutionType.SANITY, description = "Verify file name in Content-Disposition header")
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
public void checkFileNameWithRegularCharsInHeader() throws Exception
public void checkFileNameWithRegularCharsInHeader()
{
restClient.authenticateUser(user1).withCoreAPI().usingNode(file1).usingParams("attachment=false").getNodeContent();
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.assertHeaderValueContains("Content-Disposition", String.format("filename=\"%s\"", file1.getName()));
}
@Bug(id = "MNT-17545", description = "HTTP Header Injection in ContentStreamer", status = Bug.Status.FIXED)
@TestRail(section = { TestGroup.REST_API,
TestGroup.NODES }, executionType = ExecutionType.REGRESSION, description = "Verify file name with special chars is escaped in Content-Disposition header")
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.REGRESSION })
public void checkFileNameWithSpecialCharsInHeader() throws Exception
public void checkFileNameWithSpecialCharsInHeader()
{
char c1 = 127;
char c2 = 31;
@@ -88,14 +92,12 @@ public class NodesContentAndVersioningTests extends RestTest
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
@TestRail(section = { TestGroup.REST_API,
TestGroup.NODES }, executionType = ExecutionType.SANITY, description = "Verify that alfresco returns the correct encoding for files created via REST.")
public void verifyFileEncodingUsingRestAPI() throws Exception
public void verifyFileEncodingUsingRestAPI()
{
STEP("1. Create a folder, two text file templates and define the expected encoding.");
FileModel utf8File = new FileModel("utf8File", FileType.TEXT_PLAIN);
FileModel iso8859File = new FileModel("iso8859File", FileType.TEXT_PLAIN);
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
String utf8Type = "text/plain;charset=UTF-8";
String iso8859Type = "text/plain;charset=ISO-8859-1";
STEP("2. Using multipart data upload (POST nodes/{nodeId}/children) the UTF-8 encoded file.");
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("UTF-8File.txt"));
@@ -110,6 +112,8 @@ public class NodesContentAndVersioningTests extends RestTest
iso8859File.setNodeRef(fileNode.getId());
STEP("4. Retrieve the nodes and verify that the content type is the expected one (GET nodes/{nodeId}).");
String utf8Type = "text/plain;charset=UTF-8";
String iso8859Type = "text/plain;charset=ISO-8859-1";
restClient.withCoreAPI().usingNode(utf8File).getNodeContent().assertThat().contentType(utf8Type);
restClient.withCoreAPI().usingNode(iso8859File).getNodeContent().assertThat().contentType(iso8859Type);
}
@@ -119,7 +123,7 @@ public class NodesContentAndVersioningTests extends RestTest
@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
public void verifyUploadDownloadLargeFileUsingRestAPI()
{
Integer largeFileSizeBytes = Integer.MAX_VALUE;
String largeFileName = "largeFile.tmp";
@@ -145,12 +149,12 @@ public class NodesContentAndVersioningTests extends RestTest
largeFile.delete();
}
public static File getSystemTempDir() throws Exception
public static File getSystemTempDir()
{
String systemTempDirPath = System.getProperty("java.io.tmpdir");
if (systemTempDirPath == null)
{
throw new Exception("System property not available: " + "java.io.tmpdir");
throw new RuntimeException("System property not available: " + "java.io.tmpdir");
}
File systemTempDir = new File(systemTempDirPath);
return systemTempDir;
@@ -158,7 +162,7 @@ public class NodesContentAndVersioningTests extends RestTest
@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
public void testUpdateNodeContent()
{
STEP("1. Retrieve the node in order to get data to compare after update GET /nodes/{nodeId}?include=path.");
RestNodeModel initialNode = restClient.authenticateUser(user1).withCoreAPI().usingNode(file1).usingParams("include=path").getNode();
@@ -181,7 +185,7 @@ public class NodesContentAndVersioningTests extends RestTest
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
@TestRail(section = { TestGroup.REST_API, TestGroup.NODES }, executionType = ExecutionType.SANITY, description = "Test copy a node.")
public void testCopyNode() throws Exception
public void testCopyNode()
{
STEP("1. Create a lock and lock the node POST /nodes/{nodeId}/lock?include=path,isLocked.");
RestNodeLockBodyModel lockBodyModel = new RestNodeLockBodyModel();
@@ -266,7 +270,7 @@ public class NodesContentAndVersioningTests extends RestTest
RestResponse versionContent = restClient.withCoreAPI().usingNode(file2).getVersionContent("2.0");
restClient.assertStatusCodeIs(HttpStatus.OK);
assertEquals("Sample text.\n", versionContent.getResponse().body().asString());
assertEquals("Sample text.", versionContent.getResponse().body().asString());
restClient.assertHeaderValueContains("Content-Disposition", "attachment");
restClient.assertHeaderValueContains("Content-Disposition", String.format("filename=\"%s\"", file2.getName()));
});
@@ -274,7 +278,7 @@ public class NodesContentAndVersioningTests extends RestTest
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
@TestRail(section = { TestGroup.REST_API, TestGroup.NODES }, executionType = ExecutionType.SANITY, description = "Test revert and delete a node version.")
public void testRevertDeleteVersion() throws Exception
public void testRevertDeleteVersion()
{
STEP("1. Revert to version 1.0 POST /nodes/{nodeId}/versions/{versionId}/revert");
RestVersionModel version = restClient.authenticateUser(user2).withCoreAPI().usingNode(file2).revertVersion("1.0", new String("{}"));
@@ -299,7 +303,7 @@ public class NodesContentAndVersioningTests extends RestTest
@TestRail(section = { TestGroup.REST_API, TestGroup.NODES }, executionType = ExecutionType.SANITY, description = "Verify file name in Content Range header")
@Test(groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
public void checkFileNameContentRangeHeader() throws Exception
public void checkFileNameContentRangeHeader()
{
restClient.configureRequestSpec().addHeader("content-range", "bytes=1-10");
restClient.authenticateUser(user1).withCoreAPI().usingNode(file1).getNodeContent();
@@ -308,12 +312,141 @@ public class NodesContentAndVersioningTests extends RestTest
restClient.assertHeaderValueContains("content-length", String.valueOf(10));
}
@Test (groups = { TestGroup.REST_API, TestGroup.NODES })
public void checkUploadResponse()
{
STEP("Create a folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
private void createRandomFileInDirectory(String path, String fileName, int size) throws IOException {
STEP("Upload a text document to the folder.");
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("UTF-8File.txt"));
RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
restClient.assertStatusCodeIs(HttpStatus.CREATED);
fileNode.assertThat().field("id").isNotNull()
.and().field("name").is("UTF-8File.txt")
.and().field("content.mimeType").is(FileType.TEXT_PLAIN.mimeType);
}
@Test (groups = { TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY })
public void checkTextFileDownload()
{
STEP("Create a folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
STEP("Upload a text document to the folder.");
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("sampleContent.txt"));
RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
FileModel fileModel = new FileModel();
fileModel.setNodeRef(fileNode.getId());
restClient.assertStatusCodeIs(HttpStatus.CREATED);
STEP("Download the file and check the content and headers.");
RestResponse nodeContent = restClient.withCoreAPI().usingNode(fileModel).getNodeContent();
restClient.assertStatusCodeIs(HttpStatus.OK);
nodeContent.assertThat().body(Matchers.equalTo("Sample text."));
restClient.assertHeaderValueContains("Content-Disposition", "attachment; filename=\"sampleContent.txt\"; filename*=UTF-8''sampleContent.txt");
Headers responseHeaders = restClient.getResponseHeaders();
String cacheControl = responseHeaders.getValue("Cache-Control");
assertTrue(cacheControl.contains("must-revalidate"), "Cache-Control is missing \"must-revalidate\": " + cacheControl);
assertTrue(cacheControl.contains("max-age=0"), "Cache-Control is missing \"max-age=0\": " + cacheControl);
assertNotNull(responseHeaders.getValue("Expires"), "\"Expires\" header is missing");
}
@Test (groups = { TestGroup.REST_API, TestGroup.NODES })
public void checkBinaryFileDownload() throws Exception
{
STEP("Create a folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
STEP("Upload a text document to the folder.");
File binaryFile = Utility.getResourceTestDataFile("avatar.jpg");
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", binaryFile);
RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
FileModel fileModel = new FileModel();
fileModel.setNodeRef(fileNode.getId());
restClient.assertStatusCodeIs(HttpStatus.CREATED);
STEP("Download the file and check the binary content and headers.");
RestResponse nodeContent = restClient.withCoreAPI().usingNode(fileModel).getNodeContent();
restClient.assertStatusCodeIs(HttpStatus.OK);
byte[] originalBytes = Files.readAllBytes(Paths.get(binaryFile.getAbsolutePath()));
assertEquals(nodeContent.getResponse().getBody().asByteArray(), originalBytes, "Unexpected content retrieved");
restClient.assertHeaderValueContains("Content-Disposition", "attachment; filename=\"avatar.jpg\"; filename*=UTF-8''avatar.jpg");
Headers responseHeaders = restClient.getResponseHeaders();
String cacheControl = responseHeaders.getValue("Cache-Control");
assertTrue(cacheControl.contains("must-revalidate"), "Cache-Control is missing \"must-revalidate\": " + cacheControl);
assertTrue(cacheControl.contains("max-age=0"), "Cache-Control is missing \"max-age=0\": " + cacheControl);
assertNotNull(responseHeaders.getValue("Expires"), "\"Expires\" header is missing");
}
@Test (groups = { TestGroup.REST_API, TestGroup.NODES })
public void checkNotModifiedStatusCode()
{
STEP("Create a folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
STEP("Upload a text document to the folder.");
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("sampleContent.txt"));
RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
FileModel fileModel = new FileModel();
fileModel.setNodeRef(fileNode.getId());
STEP("Download the file with If-Modified-Since in the past and check for a 200 status code.");
restClient.configureRequestSpec().addHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");
restClient.withCoreAPI().usingNode(fileModel).getNodeContent();
restClient.assertStatusCodeIs(HttpStatus.OK);
STEP("Try redownloading the file the current If-Modified-Since and check for a 304 status code.");
String lastModified = restClient.getResponseHeaders().getValue("Last-Modified");
restClient.configureRequestSpec().addHeader("If-Modified-Since", lastModified);
restClient.withCoreAPI().usingNode(fileModel).getNodeContent();
restClient.assertStatusCodeIs(HttpStatus.NOT_MODIFIED);
}
@Test (groups = { TestGroup.REST_API, TestGroup.NODES })
public void checkModificationUpdatesLastModifiedHeader() throws InterruptedException
{
STEP("Create a folder in the test site.");
FolderModel folder = dataContent.usingUser(user1).usingSite(site1).createFolder(FolderModel.getRandomFolderModel());
STEP("Upload a text document to the folder.");
restClient.authenticateUser(user1).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("sampleContent.txt"));
RestNodeModel fileNode = restClient.withCoreAPI().usingNode(folder).createNode();
FileModel fileModel = new FileModel();
fileModel.setNodeRef(fileNode.getId());
STEP("Download the file and get the Last-Modified header.");
restClient.withCoreAPI().usingNode(fileModel).getNodeContent();
String oldLastModified = restClient.getResponseHeaders().getValue("Last-Modified");
STEP("Wait for a second so that the modification will be at a different datetime.");
Thread.sleep(1000);
STEP("Modify the description and check the Last-Modified header changes.");
JsonObject json = Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("cm:description", "New description")).build();
restClient.withCoreAPI().usingNode(fileModel).updateNode(json.toString());
restClient.configureRequestSpec().addHeader("If-Modified-Since", oldLastModified);
restClient.withCoreAPI().usingNode(fileModel).getNodeContent();
String newLastModified = restClient.getResponseHeaders().getValue("Last-Modified");
assertNotEquals(newLastModified, oldLastModified, "Expected Last-Modified header to change when property was updated.");
restClient.assertStatusCodeIs(HttpStatus.OK);
}
private void createRandomFileInDirectory(String path, String fileName, int size) {
String fullPath = new File(path, fileName).getPath();
RandomAccessFile file = new RandomAccessFile(fullPath,"rw");
file.setLength(size);
file.close();
try
{
RandomAccessFile file = new RandomAccessFile(fullPath, "rw");
file.setLength(size);
file.close();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
}

View File

@@ -27,10 +27,8 @@ package org.alfresco.rest.api.tests;
import static org.alfresco.rest.api.tests.util.RestApiUtil.parsePaging;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -38,14 +36,11 @@ import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -61,9 +56,9 @@ import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.rest.AbstractSingleNetworkSiteTest;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.LockInfo;
import org.alfresco.rest.api.model.ClassDefinition;
import org.alfresco.rest.api.model.ConstraintDefinition;
import org.alfresco.rest.api.model.LockInfo;
import org.alfresco.rest.api.model.NodePermissions;
import org.alfresco.rest.api.model.NodeTarget;
import org.alfresco.rest.api.model.PropertyDefinition;
@@ -106,7 +101,6 @@ import org.apache.commons.collections.map.MultiValueMap;
import org.json.simple.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
/**
@@ -3606,123 +3600,6 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
putBinary(url, payload, null, null, 415);
}
/**
* Tests download of file/content.
* <p>GET:</p>
* {@literal <host>:<port>/alfresco/api/-default-/public/alfresco/versions/1/nodes/<nodeId>/content}
*/
@Test
@Ignore("ACS-3531 Frequent intermittent failure")
public void testDownloadFileContent() throws Exception
{
setRequestContext(user1);
//
// Test plain text
//
String fileName = "quick-1.txt";
File file = getResourceFile(fileName);
MultiPartBuilder multiPartBuilder = MultiPartBuilder.create()
.setFileData(new FileData(fileName, file));
MultiPartRequest reqBody = multiPartBuilder.build();
// Upload text content
HttpResponse response = post(getNodeChildrenUrl(Nodes.PATH_MY), reqBody.getBody(), null, reqBody.getContentType(), 201);
Document document = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
String contentNodeId = document.getId();
// Check the upload response
assertEquals(fileName, document.getName());
ContentInfo contentInfo = document.getContent();
assertNotNull(contentInfo);
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentInfo.getMimeType());
// Download text content - by default with Content-Disposition header
response = getSingle(NodesEntityResource.class, contentNodeId + "/content", null, 200);
String textContent = response.getResponse();
assertEquals("The quick brown fox jumps over the lazy dog", textContent);
Map<String, String> responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertEquals("attachment; filename=\"quick-1.txt\"; filename*=UTF-8''quick-1.txt", responseHeaders.get("Content-Disposition"));
String cacheControl = responseHeaders.get("Cache-Control");
assertNotNull(cacheControl);
assertTrue(cacheControl.contains("must-revalidate"));
assertTrue(cacheControl.contains("max-age=0"));
assertNotNull(responseHeaders.get("Expires"));
String lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
assertNotNull(lastModifiedHeader);
Map<String, String> headers = Collections.singletonMap(IF_MODIFIED_SINCE_HEADER, lastModifiedHeader);
// Test 304 response
getSingle(getNodeContentUrl(contentNodeId), null, null, headers, 304);
// Update the content to change the node's modified date
Document docUpdate = new Document();
docUpdate.setProperties(Collections.singletonMap("cm:description", (Object) "desc updated!"));
// Wait a second then update, as the dates will be rounded to
// ignore millisecond when checking for If-Modified-Since
Thread.sleep(1000L);
response = put(URL_NODES, contentNodeId, toJsonAsStringNonNull(docUpdate), null, 200);
Document updatedDocument = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
assertEquals(contentNodeId, updatedDocument.getId());
// The requested "If-Modified-Since" date is older than node's modified date
response = getSingle(getNodeContentUrl(contentNodeId), null, null, headers, 200);
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertNotNull(responseHeaders.get("Cache-Control"));
assertNotNull(responseHeaders.get("Expires"));
String newLastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
assertNotNull(newLastModifiedHeader);
assertNotEquals(lastModifiedHeader, newLastModifiedHeader);
//
// Test binary (eg. PDF)
//
fileName = "quick.pdf";
file = getResourceFile(fileName);
byte[] originalBytes = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
multiPartBuilder = MultiPartBuilder.create()
.setFileData(new FileData(fileName, file));
reqBody = multiPartBuilder.build();
// Upload binary content
response = post(getNodeChildrenUrl(Nodes.PATH_MY), reqBody.getBody(), null, reqBody.getContentType(), 201);
document = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
contentNodeId = document.getId();
// Check the upload response
assertEquals(fileName, document.getName());
contentInfo = document.getContent();
assertNotNull(contentInfo);
assertEquals(MimetypeMap.MIMETYPE_PDF, contentInfo.getMimeType());
// Download binary content (as bytes) - without Content-Disposition header (attachment=false)
Map<String, String> params = new LinkedHashMap<>();
params.put("attachment", "false");
response = getSingle(NodesEntityResource.class, contentNodeId + "/content", params, 200);
byte[] bytes = response.getResponseAsBytes();
assertArrayEquals(originalBytes, bytes);
responseHeaders = response.getHeaders();
assertNotNull(responseHeaders);
assertNull(responseHeaders.get("Content-Disposition"));
assertNotNull(responseHeaders.get("Cache-Control"));
assertNotNull(responseHeaders.get("Expires"));
lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
assertNotNull(lastModifiedHeader);
headers = Collections.singletonMap(IF_MODIFIED_SINCE_HEADER, lastModifiedHeader);
// Test 304 response
getSingle(getNodeContentUrl(contentNodeId), null, null, headers, 304);
}
/**
* Tests download of file/content name.
* <p>GET:</p>