]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
fa3790b18fbb2b250344b84e97c893b26e522b29
[ceph-ci.git] /
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
3 import { NoopAnimationsModule } from '@angular/platform-browser/animations';
4 import { RouterTestingModule } from '@angular/router/testing';
5
6 import { NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
7 import { ClickOutsideModule } from 'ng-click-outside';
8 import { ToastrModule } from 'ngx-toastr';
9 import { SimplebarAngularModule } from 'simplebar-angular';
10
11 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
12 import { PrometheusService } from '../../api/prometheus.service';
13 import { RbdService } from '../../api/rbd.service';
14 import { SettingsService } from '../../api/settings.service';
15 import { NotificationType } from '../../enum/notification-type.enum';
16 import { ExecutingTask } from '../../models/executing-task';
17 import { Permissions } from '../../models/permissions';
18 import { PipesModule } from '../../pipes/pipes.module';
19 import { AuthStorageService } from '../../services/auth-storage.service';
20 import { NotificationService } from '../../services/notification.service';
21 import { PrometheusAlertService } from '../../services/prometheus-alert.service';
22 import { PrometheusNotificationService } from '../../services/prometheus-notification.service';
23 import { SummaryService } from '../../services/summary.service';
24 import { NotificationsSidebarComponent } from './notifications-sidebar.component';
25
26 describe('NotificationsSidebarComponent', () => {
27   let component: NotificationsSidebarComponent;
28   let fixture: ComponentFixture<NotificationsSidebarComponent>;
29
30   configureTestBed({
31     imports: [
32       HttpClientTestingModule,
33       PipesModule,
34       NgbProgressbarModule,
35       RouterTestingModule,
36       ToastrModule.forRoot(),
37       NoopAnimationsModule,
38       SimplebarAngularModule,
39       ClickOutsideModule
40     ],
41     declarations: [NotificationsSidebarComponent],
42     providers: [
43       i18nProviders,
44       PrometheusService,
45       SettingsService,
46       SummaryService,
47       NotificationService,
48       RbdService
49     ]
50   });
51
52   beforeEach(() => {
53     fixture = TestBed.createComponent(NotificationsSidebarComponent);
54     component = fixture.componentInstance;
55   });
56
57   it('should create', () => {
58     fixture.detectChanges();
59     expect(component).toBeTruthy();
60   });
61
62   describe('prometheus alert handling', () => {
63     let prometheusAlertService: PrometheusAlertService;
64     let prometheusNotificationService: PrometheusNotificationService;
65     let prometheusReadPermission: string;
66     let configOptReadPermission: string;
67
68     const expectPrometheusServicesToBeCalledTimes = (n: number) => {
69       expect(prometheusNotificationService.refresh).toHaveBeenCalledTimes(n);
70       expect(prometheusAlertService.refresh).toHaveBeenCalledTimes(n);
71     };
72
73     beforeEach(() => {
74       prometheusReadPermission = 'read';
75       configOptReadPermission = 'read';
76       spyOn(TestBed.inject(AuthStorageService), 'getPermissions').and.callFake(
77         () =>
78           new Permissions({
79             prometheus: [prometheusReadPermission],
80             'config-opt': [configOptReadPermission]
81           })
82       );
83
84       spyOn(TestBed.inject(PrometheusService), 'ifAlertmanagerConfigured').and.callFake((fn) =>
85         fn()
86       );
87
88       prometheusAlertService = TestBed.inject(PrometheusAlertService);
89       spyOn(prometheusAlertService, 'refresh').and.stub();
90
91       prometheusNotificationService = TestBed.inject(PrometheusNotificationService);
92       spyOn(prometheusNotificationService, 'refresh').and.stub();
93     });
94
95     it('should not refresh prometheus services if not allowed', () => {
96       prometheusReadPermission = '';
97       configOptReadPermission = 'read';
98       fixture.detectChanges();
99
100       expectPrometheusServicesToBeCalledTimes(0);
101
102       prometheusReadPermission = 'read';
103       configOptReadPermission = '';
104       fixture.detectChanges();
105
106       expectPrometheusServicesToBeCalledTimes(0);
107     });
108
109     it('should first refresh prometheus notifications and alerts during init', () => {
110       fixture.detectChanges();
111
112       expect(prometheusAlertService.refresh).toHaveBeenCalledTimes(1);
113       expectPrometheusServicesToBeCalledTimes(1);
114     });
115
116     it('should refresh prometheus services every 5s', fakeAsync(() => {
117       fixture.detectChanges();
118
119       expectPrometheusServicesToBeCalledTimes(1);
120       tick(5000);
121       expectPrometheusServicesToBeCalledTimes(2);
122       tick(15000);
123       expectPrometheusServicesToBeCalledTimes(5);
124       component.ngOnDestroy();
125     }));
126   });
127
128   describe('Running Tasks', () => {
129     let summaryService: SummaryService;
130
131     beforeEach(() => {
132       fixture.detectChanges();
133       summaryService = TestBed.inject(SummaryService);
134
135       spyOn(component, '_handleTasks').and.callThrough();
136     });
137
138     it('should handle executing tasks', () => {
139       const running_tasks = new ExecutingTask('rbd/delete', {
140         image_spec: 'somePool/someImage'
141       });
142
143       summaryService['summaryDataSource'].next({ executing_tasks: [running_tasks] });
144
145       expect(component._handleTasks).toHaveBeenCalled();
146       expect(component.executingTasks.length).toBe(1);
147       expect(component.executingTasks[0].description).toBe(`Deleting RBD 'somePool/someImage'`);
148     });
149   });
150
151   describe('Notifications', () => {
152     it('should fetch latest notifications', fakeAsync(() => {
153       const notificationService: NotificationService = TestBed.inject(NotificationService);
154       fixture.detectChanges();
155
156       expect(component.notifications.length).toBe(0);
157
158       notificationService.show(NotificationType.success, 'Sample title', 'Sample message');
159       tick(6000);
160       expect(component.notifications.length).toBe(1);
161       expect(component.notifications[0].title).toBe('Sample title');
162     }));
163   });
164
165   describe('Sidebar', () => {
166     let notificationService: NotificationService;
167
168     beforeEach(() => {
169       notificationService = TestBed.inject(NotificationService);
170       fixture.detectChanges();
171     });
172
173     it('should always close if sidebarSubject value is true', fakeAsync(() => {
174       // Closed before next value
175       expect(component.isSidebarOpened).toBeFalsy();
176       notificationService.sidebarSubject.next(true);
177       tick();
178       expect(component.isSidebarOpened).toBeFalsy();
179
180       // Opened before next value
181       component.isSidebarOpened = true;
182       expect(component.isSidebarOpened).toBeTruthy();
183       notificationService.sidebarSubject.next(true);
184       tick();
185       expect(component.isSidebarOpened).toBeFalsy();
186     }));
187
188     it('should toggle sidebar visibility if sidebarSubject value is false', () => {
189       // Closed before next value
190       expect(component.isSidebarOpened).toBeFalsy();
191       notificationService.sidebarSubject.next(false);
192       expect(component.isSidebarOpened).toBeTruthy();
193
194       // Opened before next value
195       component.isSidebarOpened = true;
196       expect(component.isSidebarOpened).toBeTruthy();
197       notificationService.sidebarSubject.next(false);
198       expect(component.isSidebarOpened).toBeFalsy();
199     });
200   });
201 });