71712: Test fixes: eventemitter to subject in confirmation modal

This commit is contained in:
Marie Verdonck
2020-07-28 01:41:55 +02:00
parent 3e0f4a54e6
commit 26905860ba
6 changed files with 66 additions and 36 deletions

View File

@@ -46,27 +46,27 @@ describe('ConfirmationModalComponent', () => {
describe('confirmPressed', () => {
beforeEach(() => {
spyOn(component.response, 'emit');
spyOn(component.response, 'next');
component.confirmPressed();
});
it('should call the close method on the active modal', () => {
expect(modalStub.close).toHaveBeenCalled();
});
it('event emitter should emit true', () => {
expect(component.response.emit).toHaveBeenCalledWith(true);
it('behaviour subject should have true as next', () => {
expect(component.response.next).toHaveBeenCalledWith(true);
});
});
describe('cancelPressed', () => {
beforeEach(() => {
spyOn(component.response, 'emit');
spyOn(component.response, 'next');
component.cancelPressed();
});
it('should call the close method on the active modal', () => {
expect(modalStub.close).toHaveBeenCalled();
});
it('event emitter should emit false', () => {
expect(component.response.emit).toHaveBeenCalledWith(false);
it('behaviour subject should have false as next', () => {
expect(component.response.next).toHaveBeenCalledWith(false);
});
});
@@ -85,7 +85,7 @@ describe('ConfirmationModalComponent', () => {
describe('when the click method emits on cancel button', () => {
beforeEach(fakeAsync(() => {
spyOn(component, 'close');
spyOn(component.response, 'emit');
spyOn(component.response, 'next');
debugElement.query(By.css('button.cancel')).triggerEventHandler('click', {});
tick();
fixture.detectChanges();
@@ -93,15 +93,15 @@ describe('ConfirmationModalComponent', () => {
it('should call the close method on the component', () => {
expect(component.close).toHaveBeenCalled();
});
it('event emitter should emit false', () => {
expect(component.response.emit).toHaveBeenCalledWith(false);
it('behaviour subject should have false as next', () => {
expect(component.response.next).toHaveBeenCalledWith(false);
});
});
describe('when the click method emits on confirm button', () => {
beforeEach(fakeAsync(() => {
spyOn(component, 'close');
spyOn(component.response, 'emit');
spyOn(component.response, 'next');
debugElement.query(By.css('button.confirm')).triggerEventHandler('click', {});
tick();
fixture.detectChanges();
@@ -109,8 +109,8 @@ describe('ConfirmationModalComponent', () => {
it('should call the close method on the component', () => {
expect(component.close).toHaveBeenCalled();
});
it('event emitter should emit true', () => {
expect(component.response.emit).toHaveBeenCalledWith(true);
it('behaviour subject should have true as next', () => {
expect(component.response.next).toHaveBeenCalledWith(true);
});
});

View File

@@ -1,6 +1,6 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { Component, Input, Output } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { Subject } from 'rxjs/internal/Subject';
import { DSpaceObject } from '../../core/shared/dspace-object.model';
@Component({
@@ -18,7 +18,7 @@ export class ConfirmationModalComponent {
* An event fired when the cancel or confirm button is clicked, with respectively false or true
*/
@Output()
response = new EventEmitter<boolean>();
response: Subject<boolean> = new Subject();
constructor(protected activeModal: NgbActiveModal) {
}
@@ -27,7 +27,7 @@ export class ConfirmationModalComponent {
* Confirm the action that led to the modal
*/
confirmPressed() {
this.response.emit(true);
this.response.next(true);
this.close();
}
@@ -35,7 +35,7 @@ export class ConfirmationModalComponent {
* Cancel the action that led to the modal and close modal
*/
cancelPressed() {
this.response.emit(false);
this.response.next(false);
this.close();
}

View File

@@ -1,24 +1,45 @@
import { of as observableOf } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { DebugElement, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { NgbActiveModal, NgbModal, NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
import { ActivatedRoute, Router } from '@angular/router';
import { METADATA_EXPORT_SCRIPT_NAME, ScriptDataService } from '../../../../core/data/processes/script-data.service';
import { Collection } from '../../../../core/shared/collection.model';
import { Community } from '../../../../core/shared/community.model';
import { Item } from '../../../../core/shared/item.model';
import { ProcessParameter } from '../../../../process-page/processes/process-parameter.model';
import { ConfirmationModalComponent } from '../../../confirmation-modal/confirmation-modal.component';
import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock';
import { NotificationsService } from '../../../notifications/notifications.service';
import { NotificationsServiceStub } from '../../../testing/notifications-service.stub';
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
import { ExportMetadataSelectorComponent } from './export-metadata-selector.component';
// No way to add entryComponents yet to testbed; alternative implemented; source: https://stackoverflow.com/questions/41689468/how-to-shallow-test-a-component-with-an-entrycomponents
@NgModule({
imports: [ NgbModalModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock
}
}),
],
exports: [],
declarations: [ConfirmationModalComponent],
providers: [],
entryComponents: [ConfirmationModalComponent],
})
class ModelTestModule { }
describe('ExportMetadataSelectorComponent', () => {
let component: ExportMetadataSelectorComponent;
let fixture: ComponentFixture<ExportMetadataSelectorComponent>;
let debugElement: DebugElement;
let modalRef;
let router;
let notificationService: NotificationsServiceStub;
@@ -61,7 +82,7 @@ describe('ExportMetadataSelectorComponent', () => {
}
);
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])],
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), ModelTestModule],
declarations: [ExportMetadataSelectorComponent],
providers: [
{ provide: NgbActiveModal, useValue: modalStub },
@@ -92,6 +113,9 @@ describe('ExportMetadataSelectorComponent', () => {
fixture = TestBed.createComponent(ExportMetadataSelectorComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
const modalService = TestBed.get(NgbModal);
modalRef = modalService.open(ConfirmationModalComponent);
modalRef.componentInstance.response = observableOf(true);
fixture.detectChanges();
});
@@ -116,6 +140,7 @@ describe('ExportMetadataSelectorComponent', () => {
describe('if collection is selected', () => {
let scriptRequestSucceeded;
beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
component.navigate(mockCollection).subscribe((succeeded: boolean) => {
scriptRequestSucceeded = succeeded;
done()
@@ -140,6 +165,7 @@ describe('ExportMetadataSelectorComponent', () => {
describe('if community is selected', () => {
let scriptRequestSucceeded;
beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
component.navigate(mockCommunity).subscribe((succeeded: boolean) => {
scriptRequestSucceeded = succeeded;
done()
@@ -164,6 +190,7 @@ describe('ExportMetadataSelectorComponent', () => {
describe('if community/collection is selected; but script invoke fails', () => {
let scriptRequestSucceeded;
beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
jasmine.getEnv().allowRespy(true);
spyOn(scriptService, 'invoke').and.returnValue(observableOf({
response:

View File

@@ -2,9 +2,8 @@ import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { take, map } from 'rxjs/operators';
import { take, map, switchMap } from 'rxjs/operators';
import { of as observableOf } from 'rxjs';
import { AuthService } from '../../../../core/auth/auth.service';
import { METADATA_EXPORT_SCRIPT_NAME, ScriptDataService } from '../../../../core/data/processes/script-data.service';
import { RequestEntry } from '../../../../core/data/request.reducer';
import { Collection } from '../../../../core/shared/collection.model';
@@ -47,21 +46,25 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp
if (dso instanceof Collection || dso instanceof Community) {
const modalRef = this.modalService.open(ConfirmationModalComponent);
modalRef.componentInstance.dso = dso;
modalRef.componentInstance.headerLabel = "confirmation-modal.export-metadata.header";
modalRef.componentInstance.infoLabel = "confirmation-modal.export-metadata.info";
modalRef.componentInstance.cancelLabel = "confirmation-modal.export-metadata.cancel";
modalRef.componentInstance.confirmLabel = "confirmation-modal.export-metadata.confirm";
modalRef.componentInstance.response.subscribe((confirm: boolean) => {
modalRef.componentInstance.headerLabel = 'confirmation-modal.export-metadata.header';
modalRef.componentInstance.infoLabel = 'confirmation-modal.export-metadata.info';
modalRef.componentInstance.cancelLabel = 'confirmation-modal.export-metadata.cancel';
modalRef.componentInstance.confirmLabel = 'confirmation-modal.export-metadata.confirm';
const resp$ = modalRef.componentInstance.response.pipe(switchMap((confirm: boolean) => {
if (confirm) {
const startScriptSucceeded = this.startScriptNotifyAndRedirect(dso, dso.handle);
startScriptSucceeded.pipe(take(1)).subscribe();
return startScriptSucceeded;
const startScriptSucceeded$ = this.startScriptNotifyAndRedirect(dso, dso.handle);
return startScriptSucceeded$.pipe(
switchMap((r: boolean) => {
return observableOf(r);
})
)
} else {
const modalRef = this.modalService.open(ExportMetadataSelectorComponent);
modalRef.componentInstance.dsoRD = createSuccessfulRemoteDataObject(dso);
}
});
}));
resp$.subscribe();
return resp$;
} else {
this.notificationsService.error(this.translationService.get('dso-selector.export-metadata.notValidDSO'));
return observableOf(false);

View File

@@ -3,7 +3,7 @@ import { Observable } from 'rxjs/internal/Observable';
import { MenuService } from './menu.service';
import { MenuID } from './initial-menus-state';
import { MenuSection } from './menu.reducer';
import { distinctUntilChanged, first, map, tap, switchMap, take } from 'rxjs/operators';
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import { hasValue } from '../empty.util';
import { MenuSectionComponent } from './menu-section/menu-section.component';

View File

@@ -105,7 +105,7 @@ export const environment: Partial<GlobalConfig> = {
},
// Angular Universal settings
universal: {
preboot: false,
preboot: true,
async: true,
time: false
},