From 54fd097fab9153efb705de7c65c1dc01b2a16799 Mon Sep 17 00:00:00 2001
From: Mykyta Maliarchuk <84377976+nikita-web-ua@users.noreply.github.com>
Date: Mon, 7 Jul 2025 10:12:49 +0200
Subject: [PATCH] [ACS-9327] Add prohibited symbols validation for Categories
dialog (#10985)
* [ACS-9327] Add prohibited symbols validation for Categories dialog
* [ACS-9327] add validator for ending dot
* [ACS-9327] use endsWith
* [ACS-9327] cr fix
* [ACS-9327] add appropriate error message
---
.../categories-management.component.html | 2 +-
.../categories-management.component.spec.ts | 30 +++++++++++++++----
.../categories-management.component.ts | 23 ++++++++++++--
lib/content-services/src/lib/i18n/en.json | 4 ++-
4 files changed, 49 insertions(+), 10 deletions(-)
diff --git a/lib/content-services/src/lib/category/categories-management/categories-management.component.html b/lib/content-services/src/lib/category/categories-management/categories-management.component.html
index 9a02fb4fe8..f0c8d0a594 100644
--- a/lib/content-services/src/lib/category/categories-management/categories-management.component.html
+++ b/lib/content-services/src/lib/category/categories-management/categories-management.component.html
@@ -6,7 +6,7 @@
placeholder="{{'CATEGORIES_MANAGEMENT.CATEGORIES_SEARCH_PLACEHOLDER' | translate }}"
adf-auto-focus
/>
- {{ categoryNameErrorMessageKey | translate }}
+ {{ categoryNameErrorMessageKey | translate }}
0" [class.adf-categories-list-fixed]="!categoryNameControlVisible">
{
expect(component.categoryNameControl.hasValidator(Validators.required)).toBeFalse();
});
- it('should display validation error when searching for empty category', fakeAsync(() => {
- typeCategory(' ');
-
- expect(getFirstError()).toBe('CATEGORIES_MANAGEMENT.ERRORS.EMPTY_CATEGORY');
- }));
-
it('should clear categories and hide category control when classifiable aspect is removed', () => {
const controlVisibilityChangeSpy = spyOn(component.categoryNameControlVisibleChange, 'emit').and.callThrough();
classifiableChangedSubject.next();
@@ -523,6 +517,30 @@ describe('CategoriesManagementComponent', () => {
expect(getCreateCategoryLabel().hidden).toBeTrue();
}));
+
+ it('should display validation error when prohibited symbol entered', fakeAsync(() => {
+ typeCategory('category:name');
+ component.categoryNameControl.markAsTouched();
+ fixture.detectChanges();
+
+ expect(getFirstError()).toBe('CATEGORIES_MANAGEMENT.ERRORS.SPECIAL_CHARACTERS');
+ }));
+
+ it('should display validation error when dot placed in the end', fakeAsync(() => {
+ typeCategory('category.');
+ component.categoryNameControl.markAsTouched();
+ fixture.detectChanges();
+
+ expect(getFirstError()).toBe('CATEGORIES_MANAGEMENT.ERRORS.ENDS_WITH_DOT');
+ }));
+
+ it('should not display validation error when dot used in positions other than the end', fakeAsync(() => {
+ typeCategory('.category.name');
+ component.categoryNameControl.markAsTouched();
+ fixture.detectChanges();
+
+ expect(component.categoryNameControl.valid).toBeTrue();
+ }));
});
});
});
diff --git a/lib/content-services/src/lib/category/categories-management/categories-management.component.ts b/lib/content-services/src/lib/category/categories-management/categories-management.component.ts
index 31e7430255..bd58cb230c 100644
--- a/lib/content-services/src/lib/category/categories-management/categories-management.component.ts
+++ b/lib/content-services/src/lib/category/categories-management/categories-management.component.ts
@@ -49,6 +49,8 @@ interface CategoryNameControlErrors {
duplicatedCategory?: boolean;
emptyCategory?: boolean;
required?: boolean;
+ specialCharacters?: boolean;
+ endsWithDot?: boolean;
}
@Component({
@@ -73,14 +75,22 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
['duplicatedExistingCategory', 'ALREADY_EXISTS'],
['duplicatedCategory', 'DUPLICATED_CATEGORY'],
['emptyCategory', 'EMPTY_CATEGORY'],
- ['required', 'REQUIRED']
+ ['required', 'REQUIRED'],
+ ['specialCharacters', 'SPECIAL_CHARACTERS'],
+ ['endsWithDot', 'ENDS_WITH_DOT']
]);
private existingCategoryLoaded$ = new Subject();
private cancelExistingCategoriesLoading$ = new Subject();
private _categoryNameControl = new FormControl(
'',
- [this.validateIfNotAlreadyAdded.bind(this), this.validateEmptyCategory, Validators.required],
+ [
+ this.validateIfNotAlreadyAdded.bind(this),
+ this.validateEmptyCategory,
+ this.validateSpecialCharacters,
+ this.validateEndsWithDot,
+ Validators.required
+ ],
this.validateIfNotAlreadyCreated.bind(this)
);
private _existingCategories: Category[];
@@ -358,6 +368,15 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
return categoryNameControl.value.length && !categoryNameControl.value.trim() ? { emptyCategory: true } : null;
}
+ private validateSpecialCharacters(categoryNameControl: FormControl): CategoryNameControlErrors | null {
+ const specialSymbolsRegex = /[:"\\|<>/?*]/;
+ return categoryNameControl.value.length && specialSymbolsRegex.test(categoryNameControl.value) ? { specialCharacters: true } : null;
+ }
+
+ private validateEndsWithDot(categoryNameControl: FormControl): CategoryNameControlErrors | null {
+ return categoryNameControl.value.trim().endsWith('.') ? { endsWithDot: true } : null;
+ }
+
private setCategoryNameControlErrorMessageKey() {
this._categoryNameErrorMessageKey = this.categoryNameControl.invalid
? `CATEGORIES_MANAGEMENT.ERRORS.${this.nameErrorMessagesByErrors.get(
diff --git a/lib/content-services/src/lib/i18n/en.json b/lib/content-services/src/lib/i18n/en.json
index 292f5178ef..0e3145cf2d 100644
--- a/lib/content-services/src/lib/i18n/en.json
+++ b/lib/content-services/src/lib/i18n/en.json
@@ -183,7 +183,9 @@
"ALREADY_EXISTS": "Category already exists",
"DUPLICATED_CATEGORY": "Category is already added",
"CREATE_CATEGORIES": "Error while creating categories",
- "EXISTING_CATEGORIES": "Some categories already exist"
+ "EXISTING_CATEGORIES": "Some categories already exist",
+ "SPECIAL_CHARACTERS": "Category name cannot contain prohibited characters",
+ "ENDS_WITH_DOT": "Category name cannot end with a dot"
},
"CATEGORIES_SEARCH_PLACEHOLDER": "Search Categories"
},