]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.spec.ts
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / cephfs / cephfs-tabs / cephfs-tabs.component.spec.ts
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { Component, Input } from '@angular/core';
3 import { ComponentFixture, TestBed } from '@angular/core/testing';
4
5 import { TreeModule } from '@circlon/angular-tree-component';
6 import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
7 import _ from 'lodash';
8 import { ToastrModule } from 'ngx-toastr';
9 import { of } from 'rxjs';
10
11 import { CephfsService } from '~/app/shared/api/cephfs.service';
12 import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
13 import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
14 import { SharedModule } from '~/app/shared/shared.module';
15 import { configureTestBed } from '~/testing/unit-test-helper';
16 import { CephfsClientsComponent } from '../cephfs-clients/cephfs-clients.component';
17 import { CephfsDetailComponent } from '../cephfs-detail/cephfs-detail.component';
18 import { CephfsDirectoriesComponent } from '../cephfs-directories/cephfs-directories.component';
19 import { CephfsTabsComponent } from './cephfs-tabs.component';
20
21 describe('CephfsTabsComponent', () => {
22 let component: CephfsTabsComponent;
23 let fixture: ComponentFixture<CephfsTabsComponent>;
24 let service: CephfsService;
25 let data: {
26 standbys: string;
27 pools: any[];
28 ranks: any[];
29 mdsCounters: object;
30 name: string;
31 clients: { status: ViewCacheStatus; data: any[] };
32 };
33
34 let old: any;
35 const getReload: any = () => component['reloadSubscriber'];
36 const setReload = (sth?: any) => (component['reloadSubscriber'] = sth);
37 const mockRunOutside = () => {
38 component['subscribeInterval'] = () => {
39 // It's mocked because the rxjs timer subscription isn't called through the use of 'tick'.
40 setReload({
41 unsubscribed: false,
42 unsubscribe: () => {
43 old = getReload();
44 getReload().unsubscribed = true;
45 setReload();
46 }
47 });
48 component.refresh();
49 };
50 };
51
52 const setSelection = (selection: any) => {
53 component.selection = selection;
54 component.ngOnChanges();
55 };
56
57 const selectFs = (id: number, name: string) => {
58 setSelection({
59 id,
60 mdsmap: {
61 info: {
62 something: {
63 name
64 }
65 }
66 }
67 });
68 };
69
70 const updateData = () => {
71 component['data'] = _.cloneDeep(data);
72 component.softRefresh();
73 };
74
75 @Component({ selector: 'cd-cephfs-chart', template: '' })
76 class CephfsChartStubComponent {
77 @Input()
78 mdsCounter: any;
79 }
80
81 configureTestBed({
82 imports: [
83 SharedModule,
84 NgbNavModule,
85 HttpClientTestingModule,
86 TreeModule,
87 ToastrModule.forRoot()
88 ],
89 declarations: [
90 CephfsTabsComponent,
91 CephfsChartStubComponent,
92 CephfsDetailComponent,
93 CephfsDirectoriesComponent,
94 CephfsClientsComponent
95 ]
96 });
97
98 beforeEach(() => {
99 fixture = TestBed.createComponent(CephfsTabsComponent);
100 component = fixture.componentInstance;
101 component.selection = undefined;
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.inject(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', () => {
126 setSelection({
127 id: 3,
128 mdsmap: {
129 info: {}
130 }
131 });
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: new TableStatusViewCache(ViewCacheStatus.ValueNone)
151 };
152 component['subscribeInterval'] = () => undefined;
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', () => {
210 setSelection(undefined);
211 expect(old.unsubscribed).toBe(true);
212 expect(getReload()).toBe(undefined); // Cleared timer subscription
213 });
214 });
215 });