1 import { Component, NgModule, TemplateRef, ViewChild } from '@angular/core';
2 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
3 import { NgForm, ReactiveFormsModule } from '@angular/forms';
5 import { Observable, Subscriber, timer as observableTimer } from 'rxjs';
7 import { DirectivesModule } from '~/app/shared/directives/directives.module';
8 import { configureTestBed, modalServiceShow } from '~/testing/unit-test-helper';
9 import { AlertPanelComponent } from '../alert-panel/alert-panel.component';
10 import { LoadingPanelComponent } from '../loading-panel/loading-panel.component';
11 import { CriticalConfirmationModalComponent } from './critical-confirmation-modal.component';
12 import { CheckboxModule, ModalService, PlaceholderService } from 'carbon-components-angular';
13 import { ModalCdsService } from '../../services/modal-cds.service';
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];
46 // Normally private - public was needed for the tests
47 constructor(public modalService: ModalCdsService) {}
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>;
94 CriticalConfirmationModalComponent,
95 LoadingPanelComponent,
98 imports: [ReactiveFormsModule, MockModule, DirectivesModule, CheckboxModule],
102 { provide: 'itemNames', useValue: [] },
103 { provide: 'itemDescription', useValue: 'entry' },
104 { provide: 'actionDescription', useValue: 'delete' }
109 mockFixture = TestBed.createComponent(MockComponent);
110 mockComponent = mockFixture.componentInstance;
111 spyOn(mockComponent.modalService, 'show').and.callFake((_modalComp, config) => {
112 const data = modalServiceShow(CriticalConfirmationModalComponent, config);
113 component = data.componentInstance;
116 mockComponent.openCtrlDriven();
117 mockFixture.detectChanges();
120 it('should create', () => {
121 expect(component).toBeTruthy();
124 it('should throw an error if no action is defined', () => {
125 component = Object.assign(component, {
127 submitActionObservable: null
129 expect(() => component.ngOnInit()).toThrowError('No submit action defined');
132 it('should test if the ctrl driven mock is set correctly through mock component', () => {
133 expect(component.bodyTemplate).toBeTruthy();
134 expect(component.submitAction).toBeTruthy();
135 expect(component.submitActionObservable).not.toBeTruthy();
138 it('should test if the modal driven mock is set correctly through mock component', () => {
139 mockComponent.openModalDriven();
140 expect(component.bodyTemplate).toBeTruthy();
141 expect(component.submitActionObservable).toBeTruthy();
142 expect(component.submitAction).not.toBeTruthy();
145 describe('component functions', () => {
146 const changeValue = (value: boolean) => {
147 const ctrl = component.deletionForm.get('confirmation');
148 ctrl.setValue(value);
150 ctrl.updateValueAndValidity();
153 it('should test hideModal', () => {
154 expect(component.hideModal).toBeTruthy();
155 spyOn(component, 'closeModal').and.callThrough();
156 expect(component.closeModal).not.toHaveBeenCalled();
157 component.hideModal();
158 expect(component.closeModal).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(true, 'required', true);
175 component.deletionForm.reset();
178 testValidation(true, 'required', true);
182 describe('deletion call', () => {
184 spyOn(component, 'stopLoadingSpinner').and.callThrough();
185 spyOn(component, 'hideModal').and.callThrough();
188 describe('Controller driven', () => {
190 spyOn(component, 'submitAction').and.callThrough();
191 spyOn(mockComponent.ctrlRef, 'close').and.callThrough();
194 it('should test fake deletion that closes modal', fakeAsync(() => {
195 // Before deletionCall
196 expect(component.submitAction).not.toHaveBeenCalled();
197 // During deletionCall
198 component.callSubmitAction();
199 expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
200 expect(component.hideModal).not.toHaveBeenCalled();
201 expect(mockComponent.ctrlRef.close).not.toHaveBeenCalled();
202 expect(component.submitAction).toHaveBeenCalled();
203 expect(mockComponent.finished).toBe(undefined);
204 // After deletionCall
206 expect(component.hideModal).not.toHaveBeenCalled();
207 expect(mockComponent.ctrlRef.close).toHaveBeenCalled();
208 expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
212 describe('Modal driven', () => {
214 mockComponent.openModalDriven();
215 spyOn(component, 'stopLoadingSpinner').and.callThrough();
216 spyOn(component, 'hideModal').and.callThrough();
217 spyOn(mockComponent, 'fakeDelete').and.callThrough();
220 it('should delete and close modal', fakeAsync(() => {
221 // During deletionCall
222 component.callSubmitAction();
223 expect(mockComponent.finished).toBe(undefined);
224 expect(component.hideModal).not.toHaveBeenCalled();
225 // After deletionCall
227 expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
228 expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
229 expect(component.hideModal).toHaveBeenCalled();