Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)

123021 jvonka: (Quick) Shared Links API - as requested, add extra +ve/-ve tests for optional "attachment" header when getting file/rendition content (via unauthenticated shared link)
   - note: also tested via the NodeApiTest (when getting file/rendition content)
   RA-829, RA-830


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@126521 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jamal Kaabi-Mofrad
2016-05-10 11:19:29 +00:00
parent a2541568a8
commit 8e27cb0de1
2 changed files with 109 additions and 46 deletions

View File

@@ -18,7 +18,6 @@
*/ */
package org.alfresco.rest.api.tests; 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.toJsonAsString; import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@@ -48,7 +47,6 @@ import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@@ -304,7 +302,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
n.setProperties(props); n.setProperties(props);
// create node // create node
HttpResponse response = post("nodes/" + parentId + "/children", runAsUserId, RestApiUtil.toJsonAsStringNonNull(n), 201); HttpResponse response = post(getNodeChildrenUrl(parentId), runAsUserId, RestApiUtil.toJsonAsStringNonNull(n), 201);
return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), returnType); return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), returnType);
} }
@@ -324,7 +322,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
.setProperties(props) .setProperties(props)
.build(); .build();
HttpResponse response = post("nodes/" + parentId + "/children", userId, reqBody.getBody(), null, reqBody.getContentType(), 201); HttpResponse response = post(getNodeChildrenUrl(parentId), userId, reqBody.getBody(), null, reqBody.getContentType(), 201);
return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class); return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
} }
@@ -351,7 +349,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
try try
{ {
HttpResponse res = post(getRenditionsUrl(sourceNodeId), userId, toJsonAsString(renditionRequest), 202); HttpResponse res = post(getNodeRenditionsUrl(sourceNodeId), userId, toJsonAsString(renditionRequest), 202);
assertNull(res.getJsonResponse()); assertNull(res.getJsonResponse());
break; break;
} }
@@ -369,7 +367,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
{ {
try try
{ {
HttpResponse response = getSingle(getRenditionsUrl(sourceNodeId), userId, renditionId, 200); HttpResponse response = getSingle(getNodeRenditionsUrl(sourceNodeId), userId, renditionId, 200);
Rendition rendition = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Rendition.class); Rendition rendition = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Rendition.class);
assertNotNull(rendition); assertNotNull(rendition);
assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus()); assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus());
@@ -387,9 +385,13 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
return null; return null;
} }
private String getRenditionsUrl(String nodeId) protected String getNodeRenditionsUrl(String nodeId)
{ {
return "nodes/" + nodeId + "/renditions"; return "nodes/" + nodeId + "/renditions";
} }
protected String getNodeChildrenUrl(String nodeId)
{
return "nodes/" + nodeId + "/children";
}
} }

View File

