mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +00:00
[ACS-6085] user is not prevented from renaming library to name containing only spaces (#3476)
* ACS-6085 Prevent user from renaming library to name containing only spaces * ACS-6085 Trimmed value * ACS-6085 Unit tests for titleErrorTranslationKey and update function * ACS-6085 Unit tests * ACS-6085 Removed redundant code * ACS-6085 Set type for validateEmptyName function * ACS-6085 Rename error translation key for required error * ACS-6085 Empty commit
This commit is contained in:
@@ -92,7 +92,7 @@
|
||||
/>
|
||||
<mat-hint *ngIf="libraryTitleExists">{{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }}</mat-hint>
|
||||
<mat-error>
|
||||
{{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }}
|
||||
{{ titleErrorTranslationKey | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
|
@@ -167,6 +167,21 @@ describe('LibraryMetadataFormComponent', () => {
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new UpdateLibraryAction(siteEntryModel));
|
||||
});
|
||||
|
||||
it('should update library node with trimmed title', () => {
|
||||
component.node.entry.role = Site.RoleEnum.SiteManager;
|
||||
siteEntryModel.title = ' some title ';
|
||||
component.node.entry.title = siteEntryModel.title;
|
||||
component.ngOnInit();
|
||||
|
||||
component.update();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
new UpdateLibraryAction({
|
||||
...siteEntryModel,
|
||||
title: siteEntryModel.title.trim()
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should call markAsPristine on form when updating valid form and has permission to update', () => {
|
||||
component.node.entry.role = Site.RoleEnum.SiteManager;
|
||||
spyOn(component.form, 'markAsPristine');
|
||||
@@ -264,6 +279,23 @@ describe('LibraryMetadataFormComponent', () => {
|
||||
expect(component.libraryTitleExists).toBe(true);
|
||||
}));
|
||||
|
||||
it('should call findSites on queriesApi with trimmed title', fakeAsync(() => {
|
||||
const title = ' test ';
|
||||
spyOn(component.queriesApi, 'findSites').and.returnValue(
|
||||
Promise.resolve({
|
||||
list: { entries: [{ entry: { title } }] }
|
||||
} as SitePaging)
|
||||
);
|
||||
component.ngOnInit();
|
||||
|
||||
component.form.controls.title.setValue(title);
|
||||
tick(300);
|
||||
expect(component.queriesApi.findSites).toHaveBeenCalledWith(title.trim(), {
|
||||
maxItems: 1,
|
||||
fields: ['title']
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not warn if library name input is the same with library node data', fakeAsync(() => {
|
||||
spyOn(component['queriesApi'], 'findSites').and.returnValue(
|
||||
Promise.resolve({
|
||||
@@ -293,4 +325,25 @@ describe('LibraryMetadataFormComponent', () => {
|
||||
tick(500);
|
||||
expect(component.libraryTitleExists).toBe(false);
|
||||
}));
|
||||
|
||||
it('should set proper titleErrorTranslationKey when there is error for empty title', () => {
|
||||
component.ngOnInit();
|
||||
|
||||
component.form.controls.title.setValue(' ');
|
||||
expect(component.titleErrorTranslationKey).toBe('LIBRARY.ERRORS.ONLY_SPACES');
|
||||
});
|
||||
|
||||
it('should set proper titleErrorTranslationKey when there is error for too long title', () => {
|
||||
component.ngOnInit();
|
||||
|
||||
component.form.controls.title.setValue('t'.repeat(257));
|
||||
expect(component.titleErrorTranslationKey).toBe('LIBRARY.ERRORS.TITLE_TOO_LONG_OR_MISSING');
|
||||
});
|
||||
|
||||
it('should set proper titleErrorTranslationKey when there is error for missing title', () => {
|
||||
component.ngOnInit();
|
||||
|
||||
component.form.controls.title.setValue('');
|
||||
expect(component.titleErrorTranslationKey).toBe('LIBRARY.ERRORS.TITLE_TOO_LONG_OR_MISSING');
|
||||
});
|
||||
});
|
||||
|
@@ -23,7 +23,17 @@
|
||||
*/
|
||||
|
||||
import { Component, Input, OnChanges, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { UntypedFormGroup, UntypedFormControl, Validators, FormGroupDirective, NgForm, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import {
|
||||
UntypedFormGroup,
|
||||
UntypedFormControl,
|
||||
Validators,
|
||||
FormGroupDirective,
|
||||
NgForm,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
FormControl,
|
||||
ValidationErrors
|
||||
} from '@angular/forms';
|
||||
import { QueriesApi, SiteEntry, SitePaging } from '@alfresco/js-api';
|
||||
import { Store } from '@ngrx/store';
|
||||
import {
|
||||
@@ -77,11 +87,17 @@ export class InstantErrorStateMatcher implements ErrorStateMatcher {
|
||||
})
|
||||
export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private _queriesApi: QueriesApi;
|
||||
private _titleErrorTranslationKey: string;
|
||||
|
||||
get queriesApi(): QueriesApi {
|
||||
this._queriesApi = this._queriesApi ?? new QueriesApi(this.alfrescoApiService.getInstance());
|
||||
return this._queriesApi;
|
||||
}
|
||||
|
||||
get titleErrorTranslationKey(): string {
|
||||
return this._titleErrorTranslationKey;
|
||||
}
|
||||
|
||||
@Input()
|
||||
node: SiteEntry;
|
||||
|
||||
@@ -96,7 +112,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
|
||||
|
||||
form: UntypedFormGroup = new UntypedFormGroup({
|
||||
id: new UntypedFormControl({ value: '', disabled: true }),
|
||||
title: new UntypedFormControl({ value: '' }, [Validators.required, Validators.maxLength(256)]),
|
||||
title: new UntypedFormControl({ value: '' }, [Validators.required, Validators.maxLength(256), this.validateEmptyName]),
|
||||
description: new UntypedFormControl({ value: '' }, [Validators.maxLength(512)]),
|
||||
visibility: new UntypedFormControl(this.libraryType[0].value)
|
||||
});
|
||||
@@ -124,7 +140,14 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
|
||||
|
||||
ngOnInit() {
|
||||
this.updateForm(this.node);
|
||||
|
||||
this.form.controls.title.statusChanges
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(
|
||||
() =>
|
||||
(this._titleErrorTranslationKey = this.form.controls.title.errors?.empty
|
||||
? 'LIBRARY.ERRORS.ONLY_SPACES'
|
||||
: 'LIBRARY.ERRORS.TITLE_TOO_LONG_OR_MISSING')
|
||||
);
|
||||
this.form.controls['title'].valueChanges
|
||||
.pipe(
|
||||
debounceTime(300),
|
||||
@@ -164,7 +187,12 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
|
||||
update() {
|
||||
if (this.canUpdateLibrary && this.form.valid) {
|
||||
this.form.markAsPristine();
|
||||
this.store.dispatch(new UpdateLibraryAction(this.form.value));
|
||||
this.store.dispatch(
|
||||
new UpdateLibraryAction({
|
||||
...this.form.value,
|
||||
title: this.form.value.title.trim()
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +210,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
|
||||
private findLibraryByTitle(libraryTitle: string): Observable<SitePaging | { list: { entries: any[] } }> {
|
||||
return from(
|
||||
this.queriesApi
|
||||
.findSites(libraryTitle, {
|
||||
.findSites(libraryTitle.trim(), {
|
||||
maxItems: 1,
|
||||
fields: ['title']
|
||||
})
|
||||
@@ -199,4 +227,8 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
|
||||
)
|
||||
.subscribe(handle);
|
||||
}
|
||||
|
||||
private validateEmptyName(control: FormControl<string>): ValidationErrors {
|
||||
return control.value.length && !control.value.trim() ? { empty: true } : null;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user