1 import { Component, NgModule, NO_ERRORS_SCHEMA, TemplateRef, ViewChild } from '@angular/core';
2 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
3 import { NgForm, ReactiveFormsModule } from '@angular/forms';
5 import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
6 import { Observable, Subscriber, timer as observableTimer } from 'rxjs';
8 import { DirectivesModule } from '~/app/shared/directives/directives.module';
9 import { ModalService } from '~/app/shared/services/modal.service';
10 import { configureTestBed, modalServiceShow } from '~/testing/unit-test-helper';
11 import { AlertPanelComponent } from '../alert-panel/alert-panel.component';
12 import { LoadingPanelComponent } from '../loading-panel/loading-panel.component';
13 import { CriticalConfirmationModalComponent } from './critical-confirmation-modal.component';
16 export class MockModule {}
20 <button type="button" class="btn btn-danger" (click)="openCtrlDriven()">
21 <i class="fa fa-times"></i>Deletion Ctrl-Test
22 <ng-template #ctrlDescription>
23 The spinner is handled by the controller if you have use the modal as ViewChild in order to
24 use it's functions to stop the spinner or close the dialog.
28 <button type="button" class="btn btn-danger" (click)="openModalDriven()">
29 <i class="fa fa-times"></i>Deletion Modal-Test
30 <ng-template #modalDescription>
31 The spinner is handled by the modal if your given deletion function returns a Observable.
37 @ViewChild('ctrlDescription', { static: true })
38 ctrlDescription: TemplateRef<any>;
39 @ViewChild('modalDescription', { static: true })
40 modalDescription: TemplateRef<any>;
41 someData = [1, 2, 3, 4, 5];
44 modalRef: NgbModalRef;
46 // Normally private - public was needed for the tests
47 constructor(public modalService: ModalService) {}
50 this.ctrlRef = this.modalService.show(CriticalConfirmationModalComponent, {
51 submitAction: this.fakeDeleteController.bind(this),
52 bodyTemplate: this.ctrlDescription
57 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
58 submitActionObservable: this.fakeDelete(),
59 bodyTemplate: this.modalDescription
64 this.finished = [6, 7, 8, 9];
68 return (): Observable<any> => {
69 return new Observable((observer: Subscriber<any>) => {
70 observableTimer(100).subscribe(() => {
71 observer.next(this.finish());
78 fakeDeleteController() {
79 observableTimer(100).subscribe(() => {
86 describe('CriticalConfirmationModalComponent', () => {
87 let mockComponent: MockComponent;
88 let component: CriticalConfirmationModalComponent;
89 let mockFixture: ComponentFixture<MockComponent>;
95 CriticalConfirmationModalComponent,
96 LoadingPanelComponent,
99 schemas: [NO_ERRORS_SCHEMA],
100 imports: [ReactiveFormsModule, MockModule, DirectivesModule, NgbModalModule],
101 providers: [NgbActiveModal]
103 [CriticalConfirmationModalComponent]
107 mockFixture = TestBed.createComponent(MockComponent);
108 mockComponent = mockFixture.componentInstance;
109 spyOn(mockComponent.modalService, 'show').and.callFake((_modalComp, config) => {
110 const data = modalServiceShow(CriticalConfirmationModalComponent, config);
111 component = data.componentInstance;
114 mockComponent.openCtrlDriven();
115 mockFixture.detectChanges();
118 it('should create', () => {
119 expect(component).toBeTruthy();
122 it('should throw an error if no action is defined', () => {
123 component = Object.assign(component, {
125 submitActionObservable: null
127 expect(() => component.ngOnInit()).toThrowError('No submit action defined');
130 it('should test if the ctrl driven mock is set correctly through mock component', () => {
131 expect(component.bodyTemplate).toBeTruthy();
132 expect(component.submitAction).toBeTruthy();
133 expect(component.submitActionObservable).not.toBeTruthy();
136 it('should test if the modal driven mock is set correctly through mock component', () => {
137 mockComponent.openModalDriven();
138 expect(component.bodyTemplate).toBeTruthy();
139 expect(component.submitActionObservable).toBeTruthy();
140 expect(component.submitAction).not.toBeTruthy();
143 describe('component functions', () => {
144 const changeValue = (value: boolean) => {
145 const ctrl = component.deletionForm.get('confirmation');
146 ctrl.setValue(value);
148 ctrl.updateValueAndValidity();
149 mockFixture.detectChanges();
152 it('should test hideModal', () => {
153 expect(component.activeModal).toBeTruthy();
154 expect(component.hideModal).toBeTruthy();
155 spyOn(component.activeModal, 'close').and.callThrough();
156 expect(component.activeModal.close).not.toHaveBeenCalled();
157 component.hideModal();
158 expect(component.activeModal.close).toHaveBeenCalled();
161 describe('validate confirmation', () => {
162 const testValidation = (submitted: boolean, error: string, expected: boolean) => {
164 component.deletionForm.showError('confirmation', <NgForm>{ submitted: submitted }, error)
169 component.deletionForm.reset();
172 it('should test empty values', () => {
173 component.deletionForm.reset();
174 testValidation(false, undefined, false);
175 testValidation(true, 'required', true);
176 component.deletionForm.reset();
179 testValidation(true, 'required', true);
183 describe('deletion call', () => {
185 spyOn(component, 'stopLoadingSpinner').and.callThrough();
186 spyOn(component, 'hideModal').and.callThrough();
189 describe('Controller driven', () => {
191 spyOn(component, 'submitAction').and.callThrough();
192 spyOn(mockComponent.ctrlRef, 'close').and.callThrough();
195 it('should test fake deletion that closes modal', fakeAsync(() => {
196 // Before deletionCall
197 expect(component.submitAction).not.toHaveBeenCalled();
198 // During deletionCall
199 component.callSubmitAction();
200 expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
201 expect(component.hideModal).not.toHaveBeenCalled();
202 expect(mockComponent.ctrlRef.close).not.toHaveBeenCalled();
203 expect(component.submitAction).toHaveBeenCalled();
204 expect(mockComponent.finished).toBe(undefined);
205 // After deletionCall
207 expect(component.hideModal).not.toHaveBeenCalled();
208 expect(mockComponent.ctrlRef.close).toHaveBeenCalled();
209 expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
213 describe('Modal driven', () => {
215 mockComponent.openModalDriven();
216 spyOn(component, 'stopLoadingSpinner').and.callThrough();
217 spyOn(component, 'hideModal').and.callThrough();
218 spyOn(mockComponent, 'fakeDelete').and.callThrough();
221 it('should delete and close modal', fakeAsync(() => {
222 // During deletionCall
223 component.callSubmitAction();
224 expect(mockComponent.finished).toBe(undefined);
225 expect(component.hideModal).not.toHaveBeenCalled();
226 // After deletionCall
228 expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
229 expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
230 expect(component.hideModal).toHaveBeenCalled();