104938 Fix ProcessDetailComponent tests

This commit is contained in:
Koen Pauwels
2023-09-01 16:11:32 +02:00
parent a59776d5a0
commit 53b0af100d
5 changed files with 36 additions and 41 deletions

View File

@@ -3,13 +3,12 @@ import { ScriptDataService } from '../../../../core/data/processes/script-data.s
import { ContentSource } from '../../../../core/shared/content-source.model'; import { ContentSource } from '../../../../core/shared/content-source.model';
import { ProcessDataService } from '../../../../core/data/processes/process-data.service'; import { ProcessDataService } from '../../../../core/data/processes/process-data.service';
import { import {
getAllCompletedRemoteData,
getAllSucceededRemoteDataPayload, getAllSucceededRemoteDataPayload,
getFirstCompletedRemoteData, getFirstCompletedRemoteData,
getFirstSucceededRemoteDataPayload getFirstSucceededRemoteDataPayload
} from '../../../../core/shared/operators'; } from '../../../../core/shared/operators';
import { filter, map, switchMap, tap } from 'rxjs/operators'; import { filter, map, switchMap, tap } from 'rxjs/operators';
import { hasValue, hasValueOperator } from '../../../../shared/empty.util'; import { hasValue } from '../../../../shared/empty.util';
import { ProcessStatus } from '../../../../process-page/processes/process-status.model'; import { ProcessStatus } from '../../../../process-page/processes/process-status.model';
import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { RequestService } from '../../../../core/data/request.service'; import { RequestService } from '../../../../core/data/request.service';

View File

