]>
Commit | Line | Data |
---|---|---|
f67539c2 | 1 | import { HttpClientTestingModule } from '@angular/common/http/testing'; |
11fdf7f2 TL |
2 | import { fakeAsync, TestBed, tick } from '@angular/core/testing'; |
3 | ||
f67539c2 | 4 | import _ from 'lodash'; |
494da23a | 5 | import { ToastrService } from 'ngx-toastr'; |
11fdf7f2 | 6 | |
f67539c2 | 7 | import { configureTestBed } from '~/testing/unit-test-helper'; |
9f95a23c | 8 | import { RbdService } from '../api/rbd.service'; |
11fdf7f2 TL |
9 | import { NotificationType } from '../enum/notification-type.enum'; |
10 | import { CdNotificationConfig } from '../models/cd-notification'; | |
11 | import { FinishedTask } from '../models/finished-task'; | |
12 | import { CdDatePipe } from '../pipes/cd-date.pipe'; | |
13 | import { NotificationService } from './notification.service'; | |
14 | import { TaskMessageService } from './task-message.service'; | |
15 | ||
16 | describe('NotificationService', () => { | |
17 | let service: NotificationService; | |
18 | const toastFakeService = { | |
19 | error: () => true, | |
20 | info: () => true, | |
21 | success: () => true | |
22 | }; | |
23 | ||
24 | configureTestBed({ | |
25 | providers: [ | |
11fdf7f2 TL |
26 | NotificationService, |
27 | TaskMessageService, | |
494da23a | 28 | { provide: ToastrService, useValue: toastFakeService }, |
9f95a23c | 29 | { provide: CdDatePipe, useValue: { transform: (d: any) => d } }, |
9f95a23c TL |
30 | RbdService |
31 | ], | |
32 | imports: [HttpClientTestingModule] | |
11fdf7f2 TL |
33 | }); |
34 | ||
35 | beforeEach(() => { | |
f67539c2 | 36 | service = TestBed.inject(NotificationService); |
11fdf7f2 TL |
37 | service.removeAll(); |
38 | }); | |
39 | ||
40 | it('should be created', () => { | |
41 | expect(service).toBeTruthy(); | |
42 | }); | |
43 | ||
44 | it('should read empty notification list', () => { | |
45 | localStorage.setItem('cdNotifications', '[]'); | |
46 | expect(service['dataSource'].getValue()).toEqual([]); | |
47 | }); | |
48 | ||
49 | it('should read old notifications', fakeAsync(() => { | |
50 | localStorage.setItem( | |
51 | 'cdNotifications', | |
52 | '[{"type":2,"message":"foobar","timestamp":"2018-05-24T09:41:32.726Z"}]' | |
53 | ); | |
54 | service = new NotificationService(null, null, null); | |
55 | expect(service['dataSource'].getValue().length).toBe(1); | |
56 | })); | |
57 | ||
58 | it('should cancel a notification', fakeAsync(() => { | |
59 | const timeoutId = service.show(NotificationType.error, 'Simple test'); | |
60 | service.cancel(timeoutId); | |
61 | tick(5000); | |
62 | expect(service['dataSource'].getValue().length).toBe(0); | |
63 | })); | |
64 | ||
81eedcae | 65 | describe('Saved notifications', () => { |
9f95a23c | 66 | const expectSavedNotificationToHave = (expected: object) => { |
81eedcae TL |
67 | tick(510); |
68 | expect(service['dataSource'].getValue().length).toBe(1); | |
69 | const notification = service['dataSource'].getValue()[0]; | |
70 | Object.keys(expected).forEach((key) => { | |
71 | expect(notification[key]).toBe(expected[key]); | |
72 | }); | |
73 | }; | |
11fdf7f2 | 74 | |
9f95a23c TL |
75 | const addNotifications = (quantity: number) => { |
76 | for (let index = 0; index < quantity; index++) { | |
77 | service.show(NotificationType.info, `${index}`); | |
78 | tick(510); | |
79 | } | |
80 | }; | |
81 | ||
81eedcae | 82 | beforeEach(() => { |
9f95a23c TL |
83 | spyOn(service, 'show').and.callThrough(); |
84 | service.cancel((<any>service)['justShownTimeoutId']); | |
81eedcae | 85 | }); |
11fdf7f2 | 86 | |
81eedcae TL |
87 | it('should create a success notification and save it', fakeAsync(() => { |
88 | service.show(new CdNotificationConfig(NotificationType.success, 'Simple test')); | |
89 | expectSavedNotificationToHave({ type: NotificationType.success }); | |
90 | })); | |
11fdf7f2 | 91 | |
81eedcae TL |
92 | it('should create an error notification and save it', fakeAsync(() => { |
93 | service.show(NotificationType.error, 'Simple test'); | |
94 | expectSavedNotificationToHave({ type: NotificationType.error }); | |
95 | })); | |
11fdf7f2 | 96 | |
81eedcae TL |
97 | it('should create an info notification and save it', fakeAsync(() => { |
98 | service.show(new CdNotificationConfig(NotificationType.info, 'Simple test')); | |
99 | expectSavedNotificationToHave({ | |
100 | type: NotificationType.info, | |
101 | title: 'Simple test', | |
102 | message: undefined | |
103 | }); | |
104 | })); | |
11fdf7f2 | 105 | |
81eedcae | 106 | it('should never have more then 10 notifications', fakeAsync(() => { |
9f95a23c | 107 | addNotifications(15); |
81eedcae TL |
108 | expect(service['dataSource'].getValue().length).toBe(10); |
109 | })); | |
110 | ||
9f95a23c | 111 | it('should show a success task notification, but not save it', fakeAsync(() => { |
81eedcae TL |
112 | const task = _.assign(new FinishedTask(), { |
113 | success: true | |
114 | }); | |
9f95a23c | 115 | |
81eedcae | 116 | service.notifyTask(task, true); |
9f95a23c TL |
117 | tick(1500); |
118 | ||
119 | expect(service.show).toHaveBeenCalled(); | |
120 | const notifications = service['dataSource'].getValue(); | |
121 | expect(notifications.length).toBe(0); | |
81eedcae | 122 | })); |
11fdf7f2 | 123 | |
81eedcae TL |
124 | it('should be able to stop notifyTask from notifying', fakeAsync(() => { |
125 | const task = _.assign(new FinishedTask(), { | |
126 | success: true | |
127 | }); | |
128 | const timeoutId = service.notifyTask(task, true); | |
129 | service.cancel(timeoutId); | |
130 | tick(100); | |
131 | expect(service['dataSource'].getValue().length).toBe(0); | |
132 | })); | |
133 | ||
134 | it('should show a error task notification', fakeAsync(() => { | |
135 | const task = _.assign( | |
136 | new FinishedTask('rbd/create', { | |
137 | pool_name: 'somePool', | |
138 | image_name: 'someImage' | |
139 | }), | |
140 | { | |
141 | success: false, | |
142 | exception: { | |
143 | code: 17 | |
144 | } | |
11fdf7f2 | 145 | } |
81eedcae TL |
146 | ); |
147 | service.notifyTask(task); | |
9f95a23c TL |
148 | |
149 | tick(1500); | |
150 | ||
151 | expect(service.show).toHaveBeenCalled(); | |
152 | const notifications = service['dataSource'].getValue(); | |
153 | expect(notifications.length).toBe(0); | |
81eedcae TL |
154 | })); |
155 | ||
156 | it('combines different notifications with the same title', fakeAsync(() => { | |
157 | service.show(NotificationType.error, '502 - Bad Gateway', 'Error occurred in path a'); | |
158 | tick(60); | |
159 | service.show(NotificationType.error, '502 - Bad Gateway', 'Error occurred in path b'); | |
160 | expectSavedNotificationToHave({ | |
161 | type: NotificationType.error, | |
162 | title: '502 - Bad Gateway', | |
163 | message: '<ul><li>Error occurred in path a</li><li>Error occurred in path b</li></ul>' | |
164 | }); | |
165 | })); | |
9f95a23c TL |
166 | |
167 | it('should remove a single notification', fakeAsync(() => { | |
168 | addNotifications(5); | |
169 | let messages = service['dataSource'].getValue().map((notification) => notification.title); | |
170 | expect(messages).toEqual(['4', '3', '2', '1', '0']); | |
171 | service.remove(2); | |
172 | messages = service['dataSource'].getValue().map((notification) => notification.title); | |
173 | expect(messages).toEqual(['4', '3', '1', '0']); | |
174 | })); | |
175 | ||
176 | it('should remove all notifications', fakeAsync(() => { | |
177 | addNotifications(5); | |
178 | expect(service['dataSource'].getValue().length).toBe(5); | |
179 | service.removeAll(); | |
180 | expect(service['dataSource'].getValue().length).toBe(0); | |
181 | })); | |
81eedcae | 182 | }); |
11fdf7f2 TL |
183 | |
184 | describe('notification queue', () => { | |
185 | const n1 = new CdNotificationConfig(NotificationType.success, 'Some success'); | |
186 | const n2 = new CdNotificationConfig(NotificationType.info, 'Some info'); | |
187 | ||
9f95a23c | 188 | const showArray = (arr: any[]) => arr.forEach((n) => service.show(n)); |
81eedcae | 189 | |
11fdf7f2 | 190 | beforeEach(() => { |
81eedcae | 191 | spyOn(service, 'save').and.stub(); |
11fdf7f2 TL |
192 | }); |
193 | ||
194 | it('filters out duplicated notifications on single call', fakeAsync(() => { | |
81eedcae TL |
195 | showArray([n1, n1, n2, n2]); |
196 | tick(510); | |
197 | expect(service.save).toHaveBeenCalledTimes(2); | |
11fdf7f2 TL |
198 | })); |
199 | ||
200 | it('filters out duplicated notifications presented in different calls', fakeAsync(() => { | |
81eedcae TL |
201 | showArray([n1, n2]); |
202 | showArray([n1, n2]); | |
203 | tick(1000); | |
204 | expect(service.save).toHaveBeenCalledTimes(2); | |
11fdf7f2 TL |
205 | })); |
206 | ||
207 | it('will reset the timeout on every call', fakeAsync(() => { | |
81eedcae TL |
208 | showArray([n1, n2]); |
209 | tick(490); | |
210 | showArray([n1, n2]); | |
211 | tick(450); | |
212 | expect(service.save).toHaveBeenCalledTimes(0); | |
213 | tick(60); | |
214 | expect(service.save).toHaveBeenCalledTimes(2); | |
11fdf7f2 TL |
215 | })); |
216 | ||
217 | it('wont filter out duplicated notifications if timeout was reached before', fakeAsync(() => { | |
81eedcae TL |
218 | showArray([n1, n2]); |
219 | tick(510); | |
220 | showArray([n1, n2]); | |
221 | tick(510); | |
222 | expect(service.save).toHaveBeenCalledTimes(4); | |
11fdf7f2 TL |
223 | })); |
224 | }); | |
225 | ||
226 | describe('showToasty', () => { | |
494da23a | 227 | let toastr: ToastrService; |
11fdf7f2 TL |
228 | const time = '2022-02-22T00:00:00.000Z'; |
229 | ||
230 | beforeEach(() => { | |
231 | const baseTime = new Date(time); | |
232 | spyOn(global, 'Date').and.returnValue(baseTime); | |
233 | spyOn(window, 'setTimeout').and.callFake((fn) => fn()); | |
234 | ||
f67539c2 | 235 | toastr = TestBed.inject(ToastrService); |
11fdf7f2 TL |
236 | // spyOn needs to know the methods before spying and can't read the array for clarification |
237 | ['error', 'info', 'success'].forEach((method: 'error' | 'info' | 'success') => | |
238 | spyOn(toastr, method).and.stub() | |
239 | ); | |
240 | }); | |
241 | ||
242 | it('should show with only title defined', () => { | |
243 | service.show(NotificationType.info, 'Some info'); | |
244 | expect(toastr.info).toHaveBeenCalledWith( | |
245 | `<small class="date">${time}</small>` + | |
9f95a23c | 246 | '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>', |
11fdf7f2 TL |
247 | 'Some info', |
248 | undefined | |
249 | ); | |
250 | }); | |
251 | ||
252 | it('should show with title and message defined', () => { | |
253 | service.show( | |
254 | () => | |
255 | new CdNotificationConfig(NotificationType.error, 'Some error', 'Some operation failed') | |
256 | ); | |
257 | expect(toastr.error).toHaveBeenCalledWith( | |
258 | 'Some operation failed<br>' + | |
259 | `<small class="date">${time}</small>` + | |
9f95a23c | 260 | '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>', |
11fdf7f2 TL |
261 | 'Some error', |
262 | undefined | |
263 | ); | |
264 | }); | |
265 | ||
266 | it('should show with title, message and application defined', () => { | |
267 | service.show( | |
268 | new CdNotificationConfig( | |
269 | NotificationType.success, | |
270 | 'Alert resolved', | |
271 | 'Some alert resolved', | |
272 | undefined, | |
273 | 'Prometheus' | |
274 | ) | |
275 | ); | |
276 | expect(toastr.success).toHaveBeenCalledWith( | |
277 | 'Some alert resolved<br>' + | |
278 | `<small class="date">${time}</small>` + | |
9f95a23c | 279 | '<i class="float-right custom-icon prometheus-icon" title="Prometheus"></i>', |
11fdf7f2 TL |
280 | 'Alert resolved', |
281 | undefined | |
282 | ); | |
283 | }); | |
284 | }); | |
285 | }); |