mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
90918: Fix RxJs issues
This commit is contained in:
@@ -3,7 +3,7 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { HALEndpointService } from './hal-endpoint.service';
|
||||
import { EndpointMapRequest } from '../data/request.models';
|
||||
import { combineLatest as observableCombineLatest, of as observableOf } from 'rxjs';
|
||||
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
@@ -162,9 +162,9 @@ describe('HALEndpointService', () => {
|
||||
return observableOf(endpointMaps[param]);
|
||||
});
|
||||
|
||||
observableCombineLatest([
|
||||
observableCombineLatest<string[]>([
|
||||
(service as any).getEndpointAt(start, 'one'),
|
||||
(service as any).getEndpointAt(start, 'one', 'two')
|
||||
(service as any).getEndpointAt(start, 'one', 'two'),
|
||||
]).subscribe(([endpoint1, endpoint2]) => {
|
||||
expect(endpoint1).toEqual(one);
|
||||
expect(endpoint2).toEqual(two);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||
import { debounceTime, filter, find, map, switchMap, take, takeWhile } from 'rxjs/operators';
|
||||
import { combineLatest as observableCombineLatest, Observable, interval } from 'rxjs';
|
||||
import { filter, find, map, switchMap, take, takeWhile, debounce, debounceTime } from 'rxjs/operators';
|
||||
import { hasNoValue, hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util';
|
||||
import { SearchResult } from '../../shared/search/models/search-result.model';
|
||||
import { PaginatedList } from '../data/paginated-list.model';
|
||||
@@ -9,6 +9,17 @@ import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||
import { BrowseDefinition } from './browse-definition.model';
|
||||
import { DSpaceObject } from './dspace-object.model';
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { MonoTypeOperatorFunction, SchedulerLike } from 'rxjs/internal/types';
|
||||
|
||||
/**
|
||||
* Use this method instead of the RxJs debounceTime if you're waiting for debouncing in tests;
|
||||
* debounceTime doesn't work with fakeAsync/tick anymore as of Angular 13.2.6 & RxJs 7.5.5
|
||||
* Workaround suggested in https://github.com/angular/angular/issues/44351#issuecomment-1107454054
|
||||
* todo: remove once the above issue is fixed
|
||||
*/
|
||||
export const debounceTimeWorkaround = <T>(dueTime: number, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T> => {
|
||||
return debounce(() => interval(dueTime, scheduler));
|
||||
};
|
||||
|
||||
export const DEBOUNCE_TIME_OPERATOR = new InjectionToken<<T>(dueTime: number) => (source: Observable<T>) => Observable<T>>('debounceTime', {
|
||||
providedIn: 'root',
|
||||
|
@@ -5,8 +5,9 @@ import { FormGroup } from '@angular/forms';
|
||||
import { hasValue, isEmpty } from '../../shared/empty.util';
|
||||
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { debounceTime, map } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { debounceTimeWorkaround as debounceTime } from '../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-profile-page-security-form',
|
||||
|
@@ -143,7 +143,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy {
|
||||
this.typesString = this.types.map((type: string) => type.toString().toLowerCase()).join(', ');
|
||||
|
||||
// Create an observable searching for the current DSO (return empty list if there's no current DSO)
|
||||
let currentDSOResult$;
|
||||
let currentDSOResult$: Observable<PaginatedList<SearchResult<DSpaceObject>>>;
|
||||
if (isNotEmpty(this.currentDSOId)) {
|
||||
currentDSOResult$ = this.search(this.getCurrentDSOQuery(), 1).pipe(getFirstSucceededRemoteDataPayload());
|
||||
} else {
|
||||
|
@@ -100,7 +100,9 @@ describe('ItemVersionsComponent', () => {
|
||||
isAuthenticated: observableOf(true),
|
||||
setRedirectUrl: {}
|
||||
});
|
||||
const authorizationServiceSpy = jasmine.createSpyObj('authorizationService', ['isAuthorized']);
|
||||
const authorizationServiceSpy = jasmine.createSpyObj('authorizationService', {
|
||||
isAuthorized: observableOf(true)
|
||||
});
|
||||
const workspaceItemDataServiceSpy = jasmine.createSpyObj('workspaceItemDataService', {
|
||||
findByItem: EMPTY,
|
||||
});
|
||||
|
@@ -61,7 +61,7 @@ export function createFailedRemoteDataObject<T>(errorMessage?: string, statusCod
|
||||
* @param timeCompleted the moment when the remoteData was completed
|
||||
*/
|
||||
export function createFailedRemoteDataObject$<T>(errorMessage?: string, statusCode?: number, timeCompleted?: number): Observable<RemoteData<T>> {
|
||||
return observableOf(createFailedRemoteDataObject(errorMessage, statusCode, timeCompleted));
|
||||
return observableOf(createFailedRemoteDataObject<T>(errorMessage, statusCode, timeCompleted));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ export function createPendingRemoteDataObject<T>(lastVerified = FIXED_TIMESTAMP)
|
||||
* @param lastVerified the moment when the remoteData was last verified
|
||||
*/
|
||||
export function createPendingRemoteDataObject$<T>(lastVerified?: number): Observable<RemoteData<T>> {
|
||||
return observableOf(createPendingRemoteDataObject(lastVerified));
|
||||
return observableOf(createPendingRemoteDataObject<T>(lastVerified));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -80,7 +80,7 @@ describe('SearchFiltersComponent', () => {
|
||||
|
||||
expect(comp.initFilters).toHaveBeenCalledTimes(1);
|
||||
|
||||
refreshFiltersEmitter.next();
|
||||
refreshFiltersEmitter.next(null);
|
||||
|
||||
expect(comp.initFilters).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
@@ -38,7 +38,7 @@ export class VocabularyTreeFlatDataSource<T, F> extends DataSource<F> {
|
||||
this._treeControl.expansionModel.changed,
|
||||
this._flattenedData
|
||||
];
|
||||
return merge(...changes).pipe(map(() => {
|
||||
return merge<any>(...changes).pipe(map((): F[] => {
|
||||
this._expandedData.next(
|
||||
this._treeFlattener.expandFlattenedNodes(this._flattenedData.value, this._treeControl));
|
||||
return this._expandedData.value;
|
||||
|
@@ -2,7 +2,7 @@ import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { getTestScheduler, hot } from 'jasmine-marbles';
|
||||
import { cold, getTestScheduler, hot } from 'jasmine-marbles';
|
||||
|
||||
import { VocabularyTreeviewService } from './vocabulary-treeview.service';
|
||||
import { VocabularyService } from '../../core/submission/vocabularies/vocabulary.service';
|
||||
@@ -14,6 +14,8 @@ import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models
|
||||
import { buildPaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { createSuccessfulRemoteDataObject } from '../remote-data.utils';
|
||||
import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model';
|
||||
import { expand, map, switchMap } from 'rxjs/operators';
|
||||
import { from as observableFrom } from 'rxjs';
|
||||
|
||||
describe('VocabularyTreeviewService test suite', () => {
|
||||
|
||||
@@ -320,10 +322,25 @@ describe('VocabularyTreeviewService test suite', () => {
|
||||
scheduler.schedule(() => service.searchByQuery(vocabularyOptions));
|
||||
scheduler.flush();
|
||||
|
||||
searchChildNode.childrenChange.next([searchChildNode3]);
|
||||
searchItemNode.childrenChange.next([searchChildNode]);
|
||||
expect(serviceAsAny.dataChange.value.length).toEqual(1);
|
||||
expect(serviceAsAny.dataChange.value).toEqual([searchItemNode]);
|
||||
// We can't check the tree by comparing root TreeviewNodes directly in this particular test;
|
||||
// Since RxJs 7, BehaviorSubjects can no longer be reliably compared because of the new currentObservers property
|
||||
// (see https://github.com/ReactiveX/rxjs/pull/6842)
|
||||
const levels$ = serviceAsAny.dataChange.pipe(
|
||||
expand((nodes: TreeviewNode[]) => { // recursively apply:
|
||||
return observableFrom(nodes).pipe( // for each node in the array...
|
||||
switchMap(node => node.childrenChange) // ...map it to the array its child nodes.
|
||||
); // because we only have one child per node in this case,
|
||||
}), // this results in an array of nodes for each level of the tree.
|
||||
map((nodes: TreeviewNode[]) => nodes.map(node => node.item)), // finally, replace nodes with their vocab entries
|
||||
);
|
||||
|
||||
// Confirm that this corresponds to the hierarchy we set up above
|
||||
expect(levels$).toBeObservable(cold('-(abcd)', {
|
||||
a: [item],
|
||||
b: [child],
|
||||
c: [child3],
|
||||
d: [] // ensure that grandchild has no children & the recursion stopped there
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -64,14 +64,24 @@ describe('SubmissionImportExternalCollectionComponent test suite', () => {
|
||||
compAsAny = null;
|
||||
});
|
||||
|
||||
it('The variable \'selectedEvent\' should be assigned', () => {
|
||||
const event = new EventEmitter<CollectionListEntry>();
|
||||
comp.selectObject(event);
|
||||
it('should emit from selectedEvent on selectObject', () => {
|
||||
spyOn(comp.selectedEvent, 'emit').and.callThrough();
|
||||
|
||||
expect(comp.selectedEvent).toEqual(event);
|
||||
const entry = {
|
||||
communities: [
|
||||
{ id: 'community1' },
|
||||
{ id: 'community2' }
|
||||
],
|
||||
collection: {
|
||||
id: 'collection'
|
||||
}
|
||||
} as CollectionListEntry;
|
||||
comp.selectObject(entry);
|
||||
|
||||
expect(comp.selectedEvent.emit).toHaveBeenCalledWith(entry);
|
||||
});
|
||||
|
||||
it('The variable \'selectedEvent\' should be assigned', () => {
|
||||
it('should dismiss modal on closeCollectionModal', () => {
|
||||
spyOn(compAsAny.activeModal, 'dismiss');
|
||||
comp.closeCollectionModal();
|
||||
|
||||
|
@@ -35,10 +35,10 @@ export class SubmissionImportExternalCollectionComponent {
|
||||
) { }
|
||||
|
||||
/**
|
||||
* This method populates the 'selectedEvent' variable.
|
||||
* This method emits the selected Collection from the 'selectedEvent' variable.
|
||||
*/
|
||||
public selectObject(event): void {
|
||||
this.selectedEvent.emit(event);
|
||||
public selectObject(object: CollectionListEntry): void {
|
||||
this.selectedEvent.emit(object);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user