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