]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.spec.ts
import 15.2.4
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / cephfs / cephfs-tabs / cephfs-tabs.component.spec.ts
CommitLineData
9f95a23c
TL
1import { HttpClientTestingModule } from '@angular/common/http/testing';
2import { Component, Input } from '@angular/core';
3import { ComponentFixture, TestBed } from '@angular/core/testing';
4
5import { TreeModule } from 'angular-tree-component';
6import * as _ from 'lodash';
7import { TabsModule } from 'ngx-bootstrap/tabs';
8import { ToastrModule } from 'ngx-toastr';
9import { of } from 'rxjs';
10
11import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
12import { CephfsService } from '../../../shared/api/cephfs.service';
13import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
9f95a23c
TL
14import { SharedModule } from '../../../shared/shared.module';
15import { CephfsClientsComponent } from '../cephfs-clients/cephfs-clients.component';
16import { CephfsDetailComponent } from '../cephfs-detail/cephfs-detail.component';
17import { CephfsDirectoriesComponent } from '../cephfs-directories/cephfs-directories.component';
18import { CephfsTabsComponent } from './cephfs-tabs.component';
19
20describe('CephfsTabsComponent', () => {
21 let component: CephfsTabsComponent;
22 let fixture: ComponentFixture<CephfsTabsComponent>;
23 let service: CephfsService;
24 let data: {
25 standbys: string;
26 pools: any[];
27 ranks: any[];
28 mdsCounters: object;
29 name: string;
30 clients: { status: ViewCacheStatus; data: any[] };
31 };
32
33 let old: any;
34 const getReload: any = () => component['reloadSubscriber'];
35 const setReload = (sth?: any) => (component['reloadSubscriber'] = sth);
36 const mockRunOutside = () => {
37 component['subscribeInterval'] = () => {
38 // It's mocked because the rxjs timer subscription ins't called through the use of 'tick'.
39 setReload({
40 unsubscribed: false,
41 unsubscribe: () => {
42 old = getReload();
43 getReload().unsubscribed = true;
44 setReload();
45 }
46 });
47 component.refresh();
48 };
49 };
50
e306af50
TL
51 const setSelection = (selection: any) => {
52 component.selection = selection;
9f95a23c
TL
53 component.ngOnChanges();
54 };
55
56 const selectFs = (id: number, name: string) => {
e306af50
TL
57 setSelection({
58 id,
59 mdsmap: {
60 info: {
61 something: {
62 name
9f95a23c
TL
63 }
64 }
65 }
e306af50 66 });
9f95a23c
TL
67 };
68
69 const updateData = () => {
70 component['data'] = _.cloneDeep(data);
71 component.softRefresh();
72 };
73
74 @Component({ selector: 'cd-cephfs-chart', template: '' })
75 class CephfsChartStubComponent {
76 @Input()
77 mdsCounter: any;
78 }
79
80 configureTestBed({
81 imports: [
82 SharedModule,
83 TabsModule.forRoot(),
84 HttpClientTestingModule,
85 TreeModule,
86 ToastrModule.forRoot()
87 ],
88 declarations: [
89 CephfsTabsComponent,
90 CephfsChartStubComponent,
91 CephfsDetailComponent,
92 CephfsDirectoriesComponent,
93 CephfsClientsComponent
94 ],
95 providers: [i18nProviders]
96 });
97
98 beforeEach(() => {
99 fixture = TestBed.createComponent(CephfsTabsComponent);
100 component = fixture.componentInstance;
e306af50 101 component.selection = undefined;
9f95a23c
TL
102 data = {
103 standbys: 'b',
104 pools: [{}, {}],
105 ranks: [{}, {}, {}],
106 mdsCounters: { a: { name: 'a', x: [], y: [] } },
107 name: 'someFs',
108 clients: {
109 status: ViewCacheStatus.ValueOk,
110 data: [{}, {}, {}, {}]
111 }
112 };
113 service = TestBed.get(CephfsService);
114 spyOn(service, 'getTabs').and.callFake(() => of(data));
115
116 fixture.detectChanges();
117 mockRunOutside();
118 setReload(); // Clears rxjs timer subscription
119 });
120
121 it('should create', () => {
122 expect(component).toBeTruthy();
123 });
124
125 it('should resist invalid mds info', () => {
e306af50
TL
126 setSelection({
127 id: 3,
128 mdsmap: {
129 info: {}
9f95a23c 130 }
e306af50 131 });
9f95a23c
TL
132 expect(component.grafanaId).toBe(undefined);
133 });
134
135 it('should find out the grafana id', () => {
136 selectFs(2, 'otherMds');
137 expect(component.grafanaId).toBe('otherMds');
138 });
139
140 it('should set default values on id change before api request', () => {
141 const defaultDetails: Record<string, any> = {
142 standbys: '',
143 pools: [],
144 ranks: [],
145 mdsCounters: {},
146 name: ''
147 };
148 const defaultClients: Record<string, any> = {
149 data: [],
150 status: ViewCacheStatus.ValueNone
151 };
152 component['subscribeInterval'] = () => {};
153 updateData();
154 expect(component.clients).not.toEqual(defaultClients);
155 expect(component.details).not.toEqual(defaultDetails);
156 selectFs(2, 'otherMds');
157 expect(component.clients).toEqual(defaultClients);
158 expect(component.details).toEqual(defaultDetails);
159 });
160
161 it('should force data updates on tab change without api requests', () => {
162 const oldClients = component.clients;
163 const oldDetails = component.details;
164 updateData();
165 expect(service.getTabs).toHaveBeenCalledTimes(0);
166 expect(component.details).not.toBe(oldDetails);
167 expect(component.clients).not.toBe(oldClients);
168 });
169
170 describe('handling of id change', () => {
171 beforeEach(() => {
172 setReload(); // Clears rxjs timer subscription
173 selectFs(2, 'otherMds');
174 old = getReload(); // Gets current subscription
175 });
176
177 it('should have called getDetails once', () => {
178 expect(component.details.pools.length).toBe(2);
179 expect(service.getTabs).toHaveBeenCalledTimes(1);
180 });
181
182 it('should not subscribe to an new interval for the same selection', () => {
183 expect(component.id).toBe(2);
184 expect(component.grafanaId).toBe('otherMds');
185 selectFs(2, 'otherMds');
186 expect(component.id).toBe(2);
187 expect(component.grafanaId).toBe('otherMds');
188 expect(getReload()).toBe(old);
189 });
190
191 it('should subscribe to an new interval', () => {
192 selectFs(3, 'anotherMds');
193 expect(getReload()).not.toBe(old); // Holds an new object
194 });
195
196 it('should unsubscribe the old interval if it exists', () => {
197 selectFs(3, 'anotherMds');
198 expect(old.unsubscribed).toBe(true);
199 });
200
201 it('should not unsubscribe if no interval exists', () => {
202 expect(() => component.ngOnDestroy()).not.toThrow();
203 });
204
205 it('should request the details of the new id', () => {
206 expect(service.getTabs).toHaveBeenCalledWith(2);
207 });
208
209 it('should should unsubscribe on deselect', () => {
e306af50 210 setSelection(undefined);
9f95a23c
TL
211 expect(old.unsubscribed).toBe(true);
212 expect(getReload()).toBe(undefined); // Cleared timer subscription
213 });
214 });
215});