1 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
2 import { Component } from '@angular/core';
3 import { ComponentFixture, TestBed } from '@angular/core/testing';
4 import { ReactiveFormsModule } from '@angular/forms';
5 import { Router, Routes } from '@angular/router';
6 import { RouterTestingModule } from '@angular/router/testing';
8 import { ToastrModule } from 'ngx-toastr';
9 import { of } from 'rxjs';
11 import { RoleService } from '~/app/shared/api/role.service';
12 import { ScopeService } from '~/app/shared/api/scope.service';
13 import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loading-panel.component';
14 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
15 import { NotificationService } from '~/app/shared/services/notification.service';
16 import { SharedModule } from '~/app/shared/shared.module';
17 import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
18 import { RoleFormComponent } from './role-form.component';
19 import { RoleFormModel } from './role-form.model';
21 describe('RoleFormComponent', () => {
22 let component: RoleFormComponent;
23 let form: CdFormGroup;
24 let fixture: ComponentFixture<RoleFormComponent>;
25 let httpTesting: HttpTestingController;
26 let roleService: RoleService;
28 const setUrl = (url: string) => Object.defineProperty(router, 'url', { value: url });
30 @Component({ selector: 'cd-fake', template: '' })
31 class FakeComponent {}
33 const routes: Routes = [{ path: 'roles', component: FakeComponent }];
38 RouterTestingModule.withRoutes(routes),
39 HttpClientTestingModule,
41 ToastrModule.forRoot(),
44 declarations: [RoleFormComponent, FakeComponent]
46 [LoadingPanelComponent]
50 fixture = TestBed.createComponent(RoleFormComponent);
51 component = fixture.componentInstance;
52 form = component.roleForm;
53 httpTesting = TestBed.inject(HttpTestingController);
54 roleService = TestBed.inject(RoleService);
55 router = TestBed.inject(Router);
56 spyOn(router, 'navigate');
57 fixture.detectChanges();
58 const notify = TestBed.inject(NotificationService);
59 spyOn(notify, 'show');
62 it('should create', () => {
63 expect(component).toBeTruthy();
64 expect(form).toBeTruthy();
67 describe('create mode', () => {
68 let formHelper: FormHelper;
71 setUrl('/user-management/roles/add');
73 formHelper = new FormHelper(form);
76 it('should not disable fields', () => {
77 ['name', 'description', 'scopes_permissions'].forEach((key) =>
78 expect(form.get(key).disabled).toBeFalsy()
82 it('should validate name required', () => {
83 formHelper.expectErrorChange('name', '', 'required');
86 it('should set mode', () => {
87 expect(component.mode).toBeUndefined();
90 it('should submit', () => {
91 const role: RoleFormModel = {
93 description: 'Role 1',
94 scopes_permissions: { osd: ['read'] }
96 formHelper.setMultipleValues(role);
98 const roleReq = httpTesting.expectOne('api/role');
99 expect(roleReq.request.method).toBe('POST');
100 expect(roleReq.request.body).toEqual(role);
102 expect(router.navigate).toHaveBeenCalledWith(['/user-management/roles']);
105 it('should check all perms for a scope', () => {
106 formHelper.setValue('scopes_permissions', { cephfs: ['read'] });
107 component.onClickCellCheckbox('grafana', 'scope');
108 const scopes_permissions = form.getValue('scopes_permissions');
109 expect(Object.keys(scopes_permissions)).toContain('grafana');
110 expect(scopes_permissions['grafana']).toEqual(['create', 'delete', 'read', 'update']);
113 it('should uncheck all perms for a scope', () => {
114 formHelper.setValue('scopes_permissions', { cephfs: ['read', 'create', 'update', 'delete'] });
115 component.onClickCellCheckbox('cephfs', 'scope');
116 const scopes_permissions = form.getValue('scopes_permissions');
117 expect(Object.keys(scopes_permissions)).not.toContain('cephfs');
120 it('should uncheck all scopes and perms', () => {
121 component.scopes = ['cephfs', 'grafana'];
122 formHelper.setValue('scopes_permissions', {
123 cephfs: ['read', 'delete'],
126 component.onClickHeaderCheckbox('scope', ({
127 target: { checked: false }
128 } as unknown) as Event);
129 const scopes_permissions = form.getValue('scopes_permissions');
130 expect(scopes_permissions).toEqual({});
133 it('should check all scopes and perms', () => {
134 component.scopes = ['cephfs', 'grafana'];
135 formHelper.setValue('scopes_permissions', {
136 cephfs: ['create', 'update'],
139 component.onClickHeaderCheckbox('scope', ({ target: { checked: true } } as unknown) as Event);
140 const scopes_permissions = form.getValue('scopes_permissions');
141 const keys = Object.keys(scopes_permissions);
142 expect(keys).toEqual(['cephfs', 'grafana']);
143 keys.forEach((key) => {
144 expect(scopes_permissions[key].sort()).toEqual(['create', 'delete', 'read', 'update']);
148 it('should check if column is checked', () => {
149 component.scopes_permissions = [
150 { scope: 'a', read: true, create: true, update: true, delete: true },
151 { scope: 'b', read: false, create: true, update: false, delete: true }
153 expect(component.isRowChecked('a')).toBeTruthy();
154 expect(component.isRowChecked('b')).toBeFalsy();
155 expect(component.isRowChecked('c')).toBeFalsy();
158 it('should check if header is checked', () => {
159 component.scopes_permissions = [
160 { scope: 'a', read: true, create: true, update: false, delete: true },
161 { scope: 'b', read: false, create: true, update: false, delete: true }
163 expect(component.isHeaderChecked('read')).toBeFalsy();
164 expect(component.isHeaderChecked('create')).toBeTruthy();
165 expect(component.isHeaderChecked('update')).toBeFalsy();
169 describe('edit mode', () => {
170 const role: RoleFormModel = {
172 description: 'Role 1',
173 scopes_permissions: { osd: ['read', 'create'] }
175 const scopes = ['osd', 'user'];
177 spyOn(roleService, 'get').and.callFake(() => of(role));
178 spyOn(TestBed.inject(ScopeService), 'list').and.callFake(() => of(scopes));
179 setUrl('/user-management/roles/edit/role1');
180 component.ngOnInit();
181 const reqScopes = httpTesting.expectOne('ui-api/scope');
182 expect(reqScopes.request.method).toBe('GET');
186 httpTesting.verify();
189 it('should disable fields if editing', () => {
190 expect(form.get('name').disabled).toBeTruthy();
191 ['description', 'scopes_permissions'].forEach((key) =>
192 expect(form.get(key).disabled).toBeFalsy()
196 it('should set control values', () => {
197 ['name', 'description', 'scopes_permissions'].forEach((key) =>
198 expect(form.getValue(key)).toBe(role[key])
202 it('should set mode', () => {
203 expect(component.mode).toBe('editing');
206 it('should submit', () => {
207 component.onClickCellCheckbox('osd', 'update');
208 component.onClickCellCheckbox('osd', 'create');
209 component.onClickCellCheckbox('user', 'read');
211 const roleReq = httpTesting.expectOne(`api/role/${role.name}`);
212 expect(roleReq.request.method).toBe('PUT');
213 expect(roleReq.request.body).toEqual({
215 description: 'Role 1',
216 scopes_permissions: { osd: ['read', 'update'], user: ['read'] }
219 expect(router.navigate).toHaveBeenCalledWith(['/user-management/roles']);