@@ -9,7 +9,7 @@
import { testFindAllDataImplementation } from '../base/find-all-data.spec'; import { testFindAllDataImplementation } from '../base/find-all-data.spec';
import { ProcessDataService, TIMER_FACTORY } from './process-data.service'; import { ProcessDataService, TIMER_FACTORY } from './process-data.service';
import { testDeleteDataImplementation } from '../base/delete-data.spec'; import { testDeleteDataImplementation } from '../base/delete-data.spec';
import { waitForAsync, TestBed, fakeAsync, tick } from '@angular/core/testing'; import { waitForAsync, TestBed } from '@angular/core/testing';
import { RequestService } from '../request.service'; import { RequestService } from '../request.service';
import { RemoteData } from '../remote-data'; import { RemoteData } from '../remote-data';
import { RequestEntryState } from '../request-entry-state.model'; import { RequestEntryState } from '../request-entry-state.model';
@@ -22,9 +22,7 @@ import { HALEndpointService } from '../../shared/hal-endpoint.service';
import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service';
import { BitstreamFormatDataService } from '../bitstream-format-data.service'; import { BitstreamFormatDataService } from '../bitstream-format-data.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { TestScheduler, RunHelpers } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { cold } from 'jasmine-marbles';
import { of } from 'rxjs';
describe('ProcessDataService', () => { describe('ProcessDataService', () => {
let testScheduler; let testScheduler;

View File

@@ -35,6 +35,22 @@ export const TIMER_FACTORY = new InjectionToken<(callback: (...args: any[]) => v
@Injectable() @Injectable()
@dataService(PROCESS) @dataService(PROCESS)
export class ProcessDataService extends IdentifiableDataService<Process> implements FindAllData<Process>, DeleteData<Process> { export class ProcessDataService extends IdentifiableDataService<Process> implements FindAllData<Process>, DeleteData<Process> {
/**
* Return true if the given process has the given status
* @protected
*/
protected static statusIs(process: Process, status: ProcessStatus): boolean {
return hasValue(process) && process.processStatus === status;
}
/**
* Return true if the given process has the status COMPLETED or FAILED
*/
public static hasCompletedOrFailed(process: Process): boolean {
return ProcessDataService.statusIs(process, ProcessStatus.COMPLETED) ||
ProcessDataService.statusIs(process, ProcessStatus.FAILED);
}
private findAllData: FindAllData<Process>; private findAllData: FindAllData<Process>;
private deleteData: DeleteData<Process>; private deleteData: DeleteData<Process>;
protected activelyBeingPolled: Map<string, NodeJS.Timeout> = new Map(); protected activelyBeingPolled: Map<string, NodeJS.Timeout> = new Map();
@@ -117,22 +133,6 @@ export class ProcessDataService extends IdentifiableDataService<Process> impleme
return this.deleteData.deleteByHref(href, copyVirtualMetadata); return this.deleteData.deleteByHref(href, copyVirtualMetadata);
} }
/**
* Return true if the given process has the given status
* @protected
*/
protected statusIs(process: Process, status: ProcessStatus): boolean {
return hasValue(process) && process.processStatus === status;
}
/**
* Return true if the given process has the status COMPLETED or FAILED
*/
public hasCompletedOrFailed(process: Process): boolean {
return this.statusIs(process, ProcessStatus.COMPLETED) ||
this.statusIs(process, ProcessStatus.FAILED);
}
/** /**
* Clear the timeout for the given process, if that timeout exists * Clear the timeout for the given process, if that timeout exists
* @protected * @protected
@@ -142,7 +142,7 @@ export class ProcessDataService extends IdentifiableDataService<Process> impleme
if (hasValue(timeout)) { if (hasValue(timeout)) {
clearTimeout(timeout); clearTimeout(timeout);
} }
}; }
/** /**
* Poll the process with the given ID, using the given interval, until that process either * Poll the process with the given ID, using the given interval, until that process either
@@ -166,7 +166,7 @@ export class ProcessDataService extends IdentifiableDataService<Process> impleme
// the polling interval time has been exceeded. // the polling interval time has been exceeded.
const sub = process$.pipe( const sub = process$.pipe(
filter((processRD: RemoteData<Process>) => filter((processRD: RemoteData<Process>) =>
!this.hasCompletedOrFailed(processRD.payload) && !ProcessDataService.hasCompletedOrFailed(processRD.payload) &&
!this.activelyBeingPolled.has(processId) !this.activelyBeingPolled.has(processId)
) )
).subscribe((processRD: RemoteData<Process>) => { ).subscribe((processRD: RemoteData<Process>) => {
@@ -183,7 +183,7 @@ export class ProcessDataService extends IdentifiableDataService<Process> impleme
// observable) that unsubscribes the previous one, removes the processId from the list of // observable) that unsubscribes the previous one, removes the processId from the list of
// processes being polled and clears any running timeouts // processes being polled and clears any running timeouts
process$.pipe( process$.pipe(
find((processRD: RemoteData<Process>) => this.hasCompletedOrFailed(processRD.payload)) find((processRD: RemoteData<Process>) => ProcessDataService.hasCompletedOrFailed(processRD.payload))
).subscribe(() => { ).subscribe(() => {
this.clearCurrentTimeout(processId); this.clearCurrentTimeout(processId);
this.activelyBeingPolled.delete(processId); this.activelyBeingPolled.delete(processId);

View File

@@ -35,7 +35,6 @@ import { NotificationsServiceStub } from '../../shared/testing/notifications-ser
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { getProcessListRoute } from '../process-page-routing.paths'; import { getProcessListRoute } from '../process-page-routing.paths';
import {ProcessStatus} from '../processes/process-status.model';
describe('ProcessDetailComponent', () => { describe('ProcessDetailComponent', () => {
let component: ProcessDetailComponent; let component: ProcessDetailComponent;
@@ -106,12 +105,11 @@ describe('ProcessDetailComponent', () => {
content: { href: 'log-selflink' } content: { href: 'log-selflink' }
} }
}); });
const processRD$ = createSuccessfulRemoteDataObject$(process);
processService = jasmine.createSpyObj('processService', { processService = jasmine.createSpyObj('processService', {
getFiles: createSuccessfulRemoteDataObject$(createPaginatedList(files)), getFiles: createSuccessfulRemoteDataObject$(createPaginatedList(files)),
delete: createSuccessfulRemoteDataObject$(null), delete: createSuccessfulRemoteDataObject$(null),
findById: processRD$, findById: createSuccessfulRemoteDataObject$(process),
autoRefreshUntilCompletion: processRD$ autoRefreshUntilCompletion: createSuccessfulRemoteDataObject$(process)
}); });
bitstreamDataService = jasmine.createSpyObj('bitstreamDataService', { bitstreamDataService = jasmine.createSpyObj('bitstreamDataService', {
findByHref: createSuccessfulRemoteDataObject$(logBitstream) findByHref: createSuccessfulRemoteDataObject$(logBitstream)
@@ -134,7 +132,7 @@ describe('ProcessDetailComponent', () => {
}); });
route = jasmine.createSpyObj('route', { route = jasmine.createSpyObj('route', {
data: observableOf({ process: processRD$ }), data: observableOf({ process: createSuccessfulRemoteDataObject$(process) }),
snapshot: { snapshot: {
params: { id: process.processId } params: { id: process.processId }
} }
@@ -149,7 +147,12 @@ describe('ProcessDetailComponent', () => {
providers: [ providers: [
{ {
provide: ActivatedRoute, provide: ActivatedRoute,
useValue: { data: observableOf({ process: createSuccessfulRemoteDataObject(process) }) } useValue: {
data: observableOf({ process: createSuccessfulRemoteDataObject(process) }),
snapshot: {
params: { id: process.processId }
}
}
}, },
{ provide: ProcessDataService, useValue: processService }, { provide: ProcessDataService, useValue: processService },
{ provide: BitstreamDataService, useValue: bitstreamDataService }, { provide: BitstreamDataService, useValue: bitstreamDataService },
@@ -160,8 +163,7 @@ describe('ProcessDetailComponent', () => {
{ provide: NotificationsService, useValue: notificationsService }, { provide: NotificationsService, useValue: notificationsService },
{ provide: Router, useValue: router }, { provide: Router, useValue: router },
], ],
// schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
schemas: []
}).compileComponents(); }).compileComponents();
})); }));

View File

@@ -1,8 +1,8 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Component, Inject, NgZone, OnInit, PLATFORM_ID } from '@angular/core'; import { Component, Inject, NgZone, OnInit, PLATFORM_ID } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { BehaviorSubject, Observable, Subscription, interval } from 'rxjs'; import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { finalize, map, switchMap, take, tap, filter, find, startWith } from 'rxjs/operators'; import { finalize, map, switchMap, take, tap, find, startWith } from 'rxjs/operators';
import { AuthService } from '../../core/auth/auth.service'; import { AuthService } from '../../core/auth/auth.service';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { BitstreamDataService } from '../../core/data/bitstream-data.service'; import { BitstreamDataService } from '../../core/data/bitstream-data.service';
@@ -109,10 +109,7 @@ export class ProcessDetailComponent implements OnInit {
this.processRD$ = this.route.data.pipe( this.processRD$ = this.route.data.pipe(
switchMap((data) => { switchMap((data) => {
if (isPlatformBrowser(this.platformId)) { if (isPlatformBrowser(this.platformId)) {
const x = this.processService.autoRefreshUntilCompletion(this.route.snapshot.params.id, 5000); return this.processService.autoRefreshUntilCompletion(this.route.snapshot.params.id, 5000);
//[data.process as RemoteData<Process>];
console.log("ASDF", x);
return x;
} else { } else {
return [data.process as RemoteData<Process>]; return [data.process as RemoteData<Process>];
} }
@@ -120,9 +117,8 @@ export class ProcessDetailComponent implements OnInit {
redirectOn4xx(this.router, this.authService), redirectOn4xx(this.router, this.authService),
); );
this.processRD$.subscribe(x => console.log("QWER", x));
this.isRefreshing$ = this.processRD$.pipe( this.isRefreshing$ = this.processRD$.pipe(
find((processRD: RemoteData<Process>) => this.processService.hasCompletedOrFailed(processRD.payload)), find((processRD: RemoteData<Process>) => ProcessDataService.hasCompletedOrFailed(processRD.payload)),
map(() => false), map(() => false),
startWith(true) startWith(true)
); );