]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.spec.ts
29a3ece96d8ae6c695283f5ea3610ef9d368ede9
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / cluster / inventory / inventory-devices / inventory-devices.component.spec.ts
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, TestBed } from '@angular/core/testing';
3 import { FormsModule } from '@angular/forms';
4 import { By } from '@angular/platform-browser';
5 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
6 import { RouterTestingModule } from '@angular/router/testing';
7
8 import { ToastrModule } from 'ngx-toastr';
9
10 import { HostService } from '~/app/shared/api/host.service';
11 import { OrchestratorService } from '~/app/shared/api/orchestrator.service';
12 import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component';
13 import { CdTableAction } from '~/app/shared/models/cd-table-action';
14 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
15 import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum';
16 import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface';
17 import { Permissions } from '~/app/shared/models/permissions';
18 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
19 import { SharedModule } from '~/app/shared/shared.module';
20 import { configureTestBed } from '~/testing/unit-test-helper';
21 import { InventoryDevicesComponent } from './inventory-devices.component';
22
23 describe('InventoryDevicesComponent', () => {
24 let component: InventoryDevicesComponent;
25 let fixture: ComponentFixture<InventoryDevicesComponent>;
26 let orchService: OrchestratorService;
27 let hostService: HostService;
28
29 const fakeAuthStorageService = {
30 getPermissions: () => {
31 return new Permissions({ osd: ['read', 'update', 'create', 'delete'] });
32 }
33 };
34
35 const mockOrchStatus = (available: boolean, features?: OrchestratorFeature[]) => {
36 const orchStatus: OrchestratorStatus = { available: available, message: '', features: {} };
37 if (features) {
38 features.forEach((feature: OrchestratorFeature) => {
39 orchStatus.features[feature] = { available: true };
40 });
41 }
42 component.orchStatus = orchStatus;
43 };
44
45 configureTestBed({
46 imports: [
47 BrowserAnimationsModule,
48 FormsModule,
49 HttpClientTestingModule,
50 SharedModule,
51 RouterTestingModule,
52 ToastrModule.forRoot()
53 ],
54 providers: [
55 { provide: AuthStorageService, useValue: fakeAuthStorageService },
56 TableActionsComponent
57 ],
58 declarations: [InventoryDevicesComponent]
59 });
60
61 beforeEach(() => {
62 fixture = TestBed.createComponent(InventoryDevicesComponent);
63 component = fixture.componentInstance;
64 hostService = TestBed.inject(HostService);
65 orchService = TestBed.inject(OrchestratorService);
66 });
67
68 it('should create', () => {
69 expect(component).toBeTruthy();
70 });
71
72 it('should have columns that are sortable', () => {
73 expect(component.columns.every((column) => Boolean(column.prop))).toBeTruthy();
74 });
75
76 it('should call inventoryDataList only when showOnlyAvailableData is true', () => {
77 const hostServiceSpy = spyOn(hostService, 'inventoryDeviceList').and.callThrough();
78 component.getDevices();
79 expect(hostServiceSpy).toBeCalledTimes(0);
80 component.showAvailDeviceOnly = true;
81 component.getDevices();
82 expect(hostServiceSpy).toBeCalledTimes(1);
83 });
84
85 describe('table actions', () => {
86 const fakeDevices = require('./fixtures/inventory_list_response.json');
87
88 beforeEach(() => {
89 component.devices = fakeDevices;
90 component.selectionType = 'single';
91 fixture.detectChanges();
92 });
93
94 const verifyTableActions = async (
95 tableActions: CdTableAction[],
96 expectResult: {
97 [action: string]: { disabled: boolean; disableDesc: string };
98 }
99 ) => {
100 fixture.detectChanges();
101 await fixture.whenStable();
102 const tableActionElement = fixture.debugElement.query(By.directive(TableActionsComponent));
103 // There is actually only one action for now
104 const actions = {};
105 tableActions.forEach((action) => {
106 const actionElement = tableActionElement.query(By.css('button'));
107 actions[action.name] = {
108 disabled: actionElement.classes.disabled,
109 disableDesc: actionElement.properties.title
110 };
111 });
112 expect(actions).toEqual(expectResult);
113 };
114
115 const testTableActions = async (
116 orch: boolean,
117 features: OrchestratorFeature[],
118 tests: { selectRow?: number; expectResults: any }[]
119 ) => {
120 mockOrchStatus(orch, features);
121 fixture.detectChanges();
122 await fixture.whenStable();
123
124 for (const test of tests) {
125 if (test.selectRow) {
126 component.selection = new CdTableSelection();
127 component.selection.selected = [test.selectRow];
128 }
129 await verifyTableActions(component.tableActions, test.expectResults);
130 }
131 };
132
133 it('should have correct states when Orchestrator is enabled', async () => {
134 const tests = [
135 {
136 expectResults: {
137 Identify: { disabled: true, disableDesc: '' }
138 }
139 },
140 {
141 selectRow: fakeDevices[0],
142 expectResults: {
143 Identify: { disabled: false, disableDesc: '' }
144 }
145 }
146 ];
147
148 const features = [OrchestratorFeature.DEVICE_BLINK_LIGHT];
149 await testTableActions(true, features, tests);
150 });
151
152 it('should have correct states when Orchestrator is disabled', async () => {
153 const resultNoOrchestrator = {
154 disabled: true,
155 disableDesc: orchService.disableMessages.noOrchestrator
156 };
157 const tests = [
158 {
159 expectResults: {
160 Identify: { disabled: true, disableDesc: '' }
161 }
162 },
163 {
164 selectRow: fakeDevices[0],
165 expectResults: {
166 Identify: resultNoOrchestrator
167 }
168 }
169 ];
170 await testTableActions(false, [], tests);
171 });
172
173 it('should have correct states when Orchestrator features are missing', async () => {
174 const resultMissingFeatures = {
175 disabled: true,
176 disableDesc: orchService.disableMessages.missingFeature
177 };
178 const expectResults = [
179 {
180 expectResults: {
181 Identify: { disabled: true, disableDesc: '' }
182 }
183 },
184 {
185 selectRow: fakeDevices[0],
186 expectResults: {
187 Identify: resultMissingFeatures
188 }
189 }
190 ];
191 await testTableActions(true, [], expectResults);
192 });
193 });
194 });