From e0dfc9a8e9f64f29c046124d71132c6305d681e6 Mon Sep 17 00:00:00 2001 From: AleksanderSklorz <115619721+AleksanderSklorz@users.noreply.github.com> Date: Thu, 2 Feb 2023 17:09:08 +0100 Subject: [PATCH] [ACS-4296] changes required after removing tags service from apps (#8223) * ACS-4296 Added getCountersForTags and findTagByName functions to TagService * ACS-4296 Import correct --- docs/content-services/services/tag.service.md | 8 ++ .../src/lib/tag/services/tag.service.spec.ts | 134 +++++++++++++++++- .../src/lib/tag/services/tag.service.ts | 43 +++++- 3 files changed, 180 insertions(+), 5 deletions(-) diff --git a/docs/content-services/services/tag.service.md b/docs/content-services/services/tag.service.md index d99a4068cd..0611186e93 100644 --- a/docs/content-services/services/tag.service.md +++ b/docs/content-services/services/tag.service.md @@ -46,6 +46,14 @@ Manages tags in Content Services. - _skipCount:_ `number` - Specify how many first results should be skipped. Default 0. - _maxItems:_ `number` - Specify max number of returned tags. Default is specified by UserPreferencesService. - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - Found tags which name contains searched name. +- **getCountersForTags**(tags: `string[]`): [`Observable`](http://reactivex.io/documentation/observable.html)``
+ Get usage counters for passed tags. + - _tags:_ `string[]` - Array of tags names for which there should be returned counters. + - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - Array of usage counters for specified tags. +- **findTagByName**(name: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)``
+ Find tag which name matches exactly to passed name. + - _name:_ `string` - Value for name which should be used during finding exact tag. + - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - Found tag which name matches exactly to passed name. ## Details diff --git a/lib/content-services/src/lib/tag/services/tag.service.spec.ts b/lib/content-services/src/lib/tag/services/tag.service.spec.ts index 1b1efa9c51..2ddcb2b3bd 100644 --- a/lib/content-services/src/lib/tag/services/tag.service.spec.ts +++ b/lib/content-services/src/lib/tag/services/tag.service.spec.ts @@ -24,9 +24,15 @@ import { throwError } from 'rxjs'; import { RequestQuery, RequestSortDefinitionInner, + ResultSetContext, + ResultSetContextFacetQueries, ResultSetPaging, + ResultSetPagingList, + Tag, TagBody, - TagEntry + TagEntry, + TagPaging, + TagPagingList } from '@alfresco/js-api'; describe('TagService', () => { @@ -140,7 +146,7 @@ describe('TagService', () => { expect(searchSpy).toHaveBeenCalledWith({ query: { language: RequestQuery.LanguageEnum.Afts, - query: `PATH:"/cm:categoryRoot/cm:taggable/*" AND cm:name:"${name}*"` + query: `PATH:"/cm:categoryRoot/cm:taggable/*" AND cm:name:"*${name}*"` }, paging: { skipCount: 0, @@ -211,5 +217,129 @@ describe('TagService', () => { expect(logService.error).toHaveBeenCalledWith(error); })); }); + + describe('getCountersForTags', () => { + let result: ResultSetPaging; + const tag1 = 'tag 1'; + + beforeEach(() => { + result = new ResultSetPaging(); + result.list = new ResultSetPagingList(); + result.list.context = new ResultSetContext(); + const facetQuery = new ResultSetContextFacetQueries(); + facetQuery.count = 2; + facetQuery.label = tag1; + facetQuery.filterQuery = `TAG:"${tag1}"`; + result.list.context.facetQueries = [facetQuery]; + }); + + it('should call search on searchApi with correct parameters', () => { + const tag2 = 'tag 2'; + spyOn(service.searchApi, 'search').and.returnValue(Promise.resolve(result)); + + service.getCountersForTags([tag1, tag2]); + expect(service.searchApi.search).toHaveBeenCalledWith({ + query: { + language: RequestQuery.LanguageEnum.Afts, + query: `*` + }, + facetQueries: [{ + query: `TAG:"${tag1}"`, + label: tag1 + }, { + query: `TAG:"${tag2}"`, + label: tag2 + }] + }); + }); + + it('should return observable which emits facet queries with counters for tags', (done) => { + spyOn(service.searchApi, 'search').and.returnValue(Promise.resolve(result)); + service.getCountersForTags([tag1]).subscribe((counters) => { + expect(counters).toBe(result.list.context.facetQueries); + done(); + }); + }); + + it('should return observable which emits undefined if context is not present', (done) => { + result.list.context = undefined; + + spyOn(service.searchApi, 'search').and.returnValue(Promise.resolve(result)); + service.getCountersForTags([tag1]).subscribe((counters) => { + expect(counters).toBeUndefined(); + done(); + }); + }); + + it('should return observable which emits undefined if list is not present', (done) => { + result.list = undefined; + + spyOn(service.searchApi, 'search').and.returnValue(Promise.resolve(result)); + service.getCountersForTags([tag1]).subscribe((counters) => { + expect(counters).toBeUndefined(); + done(); + }); + }); + + it('should call error on logService when error occurs during fetching counters for tags', fakeAsync(() => { + spyOn(logService, 'error'); + const error = 'Some error'; + spyOn(service.searchApi, 'search').and.returnValue(Promise.reject(error)); + + service.getCountersForTags([tag1]).subscribe({ + error: () => { + expect(logService.error).toHaveBeenCalledWith(error); + } + }); + tick(); + })); + }); + + describe('findTagByName', () => { + let tagPaging: TagPaging; + const tagName = 'some tag'; + + beforeEach(() => { + tagPaging = new TagPaging(); + }); + + it('should call listTags on tagsApi', () => { + spyOn(service.tagsApi, 'listTags').and.returnValue(Promise.resolve(tagPaging)); + + service.findTagByName(tagName); + + expect(service.tagsApi.listTags).toHaveBeenCalledWith({ + name: tagName + }); + }); + + it('should return observable which emits found tag', (done) => { + tagPaging.list = new TagPagingList(); + const tag = new TagEntry(); + tag.entry = new Tag(); + tag.entry.id = 'some id'; + tag.entry.tag = tagName; + tagPaging.list.entries = [tag]; + spyOn(service.tagsApi, 'listTags').and.returnValue(Promise.resolve(tagPaging)); + + service.findTagByName(tagName).subscribe((result) => { + expect(result).toBe(tag); + done(); + }); + }); + + it('should call error on logService when error occurs during fetching tag for name', fakeAsync(() => { + spyOn(logService, 'error'); + const error = 'Some error'; + spyOn(service.tagsApi, 'listTags').and.returnValue(Promise.reject(error)); + + service.findTagByName(tagName).subscribe({ + error: () => { + expect(logService.error).toHaveBeenCalledWith(error); + } + }); + tick(); + })); + }); }); }); diff --git a/lib/content-services/src/lib/tag/services/tag.service.ts b/lib/content-services/src/lib/tag/services/tag.service.ts index cf82da8524..6633c2c790 100644 --- a/lib/content-services/src/lib/tag/services/tag.service.ts +++ b/lib/content-services/src/lib/tag/services/tag.service.ts @@ -18,10 +18,11 @@ import { AlfrescoApiService, LogService, UserPreferencesService } from '@alfresco/adf-core'; import { EventEmitter, Injectable, Output } from '@angular/core'; import { from, Observable, throwError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; +import { catchError, map } from 'rxjs/operators'; import { RequestQuery, RequestSortDefinitionInner, + ResultSetContextFacetQueries, ResultSetPaging, SearchApi, TagBody, @@ -159,7 +160,8 @@ export class TagService { * @param maxItems Specify max number of returned tags. Default is specified by UserPreferencesService. * @returns Found tags which name contains searched name. */ - searchTags(name: string, skipCount: number = 0, maxItems: number = this.userPreferencesService.paginationSize): Observable { + searchTags(name: string, skipCount = 0, maxItems?: number): Observable { + maxItems = maxItems || this.userPreferencesService.paginationSize; const sortingByName: RequestSortDefinitionInner = new RequestSortDefinitionInner(); sortingByName.field = 'cm:name'; sortingByName.ascending = true; @@ -167,7 +169,7 @@ export class TagService { return from(this.searchApi.search({ query: { language: RequestQuery.LanguageEnum.Afts, - query: `PATH:"/cm:categoryRoot/cm:taggable/*" AND cm:name:"${name}*"` + query: `PATH:"/cm:categoryRoot/cm:taggable/*" AND cm:name:"*${name}*"` }, paging: { skipCount, @@ -177,6 +179,41 @@ export class TagService { })).pipe(catchError((error) => this.handleError(error))); } + /** + * Get usage counters for passed tags. + * + * @param tags Array of tags names for which there should be returned counters. + * @returns Array of usage counters for specified tags. + */ + getCountersForTags(tags: string[]): Observable { + return from(this.searchApi.search({ + query: { + language: RequestQuery.LanguageEnum.Afts, + query: `*` + }, + facetQueries: tags.map((tag) => ({ + query: `TAG:"${tag}"`, + label: tag + })) + })).pipe( + map((paging) => paging.list?.context?.facetQueries), + catchError((error) => this.handleError(error)) + ); + } + + /** + * Find tag which name matches exactly to passed name. + * + * @param name Value for name which should be used during finding exact tag. + * @returns Found tag which name matches exactly to passed name. + */ + findTagByName(name: string): Observable { + return this.getAllTheTags({ name }).pipe( + map((result) => result.list.entries[0]), + catchError((error) => this.handleError(error)) + ); + } + private handleError(error: any) { this.logService.error(error); return throwError(error || 'Server error');