1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { fakeAsync, TestBed, tick } from '@angular/core/testing';
4 import { ToastModule, ToastsManager } from 'ng2-toastr';
5 import { of } from 'rxjs';
11 } from '../../../testing/unit-test-helper';
12 import { PrometheusService } from '../api/prometheus.service';
13 import { NotificationType } from '../enum/notification-type.enum';
14 import { CdNotificationConfig } from '../models/cd-notification';
15 import { PrometheusNotification } from '../models/prometheus-alerts';
16 import { SharedModule } from '../shared.module';
17 import { NotificationService } from './notification.service';
18 import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
19 import { PrometheusNotificationService } from './prometheus-notification.service';
21 describe('PrometheusNotificationService', () => {
22 let service: PrometheusNotificationService;
23 let notificationService: NotificationService;
24 let notifications: PrometheusNotification[];
25 let prometheusService: PrometheusService;
26 let prometheus: PrometheusHelper;
27 let shown: CdNotificationConfig[];
29 const toastFakeService = {
36 imports: [ToastModule.forRoot(), SharedModule, HttpClientTestingModule],
38 PrometheusNotificationService,
39 PrometheusAlertFormatter,
41 { provide: ToastsManager, useValue: toastFakeService }
46 prometheus = new PrometheusHelper();
48 service = TestBed.get(PrometheusNotificationService);
49 service['notifications'] = [];
51 notificationService = TestBed.get(NotificationService);
53 spyOn(notificationService, 'show').and.callThrough();
54 spyOn(notificationService, 'save').and.callFake((n) => shown.push(n));
56 spyOn(window, 'setTimeout').and.callFake((fn: Function) => fn());
58 prometheusService = TestBed.get(PrometheusService);
59 spyOn(prometheusService, 'getNotifications').and.callFake(() => of(notifications));
61 notifications = [prometheus.createNotification()];
64 it('should create', () => {
65 expect(service).toBeTruthy();
68 describe('getLastNotification', () => {
69 it('returns an empty object on the first call', () => {
71 expect(prometheusService.getNotifications).toHaveBeenCalledWith(undefined);
72 expect(service['notifications'].length).toBe(1);
75 it('returns last notification on any other call', () => {
77 notifications = [prometheus.createNotification(1, 'resolved')];
79 expect(prometheusService.getNotifications).toHaveBeenCalledWith(service['notifications'][0]);
80 expect(service['notifications'].length).toBe(2);
82 notifications = [prometheus.createNotification(2)];
84 notifications = [prometheus.createNotification(3, 'resolved')];
86 expect(prometheusService.getNotifications).toHaveBeenCalledWith(service['notifications'][2]);
87 expect(service['notifications'].length).toBe(4);
91 it('notifies not on the first call', () => {
93 expect(notificationService.show).not.toHaveBeenCalled();
96 describe('looks of fired notifications', () => {
97 const asyncRefresh = () => {
102 const expectShown = (expected: {}[]) => {
104 expect(shown.length).toBe(expected.length);
105 expected.forEach((e, i) =>
106 Object.keys(e).forEach((key) => expect(shown[i][key]).toEqual(expected[i][key]))
114 it('notifies on the second call', () => {
116 expect(notificationService.show).toHaveBeenCalledTimes(1);
119 it('notify looks on single notification with single alert like', fakeAsync(() => {
122 new CdNotificationConfig(
123 NotificationType.error,
125 'alert0 is firing ' + prometheus.createLink('http://alert0'),
132 it('raises multiple pop overs for a single notification with multiple alerts', fakeAsync(() => {
134 notifications[0].alerts.push(prometheus.createNotificationAlert('alert1', 'resolved'));
137 new CdNotificationConfig(
138 NotificationType.error,
140 'alert0 is firing ' + prometheus.createLink('http://alert0'),
144 new CdNotificationConfig(
145 NotificationType.success,
147 'alert1 is resolved ' + prometheus.createLink('http://alert1'),
154 it('should raise multiple notifications if they do not look like each other', fakeAsync(() => {
155 notifications[0].alerts.push(prometheus.createNotificationAlert('alert1'));
156 notifications.push(prometheus.createNotification());
157 notifications[1].alerts.push(prometheus.createNotificationAlert('alert2'));
160 new CdNotificationConfig(
161 NotificationType.error,
163 'alert0 is firing ' + prometheus.createLink('http://alert0'),
167 new CdNotificationConfig(
168 NotificationType.error,
170 'alert1 is firing ' + prometheus.createLink('http://alert1'),
174 new CdNotificationConfig(
175 NotificationType.error,
177 'alert2 is firing ' + prometheus.createLink('http://alert2'),
184 it('only shows toasties if it got new data', () => {
186 expect(notificationService.show).toHaveBeenCalledTimes(1);
190 expect(notificationService.show).toHaveBeenCalledTimes(1);
191 notifications = [prometheus.createNotification()];
193 expect(notificationService.show).toHaveBeenCalledTimes(2);
195 expect(notificationService.show).toHaveBeenCalledTimes(3);
198 it('filters out duplicated and non user visible changes in notifications', fakeAsync(() => {
199 // Return 2 notifications with 3 duplicated alerts and 1 non visible changed alert
200 const secondAlert = prometheus.createNotificationAlert('alert0');
201 secondAlert.endsAt = new Date().toString(); // Should be ignored as it's not visible
202 notifications[0].alerts.push(secondAlert);
203 notifications.push(prometheus.createNotification());
204 notifications[1].alerts.push(prometheus.createNotificationAlert('alert0'));
205 notifications[1].notified = 'by somebody else';
209 new CdNotificationConfig(
210 NotificationType.error,
212 'alert0 is firing ' + prometheus.createLink('http://alert0'),