1 import { DatePipe } from '@angular/common';
2 import { fakeAsync, TestBed, tick } from '@angular/core/testing';
4 import * as _ from 'lodash';
5 import { ToastsManager } from 'ng2-toastr';
7 import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
8 import { NotificationType } from '../enum/notification-type.enum';
9 import { CdNotificationConfig } from '../models/cd-notification';
10 import { FinishedTask } from '../models/finished-task';
11 import { CdDatePipe } from '../pipes/cd-date.pipe';
12 import { NotificationService } from './notification.service';
13 import { TaskMessageService } from './task-message.service';
15 describe('NotificationService', () => {
16 let service: NotificationService;
17 const toastFakeService = {
29 { provide: ToastsManager, useValue: toastFakeService },
30 { provide: CdDatePipe, useValue: { transform: (d) => d } },
36 service = TestBed.get(NotificationService);
40 it('should be created', () => {
41 expect(service).toBeTruthy();
44 it('should read empty notification list', () => {
45 localStorage.setItem('cdNotifications', '[]');
46 expect(service['dataSource'].getValue()).toEqual([]);
49 it('should read old notifications', fakeAsync(() => {
52 '[{"type":2,"message":"foobar","timestamp":"2018-05-24T09:41:32.726Z"}]'
54 service = new NotificationService(null, null, null);
55 expect(service['dataSource'].getValue().length).toBe(1);
58 it('should cancel a notification', fakeAsync(() => {
59 const timeoutId = service.show(NotificationType.error, 'Simple test');
60 service.cancel(timeoutId);
62 expect(service['dataSource'].getValue().length).toBe(0);
65 it('should create a success notification and save it', fakeAsync(() => {
66 service.show(new CdNotificationConfig(NotificationType.success, 'Simple test'));
68 expect(service['dataSource'].getValue().length).toBe(1);
69 expect(service['dataSource'].getValue()[0].type).toBe(NotificationType.success);
72 it('should create an error notification and save it', fakeAsync(() => {
73 service.show(NotificationType.error, 'Simple test');
75 expect(service['dataSource'].getValue().length).toBe(1);
76 expect(service['dataSource'].getValue()[0].type).toBe(NotificationType.error);
79 it('should create an info notification and save it', fakeAsync(() => {
80 service.show(new CdNotificationConfig(NotificationType.info, 'Simple test'));
82 expect(service['dataSource'].getValue().length).toBe(1);
83 const notification = service['dataSource'].getValue()[0];
84 expect(notification.type).toBe(NotificationType.info);
85 expect(notification.title).toBe('Simple test');
86 expect(notification.message).toBe(undefined);
89 it('should never have more then 10 notifications', fakeAsync(() => {
90 for (let index = 0; index < 15; index++) {
91 service.show(NotificationType.info, 'Simple test');
94 expect(service['dataSource'].getValue().length).toBe(10);
97 it('should show a success task notification', fakeAsync(() => {
98 const task = _.assign(new FinishedTask(), {
101 service.notifyTask(task, true);
103 expect(service['dataSource'].getValue().length).toBe(1);
104 const notification = service['dataSource'].getValue()[0];
105 expect(notification.type).toBe(NotificationType.success);
106 expect(notification.title).toBe('Executed unknown task');
107 expect(notification.message).toBe(undefined);
110 it('should be able to stop notifyTask from notifying', fakeAsync(() => {
111 const task = _.assign(new FinishedTask(), {
114 const timeoutId = service.notifyTask(task, true);
115 service.cancel(timeoutId);
117 expect(service['dataSource'].getValue().length).toBe(0);
120 it('should show a error task notification', fakeAsync(() => {
121 const task = _.assign(
122 new FinishedTask('rbd/create', {
123 pool_name: 'somePool',
124 image_name: 'someImage'
133 service.notifyTask(task);
135 expect(service['dataSource'].getValue().length).toBe(1);
136 const notification = service['dataSource'].getValue()[0];
137 expect(notification.type).toBe(NotificationType.error);
138 expect(notification.title).toBe(`Failed to create RBD 'somePool/someImage'`);
139 expect(notification.message).toBe(`Name is already used by RBD 'somePool/someImage'.`);
142 describe('notification queue', () => {
143 const n1 = new CdNotificationConfig(NotificationType.success, 'Some success');
144 const n2 = new CdNotificationConfig(NotificationType.info, 'Some info');
147 spyOn(service, 'show').and.stub();
150 it('filters out duplicated notifications on single call', fakeAsync(() => {
151 service.queueNotifications([n1, n1, n2, n2]);
153 expect(service.show).toHaveBeenCalledTimes(2);
156 it('filters out duplicated notifications presented in different calls', fakeAsync(() => {
157 service.queueNotifications([n1, n2]);
158 service.queueNotifications([n1, n2]);
160 expect(service.show).toHaveBeenCalledTimes(2);
163 it('will reset the timeout on every call', fakeAsync(() => {
164 service.queueNotifications([n1, n2]);
166 service.queueNotifications([n1, n2]);
168 expect(service.show).toHaveBeenCalledTimes(0);
170 expect(service.show).toHaveBeenCalledTimes(2);
173 it('wont filter out duplicated notifications if timeout was reached before', fakeAsync(() => {
174 service.queueNotifications([n1, n2]);
176 service.queueNotifications([n1, n2]);
178 expect(service.show).toHaveBeenCalledTimes(4);
182 describe('showToasty', () => {
183 let toastr: ToastsManager;
184 const time = '2022-02-22T00:00:00.000Z';
187 const baseTime = new Date(time);
188 spyOn(global, 'Date').and.returnValue(baseTime);
189 spyOn(window, 'setTimeout').and.callFake((fn) => fn());
191 toastr = TestBed.get(ToastsManager);
192 // spyOn needs to know the methods before spying and can't read the array for clarification
193 ['error', 'info', 'success'].forEach((method: 'error' | 'info' | 'success') =>
194 spyOn(toastr, method).and.stub()
198 it('should show with only title defined', () => {
199 service.show(NotificationType.info, 'Some info');
200 expect(toastr.info).toHaveBeenCalledWith(
201 `<small class="date">${time}</small>` +
202 '<i class="pull-right custom-icon ceph-icon" title="Ceph"></i>',
208 it('should show with title and message defined', () => {
211 new CdNotificationConfig(NotificationType.error, 'Some error', 'Some operation failed')
213 expect(toastr.error).toHaveBeenCalledWith(
214 'Some operation failed<br>' +
215 `<small class="date">${time}</small>` +
216 '<i class="pull-right custom-icon ceph-icon" title="Ceph"></i>',
222 it('should show with title, message and application defined', () => {
224 new CdNotificationConfig(
225 NotificationType.success,
227 'Some alert resolved',
232 expect(toastr.success).toHaveBeenCalledWith(
233 'Some alert resolved<br>' +
234 `<small class="date">${time}</small>` +
235 '<i class="pull-right custom-icon prometheus-icon" title="Prometheus"></i>',