]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | import { HttpClientTestingModule } from '@angular/common/http/testing'; |
2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
11fdf7f2 TL |
3 | import { RouterTestingModule } from '@angular/router/testing'; |
4 | ||
11fdf7f2 TL |
5 | import { AlertModule } from 'ngx-bootstrap/alert'; |
6 | import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; | |
7 | import { ModalModule } from 'ngx-bootstrap/modal'; | |
8 | import { TabsModule } from 'ngx-bootstrap/tabs'; | |
9 | import { TooltipModule } from 'ngx-bootstrap/tooltip'; | |
494da23a | 10 | import { ToastrModule } from 'ngx-toastr'; |
11fdf7f2 TL |
11 | import { BehaviorSubject, of } from 'rxjs'; |
12 | ||
13 | import { | |
14 | configureTestBed, | |
eafe8130 | 15 | expectItemTasks, |
11fdf7f2 TL |
16 | i18nProviders, |
17 | PermissionHelper | |
18 | } from '../../../../testing/unit-test-helper'; | |
19 | import { RbdService } from '../../../shared/api/rbd.service'; | |
11fdf7f2 TL |
20 | import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component'; |
21 | import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum'; | |
22 | import { ExecutingTask } from '../../../shared/models/executing-task'; | |
23 | import { SummaryService } from '../../../shared/services/summary.service'; | |
24 | import { TaskListService } from '../../../shared/services/task-list.service'; | |
25 | import { SharedModule } from '../../../shared/shared.module'; | |
26 | import { RbdConfigurationListComponent } from '../rbd-configuration-list/rbd-configuration-list.component'; | |
27 | import { RbdDetailsComponent } from '../rbd-details/rbd-details.component'; | |
28 | import { RbdSnapshotListComponent } from '../rbd-snapshot-list/rbd-snapshot-list.component'; | |
9f95a23c | 29 | import { RbdTabsComponent } from '../rbd-tabs/rbd-tabs.component'; |
11fdf7f2 TL |
30 | import { RbdListComponent } from './rbd-list.component'; |
31 | import { RbdModel } from './rbd-model'; | |
32 | ||
33 | describe('RbdListComponent', () => { | |
34 | let fixture: ComponentFixture<RbdListComponent>; | |
35 | let component: RbdListComponent; | |
36 | let summaryService: SummaryService; | |
37 | let rbdService: RbdService; | |
38 | ||
9f95a23c | 39 | const refresh = (data: any) => { |
11fdf7f2 TL |
40 | summaryService['summaryDataSource'].next(data); |
41 | }; | |
42 | ||
43 | configureTestBed({ | |
44 | imports: [ | |
45 | SharedModule, | |
46 | BsDropdownModule.forRoot(), | |
47 | TabsModule.forRoot(), | |
48 | ModalModule.forRoot(), | |
49 | TooltipModule.forRoot(), | |
494da23a | 50 | ToastrModule.forRoot(), |
11fdf7f2 TL |
51 | AlertModule.forRoot(), |
52 | RouterTestingModule, | |
53 | HttpClientTestingModule | |
54 | ], | |
55 | declarations: [ | |
56 | RbdListComponent, | |
57 | RbdDetailsComponent, | |
58 | RbdSnapshotListComponent, | |
9f95a23c TL |
59 | RbdConfigurationListComponent, |
60 | RbdTabsComponent | |
11fdf7f2 TL |
61 | ], |
62 | providers: [TaskListService, i18nProviders] | |
63 | }); | |
64 | ||
65 | beforeEach(() => { | |
66 | fixture = TestBed.createComponent(RbdListComponent); | |
67 | component = fixture.componentInstance; | |
68 | summaryService = TestBed.get(SummaryService); | |
69 | rbdService = TestBed.get(RbdService); | |
70 | ||
71 | // this is needed because summaryService isn't being reset after each test. | |
72 | summaryService['summaryDataSource'] = new BehaviorSubject(null); | |
73 | summaryService['summaryData$'] = summaryService['summaryDataSource'].asObservable(); | |
74 | }); | |
75 | ||
76 | it('should create', () => { | |
77 | expect(component).toBeTruthy(); | |
78 | }); | |
79 | ||
80 | describe('after ngOnInit', () => { | |
81 | beforeEach(() => { | |
82 | fixture.detectChanges(); | |
83 | spyOn(rbdService, 'list').and.callThrough(); | |
84 | }); | |
85 | ||
86 | it('should load images on init', () => { | |
87 | refresh({}); | |
88 | expect(rbdService.list).toHaveBeenCalled(); | |
89 | }); | |
90 | ||
91 | it('should not load images on init because no data', () => { | |
92 | refresh(undefined); | |
93 | expect(rbdService.list).not.toHaveBeenCalled(); | |
94 | }); | |
95 | ||
96 | it('should call error function on init when summary service fails', () => { | |
97 | spyOn(component.table, 'reset'); | |
98 | summaryService['summaryDataSource'].error(undefined); | |
99 | expect(component.table.reset).toHaveBeenCalled(); | |
100 | expect(component.viewCacheStatusList).toEqual([{ status: ViewCacheStatus.ValueException }]); | |
101 | }); | |
102 | }); | |
103 | ||
9f95a23c TL |
104 | describe('handling of deletion', () => { |
105 | beforeEach(() => { | |
106 | fixture.detectChanges(); | |
107 | }); | |
108 | ||
109 | it('should check if there are no snapshots', () => { | |
110 | component.selection.add({ | |
111 | id: '-1', | |
112 | name: 'rbd1', | |
113 | pool_name: 'rbd' | |
114 | }); | |
115 | expect(component.hasSnapshots()).toBeFalsy(); | |
116 | }); | |
117 | ||
118 | it('should check if there are snapshots', () => { | |
119 | component.selection.add({ | |
120 | id: '-1', | |
121 | name: 'rbd1', | |
122 | pool_name: 'rbd', | |
123 | snapshots: [{}, {}] | |
124 | }); | |
125 | expect(component.hasSnapshots()).toBeTruthy(); | |
126 | }); | |
127 | ||
128 | it('should get delete disable description', () => { | |
129 | component.selection.add({ | |
130 | id: '-1', | |
131 | name: 'rbd1', | |
132 | pool_name: 'rbd', | |
133 | snapshots: [ | |
134 | { | |
135 | children: [{}] | |
136 | } | |
137 | ] | |
138 | }); | |
139 | expect(component.getDeleteDisableDesc()).toBe( | |
140 | 'This RBD has cloned snapshots. Please delete related RBDs before deleting this RBD.' | |
141 | ); | |
142 | }); | |
143 | ||
144 | it('should list all protected snapshots', () => { | |
145 | component.selection.add({ | |
146 | id: '-1', | |
147 | name: 'rbd1', | |
148 | pool_name: 'rbd', | |
149 | snapshots: [ | |
150 | { | |
151 | name: 'snap1', | |
152 | is_protected: false | |
153 | }, | |
154 | { | |
155 | name: 'snap2', | |
156 | is_protected: true | |
157 | } | |
158 | ] | |
159 | }); | |
160 | ||
161 | expect(component.listProtectedSnapshots()).toEqual(['snap2']); | |
162 | }); | |
163 | }); | |
164 | ||
11fdf7f2 TL |
165 | describe('handling of executing tasks', () => { |
166 | let images: RbdModel[]; | |
167 | ||
9f95a23c | 168 | const addImage = (name: string) => { |
11fdf7f2 TL |
169 | const model = new RbdModel(); |
170 | model.id = '-1'; | |
171 | model.name = name; | |
172 | model.pool_name = 'rbd'; | |
173 | images.push(model); | |
174 | }; | |
175 | ||
176 | const addTask = (name: string, image_name: string) => { | |
177 | const task = new ExecutingTask(); | |
178 | task.name = name; | |
179 | switch (task.name) { | |
180 | case 'rbd/copy': | |
181 | task.metadata = { | |
182 | dest_pool_name: 'rbd', | |
9f95a23c | 183 | dest_namespace: null, |
11fdf7f2 TL |
184 | dest_image_name: 'd' |
185 | }; | |
186 | break; | |
187 | case 'rbd/clone': | |
188 | task.metadata = { | |
189 | child_pool_name: 'rbd', | |
9f95a23c | 190 | child_namespace: null, |
11fdf7f2 TL |
191 | child_image_name: 'd' |
192 | }; | |
193 | break; | |
9f95a23c | 194 | case 'rbd/create': |
11fdf7f2 TL |
195 | task.metadata = { |
196 | pool_name: 'rbd', | |
9f95a23c | 197 | namespace: null, |
11fdf7f2 TL |
198 | image_name: image_name |
199 | }; | |
200 | break; | |
9f95a23c TL |
201 | default: |
202 | task.metadata = { | |
203 | image_spec: `rbd/${image_name}` | |
204 | }; | |
205 | break; | |
11fdf7f2 TL |
206 | } |
207 | summaryService.addRunningTask(task); | |
208 | }; | |
209 | ||
11fdf7f2 TL |
210 | beforeEach(() => { |
211 | images = []; | |
212 | addImage('a'); | |
213 | addImage('b'); | |
214 | addImage('c'); | |
215 | component.images = images; | |
216 | refresh({ executing_tasks: [], finished_tasks: [] }); | |
217 | spyOn(rbdService, 'list').and.callFake(() => | |
9f95a23c | 218 | of([{ pool_name: 'rbd', status: 1, value: images }]) |
11fdf7f2 TL |
219 | ); |
220 | fixture.detectChanges(); | |
221 | }); | |
222 | ||
223 | it('should gets all images without tasks', () => { | |
224 | expect(component.images.length).toBe(3); | |
9f95a23c | 225 | expect(component.images.every((image: any) => !image.cdExecuting)).toBeTruthy(); |
11fdf7f2 TL |
226 | }); |
227 | ||
228 | it('should add a new image from a task', () => { | |
229 | addTask('rbd/create', 'd'); | |
230 | expect(component.images.length).toBe(4); | |
eafe8130 TL |
231 | expectItemTasks(component.images[0], undefined); |
232 | expectItemTasks(component.images[1], undefined); | |
233 | expectItemTasks(component.images[2], undefined); | |
234 | expectItemTasks(component.images[3], 'Creating'); | |
11fdf7f2 TL |
235 | }); |
236 | ||
237 | it('should show when a image is being cloned', () => { | |
238 | addTask('rbd/clone', 'd'); | |
239 | expect(component.images.length).toBe(4); | |
eafe8130 TL |
240 | expectItemTasks(component.images[0], undefined); |
241 | expectItemTasks(component.images[1], undefined); | |
242 | expectItemTasks(component.images[2], undefined); | |
243 | expectItemTasks(component.images[3], 'Cloning'); | |
11fdf7f2 TL |
244 | }); |
245 | ||
246 | it('should show when a image is being copied', () => { | |
247 | addTask('rbd/copy', 'd'); | |
248 | expect(component.images.length).toBe(4); | |
eafe8130 TL |
249 | expectItemTasks(component.images[0], undefined); |
250 | expectItemTasks(component.images[1], undefined); | |
251 | expectItemTasks(component.images[2], undefined); | |
252 | expectItemTasks(component.images[3], 'Copying'); | |
11fdf7f2 TL |
253 | }); |
254 | ||
255 | it('should show when an existing image is being modified', () => { | |
256 | addTask('rbd/edit', 'a'); | |
257 | addTask('rbd/delete', 'b'); | |
258 | addTask('rbd/flatten', 'c'); | |
259 | expect(component.images.length).toBe(3); | |
eafe8130 TL |
260 | expectItemTasks(component.images[0], 'Updating'); |
261 | expectItemTasks(component.images[1], 'Deleting'); | |
262 | expectItemTasks(component.images[2], 'Flattening'); | |
11fdf7f2 TL |
263 | }); |
264 | }); | |
265 | ||
9f95a23c TL |
266 | it('should test all TableActions combinations', () => { |
267 | const permissionHelper: PermissionHelper = new PermissionHelper(component.permission); | |
268 | const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions( | |
269 | component.tableActions | |
270 | ); | |
271 | ||
272 | expect(tableActions).toEqual({ | |
273 | 'create,update,delete': { | |
274 | actions: ['Create', 'Edit', 'Copy', 'Flatten', 'Delete', 'Move to Trash'], | |
275 | primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' } | |
276 | }, | |
277 | 'create,update': { | |
278 | actions: ['Create', 'Edit', 'Copy', 'Flatten'], | |
279 | primary: { multiple: 'Create', executing: 'Edit', single: 'Edit', no: 'Create' } | |
280 | }, | |
281 | 'create,delete': { | |
282 | actions: ['Create', 'Copy', 'Delete', 'Move to Trash'], | |
283 | primary: { multiple: 'Create', executing: 'Copy', single: 'Copy', no: 'Create' } | |
284 | }, | |
285 | create: { | |
286 | actions: ['Create', 'Copy'], | |
287 | primary: { multiple: 'Create', executing: 'Copy', single: 'Copy', no: 'Create' } | |
288 | }, | |
289 | 'update,delete': { | |
290 | actions: ['Edit', 'Flatten', 'Delete', 'Move to Trash'], | |
291 | primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' } | |
292 | }, | |
293 | update: { | |
294 | actions: ['Edit', 'Flatten'], | |
295 | primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' } | |
296 | }, | |
297 | delete: { | |
298 | actions: ['Delete', 'Move to Trash'], | |
299 | primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' } | |
300 | }, | |
301 | 'no-permissions': { | |
302 | actions: [], | |
303 | primary: { multiple: '', executing: '', single: '', no: '' } | |
304 | } | |
11fdf7f2 TL |
305 | }); |
306 | }); | |
307 | }); |