diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html index ecd2fea59e..56ec59cf06 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html @@ -5,6 +5,7 @@ id="abp-modal-dialog" class="modal-dialog modal-{{ size }}" role="document" + [class.modal-dialog-centered]="centered" [@dialog]="isModalOpen" #abpModalContent > diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts index 718de17394..6f52f5a95e 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts @@ -13,10 +13,10 @@ import { } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { debounceTime, filter, takeUntil } from 'rxjs/operators'; +import { dialogAnimation, fadeAnimation } from '../../animations/modal.animations'; import { Toaster } from '../../models/toaster'; import { ConfirmationService } from '../../services/confirmation.service'; import { ButtonComponent } from '../button/button.component'; -import { fadeAnimation, dialogAnimation } from '../../animations/modal.animations'; export type ModalSize = 'sm' | 'md' | 'lg' | 'xl'; @@ -134,9 +134,9 @@ export class ModalComponent implements OnDestroy { .pipe( takeUntil(this.destroy$), debounceTime(150), - filter((key: KeyboardEvent) => key && key.code === 'Escape'), + filter((key: KeyboardEvent) => key && key.key === 'Escape'), ) - .subscribe(_ => { + .subscribe(() => { this.close(); }); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/modal.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/modal.component.spec.ts new file mode 100644 index 0000000000..e91a7db48c --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/modal.component.spec.ts @@ -0,0 +1,126 @@ +import { LocalizationPipe } from '@abp/ng.core'; +import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; +import { Store } from '@ngxs/store'; +import { MessageService } from 'primeng/components/common/messageservice'; +import { ToastModule } from 'primeng/toast'; +import { ConfirmationComponent, ModalComponent, ButtonComponent } from '../components'; + +describe('ModalComponent', () => { + let spectator: SpectatorHost; + let appearFn; + let disappearFn; + const createHost = createHostFactory({ + component: ModalComponent, + imports: [ToastModule], + declarations: [ConfirmationComponent, LocalizationPipe, ButtonComponent], + providers: [MessageService], + mocks: [Store], + }); + + beforeEach(() => { + appearFn = jest.fn(() => null); + disappearFn = jest.fn(() => null); + + spectator = createHost( + ` + +
+
+ + +
+ +
+
+ + + + + Submit + +
+ `, + { + hostProps: { + visible: true, + busy: false, + ngDirty: true, + appearFn, + disappearFn, + }, + }, + ); + }); + + it('should be created', () => { + expect(spectator.query('div.modal')).toBeTruthy(); + expect(spectator.query('div.modal-backdrop')).toBeTruthy(); + expect(spectator.query('div#abp-modal-dialog')).toBeTruthy(); + }); + + it('should works right the inputs', () => { + expect(spectator.query('div.test')).toBeTruthy(); + expect(spectator.query('div.modal-sm')).toBeTruthy(); + expect(spectator.query('div.modal-dialog-centered')).toBeTruthy(); + }); + + it('should emit the appear output', () => { + expect(appearFn).toHaveBeenCalled(); + }); + + it('should emit the disappear output', () => { + spectator.hostComponent.visible = false; + spectator.detectChanges(); + expect(disappearFn).toHaveBeenCalled(); + }); + + it('should open the confirmation popup and works correct', () => { + spectator.click('#abp-modal-close-button'); + expect(disappearFn).not.toHaveBeenCalled(); + + expect(spectator.query('p-toast')).toBeTruthy(); + spectator.click('button#cancel'); + expect(spectator.query('div.modal')).toBeTruthy(); + + spectator.click('#abp-modal-close-button'); + spectator.click('button#confirm'); + expect(spectator.query('div.modal')).toBeFalsy(); + expect(disappearFn).toHaveBeenCalled(); + }); + + it('should close with the abpClose', done => { + spectator.hostComponent.ngDirty = false; + spectator.detectChanges(); + setTimeout(() => { + spectator.click('#abp-close'); + expect(disappearFn).toHaveBeenCalled(); + done(); + }, 10); + }); + + it('should close with esc key', done => { + spectator.hostComponent.ngDirty = false; + spectator.detectChanges(); + setTimeout(() => { + spectator.dispatchKeyboardEvent(document.body, 'keyup', 'Escape'); + }, 0); + setTimeout(() => { + expect(spectator.component.visible).toBe(false); + done(); + }, 200); + }); + + it('should not close when busy is true', done => { + setTimeout(() => { + spectator.hostComponent.busy = true; + spectator.hostComponent.ngDirty = false; + spectator.detectChanges(); + spectator.click('#abp-modal-close-button'); + expect(disappearFn).not.toHaveBeenCalled(); + expect(spectator.component.abpSubmit.loading).toBe(true); + done(); + }, 0); + }); +});