diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts index fc4052a52e1..9abdd8d366f 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts @@ -13,7 +13,6 @@ import { AuthorizationDataService } from '../../../core/data/feature-authorizati import { ScriptDataService } from '../../../core/data/processes/script-data.service'; import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; import { Process } from '../../../process-page/processes/process.model'; -import { Script } from '../../../process-page/scripts/script.model'; import { NotificationsService } from '../../notifications/notifications.service'; import { createFailedRemoteDataObject$, @@ -33,7 +32,6 @@ describe('SearchExportCsvComponent', () => { let notificationsService; let router; - const script = Object.assign(new Script(), { id: 'metadata-export-search', name: 'metadata-export-search' }); const process = Object.assign(new Process(), { processId: 5, scriptName: 'metadata-export-search' }); const searchConfig = new PaginatedSearchOptions({ @@ -49,7 +47,7 @@ describe('SearchExportCsvComponent', () => { function initBeforeEachAsync() { scriptDataService = jasmine.createSpyObj('scriptDataService', { - findById: createSuccessfulRemoteDataObject$(script), + scriptWithNameExistsAndCanExecute: observableOf(true), invoke: createSuccessfulRemoteDataObject$(process), }); authorizationDataService = jasmine.createSpyObj('authorizationService', { @@ -117,15 +115,22 @@ describe('SearchExportCsvComponent', () => { describe('when the metadata-export-search script is not present', () => { beforeEach(waitForAsync(() => { initBeforeEachAsync(); - (scriptDataService.findById as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Not found', 404)); + (scriptDataService.scriptWithNameExistsAndCanExecute as jasmine.Spy).and.returnValue(observableOf(false)); })); - beforeEach(() => { - initBeforeEach(); - }); + it('should should not add the button', () => { + initBeforeEach(); + const debugElement = fixture.debugElement.query(By.css('button.export-button')); expect(debugElement).toBeNull(); }); + + it('should not call scriptWithNameExistsAndCanExecute when unauthorized', () => { + (authorizationDataService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false)); + initBeforeEach(); + + expect(scriptDataService.scriptWithNameExistsAndCanExecute).not.toHaveBeenCalled(); + }); }); }); describe('export', () => { diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts index 9e25e387c21..f8ec2012b1b 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -13,11 +13,13 @@ import { TranslateModule, TranslateService, } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; import { - combineLatest as observableCombineLatest, - Observable, -} from 'rxjs'; -import { map } from 'rxjs/operators'; + filter, + map, + startWith, + switchMap, +} from 'rxjs/operators'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; @@ -32,6 +34,7 @@ import { } from '../../empty.util'; import { NotificationsService } from '../../notifications/notifications.service'; import { PaginatedSearchOptions } from '../models/paginated-search-options.model'; +import { SearchFilter } from '../models/search-filter.model'; @Component({ selector: 'ds-search-export-csv', @@ -69,15 +72,11 @@ export class SearchExportCsvComponent implements OnInit { } ngOnInit(): void { - const scriptExists$ = this.scriptDataService.findById('metadata-export-search').pipe( - getFirstCompletedRemoteData(), - map((rd) => rd.isSuccess && hasValue(rd.payload)), - ); - - const isAuthorized$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf); - - this.shouldShowButton$ = observableCombineLatest([scriptExists$, isAuthorized$]).pipe( - map(([scriptExists, isAuthorized]: [boolean, boolean]) => scriptExists && isAuthorized), + this.shouldShowButton$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf).pipe( + filter((isAuthorized: boolean) => isAuthorized), + switchMap(() => this.scriptDataService.scriptWithNameExistsAndCanExecute('metadata-export-search')), + map((canExecute: boolean) => canExecute), + startWith(false), ); } @@ -97,19 +96,19 @@ export class SearchExportCsvComponent implements OnInit { parameters.push({ name: '-c', value: this.searchConfig.configuration }); } if (isNotEmpty(this.searchConfig.filters)) { - this.searchConfig.filters.forEach((filter) => { - if (hasValue(filter.values)) { - filter.values.forEach((value) => { + this.searchConfig.filters.forEach((searchFilter: SearchFilter) => { + if (hasValue(searchFilter.values)) { + searchFilter.values.forEach((value: string) => { let operator; let filterValue; - if (hasValue(filter.operator)) { - operator = filter.operator; + if (hasValue(searchFilter.operator)) { + operator = searchFilter.operator; filterValue = value; } else { operator = value.substring(value.lastIndexOf(',') + 1); filterValue = value.substring(0, value.lastIndexOf(',')); } - const valueToAdd = `${filter.key.substring(2)},${operator}=${filterValue}`; + const valueToAdd = `${searchFilter.key.substring(2)},${operator}=${filterValue}`; parameters.push({ name: '-f', value: valueToAdd }); }); } diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index f09c4f18f48..0bb708db91e 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -160,7 +160,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { this.currentUrl = this.router.url; this.currentPage = this.getCurrentPage().pipe(distinctUntilChanged()); this.searchOptions$ = this.searchConfigService.searchOptions.pipe( - map((options: SearchOptions) => hasNoValue(this.scope) ? options : Object.assign({}, options, { + map((options: SearchOptions) => hasNoValue(this.scope) ? options : Object.assign(new SearchOptions(options), { scope: this.scope, })), );