mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merge branch 'master' of github.com:Alfresco/alfresco-community-repo into ACS-4636-CreateTagCountParamSupport
This commit is contained in:
@@ -164,21 +164,25 @@ public class TagsImpl implements Tags
|
||||
taggingService.deleteTag(storeRef, tagValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params)
|
||||
{
|
||||
Paging paging = params.getPaging();
|
||||
Map<Integer, Collection<String>> namesFilters = resolveTagNamesQuery(params.getQuery());
|
||||
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(storeRef, Util.getPagingRequest(paging), namesFilters.get(EQUALS), namesFilters.get(MATCHES));
|
||||
Paging paging = params.getPaging();
|
||||
Map<Integer, Collection<String>> namesFilters = resolveTagNamesQuery(params.getQuery());
|
||||
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(storeRef, Util.getPagingRequest(paging), namesFilters.get(EQUALS), namesFilters.get(MATCHES));
|
||||
|
||||
Integer totalItems = results.getTotalResultCount().getFirst();
|
||||
List<Pair<NodeRef, String>> page = results.getPage();
|
||||
List<Tag> tags = new ArrayList<>(page.size());
|
||||
List<Pair<String, Integer>> tagsByCount;
|
||||
Map<String, Integer> tagsByCountMap = new HashMap<>();
|
||||
for (Pair<NodeRef, String> pair : page)
|
||||
{
|
||||
Tag selectedTag = new Tag(pair.getFirst(), pair.getSecond());
|
||||
tags.add(selectedTag);
|
||||
}
|
||||
if (params.getInclude().contains(PARAM_INCLUDE_COUNT))
|
||||
{
|
||||
tagsByCount = taggingService.findTaggedNodesAndCountByTagName(storeRef);
|
||||
List<Pair<String, Integer>> tagsByCount = taggingService.findTaggedNodesAndCountByTagName(storeRef);
|
||||
Map<String, Integer> tagsByCountMap = new HashMap<>();
|
||||
if (tagsByCount != null)
|
||||
{
|
||||
for (Pair<String, Integer> tagByCountElem : tagsByCount)
|
||||
@@ -186,12 +190,7 @@ public class TagsImpl implements Tags
|
||||
tagsByCountMap.put(tagByCountElem.getFirst(), tagByCountElem.getSecond());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Pair<NodeRef, String> pair : page)
|
||||
{
|
||||
Tag selectedTag = new Tag(pair.getFirst(), pair.getSecond());
|
||||
selectedTag.setCount(Optional.ofNullable(tagsByCountMap.get(selectedTag.getTag())).orElse(0));
|
||||
tags.add(selectedTag);
|
||||
tags.forEach(tag -> tag.setCount(Optional.ofNullable(tagsByCountMap.get(tag.getTag())).orElse(0)));
|
||||
}
|
||||
|
||||
return CollectionWithPagingInfo.asPaged(paging, tags, results.hasMoreItems(), totalItems);
|
||||
|
@@ -129,7 +129,7 @@ public class TagsImplTest
|
||||
|
||||
then(taggingServiceMock).should().getTags(eq(STORE_REF_WORKSPACE_SPACESSTORE), any(PagingRequest.class), isNull(), isNull());
|
||||
then(taggingServiceMock).shouldHaveNoMoreInteractions();
|
||||
final List<Tag> expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream().peek(tag -> tag.setCount(0)).collect(toList());
|
||||
final List<Tag> expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME));
|
||||
assertEquals(expectedTags, actualTags.getCollection());
|
||||
}
|
||||
|
||||
@@ -151,6 +151,30 @@ public class TagsImplTest
|
||||
assertEquals(expectedTags, actualTags.getCollection());
|
||||
}
|
||||
|
||||
/** Check that we can get counts for two tags - one in use and one not applied to any nodes. */
|
||||
@Test
|
||||
public void testGetTags_verifyCountPopulatedCorrectly()
|
||||
{
|
||||
NodeRef tagNodeA = new NodeRef("tag://A/");
|
||||
NodeRef tagNodeB = new NodeRef("tag://B/");
|
||||
List<Pair<NodeRef, String>> tagPairs = List.of(new Pair<>(tagNodeA, "tagA"), new Pair<>(tagNodeB, "tagB"));
|
||||
|
||||
given(parametersMock.getPaging()).willReturn(pagingMock);
|
||||
given(taggingServiceMock.getTags(any(StoreRef.class), any(PagingRequest.class), any(), any())).willReturn(pagingResultsMock);
|
||||
given(pagingResultsMock.getTotalResultCount()).willReturn(new Pair<>(Integer.MAX_VALUE, 0));
|
||||
given(pagingResultsMock.getPage()).willReturn(tagPairs);
|
||||
given(parametersMock.getInclude()).willReturn(List.of("count"));
|
||||
// Only tagA is included in the returned list since tagB is not in use.
|
||||
given(taggingServiceMock.findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE)).willReturn(List.of(new Pair<>("tagA", 5)));
|
||||
|
||||
final CollectionWithPagingInfo<Tag> actualTags = objectUnderTest.getTags(STORE_REF_WORKSPACE_SPACESSTORE, parametersMock);
|
||||
|
||||
then(taggingServiceMock).should().findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
final List<Tag> expectedTags = List.of(Tag.builder().tag("tagA").nodeRef(tagNodeA).count(5).create(),
|
||||
Tag.builder().tag("tagB").nodeRef(tagNodeB).count(0).create());
|
||||
assertEquals(expectedTags, actualTags.getCollection());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTags_withEqualsClauseWhereQuery()
|
||||
{
|
||||
|
@@ -734,195 +734,6 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests shared links to file (content) in a multi-tenant system.
|
||||
*
|
||||
* <p>POST:</p>
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links}
|
||||
*
|
||||
* <p>DELETE:</p>
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links/<sharedId>}
|
||||
*
|
||||
* <p>GET:</p>
|
||||
* The following do not require authentication
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links/<sharedId>}
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links/<sharedId>/content}
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links/<sharedId>/renditions}
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links/<sharedId>/renditions/<renditionId>}
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links/<sharedId>/renditions/<renditionId>/content}
|
||||
*
|
||||
*/
|
||||
// TODO now covered by testSharedLinkCreateGetDelete ? (since base class now uses tenant context by default)
|
||||
@Test
|
||||
public void testSharedLinkCreateGetDelete_MultiTenant() throws Exception
|
||||
{
|
||||
// As user1
|
||||
setRequestContext(user1);
|
||||
|
||||
String docLibNodeId = getSiteContainerNodeId(tSiteId, "documentLibrary");
|
||||
|
||||
String folderName = "folder" + System.currentTimeMillis() + "_1";
|
||||
String folderId = createFolder(docLibNodeId, folderName, null).getId();
|
||||
|
||||
// create doc d1 - pdf
|
||||
String fileName1 = "quick" + RUNID + "_1.pdf";
|
||||
File file1 = getResourceFile("quick.pdf");
|
||||
|
||||
byte[] file1_originalBytes = Files.readAllBytes(Paths.get(file1.getAbsolutePath()));
|
||||
|
||||
String file1_MimeType = MimetypeMap.MIMETYPE_PDF;
|
||||
|
||||
MultiPartBuilder.MultiPartRequest reqBody = MultiPartBuilder.create()
|
||||
.setFileData(new MultiPartBuilder.FileData(fileName1, file1, file1_MimeType))
|
||||
.build();
|
||||
|
||||
HttpResponse response = post(getNodeChildrenUrl(folderId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||
Document doc1 = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
String d1Id = doc1.getId();
|
||||
assertNotNull(d1Id);
|
||||
|
||||
// create shared link to document 1
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("nodeId", d1Id);
|
||||
response = post(URL_SHARED_LINKS, toJsonAsStringNonNull(body), 201);
|
||||
QuickShareLink resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
|
||||
String shared1Id = resp.getId();
|
||||
assertNotNull(shared1Id);
|
||||
assertEquals(d1Id, resp.getNodeId());
|
||||
assertEquals(fileName1, resp.getName());
|
||||
assertEquals(file1_MimeType, resp.getContent().getMimeType());
|
||||
assertEquals(user1, resp.getSharedByUser().getId());
|
||||
|
||||
// allowable operations not included - no params
|
||||
response = getSingle(QuickShareLinkEntityResource.class, shared1Id, null, 200);
|
||||
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
|
||||
assertNull(resp.getAllowableOperations());
|
||||
|
||||
setRequestContext(null);
|
||||
|
||||
// unauth access to get shared link info
|
||||
Map<String, String> params = Collections.singletonMap("include", "allowableOperations"); // note: this will be ignore for unauth access
|
||||
response = getSingle(QuickShareLinkEntityResource.class, shared1Id, params, 200);
|
||||
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
|
||||
assertEquals(shared1Id, resp.getId());
|
||||
assertEquals(fileName1, resp.getName());
|
||||
assertEquals(d1Id, resp.getNodeId());
|
||||
assertNull(resp.getAllowableOperations()); // include is ignored
|
||||
assertNull(resp.getAllowableOperationsOnTarget()); // include is ignored
|
||||
|
||||
|
||||
// unauth access to file 1 content (via shared link)
|
||||
response = getSingle(QuickShareLinkEntityResource.class, shared1Id + "/content", null, 200);
|
||||
assertArrayEquals(file1_originalBytes, response.getResponseAsBytes());
|
||||
Map<String, String> responseHeaders = response.getHeaders();
|
||||
assertNotNull(responseHeaders);
|
||||
assertEquals(file1_MimeType + ";charset=utf-8", responseHeaders.get("Content-Type"));
|
||||
assertNotNull(responseHeaders.get("Expires"));
|
||||
assertEquals("attachment; filename=\"" + fileName1 + "\"; filename*=UTF-8''" + fileName1 + "", responseHeaders.get("Content-Disposition"));
|
||||
String lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
|
||||
assertNotNull(lastModifiedHeader);
|
||||
// Test 304 response
|
||||
Map<String, String> headers = Collections.singletonMap(IF_MODIFIED_SINCE_HEADER, lastModifiedHeader);
|
||||
getSingle(URL_SHARED_LINKS, shared1Id + "/content", null, headers, 304);
|
||||
|
||||
// unauth access to file 1 content (via shared link) - without Content-Disposition header (attachment=false)
|
||||
params = new HashMap<>();
|
||||
params.put("attachment", "false");
|
||||
response = getSingle(QuickShareLinkEntityResource.class, shared1Id + "/content", params, 200);
|
||||
assertArrayEquals(file1_originalBytes, response.getResponseAsBytes());
|
||||
responseHeaders = response.getHeaders();
|
||||
assertNotNull(responseHeaders);
|
||||
assertEquals(file1_MimeType + ";charset=utf-8", responseHeaders.get("Content-Type"));
|
||||
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
|
||||
assertNotNull(responseHeaders.get("Expires"));
|
||||
assertNull(responseHeaders.get("Content-Disposition"));
|
||||
|
||||
// -ve shared link rendition tests
|
||||
{
|
||||
// -ve test - try to get non-existent rendition content
|
||||
getSingle(QuickShareLinkEntityResource.class, shared1Id + "/renditions/doclib/content", null, 404);
|
||||
|
||||
// -ve test - try to get unregistered rendition content
|
||||
getSingle(QuickShareLinkEntityResource.class, shared1Id + "/renditions/dummy/content", null, 404);
|
||||
}
|
||||
|
||||
// unauth access to get rendition info for a shared link (available => CREATED rendition only)
|
||||
// -ve shared link rendition tests
|
||||
{
|
||||
// -ve test - try to get not created rendition for the given shared link
|
||||
getSingle(QuickShareLinkEntityResource.class, shared1Id + "/renditions/doclib", null, 404);
|
||||
|
||||
// -ve test - try to get unregistered rendition
|
||||
getSingle(QuickShareLinkEntityResource.class, shared1Id + "/renditions/dummy", null, 404);
|
||||
}
|
||||
|
||||
// unauth access to get shared link renditions info (available => CREATED renditions only)
|
||||
response = getAll(URL_SHARED_LINKS + "/" + shared1Id + "/renditions", null, 200);
|
||||
List<Rendition> renditions = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Rendition.class);
|
||||
assertEquals(0, renditions.size());
|
||||
|
||||
// create rendition of pdf doc - note: for some reason create rendition of txt doc fail on build m/c (TBC) ?
|
||||
setRequestContext(user1);
|
||||
|
||||
Rendition rendition = createAndGetRendition(d1Id, "doclib");
|
||||
assertNotNull(rendition);
|
||||
assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus());
|
||||
|
||||
setRequestContext(null);
|
||||
|
||||
// unauth access to get shared link renditions info (available => CREATED renditions only)
|
||||
response = getAll(URL_SHARED_LINKS + "/" + shared1Id + "/renditions", null, 200);
|
||||
renditions = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Rendition.class);
|
||||
assertEquals(1, renditions.size());
|
||||
assertEquals(Rendition.RenditionStatus.CREATED, renditions.get(0).getStatus());
|
||||
assertEquals("doclib", renditions.get(0).getId());
|
||||
|
||||
// unauth access to get rendition info for a shared link (available => CREATED rendition only)
|
||||
{
|
||||
// get a created rendition for the given shared link
|
||||
getSingle(QuickShareLinkEntityResource.class, shared1Id + "/renditions/doclib", null, 200);
|
||||
}
|
||||
|
||||
// unauth access to get shared link file rendition content
|
||||
response = getSingle(QuickShareLinkEntityResource.class, shared1Id + "/renditions/doclib/content", null, 200);
|
||||
assertTrue(response.getResponseAsBytes().length > 0);
|
||||
responseHeaders = response.getHeaders();
|
||||
assertNotNull(responseHeaders);
|
||||
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG + ";charset=utf-8", responseHeaders.get("Content-Type"));
|
||||
assertNotNull(responseHeaders.get(LAST_MODIFIED_HEADER));
|
||||
assertNotNull(responseHeaders.get("Expires"));
|
||||
String docName = "doclib";
|
||||
assertEquals("attachment; filename=\"" + docName + "\"; filename*=UTF-8''" + docName + "", responseHeaders.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, shared1Id + "/renditions/doclib/content", params, 200);
|
||||
assertTrue(response.getResponseAsBytes().length > 0);
|
||||
responseHeaders = response.getHeaders();
|
||||
assertNotNull(responseHeaders);
|
||||
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG + ";charset=utf-8", responseHeaders.get("Content-Type"));
|
||||
assertNotNull(responseHeaders.get("Expires"));
|
||||
assertNull(responseHeaders.get("Content-Disposition"));
|
||||
lastModifiedHeader = responseHeaders.get(LAST_MODIFIED_HEADER);
|
||||
assertNotNull(lastModifiedHeader);
|
||||
// Test 304 response
|
||||
headers = Collections.singletonMap(IF_MODIFIED_SINCE_HEADER, lastModifiedHeader);
|
||||
getSingle(URL_SHARED_LINKS, shared1Id + "/renditions/doclib/content", null, headers, 304);
|
||||
|
||||
// -ve test - userTwoN1 cannot delete shared link
|
||||
setRequestContext(user2);
|
||||
deleteSharedLink(shared1Id, 403);
|
||||
|
||||
// -ve test - unauthenticated
|
||||
setRequestContext(null);
|
||||
deleteSharedLink(shared1Id, 401);
|
||||
|
||||
// delete shared link
|
||||
setRequestContext(user1);
|
||||
deleteSharedLink(shared1Id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests shared links to file with expiry date.
|
||||
* <p>POST:</p>
|
||||
|
Reference in New Issue
Block a user