diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts
index 90f35cb339..0807bf632e 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts
@@ -1,87 +1,122 @@
import { CoreModule } from '@abp/ng.core';
-import { Component } from '@angular/core';
-import { RouterTestingModule } from '@angular/router/testing';
-import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
+import { NgModule } from '@angular/core';
+import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { NgxsModule } from '@ngxs/store';
+import { timer } from 'rxjs';
+import { ToastContainerComponent } from '../components/toast-container/toast-container.component';
+import { ToastComponent } from '../components/toast/toast.component';
import { ToasterService } from '../services/toaster.service';
-import { ThemeSharedModule } from '../theme-shared.module';
-import { OAuthService } from 'angular-oauth2-oidc';
-
-@Component({
- selector: 'abp-dummy',
- template: `
-
- `,
+
+@NgModule({
+ exports: [ToastContainerComponent],
+ entryComponents: [ToastContainerComponent],
+ declarations: [ToastContainerComponent, ToastComponent],
+ imports: [CoreModule.forTest()],
})
-class DummyComponent {
- constructor(public toaster: ToasterService) {}
-}
+export class MockModule {}
describe('ToasterService', () => {
- let spectator: Spectator;
+ let spectator: SpectatorService;
let service: ToasterService;
- const createComponent = createComponentFactory({
- component: DummyComponent,
- imports: [CoreModule, ThemeSharedModule.forRoot(), NgxsModule.forRoot(), RouterTestingModule],
- mocks: [OAuthService],
+ const createService = createServiceFactory({
+ service: ToasterService,
+ imports: [NgxsModule.forRoot(), CoreModule.forTest(), MockModule],
});
beforeEach(() => {
- spectator = createComponent();
- service = spectator.get(ToasterService);
+ spectator = createService();
+ service = spectator.service;
+ });
+
+ afterEach(() => {
+ clearElements();
});
- test.skip('should display an error toast', () => {
- service.error('test', 'title');
+ test('should display a toast', async () => {
+ service.show('MESSAGE', 'TITLE');
- spectator.detectChanges();
+ await timer(0).toPromise();
+ service['containerComponentRef'].changeDetectorRef.detectChanges();
- expect(spectator.query('div.toast')).toBeTruthy();
- expect(spectator.query('.toast-icon i')).toHaveClass('fa-times-circle');
- expect(spectator.query('div.toast-title')).toHaveText('title');
- expect(spectator.query('p.toast-message')).toHaveText('test');
+ expect(selectToasterElement('.fa-exclamation-circle')).toBeTruthy();
+ expect(selectToasterContent('.toast-title')).toBe('TITLE');
+ expect(selectToasterContent('.toast-message')).toBe('MESSAGE');
});
- test.skip('should display a warning toast', () => {
- service.warn('test', 'title');
- spectator.detectChanges();
- expect(spectator.query('.toast-icon i')).toHaveClass('fa-exclamation-triangle');
+ test.each`
+ type | selector | icon
+ ${'info'} | ${'.toast-info'} | ${'.fa-info-circle'}
+ ${'success'} | ${'.toast-success'} | ${'.fa-check-circle'}
+ ${'warn'} | ${'.toast-warning'} | ${'.fa-exclamation-triangle'}
+ ${'error'} | ${'.toast-error'} | ${'.fa-times-circle'}
+ `('should display $type toast', async ({ type, selector, icon }) => {
+ service[type]('MESSAGE', 'TITLE');
+
+ await timer(0).toPromise();
+ service['containerComponentRef'].changeDetectorRef.detectChanges();
+
+ expect(selectToasterContent('.toast-title')).toBe('TITLE');
+ expect(selectToasterContent('.toast-message')).toBe('MESSAGE');
+ expect(selectToasterElement()).toBe(document.querySelector(selector));
+ expect(selectToasterElement(icon)).toBeTruthy();
});
- test.skip('should display a success toast', () => {
- service.success('test', 'title');
- spectator.detectChanges();
- expect(spectator.query('.toast-icon i')).toHaveClass('fa-check-circle');
+ test('should display multiple toasts', async () => {
+ service.show('MESSAGE_1', 'TITLE_1');
+ service.show('MESSAGE_2', 'TITLE_2');
+
+ await timer(0).toPromise();
+ service['containerComponentRef'].changeDetectorRef.detectChanges();
+
+ const titles = document.querySelectorAll('.toast-title');
+ expect(titles.length).toBe(2);
+
+ const messages = document.querySelectorAll('.toast-message');
+ expect(messages.length).toBe(2);
});
- test.skip('should display an info toast', () => {
- service.info('test', 'title');
- spectator.detectChanges();
- expect(spectator.query('.toast-icon i')).toHaveClass('fa-info-circle');
+ test('should remove a toast when remove is called', async () => {
+ service.show('MESSAGE');
+ service.remove(0);
+
+ await timer(0).toPromise();
+ service['containerComponentRef'].changeDetectorRef.detectChanges();
+
+ expect(selectToasterElement()).toBeNull();
});
- test.skip('should display multiple toasts', () => {
- service.info('detail1', 'summary1');
- service.info('detail2', 'summary2');
-
- spectator.detectChanges();
- expect(spectator.queryAll('div.toast-title').map(node => node.textContent.trim())).toEqual([
- 'summary1',
- 'summary2',
- ]);
- expect(spectator.queryAll('p.toast-message').map(node => node.textContent.trim())).toEqual([
- 'detail1',
- 'detail2',
- ]);
+ test('should remove toasts when clear is called', async () => {
+ service.show('MESSAGE');
+ service.clear();
+
+ await timer(0).toPromise();
+ service['containerComponentRef'].changeDetectorRef.detectChanges();
+
+ expect(selectToasterElement()).toBeNull();
});
- test.skip('should remove the opened toasts', () => {
- service.info('test', 'title');
- spectator.detectChanges();
- expect(spectator.query('div.toast')).toBeTruthy();
+ test('should remove toasts based on containerKey when clear is called with key', async () => {
+ service.show('MESSAGE_1', 'TITLE_1', 'neutral', { containerKey: 'x' });
+ service.show('MESSAGE_2', 'TITLE_2', 'neutral', { containerKey: 'y' });
+ service.clear('x');
- service.clear();
- spectator.detectChanges();
- expect(spectator.query('p-div.toast')).toBeFalsy();
+ await timer(0).toPromise();
+ service['containerComponentRef'].changeDetectorRef.detectChanges();
+
+ expect(selectToasterElement('.fa-exclamation-circle')).toBeTruthy();
+ expect(selectToasterContent('.toast-title')).toBe('TITLE_2');
+ expect(selectToasterContent('.toast-message')).toBe('MESSAGE_2');
});
});
+
+function clearElements(selector = '.toast') {
+ document.querySelectorAll(selector).forEach(element => element.parentNode.removeChild(element));
+}
+
+function selectToasterContent(selector = '.toast'): string {
+ return selectToasterElement(selector).textContent.trim();
+}
+
+function selectToasterElement(selector = '.toast'): T {
+ return document.querySelector(selector);
+}