]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts
import 15.2.5
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / core / auth / user-form / user-form.component.spec.ts
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';
7
8 import { ButtonsModule } from 'ngx-bootstrap/buttons';
9 import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
10 import { BsModalService } from 'ngx-bootstrap/modal';
11 import { ToastrModule } from 'ngx-toastr';
12 import { of } from 'rxjs';
13
14 import { configureTestBed, FormHelper, i18nProviders } from '../../../../testing/unit-test-helper';
15 import { RoleService } from '../../../shared/api/role.service';
16 import { SettingsService } from '../../../shared/api/settings.service';
17 import { UserService } from '../../../shared/api/user.service';
18 import { ComponentsModule } from '../../../shared/components/components.module';
19 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
20 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
21 import { NotificationService } from '../../../shared/services/notification.service';
22 import { SharedModule } from '../../../shared/shared.module';
23 import { PasswordPolicyService } from './../../../shared/services/password-policy.service';
24 import { UserFormComponent } from './user-form.component';
25 import { UserFormModel } from './user-form.model';
26
27 describe('UserFormComponent', () => {
28 let component: UserFormComponent;
29 let form: CdFormGroup;
30 let fixture: ComponentFixture<UserFormComponent>;
31 let httpTesting: HttpTestingController;
32 let userService: UserService;
33 let modalService: BsModalService;
34 let router: Router;
35 let formHelper: FormHelper;
36
37 const setUrl = (url: string) => Object.defineProperty(router, 'url', { value: url });
38
39 @Component({ selector: 'cd-fake', template: '' })
40 class FakeComponent {}
41
42 const routes: Routes = [
43 { path: 'login', component: FakeComponent },
44 { path: 'users', component: FakeComponent }
45 ];
46
47 configureTestBed({
48 imports: [
49 RouterTestingModule.withRoutes(routes),
50 HttpClientTestingModule,
51 ReactiveFormsModule,
52 ComponentsModule,
53 ToastrModule.forRoot(),
54 SharedModule,
55 ButtonsModule.forRoot(),
56 BsDatepickerModule.forRoot()
57 ],
58 declarations: [UserFormComponent, FakeComponent],
59 providers: i18nProviders
60 });
61
62 beforeEach(() => {
63 spyOn(TestBed.get(PasswordPolicyService), 'getHelpText').and.callFake(() => of(''));
64 fixture = TestBed.createComponent(UserFormComponent);
65 component = fixture.componentInstance;
66 form = component.userForm;
67 httpTesting = TestBed.get(HttpTestingController);
68 userService = TestBed.get(UserService);
69 modalService = TestBed.get(BsModalService);
70 router = TestBed.get(Router);
71 spyOn(router, 'navigate');
72 fixture.detectChanges();
73 const notify = TestBed.get(NotificationService);
74 spyOn(notify, 'show');
75 formHelper = new FormHelper(form);
76 });
77
78 it('should create', () => {
79 expect(component).toBeTruthy();
80 expect(form).toBeTruthy();
81 });
82
83 describe('create mode', () => {
84 beforeEach(() => {
85 setUrl('/user-management/users/add');
86 component.ngOnInit();
87 });
88
89 it('should not disable fields', () => {
90 [
91 'username',
92 'name',
93 'password',
94 'confirmpassword',
95 'email',
96 'roles',
97 'pwdExpirationDate'
98 ].forEach((key) => expect(form.get(key).disabled).toBeFalsy());
99 });
100
101 it('should validate username required', () => {
102 formHelper.expectErrorChange('username', '', 'required');
103 formHelper.expectValidChange('username', 'user1');
104 });
105
106 it('should validate password match', () => {
107 formHelper.setValue('password', 'aaa');
108 formHelper.expectErrorChange('confirmpassword', 'bbb', 'match');
109 formHelper.expectValidChange('confirmpassword', 'aaa');
110 });
111
112 it('should validate email', () => {
113 formHelper.expectErrorChange('email', 'aaa', 'email');
114 });
115
116 it('should set mode', () => {
117 expect(component.mode).toBeUndefined();
118 });
119
120 it('should submit', () => {
121 const user: UserFormModel = {
122 username: 'user0',
123 password: 'pass0',
124 name: 'User 0',
125 email: 'user0@email.com',
126 roles: ['administrator'],
127 enabled: true,
128 pwdExpirationDate: undefined,
129 pwdUpdateRequired: true
130 };
131 formHelper.setMultipleValues(user);
132 formHelper.setValue('confirmpassword', user.password);
133 component.submit();
134 const userReq = httpTesting.expectOne('api/user');
135 expect(userReq.request.method).toBe('POST');
136 expect(userReq.request.body).toEqual(user);
137 userReq.flush({});
138 expect(router.navigate).toHaveBeenCalledWith(['/user-management/users']);
139 });
140 });
141
142 describe('edit mode', () => {
143 const user: UserFormModel = {
144 username: 'user1',
145 password: undefined,
146 name: 'User 1',
147 email: 'user1@email.com',
148 roles: ['administrator'],
149 enabled: true,
150 pwdExpirationDate: undefined,
151 pwdUpdateRequired: true
152 };
153 const roles = [
154 {
155 name: 'administrator',
156 description: 'Administrator',
157 scopes_permissions: {
158 user: ['create', 'delete', 'read', 'update']
159 }
160 },
161 {
162 name: 'read-only',
163 description: 'Read-Only',
164 scopes_permissions: {
165 user: ['read']
166 }
167 },
168 {
169 name: 'user-manager',
170 description: 'User Manager',
171 scopes_permissions: {
172 user: ['create', 'delete', 'read', 'update']
173 }
174 }
175 ];
176
177 beforeEach(() => {
178 spyOn(userService, 'get').and.callFake(() => of(user));
179 spyOn(TestBed.get(RoleService), 'list').and.callFake(() => of(roles));
180 setUrl('/user-management/users/edit/user1');
181 spyOn(TestBed.get(SettingsService), 'getStandardSettings').and.callFake(() =>
182 of({
183 user_pwd_expiration_warning_1: 10,
184 user_pwd_expiration_warning_2: 5,
185 user_pwd_expiration_span: 90
186 })
187 );
188 component.ngOnInit();
189 const req = httpTesting.expectOne('api/role');
190 expect(req.request.method).toBe('GET');
191 req.flush(roles);
192 httpTesting.expectOne('ui-api/standard_settings');
193 });
194
195 afterEach(() => {
196 httpTesting.verify();
197 });
198
199 it('should disable fields if editing', () => {
200 expect(form.get('username').disabled).toBeTruthy();
201 ['name', 'password', 'confirmpassword', 'email', 'roles'].forEach((key) =>
202 expect(form.get(key).disabled).toBeFalsy()
203 );
204 });
205
206 it('should set control values', () => {
207 ['username', 'name', 'email', 'roles'].forEach((key) =>
208 expect(form.getValue(key)).toBe(user[key])
209 );
210 ['password', 'confirmpassword'].forEach((key) => expect(form.getValue(key)).toBeFalsy());
211 });
212
213 it('should set mode', () => {
214 expect(component.mode).toBe('editing');
215 });
216
217 it('should alert if user is removing needed role permission', () => {
218 spyOn(TestBed.get(AuthStorageService), 'getUsername').and.callFake(() => user.username);
219 let modalBodyTpl = null;
220 spyOn(modalService, 'show').and.callFake((_content, config) => {
221 modalBodyTpl = config.initialState.bodyTpl;
222 });
223 formHelper.setValue('roles', ['read-only']);
224 component.submit();
225 expect(modalBodyTpl).toEqual(component.removeSelfUserReadUpdatePermissionTpl);
226 });
227
228 it('should logout if current user roles have been changed', () => {
229 spyOn(TestBed.get(AuthStorageService), 'getUsername').and.callFake(() => user.username);
230 formHelper.setValue('roles', ['user-manager']);
231 component.submit();
232 const userReq = httpTesting.expectOne(`api/user/${user.username}`);
233 expect(userReq.request.method).toBe('PUT');
234 userReq.flush({});
235 const authReq = httpTesting.expectOne('api/auth/logout');
236 expect(authReq.request.method).toBe('POST');
237 });
238
239 it('should submit', () => {
240 spyOn(TestBed.get(AuthStorageService), 'getUsername').and.callFake(() => user.username);
241 component.submit();
242 const userReq = httpTesting.expectOne(`api/user/${user.username}`);
243 expect(userReq.request.method).toBe('PUT');
244 expect(userReq.request.body).toEqual({
245 username: 'user1',
246 password: '',
247 pwdUpdateRequired: true,
248 name: 'User 1',
249 email: 'user1@email.com',
250 roles: ['administrator'],
251 enabled: true
252 });
253 userReq.flush({});
254 expect(router.navigate).toHaveBeenCalledWith(['/user-management/users']);
255 });
256 });
257 });