]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | import { HttpClientTestingModule } from '@angular/common/http/testing'; |
2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
3 | import { By } from '@angular/platform-browser'; | |
4 | import { RouterTestingModule } from '@angular/router/testing'; | |
5 | ||
11fdf7f2 TL |
6 | import { TreeModule } from 'ng2-tree'; |
7 | import { TabsModule } from 'ngx-bootstrap/tabs'; | |
494da23a | 8 | import { ToastrModule } from 'ngx-toastr'; |
11fdf7f2 TL |
9 | import { BehaviorSubject, of } from 'rxjs'; |
10 | ||
11 | import { | |
12 | configureTestBed, | |
eafe8130 | 13 | expectItemTasks, |
11fdf7f2 TL |
14 | i18nProviders, |
15 | PermissionHelper | |
16 | } from '../../../../testing/unit-test-helper'; | |
17 | import { IscsiService } from '../../../shared/api/iscsi.service'; | |
18 | import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component'; | |
19 | import { ExecutingTask } from '../../../shared/models/executing-task'; | |
20 | import { SummaryService } from '../../../shared/services/summary.service'; | |
21 | import { TaskListService } from '../../../shared/services/task-list.service'; | |
22 | import { SharedModule } from '../../../shared/shared.module'; | |
23 | import { IscsiTabsComponent } from '../iscsi-tabs/iscsi-tabs.component'; | |
24 | import { IscsiTargetDetailsComponent } from '../iscsi-target-details/iscsi-target-details.component'; | |
25 | import { IscsiTargetListComponent } from './iscsi-target-list.component'; | |
26 | ||
27 | describe('IscsiTargetListComponent', () => { | |
28 | let component: IscsiTargetListComponent; | |
29 | let fixture: ComponentFixture<IscsiTargetListComponent>; | |
30 | let summaryService: SummaryService; | |
31 | let iscsiService: IscsiService; | |
32 | ||
33 | const refresh = (data) => { | |
34 | summaryService['summaryDataSource'].next(data); | |
35 | }; | |
36 | ||
37 | configureTestBed({ | |
38 | imports: [ | |
39 | HttpClientTestingModule, | |
40 | RouterTestingModule, | |
41 | SharedModule, | |
42 | TabsModule.forRoot(), | |
43 | TreeModule, | |
494da23a | 44 | ToastrModule.forRoot() |
11fdf7f2 TL |
45 | ], |
46 | declarations: [IscsiTargetListComponent, IscsiTabsComponent, IscsiTargetDetailsComponent], | |
47 | providers: [TaskListService, i18nProviders] | |
48 | }); | |
49 | ||
50 | beforeEach(() => { | |
51 | fixture = TestBed.createComponent(IscsiTargetListComponent); | |
52 | component = fixture.componentInstance; | |
53 | summaryService = TestBed.get(SummaryService); | |
54 | iscsiService = TestBed.get(IscsiService); | |
55 | ||
56 | // this is needed because summaryService isn't being reset after each test. | |
57 | summaryService['summaryDataSource'] = new BehaviorSubject(null); | |
58 | summaryService['summaryData$'] = summaryService['summaryDataSource'].asObservable(); | |
59 | ||
60 | spyOn(iscsiService, 'status').and.returnValue(of({ available: true })); | |
eafe8130 | 61 | spyOn(iscsiService, 'version').and.returnValue(of({ ceph_iscsi_config_version: 11 })); |
11fdf7f2 TL |
62 | }); |
63 | ||
64 | it('should create', () => { | |
65 | expect(component).toBeTruthy(); | |
66 | }); | |
67 | ||
68 | describe('after ngOnInit', () => { | |
69 | beforeEach(() => { | |
70 | spyOn(iscsiService, 'listTargets').and.callThrough(); | |
71 | fixture.detectChanges(); | |
72 | }); | |
73 | ||
74 | it('should load targets on init', () => { | |
75 | refresh({}); | |
76 | expect(iscsiService.status).toHaveBeenCalled(); | |
77 | expect(iscsiService.listTargets).toHaveBeenCalled(); | |
78 | }); | |
79 | ||
80 | it('should not load targets on init because no data', () => { | |
81 | refresh(undefined); | |
82 | expect(iscsiService.listTargets).not.toHaveBeenCalled(); | |
83 | }); | |
84 | ||
85 | it('should call error function on init when summary service fails', () => { | |
86 | spyOn(component.table, 'reset'); | |
87 | summaryService['summaryDataSource'].error(undefined); | |
88 | expect(component.table.reset).toHaveBeenCalled(); | |
89 | }); | |
90 | }); | |
91 | ||
92 | describe('handling of executing tasks', () => { | |
93 | let targets: any[]; | |
94 | ||
95 | const addTarget = (name) => { | |
96 | const model: any = { | |
97 | target_iqn: name, | |
98 | portals: [{ host: 'node1', ip: '192.168.100.201' }], | |
99 | disks: [{ pool: 'rbd', image: 'disk_1', controls: {} }], | |
100 | clients: [ | |
101 | { | |
102 | client_iqn: 'iqn.1994-05.com.redhat:rh7-client', | |
103 | luns: [{ pool: 'rbd', image: 'disk_1' }], | |
104 | auth: { | |
105 | user: 'myiscsiusername', | |
106 | password: 'myiscsipassword', | |
107 | mutual_user: null, | |
108 | mutual_password: null | |
109 | } | |
110 | } | |
111 | ], | |
112 | groups: [], | |
113 | target_controls: {} | |
114 | }; | |
115 | targets.push(model); | |
116 | }; | |
117 | ||
118 | const addTask = (name: string, target_iqn: string) => { | |
119 | const task = new ExecutingTask(); | |
120 | task.name = name; | |
121 | switch (task.name) { | |
122 | case 'iscsi/target/create': | |
123 | task.metadata = { | |
124 | target_iqn: target_iqn | |
125 | }; | |
126 | break; | |
127 | case 'iscsi/target/delete': | |
128 | task.metadata = { | |
129 | target_iqn: target_iqn | |
130 | }; | |
131 | break; | |
132 | default: | |
133 | task.metadata = { | |
134 | target_iqn: target_iqn | |
135 | }; | |
136 | break; | |
137 | } | |
138 | summaryService.addRunningTask(task); | |
139 | }; | |
140 | ||
11fdf7f2 TL |
141 | beforeEach(() => { |
142 | targets = []; | |
143 | addTarget('iqn.a'); | |
144 | addTarget('iqn.b'); | |
145 | addTarget('iqn.c'); | |
146 | ||
147 | component.targets = targets; | |
148 | refresh({ executing_tasks: [], finished_tasks: [] }); | |
149 | spyOn(iscsiService, 'listTargets').and.callFake(() => of(targets)); | |
150 | fixture.detectChanges(); | |
151 | }); | |
152 | ||
153 | it('should gets all targets without tasks', () => { | |
154 | expect(component.targets.length).toBe(3); | |
155 | expect(component.targets.every((target) => !target.cdExecuting)).toBeTruthy(); | |
156 | }); | |
157 | ||
158 | it('should add a new target from a task', () => { | |
159 | addTask('iscsi/target/create', 'iqn.d'); | |
160 | expect(component.targets.length).toBe(4); | |
eafe8130 TL |
161 | expectItemTasks(component.targets[0], undefined); |
162 | expectItemTasks(component.targets[1], undefined); | |
163 | expectItemTasks(component.targets[2], undefined); | |
164 | expectItemTasks(component.targets[3], 'Creating'); | |
11fdf7f2 TL |
165 | }); |
166 | ||
167 | it('should show when an existing target is being modified', () => { | |
168 | addTask('iscsi/target/delete', 'iqn.b'); | |
169 | expect(component.targets.length).toBe(3); | |
eafe8130 | 170 | expectItemTasks(component.targets[1], 'Deleting'); |
11fdf7f2 TL |
171 | }); |
172 | }); | |
173 | ||
174 | describe('show action buttons and drop down actions depending on permissions', () => { | |
175 | let tableActions: TableActionsComponent; | |
176 | let scenario: { fn; empty; single }; | |
177 | let permissionHelper: PermissionHelper; | |
178 | ||
179 | const getTableActionComponent = (): TableActionsComponent => { | |
180 | fixture.detectChanges(); | |
181 | return fixture.debugElement.query(By.directive(TableActionsComponent)).componentInstance; | |
182 | }; | |
183 | ||
184 | beforeEach(() => { | |
185 | permissionHelper = new PermissionHelper(component.permissions.iscsi, () => | |
186 | getTableActionComponent() | |
187 | ); | |
188 | scenario = { | |
189 | fn: () => tableActions.getCurrentButton().name, | |
190 | single: 'Edit', | |
eafe8130 | 191 | empty: 'Create' |
11fdf7f2 TL |
192 | }; |
193 | }); | |
194 | ||
195 | describe('with all', () => { | |
196 | beforeEach(() => { | |
197 | tableActions = permissionHelper.setPermissionsAndGetActions(1, 1, 1); | |
198 | }); | |
199 | ||
eafe8130 | 200 | it(`shows 'Edit' for single selection else 'Create' as main action`, () => { |
11fdf7f2 TL |
201 | permissionHelper.testScenarios(scenario); |
202 | }); | |
203 | ||
204 | it('shows all actions', () => { | |
205 | expect(tableActions.tableActions.length).toBe(3); | |
206 | expect(tableActions.tableActions).toEqual(component.tableActions); | |
207 | }); | |
208 | }); | |
209 | ||
210 | describe('with read, create and update', () => { | |
211 | beforeEach(() => { | |
212 | tableActions = permissionHelper.setPermissionsAndGetActions(1, 1, 0); | |
213 | scenario.single = 'Edit'; | |
214 | }); | |
215 | ||
216 | it(`should always show 'Edit'`, () => { | |
217 | permissionHelper.testScenarios(scenario); | |
218 | }); | |
219 | ||
220 | it(`shows all actions except for 'Delete'`, () => { | |
221 | expect(tableActions.tableActions.length).toBe(2); | |
222 | component.tableActions.pop(); | |
223 | expect(tableActions.tableActions).toEqual(component.tableActions); | |
224 | }); | |
225 | }); | |
226 | ||
227 | describe('with read, create and delete', () => { | |
228 | beforeEach(() => { | |
229 | tableActions = permissionHelper.setPermissionsAndGetActions(1, 0, 1); | |
230 | }); | |
231 | ||
eafe8130 | 232 | it(`shows 'Delete' for single selection else 'Create' as main action`, () => { |
11fdf7f2 TL |
233 | scenario.single = 'Delete'; |
234 | permissionHelper.testScenarios(scenario); | |
235 | }); | |
236 | ||
eafe8130 | 237 | it(`shows 'Create' and 'Delete' actions`, () => { |
11fdf7f2 TL |
238 | expect(tableActions.tableActions.length).toBe(2); |
239 | expect(tableActions.tableActions).toEqual([ | |
240 | component.tableActions[0], | |
241 | component.tableActions[2] | |
242 | ]); | |
243 | }); | |
244 | }); | |
245 | ||
246 | describe('with read, edit and delete', () => { | |
247 | beforeEach(() => { | |
248 | tableActions = permissionHelper.setPermissionsAndGetActions(0, 1, 1); | |
249 | }); | |
250 | ||
251 | it(`shows always 'Edit' as main action`, () => { | |
252 | scenario.empty = 'Edit'; | |
253 | permissionHelper.testScenarios(scenario); | |
254 | }); | |
255 | ||
256 | it(`shows 'Edit' and 'Delete' actions`, () => { | |
257 | expect(tableActions.tableActions.length).toBe(2); | |
258 | expect(tableActions.tableActions).toEqual([ | |
259 | component.tableActions[1], | |
260 | component.tableActions[2] | |
261 | ]); | |
262 | }); | |
263 | }); | |
264 | ||
265 | describe('with read and create', () => { | |
266 | beforeEach(() => { | |
267 | tableActions = permissionHelper.setPermissionsAndGetActions(1, 0, 0); | |
268 | }); | |
269 | ||
eafe8130 TL |
270 | it(`shows 'Create' for single selection and 'Create' as main action`, () => { |
271 | scenario.single = 'Create'; | |
11fdf7f2 TL |
272 | permissionHelper.testScenarios(scenario); |
273 | }); | |
274 | ||
eafe8130 | 275 | it(`shows 'Create' actions`, () => { |
11fdf7f2 TL |
276 | expect(tableActions.tableActions.length).toBe(1); |
277 | expect(tableActions.tableActions).toEqual([component.tableActions[0]]); | |
278 | }); | |
279 | }); | |
280 | ||
281 | describe('with read and edit', () => { | |
282 | beforeEach(() => { | |
283 | tableActions = permissionHelper.setPermissionsAndGetActions(0, 1, 0); | |
284 | }); | |
285 | ||
286 | it(`shows no actions`, () => { | |
287 | expect(tableActions.tableActions.length).toBe(1); | |
288 | expect(tableActions.tableActions).toEqual([component.tableActions[1]]); | |
289 | }); | |
290 | }); | |
291 | ||
292 | describe('with read and delete', () => { | |
293 | beforeEach(() => { | |
294 | tableActions = permissionHelper.setPermissionsAndGetActions(0, 0, 1); | |
295 | }); | |
296 | ||
297 | it(`shows always 'Delete' as main action`, () => { | |
298 | scenario.single = 'Delete'; | |
299 | scenario.empty = 'Delete'; | |
300 | permissionHelper.testScenarios(scenario); | |
301 | }); | |
302 | ||
303 | it(`shows 'Delete' actions`, () => { | |
304 | expect(tableActions.tableActions.length).toBe(1); | |
305 | expect(tableActions.tableActions).toEqual([component.tableActions[2]]); | |
306 | }); | |
307 | }); | |
308 | ||
309 | describe('with only read', () => { | |
310 | beforeEach(() => { | |
311 | tableActions = permissionHelper.setPermissionsAndGetActions(0, 0, 0); | |
312 | }); | |
313 | ||
314 | it('shows no main action', () => { | |
315 | permissionHelper.testScenarios({ | |
316 | fn: () => tableActions.getCurrentButton(), | |
317 | single: undefined, | |
318 | empty: undefined | |
319 | }); | |
320 | }); | |
321 | ||
322 | it('shows no actions', () => { | |
323 | expect(tableActions.tableActions.length).toBe(0); | |
324 | expect(tableActions.tableActions).toEqual([]); | |
325 | }); | |
326 | }); | |
327 | }); | |
328 | }); |