1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { Component, Input } from '@angular/core';
3 import { ComponentFixture, TestBed } from '@angular/core/testing';
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';
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';
21 describe('CephfsTabsComponent', () => {
22 let component: CephfsTabsComponent;
23 let fixture: ComponentFixture<CephfsTabsComponent>;
24 let service: CephfsService;
31 clients: { status: ViewCacheStatus; data: 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'.
44 getReload().unsubscribed = true;
52 const setSelection = (selection: any) => {
53 component.selection = selection;
54 component.ngOnChanges();
57 const selectFs = (id: number, name: string) => {
70 const updateData = () => {
71 component['data'] = _.cloneDeep(data);
72 component.softRefresh();
75 @Component({ selector: 'cd-cephfs-chart', template: '' })
76 class CephfsChartStubComponent {
85 HttpClientTestingModule,
87 ToastrModule.forRoot()
91 CephfsChartStubComponent,
92 CephfsDetailComponent,
93 CephfsDirectoriesComponent,
94 CephfsClientsComponent
99 fixture = TestBed.createComponent(CephfsTabsComponent);
100 component = fixture.componentInstance;
101 component.selection = undefined;
106 mdsCounters: { a: { name: 'a', x: [], y: [] } },
109 status: ViewCacheStatus.ValueOk,
110 data: [{}, {}, {}, {}]
113 service = TestBed.inject(CephfsService);
114 spyOn(service, 'getTabs').and.callFake(() => of(data));
116 fixture.detectChanges();
118 setReload(); // Clears rxjs timer subscription
121 it('should create', () => {
122 expect(component).toBeTruthy();
125 it('should resist invalid mds info', () => {
132 expect(component.grafanaId).toBe(undefined);
135 it('should find out the grafana id', () => {
136 selectFs(2, 'otherMds');
137 expect(component.grafanaId).toBe('otherMds');
140 it('should set default values on id change before api request', () => {
141 const defaultDetails: Record<string, any> = {
148 const defaultClients: Record<string, any> = {
150 status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
152 component['subscribeInterval'] = () => undefined;
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);
161 it('should force data updates on tab change without api requests', () => {
162 const oldClients = component.clients;
163 const oldDetails = component.details;
165 expect(service.getTabs).toHaveBeenCalledTimes(0);
166 expect(component.details).not.toBe(oldDetails);
167 expect(component.clients).not.toBe(oldClients);
170 describe('handling of id change', () => {
172 setReload(); // Clears rxjs timer subscription
173 selectFs(2, 'otherMds');
174 old = getReload(); // Gets current subscription
177 it('should have called getDetails once', () => {
178 expect(component.details.pools.length).toBe(2);
179 expect(service.getTabs).toHaveBeenCalledTimes(1);
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);
191 it('should subscribe to an new interval', () => {
192 selectFs(3, 'anotherMds');
193 expect(getReload()).not.toBe(old); // Holds an new object
196 it('should unsubscribe the old interval if it exists', () => {
197 selectFs(3, 'anotherMds');
198 expect(old.unsubscribed).toBe(true);
201 it('should not unsubscribe if no interval exists', () => {
202 expect(() => component.ngOnDestroy()).not.toThrow();
205 it('should request the details of the new id', () => {
206 expect(service.getTabs).toHaveBeenCalledWith(2);
209 it('should should unsubscribe on deselect', () => {
210 setSelection(undefined);
211 expect(old.unsubscribed).toBe(true);
212 expect(getReload()).toBe(undefined); // Cleared timer subscription