]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
514f458483ea7e28d6b8ac424cd64c34aed324c8
[ceph.git] /
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
3 import { RouterTestingModule } from '@angular/router/testing';
4
5 import { ToastModule } from 'ng2-toastr';
6 import { BsModalRef, BsModalService } from 'ngx-bootstrap';
7 import { Subject, throwError as observableThrowError } from 'rxjs';
8
9 import { configureTestBed } from '../../../../testing/unit-test-helper';
10 import { ApiModule } from '../../../shared/api/api.module';
11 import { RbdService } from '../../../shared/api/rbd.service';
12 import { ComponentsModule } from '../../../shared/components/components.module';
13 import { DataTableModule } from '../../../shared/datatable/datatable.module';
14 import { ExecutingTask } from '../../../shared/models/executing-task';
15 import { Permissions } from '../../../shared/models/permissions';
16 import { PipesModule } from '../../../shared/pipes/pipes.module';
17 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
18 import { NotificationService } from '../../../shared/services/notification.service';
19 import { ServicesModule } from '../../../shared/services/services.module';
20 import { SummaryService } from '../../../shared/services/summary.service';
21 import { TaskListService } from '../../../shared/services/task-list.service';
22 import { RbdSnapshotListComponent } from './rbd-snapshot-list.component';
23 import { RbdSnapshotModel } from './rbd-snapshot.model';
24
25 describe('RbdSnapshotListComponent', () => {
26   let component: RbdSnapshotListComponent;
27   let fixture: ComponentFixture<RbdSnapshotListComponent>;
28   let summaryService: SummaryService;
29
30   const fakeAuthStorageService = {
31     isLoggedIn: () => {
32       return true;
33     },
34     getPermissions: () => {
35       return new Permissions({ 'rbd-image': ['read', 'update', 'create', 'delete'] });
36     }
37   };
38
39   configureTestBed({
40     declarations: [RbdSnapshotListComponent],
41     imports: [
42       DataTableModule,
43       ComponentsModule,
44       ToastModule.forRoot(),
45       ServicesModule,
46       ApiModule,
47       HttpClientTestingModule,
48       RouterTestingModule,
49       PipesModule
50     ],
51     providers: [
52       { provide: AuthStorageService, useValue: fakeAuthStorageService },
53       SummaryService,
54       TaskListService
55     ]
56   });
57
58   beforeEach(() => {
59     fixture = TestBed.createComponent(RbdSnapshotListComponent);
60     component = fixture.componentInstance;
61     summaryService = TestBed.get(SummaryService);
62     fixture.detectChanges();
63   });
64
65   it('should create', () => {
66     expect(component).toBeTruthy();
67   });
68
69   describe('api delete request', () => {
70     let called;
71     let rbdService: RbdService;
72     let notificationService: NotificationService;
73     let authStorageService: AuthStorageService;
74
75     beforeEach(() => {
76       called = false;
77       rbdService = new RbdService(null);
78       notificationService = new NotificationService(null, null);
79       authStorageService = new AuthStorageService();
80       authStorageService.set('user', { 'rbd-image': ['create', 'read', 'update', 'delete'] });
81       component = new RbdSnapshotListComponent(
82         authStorageService,
83         null,
84         null,
85         null,
86         rbdService,
87         null,
88         notificationService,
89         null,
90         null
91       );
92       spyOn(rbdService, 'deleteSnapshot').and.returnValue(observableThrowError({ status: 500 }));
93       spyOn(notificationService, 'notifyTask').and.stub();
94       component.modalRef = new BsModalRef();
95       component.modalRef.content = {
96         stopLoadingSpinner: () => (called = true)
97       };
98     });
99
100     it('should call stopLoadingSpinner if the request fails', <any>fakeAsync(() => {
101       expect(called).toBe(false);
102       component._asyncTask('deleteSnapshot', 'rbd/snap/delete', 'someName');
103       tick(500);
104       expect(called).toBe(true);
105     }));
106   });
107
108   describe('handling of executing tasks', () => {
109     let snapshots: RbdSnapshotModel[];
110
111     const addSnapshot = (name) => {
112       const model = new RbdSnapshotModel();
113       model.id = 1;
114       model.name = name;
115       snapshots.push(model);
116     };
117
118     const addTask = (task_name: string, snapshot_name: string) => {
119       const task = new ExecutingTask();
120       task.name = task_name;
121       task.metadata = {
122         pool_name: 'rbd',
123         image_name: 'foo',
124         snapshot_name: snapshot_name
125       };
126       summaryService.addRunningTask(task);
127     };
128
129     const expectImageTasks = (snapshot: RbdSnapshotModel, executing: string) => {
130       expect(snapshot.cdExecuting).toEqual(executing);
131     };
132
133     const refresh = (data) => {
134       summaryService['summaryDataSource'].next(data);
135     };
136
137     beforeEach(() => {
138       snapshots = [];
139       addSnapshot('a');
140       addSnapshot('b');
141       addSnapshot('c');
142       component.snapshots = snapshots;
143       component.poolName = 'rbd';
144       component.rbdName = 'foo';
145       refresh({ executing_tasks: [], finished_tasks: [] });
146       component.ngOnChanges();
147       fixture.detectChanges();
148     });
149
150     it('should gets all snapshots without tasks', () => {
151       expect(component.snapshots.length).toBe(3);
152       expect(component.snapshots.every((image) => !image.cdExecuting)).toBeTruthy();
153     });
154
155     it('should add a new image from a task', () => {
156       addTask('rbd/snap/create', 'd');
157       expect(component.snapshots.length).toBe(4);
158       expectImageTasks(component.snapshots[0], undefined);
159       expectImageTasks(component.snapshots[1], undefined);
160       expectImageTasks(component.snapshots[2], undefined);
161       expectImageTasks(component.snapshots[3], 'Creating');
162     });
163
164     it('should show when an existing image is being modified', () => {
165       addTask('rbd/snap/edit', 'a');
166       addTask('rbd/snap/delete', 'b');
167       addTask('rbd/snap/rollback', 'c');
168       expect(component.snapshots.length).toBe(3);
169       expectImageTasks(component.snapshots[0], 'Updating');
170       expectImageTasks(component.snapshots[1], 'Deleting');
171       expectImageTasks(component.snapshots[2], 'Rolling back');
172     });
173   });
174
175   describe('snapshot modal dialog', () => {
176     beforeEach(() => {
177       component.poolName = 'pool01';
178       component.rbdName = 'image01';
179       spyOn(TestBed.get(BsModalService), 'show').and.callFake((content) => {
180         const ref = new BsModalRef();
181         ref.content = new content();
182         ref.content.onSubmit = new Subject();
183         return ref;
184       });
185     });
186
187     it('should display old snapshot name', () => {
188       component.openSnapshotModal('rbd/snap/edit', 'oldname');
189       expect(component.modalRef.content.snapName).toBe('oldname');
190       expect(component.modalRef.content.editing).toBeTruthy();
191     });
192
193     it('should display suggested snapshot name', () => {
194       component.openSnapshotModal('rbd/snap/create');
195       expect(component.modalRef.content.snapName).toMatch(
196         RegExp(`^${component.rbdName}-\\d+T\\d+Z\$`)
197       );
198     });
199   });
200 });