@@ -32,6 +32,7 @@ import org.alfresco.rest.api.tests.client.PublicApiClient.Paging;
import org.alfresco.rest.api.tests.client.data.Document; import org.alfresco.rest.api.tests.client.data.Document;
import org.alfresco.rest.api.tests.client.data.Node; import org.alfresco.rest.api.tests.client.data.Node;
import org.alfresco.rest.api.tests.client.data.Rendition; import org.alfresco.rest.api.tests.client.data.Rendition;
import org.alfresco.rest.api.tests.util.MultiPartBuilder;
import org.alfresco.rest.api.tests.util.RestApiUtil; import org.alfresco.rest.api.tests.util.RestApiUtil;
import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
@@ -39,6 +40,9 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
@@ -129,43 +133,54 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
{ {
// As user 1 ... // As user 1 ...
// create doc d1 // create doc d1 - plain text
String sharedFolderNodeId = getSharedNodeId(user1); String sharedFolderNodeId = getSharedNodeId(user1);
String content1Text = "The quick brown fox jumps over the lazy dog 1."; String content1Text = "The quick brown fox jumps over the lazy dog 1.";
String docName1 = "content" + RUNID + "_1.txt"; String fileName1 = "content" + RUNID + "_1.txt";
Document doc1 = createTextFile(user1, sharedFolderNodeId, docName1, content1Text); Document doc1 = createTextFile(user1, sharedFolderNodeId, fileName1, content1Text);
String d1Id = doc1.getId(); String d1Id = doc1.getId();
// create doc d2 // create doc d2 - pdf
String myFolderNodeId = getMyNodeId(user1); String myFolderNodeId = getMyNodeId(user1);
String content2Text = "The quick brown fox jumps over the lazy dog 1.";
String docName2 = "content" + RUNID + "_2.txt"; String fileName2 = "quick"+RUNID+"_2.pdf";
Document doc2 = createTextFile(user1, myFolderNodeId, docName2, content2Text); File file = getResourceFile("quick.pdf");
byte[] file2_originalBytes = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
String file2_MimeType = MimetypeMap.MIMETYPE_PDF;
MultiPartBuilder multiPartBuilder = MultiPartBuilder.create()
.setFileData(new MultiPartBuilder.FileData(fileName2, file, file2_MimeType));
MultiPartBuilder.MultiPartRequest reqBody = multiPartBuilder.build();
HttpResponse response = post(getNodeChildrenUrl(myFolderNodeId), user1, reqBody.getBody(), null, reqBody.getContentType(), 201);
Document doc2 = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
String d2Id = doc2.getId(); String d2Id = doc2.getId();
// As user 2 ... // As user 2 ...
HttpResponse response = getSingle(NodesEntityResource.class, user2, d1Id, null, 200); response = getSingle(NodesEntityResource.class, user2, d1Id, null, 200);
Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class); Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
Date docModifiedAt = nodeResp.getModifiedAt(); Date docModifiedAt = nodeResp.getModifiedAt();
String docModifiedBy = nodeResp.getModifiedByUser().getId(); String docModifiedBy = nodeResp.getModifiedByUser().getId();
assertEquals(user1, docModifiedBy); assertEquals(user1, docModifiedBy);
// create shared link // create shared link to document 1
Map<String, String> body = new HashMap<>(); Map<String, String> body = new HashMap<>();
body.put("nodeId", d1Id); body.put("nodeId", d1Id);
response = post(URL_SHARED_LINKS, user2, toJsonAsStringNonNull(body), 201); response = post(URL_SHARED_LINKS, user2, toJsonAsStringNonNull(body), 201);
QuickShareLink resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); QuickShareLink resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
String sharedId = resp.getId(); String shared1Id = resp.getId();
assertNotNull(sharedId); assertNotNull(shared1Id);
assertEquals(d1Id, resp.getNodeId()); assertEquals(d1Id, resp.getNodeId());
assertEquals(docName1, resp.getName()); assertEquals(fileName1, resp.getName());
String expectedMimeType = MimetypeMap.MIMETYPE_TEXT_PLAIN; String file1_MimeType = MimetypeMap.MIMETYPE_TEXT_PLAIN;
assertEquals(expectedMimeType, resp.getContent().getMimeType()); assertEquals(file1_MimeType, resp.getContent().getMimeType());
assertEquals("Plain Text", resp.getContent().getMimeTypeName()); assertEquals("Plain Text", resp.getContent().getMimeTypeName());
assertEquals(new Long(content1Text.length()), resp.getContent().getSizeInBytes()); assertEquals(new Long(content1Text.length()), resp.getContent().getSizeInBytes());
@@ -182,13 +197,24 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
post(URL_SHARED_LINKS, user2, toJsonAsStringNonNull(body), 409); post(URL_SHARED_LINKS, user2, toJsonAsStringNonNull(body), 409);
// As user 1 ...
// create shared link to document 2
body = new HashMap<>();
body.put("nodeId", d2Id);
response = post(URL_SHARED_LINKS, user1, toJsonAsStringNonNull(body), 201);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
String shared2Id = resp.getId();
// auth access to get shared link info - as user1 // auth access to get shared link info - as user1
Map<String, String> params = Collections.singletonMap("include", "allowableOperations"); Map<String, String> params = Collections.singletonMap("include", "allowableOperations");
response = getSingle(QuickShareLinkEntityResource.class, user1, sharedId, params, 200); response = getSingle(QuickShareLinkEntityResource.class, user1, shared1Id, params, 200);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertEquals(sharedId, resp.getId()); assertEquals(shared1Id, resp.getId());
assertEquals(docName1, resp.getName()); assertEquals(fileName1, resp.getName());
assertEquals(d1Id, resp.getNodeId()); assertEquals(d1Id, resp.getNodeId());
assertEquals(user1, resp.getModifiedByUser().getId()); // returned if authenticated assertEquals(user1, resp.getModifiedByUser().getId()); // returned if authenticated
@@ -198,11 +224,11 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
// auth access to get shared link info - as user2 // auth access to get shared link info - as user2
params = Collections.singletonMap("include", "allowableOperations"); params = Collections.singletonMap("include", "allowableOperations");
response = getSingle(QuickShareLinkEntityResource.class, user2, sharedId, params, 200); response = getSingle(QuickShareLinkEntityResource.class, user2, shared1Id, params, 200);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertEquals(sharedId, resp.getId()); assertEquals(shared1Id, resp.getId());
assertEquals(docName1, resp.getName()); assertEquals(fileName1, resp.getName());
assertEquals(d1Id, resp.getNodeId()); assertEquals(d1Id, resp.getNodeId());
assertEquals(user1, resp.getModifiedByUser().getId()); // returned if authenticated assertEquals(user1, resp.getModifiedByUser().getId()); // returned if authenticated
@@ -212,18 +238,18 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertEquals("delete", resp.getAllowableOperations().get(0)); assertEquals("delete", resp.getAllowableOperations().get(0));
// allowable operations not included // allowable operations not included
response = getSingle(QuickShareLinkEntityResource.class, user2, sharedId, null, 200); response = getSingle(QuickShareLinkEntityResource.class, user2, shared1Id, null, 200);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertNull(resp.getAllowableOperations()); assertNull(resp.getAllowableOperations());
// unauth access to get shared link info // unauth access to get shared link info
params = Collections.singletonMap("include", "allowableOperations"); // note: this will be ignore for unauth access params = Collections.singletonMap("include", "allowableOperations"); // note: this will be ignore for unauth access
response = getSingle(QuickShareLinkEntityResource.class, null, sharedId, params, 200); response = getSingle(QuickShareLinkEntityResource.class, null, shared1Id, params, 200);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertEquals(sharedId, resp.getId()); assertEquals(shared1Id, resp.getId());
assertEquals(docName1, resp.getName()); assertEquals(fileName1, resp.getName());
assertNull(resp.getNodeId()); // nodeId not returned assertNull(resp.getNodeId()); // nodeId not returned
assertNull(resp.getAllowableOperations()); // include is ignored assertNull(resp.getAllowableOperations()); // include is ignored
@@ -233,16 +259,45 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertEquals(user2+" "+user2, resp.getSharedByUser().getDisplayName()); assertEquals(user2+" "+user2, resp.getSharedByUser().getDisplayName());
// unauth access to get shared link file content // unauth access to file 1 content (via shared link)
response = getSingle(QuickShareLinkEntityResource.class, null, sharedId + "/content", null, 200); response = getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/content", null, 200);
assertArrayEquals(content1Text.getBytes(), response.getResponseAsBytes());
assertEquals(file1_MimeType+";charset=UTF-8", response.getHeaders().get("Content-Type"));
assertEquals("attachment; filename=\"" + fileName1 + "\"; filename*=UTF-8''" + fileName1 + "", response.getHeaders().get("Content-Disposition"));
assertEquals(content1Text, response.getResponse()); // -ve test - unauth access to get shared link file content - without Content-Disposition header (attachment=false) - header ignored (plain text is not in white list)
assertEquals(expectedMimeType+";charset=UTF-8", response.getHeaders().get("Content-Type")); params = new HashMap<>();
assertEquals("attachment; filename=\"" + docName1 + "\"; filename*=UTF-8''" + docName1 + "", response.getHeaders().get("Content-Disposition")); params.put("attachment", "false");
response = getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/content", params, 200);
assertEquals(file1_MimeType+";charset=UTF-8", response.getHeaders().get("Content-Type"));
assertArrayEquals(content1Text.getBytes(), response.getResponseAsBytes());
assertEquals("attachment; filename=\"" + fileName1 + "\"; filename*=UTF-8''" + fileName1 + "", response.getHeaders().get("Content-Disposition"));
// unauth access to file 2 content (via shared link)
response = getSingle(QuickShareLinkEntityResource.class, null, shared2Id + "/content", null, 200);
assertArrayEquals(file2_originalBytes, response.getResponseAsBytes());
assertEquals(file2_MimeType+";charset=UTF-8", response.getHeaders().get("Content-Type"));
assertEquals("attachment; filename=\"" + fileName2 + "\"; filename*=UTF-8''" + fileName2 + "", response.getHeaders().get("Content-Disposition"));
// unauth access to file 2 content (via shared link) - without Content-Disposition header (attachment=false)
params = new HashMap<>();
params.put("attachment", "false");
response = getSingle(QuickShareLinkEntityResource.class, null, shared2Id + "/content", params, 200);
assertEquals(file2_MimeType+";charset=UTF-8", response.getHeaders().get("Content-Type"));
assertArrayEquals(file2_originalBytes, response.getResponseAsBytes());
assertNull(response.getHeaders().get("Content-Disposition"));
// -ve shared link rendition tests
{
// -ve test - try to get non-existent rendition content // -ve test - try to get non-existent rendition content
getSingle(QuickShareLinkEntityResource.class, null, sharedId + "/renditions/doclib/content", null, 404); getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/renditions/doclib/content", null, 404);
// -ve test - try to get unregistered rendition content
getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/renditions/dummy/content", null, 404);
}
// create rendition // create rendition
Rendition rendition = createAndGetRendition(user2, d1Id, "doclib"); Rendition rendition = createAndGetRendition(user2, d1Id, "doclib");
@@ -250,17 +305,23 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus()); assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus());
// unauth access to get shared link file rendition content // unauth access to get shared link file rendition content
response = getSingle(QuickShareLinkEntityResource.class, null, sharedId + "/renditions/doclib/content", null, 200); response = getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/renditions/doclib/content", null, 200);
String docName = "doclib";
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=UTF-8", response.getHeaders().get("Content-Type")); assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=UTF-8", response.getHeaders().get("Content-Type"));
String docName = "doclib";
assertEquals("attachment; filename=\"" + docName + "\"; filename*=UTF-8''" + docName + "", response.getHeaders().get("Content-Disposition")); assertEquals("attachment; filename=\"" + docName + "\"; filename*=UTF-8''" + docName + "", response.getHeaders().get("Content-Disposition"));
// unauth access to get shared link file rendition content - without Content-Disposition header (attachment=false)
params = new HashMap<>();
params.put("attachment", "false");
response = getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/renditions/doclib/content", params, 200);
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG+";charset=UTF-8", response.getHeaders().get("Content-Type"));
assertNull(response.getHeaders().get("Content-Disposition"));
// -ve delete tests // -ve delete tests
{ {
// -ve test - user1 cannot delete shared link // -ve test - user1 cannot delete shared link
delete(URL_SHARED_LINKS, user1, sharedId, 403); delete(URL_SHARED_LINKS, user1, shared1Id, 403);
// -ve test - delete - cannot delete non-existent link // -ve test - delete - cannot delete non-existent link
delete(URL_SHARED_LINKS, user1, "dummy", 404); delete(URL_SHARED_LINKS, user1, "dummy", 404);
@@ -297,10 +358,10 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
// delete shared link // delete shared link
delete(URL_SHARED_LINKS, user2, sharedId, 204); delete(URL_SHARED_LINKS, user2, shared1Id, 204);
// -ve test - delete - cannot delete non-existent link // -ve test - delete - cannot delete non-existent link
delete(URL_SHARED_LINKS, user1, sharedId, 404); delete(URL_SHARED_LINKS, user1, shared1Id, 404);
response = getSingle(NodesEntityResource.class, user2, d1Id, null, 200); response = getSingle(NodesEntityResource.class, user2, d1Id, null, 200);
@@ -313,8 +374,8 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
// -ve get tests // -ve get tests
{ {
// try to get link that has been deleted (see above) // try to get link that has been deleted (see above)
getSingle(QuickShareLinkEntityResource.class, null, sharedId, null, 404); getSingle(QuickShareLinkEntityResource.class, null, shared1Id, null, 404);
getSingle(QuickShareLinkEntityResource.class, null, sharedId + "/content", null, 404); getSingle(QuickShareLinkEntityResource.class, null, shared1Id + "/content", null, 404);
// try to get non-existent link // try to get non-existent link
getSingle(QuickShareLinkEntityResource.class, null, "dummy", null, 404); getSingle(QuickShareLinkEntityResource.class, null, "dummy", null, 404);