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 { 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 { 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>;
95 CriticalConfirmationModalComponent,
96 LoadingPanelComponent,
99 schemas: [NO_ERRORS_SCHEMA],
100 imports: [ReactiveFormsModule, MockModule, DirectivesModule],
104 { provide: 'itemNames', useValue: [] },
105 { provide: 'itemDescription', useValue: 'entry' },
106 { provide: 'actionDescription', useValue: 'delete' }
109 [CriticalConfirmationModalComponent]
113 mockFixture = TestBed.createComponent(MockComponent);
114 mockComponent = mockFixture.componentInstance;
115 spyOn(mockComponent.modalService, 'show').and.callFake((_modalComp, config) => {
116 const data = modalServiceShow(CriticalConfirmationModalComponent, config);
117 component = data.componentInstance;
120 mockComponent.openCtrlDriven();
121 mockFixture.detectChanges();
124 it('should create', () => {
125 expect(component).toBeTruthy();
128 it('should throw an error if no action is defined', () => {
129 component = Object.assign(component, {
131 submitActionObservable: null
133 expect(() => component.ngOnInit()).toThrowError('No submit action defined');
136 it('should test if the ctrl driven mock is set correctly through mock component', () => {
137 expect(component.bodyTemplate).toBeTruthy();
138 expect(component.submitAction).toBeTruthy();
139 expect(component.submitActionObservable).not.toBeTruthy();
142 it('should test if the modal driven mock is set correctly through mock component', () => {
143 mockComponent.openModalDriven();
144 expect(component.bodyTemplate).toBeTruthy();
145 expect(component.submitActionObservable).toBeTruthy();
146 expect(component.submitAction).not.toBeTruthy();
149 describe('component functions', () => {
150 const changeValue = (value: boolean) => {
151 const ctrl = component.deletionForm.get('confirmation');
152 ctrl.setValue(value);
154 ctrl.updateValueAndValidity();
157 it('should test hideModal', () => {
158 expect(component.hideModal).toBeTruthy();
159 spyOn(component, 'closeModal').and.callThrough();
160 expect(component.closeModal).not.toHaveBeenCalled();
161 component.hideModal();
162 expect(component.closeModal).toHaveBeenCalled();
165 describe('validate confirmation', () => {
166 const testValidation = (submitted: boolean, error: string, expected: boolean) => {
168 component.deletionForm.showError('confirmation', <NgForm>{ submitted: submitted }, error)
173 component.deletionForm.reset();
176 it('should test empty values', () => {
177 component.deletionForm.reset();
178 testValidation(true, 'required', true);
179 component.deletionForm.reset();
182 testValidation(true, 'required', true);
186 describe('deletion call', () => {
188 spyOn(component, 'stopLoadingSpinner').and.callThrough();
189 spyOn(component, 'hideModal').and.callThrough();
192 describe('Controller driven', () => {
194 spyOn(component, 'submitAction').and.callThrough();
195 spyOn(mockComponent.ctrlRef, 'close').and.callThrough();
198 it('should test fake deletion that closes modal', fakeAsync(() => {
199 // Before deletionCall
200 expect(component.submitAction).not.toHaveBeenCalled();
201 // During deletionCall
202 component.callSubmitAction();
203 expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
204 expect(component.hideModal).not.toHaveBeenCalled();
205 expect(mockComponent.ctrlRef.close).not.toHaveBeenCalled();
206 expect(component.submitAction).toHaveBeenCalled();
207 expect(mockComponent.finished).toBe(undefined);
208 // After deletionCall
210 expect(component.hideModal).not.toHaveBeenCalled();
211 expect(mockComponent.ctrlRef.close).toHaveBeenCalled();
212 expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
216 describe('Modal driven', () => {
218 mockComponent.openModalDriven();
219 spyOn(component, 'stopLoadingSpinner').and.callThrough();
220 spyOn(component, 'hideModal').and.callThrough();
221 spyOn(mockComponent, 'fakeDelete').and.callThrough();
224 it('should delete and close modal', fakeAsync(() => {
225 // During deletionCall
226 component.callSubmitAction();
227 expect(mockComponent.finished).toBe(undefined);
228 expect(component.hideModal).not.toHaveBeenCalled();
229 // After deletionCall
231 expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
232 expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
233 expect(component.hideModal).toHaveBeenCalled();