mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
78001: RelationshipEffects test fixes
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { Router, UrlTree } from '@angular/router';
|
import { Router, UrlTree } from '@angular/router';
|
||||||
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||||
import { filter, find, map, mergeMap, switchMap, take, takeWhile, tap } from 'rxjs/operators';
|
import { debounceTime, filter, find, map, mergeMap, switchMap, take, takeWhile, tap } from 'rxjs/operators';
|
||||||
import { hasNoValue, hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util';
|
import { hasNoValue, hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { SearchResult } from '../../shared/search/search-result.model';
|
import { SearchResult } from '../../shared/search/search-result.model';
|
||||||
import { PaginatedList } from '../data/paginated-list.model';
|
import { PaginatedList } from '../data/paginated-list.model';
|
||||||
@@ -15,6 +15,12 @@ import { DSpaceObject } from './dspace-object.model';
|
|||||||
import { getForbiddenRoute, getPageNotFoundRoute } from '../../app-routing-paths';
|
import { getForbiddenRoute, getPageNotFoundRoute } from '../../app-routing-paths';
|
||||||
import { getEndUserAgreementPath } from '../../info/info-routing-paths';
|
import { getEndUserAgreementPath } from '../../info/info-routing-paths';
|
||||||
import { AuthService } from '../auth/auth.service';
|
import { AuthService } from '../auth/auth.service';
|
||||||
|
import { InjectionToken } from '@angular/core';
|
||||||
|
|
||||||
|
export const DEBOUNCE_TIME_OPERATOR = new InjectionToken<<T>(dueTime: number) => (source: Observable<T>) => Observable<T>>('debounceTime', {
|
||||||
|
providedIn: 'root',
|
||||||
|
factory: () => debounceTime
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file contains custom RxJS operators that can be used in multiple places
|
* This file contains custom RxJS operators that can be used in multiple places
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
|
|
||||||
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs';
|
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs';
|
||||||
import { TestScheduler } from 'rxjs/testing';
|
|
||||||
import { provideMockActions } from '@ngrx/effects/testing';
|
import { provideMockActions } from '@ngrx/effects/testing';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { RelationshipEffects } from './relationship.effects';
|
import { RelationshipEffects } from './relationship.effects';
|
||||||
import { AddRelationshipAction, RelationshipActionTypes, RemoveRelationshipAction } from './relationship.actions';
|
import { AddRelationshipAction, RelationshipActionTypes, RemoveRelationshipAction } from './relationship.actions';
|
||||||
import { Item } from '../../../../../core/shared/item.model';
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
@@ -23,6 +20,9 @@ import { RequestService } from '../../../../../core/data/request.service';
|
|||||||
import { NotificationsService } from '../../../../notifications/notifications.service';
|
import { NotificationsService } from '../../../../notifications/notifications.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { SelectableListService } from '../../../../object-list/selectable-list/selectable-list.service';
|
import { SelectableListService } from '../../../../object-list/selectable-list/selectable-list.service';
|
||||||
|
import { cold, hot } from 'jasmine-marbles';
|
||||||
|
import { DEBOUNCE_TIME_OPERATOR } from '../../../../../core/shared/operators';
|
||||||
|
import { last } from 'rxjs/operators';
|
||||||
|
|
||||||
describe('RelationshipEffects', () => {
|
describe('RelationshipEffects', () => {
|
||||||
let relationEffects: RelationshipEffects;
|
let relationEffects: RelationshipEffects;
|
||||||
@@ -51,7 +51,6 @@ describe('RelationshipEffects', () => {
|
|||||||
let notificationsService;
|
let notificationsService;
|
||||||
let translateService;
|
let translateService;
|
||||||
let selectableListService;
|
let selectableListService;
|
||||||
let testScheduler: TestScheduler;
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
testUUID1 = '20e24c2f-a00a-467c-bdee-c929e79bf08d';
|
testUUID1 = '20e24c2f-a00a-467c-bdee-c929e79bf08d';
|
||||||
@@ -131,6 +130,7 @@ describe('RelationshipEffects', () => {
|
|||||||
{ provide: NotificationsService, useValue: notificationsService },
|
{ provide: NotificationsService, useValue: notificationsService },
|
||||||
{ provide: TranslateService, useValue: translateService },
|
{ provide: TranslateService, useValue: translateService },
|
||||||
{ provide: SelectableListService, useValue: selectableListService },
|
{ provide: SelectableListService, useValue: selectableListService },
|
||||||
|
{ provide: DEBOUNCE_TIME_OPERATOR, useValue: jasmine.createSpy('debounceTime').and.returnValue((v) => v.pipe(last())) },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@@ -140,9 +140,6 @@ describe('RelationshipEffects', () => {
|
|||||||
identifier = (relationEffects as any).createIdentifier(leftItem, rightItem, relationshipType.leftwardType);
|
identifier = (relationEffects as any).createIdentifier(leftItem, rightItem, relationshipType.leftwardType);
|
||||||
spyOn((relationEffects as any), 'addRelationship').and.stub();
|
spyOn((relationEffects as any), 'addRelationship').and.stub();
|
||||||
spyOn((relationEffects as any), 'removeRelationship').and.stub();
|
spyOn((relationEffects as any), 'removeRelationship').and.stub();
|
||||||
testScheduler = new TestScheduler((actual, expected) => {
|
|
||||||
expect(actual).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('mapLastActions$', () => {
|
describe('mapLastActions$', () => {
|
||||||
@@ -151,15 +148,13 @@ describe('RelationshipEffects', () => {
|
|||||||
let action;
|
let action;
|
||||||
|
|
||||||
it('should set the current value debounceMap and the value of the initialActionMap to ADD_RELATIONSHIP', () => {
|
it('should set the current value debounceMap and the value of the initialActionMap to ADD_RELATIONSHIP', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
action = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
action = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--a-|', { a: action });
|
||||||
actions = hot('--a-|', { a: action });
|
const expected = cold('--b-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--b-|', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
|
||||||
// TODO check following expectations with the implementation
|
expect((relationEffects as any).initialActionMap[identifier]).toBe(action.type);
|
||||||
// expect((relationEffects as any).initialActionMap[identifier]).toBe(action.type);
|
expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
||||||
// expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -172,14 +167,14 @@ describe('RelationshipEffects', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should set the current value debounceMap to ADD_RELATIONSHIP but not change the value of the initialActionMap', () => {
|
it('should set the current value debounceMap to ADD_RELATIONSHIP but not change the value of the initialActionMap', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
action = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
action = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--a-|', { a: action });
|
||||||
actions = hot('--a-|', { a: action });
|
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--b-|', { b: undefined });
|
const expected = cold('--b-|', { b: undefined });
|
||||||
flush();
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
expect((relationEffects as any).initialActionMap[identifier]).toBe(testActionType);
|
|
||||||
expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
expect((relationEffects as any).initialActionMap[identifier]).toBe(testActionType);
|
||||||
});
|
expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -188,30 +183,26 @@ describe('RelationshipEffects', () => {
|
|||||||
describe('When the last value in the debounceMap is also an ADD_RELATIONSHIP action', () => {
|
describe('When the last value in the debounceMap is also an ADD_RELATIONSHIP action', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(relationEffects as any).initialActionMap[identifier] = RelationshipActionTypes.ADD_RELATIONSHIP;
|
(relationEffects as any).initialActionMap[identifier] = RelationshipActionTypes.ADD_RELATIONSHIP;
|
||||||
|
((relationEffects as any).debounceTime as jasmine.Spy).and.returnValue((v) => v);
|
||||||
});
|
});
|
||||||
it('should call addRelationship on the effect', () => {
|
it('should call addRelationship on the effect', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
action = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
action = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--a-|', { a: action });
|
||||||
actions = hot('--a-|', { a: action });
|
const expected = cold('--b-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--b-|', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
expect((relationEffects as any).addRelationship).toHaveBeenCalledWith(leftItem, rightItem, relationshipType.leftwardType, '1234', undefined);
|
||||||
expect((relationEffects as any).addRelationship).toHaveBeenCalledWith(leftItem, rightItem, relationshipType.leftwardType, '1234', undefined);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When the last value in the debounceMap is instead a REMOVE_RELATIONSHIP action', () => {
|
describe('When the last value in the debounceMap is instead a REMOVE_RELATIONSHIP action', () => {
|
||||||
|
|
||||||
it('should <b>not</b> call removeRelationship or addRelationship on the effect', () => {
|
it('should <b>not</b> call removeRelationship or addRelationship on the effect', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
const actiona = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
const actiona = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
const actionb = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
const actionb = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--ab-|', { a: actiona, b: actionb });
|
||||||
actions = hot('--ab-|', { a: actiona, b: actionb });
|
const expected = cold('--bb-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--bb-|', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
expect((relationEffects as any).addRelationship).not.toHaveBeenCalled();
|
||||||
expect((relationEffects as any).addRelationship).not.toHaveBeenCalled();
|
expect((relationEffects as any).removeRelationship).not.toHaveBeenCalled();
|
||||||
expect((relationEffects as any).removeRelationship).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -222,15 +213,13 @@ describe('RelationshipEffects', () => {
|
|||||||
let action;
|
let action;
|
||||||
|
|
||||||
it('should set the current value debounceMap and the value of the initialActionMap to REMOVE_RELATIONSHIP', () => {
|
it('should set the current value debounceMap and the value of the initialActionMap to REMOVE_RELATIONSHIP', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
action = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
action = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--a-|', { a: action });
|
||||||
actions = hot('--a-|', { a: action });
|
const expected = cold('--b-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--b-|', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
|
||||||
// TODO check following expectations with the implementation
|
expect((relationEffects as any).initialActionMap[identifier]).toBe(action.type);
|
||||||
// expect((relationEffects as any).initialActionMap[identifier]).toBe(action.type);
|
expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
||||||
// expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -238,20 +227,19 @@ describe('RelationshipEffects', () => {
|
|||||||
let action;
|
let action;
|
||||||
const testActionType = 'TEST_TYPE';
|
const testActionType = 'TEST_TYPE';
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
((relationEffects as any).debounceTime as jasmine.Spy).and.returnValue((v) => v);
|
||||||
(relationEffects as any).initialActionMap[identifier] = testActionType;
|
(relationEffects as any).initialActionMap[identifier] = testActionType;
|
||||||
(relationEffects as any).debounceMap[identifier] = new BehaviorSubject<string>(testActionType);
|
(relationEffects as any).debounceMap[identifier] = new BehaviorSubject<string>(testActionType);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the current value debounceMap to REMOVE_RELATIONSHIP but not change the value of the initialActionMap', () => {
|
it('should set the current value debounceMap to REMOVE_RELATIONSHIP but not change the value of the initialActionMap', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
action = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
action = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--a-|', { a: action });
|
||||||
actions = hot('--a-|', { a: action });
|
const expected = cold('--b-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--b-|', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
|
||||||
// TODO check following expectations with the implementation
|
expect((relationEffects as any).initialActionMap[identifier]).toBe(testActionType);
|
||||||
// expect((relationEffects as any).initialActionMap[identifier]).toBe(testActionType);
|
expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
||||||
// expect((relationEffects as any).debounceMap[identifier].value).toBe(action.type);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -259,32 +247,28 @@ describe('RelationshipEffects', () => {
|
|||||||
let action;
|
let action;
|
||||||
describe('When the last value in the debounceMap is also an REMOVE_RELATIONSHIP action', () => {
|
describe('When the last value in the debounceMap is also an REMOVE_RELATIONSHIP action', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
((relationEffects as any).debounceTime as jasmine.Spy).and.returnValue((v) => v);
|
||||||
(relationEffects as any).initialActionMap[identifier] = RelationshipActionTypes.REMOVE_RELATIONSHIP;
|
(relationEffects as any).initialActionMap[identifier] = RelationshipActionTypes.REMOVE_RELATIONSHIP;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call removeRelationship on the effect', () => {
|
it('should call removeRelationship on the effect', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
action = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
action = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--a-|', { a: action });
|
||||||
actions = hot('a', { a: action });
|
const expected = cold('--b-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('b', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
expect((relationEffects as any).removeRelationship).toHaveBeenCalledWith(leftItem, rightItem, relationshipType.leftwardType, '1234',);
|
||||||
expect((relationEffects as any).removeRelationship).toHaveBeenCalledWith(leftItem, rightItem, relationshipType.leftwardType, '1234',);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When the last value in the debounceMap is instead a ADD_RELATIONSHIP action', () => {
|
describe('When the last value in the debounceMap is instead a ADD_RELATIONSHIP action', () => {
|
||||||
|
|
||||||
it('should <b>not</b> call addRelationship or removeRelationship on the effect', () => {
|
it('should <b>not</b> call addRelationship or removeRelationship on the effect', () => {
|
||||||
testScheduler.run(({ hot, expectObservable, flush }) => {
|
const actionb = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
const actionb = new RemoveRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
const actiona = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
||||||
const actiona = new AddRelationshipAction(leftItem, rightItem, relationshipType.leftwardType, '1234');
|
actions = hot('--ab-|', { a: actiona, b: actionb });
|
||||||
actions = hot('--ab-|', { a: actiona, b: actionb });
|
const expected = cold('--bb-|', { b: undefined });
|
||||||
expectObservable(relationEffects.mapLastActions$).toBe('--bb-|', { b: undefined });
|
expect(relationEffects.mapLastActions$).toBeObservable(expected);
|
||||||
flush();
|
expect((relationEffects as any).addRelationship).not.toHaveBeenCalled();
|
||||||
expect((relationEffects as any).addRelationship).not.toHaveBeenCalled();
|
expect((relationEffects as any).removeRelationship).not.toHaveBeenCalled();
|
||||||
expect((relationEffects as any).removeRelationship).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Inject, Injectable } from '@angular/core';
|
||||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
import { Actions, Effect, ofType } from '@ngrx/effects';
|
||||||
import { debounceTime, filter, map, mergeMap, switchMap, take } from 'rxjs/operators';
|
import { filter, map, mergeMap, switchMap, take } from 'rxjs/operators';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { RelationshipService } from '../../../../../core/data/relationship.service';
|
import { RelationshipService } from '../../../../../core/data/relationship.service';
|
||||||
import {
|
import {
|
||||||
getRemoteDataPayload,
|
getRemoteDataPayload,
|
||||||
getFirstSucceededRemoteData
|
getFirstSucceededRemoteData, DEBOUNCE_TIME_OPERATOR
|
||||||
} from '../../../../../core/shared/operators';
|
} from '../../../../../core/shared/operators';
|
||||||
import {
|
import {
|
||||||
AddRelationshipAction,
|
AddRelationshipAction,
|
||||||
@@ -71,7 +71,7 @@ export class RelationshipEffects {
|
|||||||
this.initialActionMap[identifier] = action.type;
|
this.initialActionMap[identifier] = action.type;
|
||||||
this.debounceMap[identifier] = new BehaviorSubject<string>(action.type);
|
this.debounceMap[identifier] = new BehaviorSubject<string>(action.type);
|
||||||
this.debounceMap[identifier].pipe(
|
this.debounceMap[identifier].pipe(
|
||||||
debounceTime(DEBOUNCE_TIME),
|
this.debounceTime(DEBOUNCE_TIME),
|
||||||
take(1)
|
take(1)
|
||||||
).subscribe(
|
).subscribe(
|
||||||
(type) => {
|
(type) => {
|
||||||
@@ -159,6 +159,7 @@ export class RelationshipEffects {
|
|||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private selectableListService: SelectableListService,
|
private selectableListService: SelectableListService,
|
||||||
|
@Inject(DEBOUNCE_TIME_OPERATOR) private debounceTime: <T>(dueTime: number) => (source: Observable<T>) => Observable<T>,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user