1 import { Component, NgModule, NO_ERRORS_SCHEMA, TemplateRef, ViewChild } from '@angular/core';
2 import { ComponentFixture, TestBed } from '@angular/core/testing';
3 import { ReactiveFormsModule } from '@angular/forms';
4 import { RouterTestingModule } from '@angular/router/testing';
6 import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
8 import { By } from '@angular/platform-browser';
14 } from '../../../../testing/unit-test-helper';
15 import { BackButtonComponent } from '../back-button/back-button.component';
16 import { ModalComponent } from '../modal/modal.component';
17 import { SubmitButtonComponent } from '../submit-button/submit-button.component';
18 import { ConfirmationModalComponent } from './confirmation-modal.component';
21 entryComponents: [ConfirmationModalComponent]
23 export class MockModule {}
27 <ng-template #fillTpl>
28 Template based description.
33 @ViewChild('fillTpl', { static: true })
34 fillTpl: TemplateRef<any>;
38 // Normally private, but public is needed by tests
39 constructor(public modalService: BsModalService) {}
41 private openModal(extendBaseState = {}) {
42 this.modalRef = this.modalService.show(ConfirmationModalComponent, {
43 initialState: Object.assign(
45 titleText: 'Title is a must have',
46 buttonText: 'Action label',
47 bodyTpl: this.fillTpl,
48 description: 'String based description.',
50 this.returnValue = 'The submit action has to hide manually.';
65 onCancel: () => (this.returnValue = 'If you have todo something besides hiding the modal.')
70 describe('ConfirmationModalComponent', () => {
71 let component: ConfirmationModalComponent;
72 let fixture: ComponentFixture<ConfirmationModalComponent>;
73 let mockComponent: MockComponent;
74 let mockFixture: ComponentFixture<MockComponent>;
75 let modalService: BsModalService;
76 let fh: FixtureHelper;
79 * The hide method of `BsModalService` doesn't emit events during tests that's why it's mocked.
81 * The only events of hide are `null`, `'backdrop-click'` and `'esc'` as described here:
82 * https://ngx-universal.herokuapp.com/#/modals#service-events
84 const hide = (x: string) => modalService.onHide.emit(null || x);
86 const expectReturnValue = (v: string) => expect(mockComponent.returnValue).toBe(v);
90 ConfirmationModalComponent,
96 schemas: [NO_ERRORS_SCHEMA],
97 imports: [ModalModule.forRoot(), ReactiveFormsModule, MockModule, RouterTestingModule],
98 providers: [BsModalRef, i18nProviders, SubmitButtonComponent]
102 fh = new FixtureHelper();
103 mockFixture = TestBed.createComponent(MockComponent);
104 mockComponent = mockFixture.componentInstance;
105 mockFixture.detectChanges();
106 modalService = TestBed.get(BsModalService);
107 spyOn(modalService, 'show').and.callFake((_modalComp, config) => {
108 const data = modalServiceShow(ConfirmationModalComponent, config);
109 fixture = data.fixture;
110 component = data.component;
111 spyOn(component.modalRef, 'hide').and.callFake(hide);
112 fh.updateFixture(fixture);
117 it('should create', () => {
118 mockComponent.basicModal();
119 expect(component).toBeTruthy();
122 describe('Throws errors', () => {
123 const expectError = (config: object, expected: string) => {
124 mockComponent.basicModal();
125 component = Object.assign(component, config);
126 expect(() => component.ngOnInit()).toThrowError(expected);
129 it('has no submit action defined', () => {
134 'No submit action defined'
138 it('has no title defined', () => {
147 it('has no action name defined', () => {
150 buttonText: undefined
152 'No action name defined'
156 it('has no description defined', () => {
160 description: undefined
162 'No description defined'
167 describe('basics', () => {
169 mockComponent.basicModal();
170 spyOn(mockComponent.modalRef, 'hide').and.callFake(hide);
173 it('should show the correct title', () => {
174 expect(fh.getText('.modal-title')).toBe('Title is a must have');
177 it('should show the correct action name', () => {
178 expect(fh.getText('.tc_submitButton')).toBe('Action label');
181 it('should use the correct submit action', () => {
182 // In order to ignore the `ElementRef` usage of `SubmitButtonComponent`
184 fixture.debugElement.query(By.directive(SubmitButtonComponent)).componentInstance,
187 fh.clickElement('.tc_submitButton');
188 expect(mockComponent.modalRef.hide).toHaveBeenCalledTimes(1);
189 expect(component.modalRef.hide).toHaveBeenCalledTimes(0);
190 expectReturnValue('The submit action has to hide manually.');
193 it('should use the default cancel action', () => {
194 fh.clickElement('.tc_backButton');
195 expect(mockComponent.modalRef.hide).toHaveBeenCalledTimes(0);
196 expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
197 expectReturnValue(undefined);
200 it('should show the description', () => {
201 expect(fh.getText('.modal-body')).toBe(
202 'Template based description. String based description.'
207 describe('custom cancel action', () => {
208 const expectCancelValue = () =>
209 expectReturnValue('If you have todo something besides hiding the modal.');
212 mockComponent.customCancelModal();
215 it('should use custom cancel action', () => {
216 fh.clickElement('.tc_backButton');
220 it('should use custom cancel action if escape was pressed', () => {
225 it('should use custom cancel action if clicked outside the modal', () => {
226 hide('backdrop-click');
230 it('should unsubscribe on destroy', () => {
231 hide('backdrop-click');
233 const s = 'This value will not be changed.';
234 mockComponent.returnValue = s;
235 component.ngOnDestroy();
236 hide('backdrop-click');
237 expectReturnValue(s);