]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.spec.ts
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / components / notifications-sidebar / notifications-sidebar.component.spec.ts
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
3 import { RouterTestingModule } from '@angular/router/testing';
4
5 import { ClickOutsideModule } from 'ng-click-outside';
6 import { PopoverModule } from 'ngx-bootstrap/popover';
7 import { ProgressbarModule } from 'ngx-bootstrap/progressbar';
8 import { ToastrModule } from 'ngx-toastr';
9 import { SimplebarAngularModule } from 'simplebar-angular';
10
11 import { NoopAnimationsModule } from '@angular/platform-browser/animations';
12 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
13 import { PrometheusService } from '../../api/prometheus.service';
14 import { RbdService } from '../../api/rbd.service';
15 import { SettingsService } from '../../api/settings.service';
16 import { NotificationType } from '../../enum/notification-type.enum';
17 import { ExecutingTask } from '../../models/executing-task';
18 import { Permissions } from '../../models/permissions';
19 import { PipesModule } from '../../pipes/pipes.module';
20 import { AuthStorageService } from '../../services/auth-storage.service';
21 import { NotificationService } from '../../services/notification.service';
22 import { PrometheusAlertService } from '../../services/prometheus-alert.service';
23 import { PrometheusNotificationService } from '../../services/prometheus-notification.service';
24 import { SummaryService } from '../../services/summary.service';
25 import { NotificationsSidebarComponent } from './notifications-sidebar.component';
26
27 describe('NotificationsSidebarComponent', () => {
28 let component: NotificationsSidebarComponent;
29 let fixture: ComponentFixture<NotificationsSidebarComponent>;
30
31 configureTestBed({
32 imports: [
33 HttpClientTestingModule,
34 PipesModule,
35 PopoverModule.forRoot(),
36 ProgressbarModule.forRoot(),
37 RouterTestingModule,
38 ToastrModule.forRoot(),
39 NoopAnimationsModule,
40 SimplebarAngularModule,
41 ClickOutsideModule
42 ],
43 declarations: [NotificationsSidebarComponent],
44 providers: [
45 i18nProviders,
46 PrometheusService,
47 SettingsService,
48 SummaryService,
49 NotificationService,
50 RbdService
51 ]
52 });
53
54 beforeEach(() => {
55 fixture = TestBed.createComponent(NotificationsSidebarComponent);
56 component = fixture.componentInstance;
57 });
58
59 it('should create', () => {
60 fixture.detectChanges();
61 expect(component).toBeTruthy();
62 });
63
64 describe('prometheus alert handling', () => {
65 let prometheusAlertService: PrometheusAlertService;
66 let prometheusNotificationService: PrometheusNotificationService;
67 let prometheusReadPermission: string;
68 let configOptReadPermission: string;
69
70 const expectPrometheusServicesToBeCalledTimes = (n: number) => {
71 expect(prometheusNotificationService.refresh).toHaveBeenCalledTimes(n);
72 expect(prometheusAlertService.refresh).toHaveBeenCalledTimes(n);
73 };
74
75 beforeEach(() => {
76 prometheusReadPermission = 'read';
77 configOptReadPermission = 'read';
78 spyOn(TestBed.get(AuthStorageService), 'getPermissions').and.callFake(
79 () =>
80 new Permissions({
81 prometheus: [prometheusReadPermission],
82 'config-opt': [configOptReadPermission]
83 })
84 );
85
86 spyOn(TestBed.get(PrometheusService), 'ifAlertmanagerConfigured').and.callFake((fn) => fn());
87
88 prometheusAlertService = TestBed.get(PrometheusAlertService);
89 spyOn(prometheusAlertService, 'refresh').and.stub();
90
91 prometheusNotificationService = TestBed.get(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.get(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.get(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.get(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 });