mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ACS-4749] add button is enabled for comment contains only spaces (#10577)
* [ACS-4749] Disabled add button for comment when comment has only spaces * [ACS-4749] Unit tests * [ACS-4749] Removed redundant code * [ACS-4749] Fixed sonar issue * [ACS-4749] Resolved issues after rebase * [ACS-4749] Addressed PR comment
This commit is contained in:
parent
e6278109d8
commit
1634716bbe
@ -8,22 +8,22 @@
|
||||
matInput
|
||||
id="comment-input"
|
||||
class="adf-text-text-area"
|
||||
[placeholder]='"COMMENTS.ADD" | translate'
|
||||
[placeholder]='("COMMENTS.ADD" | translate) + "*"'
|
||||
[attr.aria-label]="'COMMENTS.ADD' | translate"
|
||||
[(ngModel)]="message"
|
||||
[formControl]="commentControl"
|
||||
(keydown.escape)="clearMessage($event)"
|
||||
>
|
||||
</textarea>
|
||||
<mat-error *ngIf="commentControl.invalid && commentControl.touched">{{ 'COMMENTS.EMPTY_ERROR' | translate }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-comments-input-actions">
|
||||
<button
|
||||
mat-button
|
||||
class="adf-comments-input-add"
|
||||
data-automation-id="comments-input-add"
|
||||
color="primary"
|
||||
(click)="addComment()"
|
||||
[disabled]="!message"
|
||||
[disabled]="commentControl.invalid"
|
||||
>
|
||||
{{ 'COMMENTS.ADD' | translate }}
|
||||
</button>
|
||||
|
@ -12,10 +12,15 @@ adf-comments {
|
||||
|
||||
#{$mat-form-field} {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#{$mat-form-field-subscript-wrapper} {
|
||||
display: none;
|
||||
&#{$mat-form-field-invalid} {
|
||||
#{$mat-input-element} {
|
||||
&::placeholder,
|
||||
&:focus::placeholder {
|
||||
color: var(--theme-warn-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#{$mat-form-field-wrapper} {
|
||||
|
@ -25,6 +25,7 @@ import { CommentsService } from './interfaces/comments-service.interface';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NoopTranslateModule } from '../testing/noop-translate.module';
|
||||
import { UnitTestingUtils } from '../testing/unit-testing-utils';
|
||||
import { MatError } from '@angular/material/form-field';
|
||||
|
||||
describe('CommentsComponent', () => {
|
||||
let component: CommentsComponent;
|
||||
@ -156,6 +157,10 @@ describe('CommentsComponent', () => {
|
||||
});
|
||||
|
||||
describe('Add comment', () => {
|
||||
const getError = (): string => testingUtils.getByDirective(MatError)?.nativeElement?.textContent;
|
||||
|
||||
const getAddCommentButton = (): HTMLButtonElement => testingUtils.getByDataAutomationId('comments-input-add').nativeElement;
|
||||
|
||||
beforeEach(() => {
|
||||
component.id = '123';
|
||||
fixture.detectChanges();
|
||||
@ -163,8 +168,8 @@ describe('CommentsComponent', () => {
|
||||
});
|
||||
|
||||
it('should normalize comment when user input contains spaces sequence', async () => {
|
||||
component.message = 'test comment';
|
||||
testingUtils.clickByCSS('.adf-comments-input-add');
|
||||
component.commentControl.setValue('test comment');
|
||||
getAddCommentButton().dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@ -184,8 +189,8 @@ describe('CommentsComponent', () => {
|
||||
getCommentSpy.and.returnValue(of([]));
|
||||
addCommentSpy.and.returnValue(commentsResponseMock.addComment(commentText));
|
||||
|
||||
component.message = commentText;
|
||||
testingUtils.clickByCSS('.adf-comments-input-add');
|
||||
component.commentControl.setValue(commentText);
|
||||
getAddCommentButton().dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@ -195,9 +200,10 @@ describe('CommentsComponent', () => {
|
||||
});
|
||||
|
||||
it('should call service to add a comment when add button is pressed', async () => {
|
||||
component.message = 'Test Comment';
|
||||
addCommentSpy.and.returnValue(commentsResponseMock.addComment(component.message));
|
||||
testingUtils.clickByCSS('.adf-comments-input-add');
|
||||
const comment = 'Test Comment';
|
||||
component.commentControl.setValue(comment);
|
||||
addCommentSpy.and.returnValue(commentsResponseMock.addComment(comment));
|
||||
getAddCommentButton().dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@ -209,8 +215,8 @@ describe('CommentsComponent', () => {
|
||||
});
|
||||
|
||||
it('should not call service to add a comment when comment is empty', async () => {
|
||||
component.message = '';
|
||||
testingUtils.clickByCSS('.adf-comments-input-add');
|
||||
component.commentControl.setValue('');
|
||||
getAddCommentButton().dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@ -231,7 +237,7 @@ describe('CommentsComponent', () => {
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
const emitSpy = spyOn(component.error, 'emit');
|
||||
addCommentSpy.and.returnValue(throwError(() => new Error('error')));
|
||||
component.message = 'Test comment';
|
||||
component.commentControl.setValue('Test comment');
|
||||
component.addComment();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
@ -255,9 +261,85 @@ describe('CommentsComponent', () => {
|
||||
});
|
||||
|
||||
it('should not add comment if message is empty', () => {
|
||||
component.message = '';
|
||||
component.commentControl.setValue('');
|
||||
component.addComment();
|
||||
expect(addCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not display error message initially', () => {
|
||||
expect(getError()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should display error message when comment is empty and was touched', () => {
|
||||
component.commentControl.setValue('');
|
||||
component.commentControl.markAsTouched();
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getError()).toBe('COMMENTS.EMPTY_ERROR');
|
||||
});
|
||||
|
||||
it('should display error message when comment has only spaces and was touched', () => {
|
||||
component.commentControl.setValue(' ');
|
||||
component.commentControl.markAsTouched();
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getError()).toBe('COMMENTS.EMPTY_ERROR');
|
||||
});
|
||||
|
||||
it('should not display error message when comment is empty but was not touched', () => {
|
||||
component.commentControl.setValue('');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getError()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not display error message when comment has only spaces but was not touched', () => {
|
||||
component.commentControl.setValue(' ');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getError()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not display error message when comment is not empty and was touched', () => {
|
||||
component.commentControl.setValue('Some comment');
|
||||
component.commentControl.markAsTouched();
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getError()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not display error message when comment is not empty and was not touched', () => {
|
||||
component.commentControl.setValue('Some comment');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getError()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should disable add button initially', () => {
|
||||
expect(getAddCommentButton().disabled).toBeTrue();
|
||||
});
|
||||
|
||||
it('should disable add button when comment is empty', () => {
|
||||
component.commentControl.setValue('Some comment');
|
||||
component.commentControl.setValue('');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getAddCommentButton().disabled).toBeTrue();
|
||||
});
|
||||
|
||||
it('should disable add button when comment has only spaces', () => {
|
||||
component.commentControl.setValue('Some comment');
|
||||
component.commentControl.setValue(' ');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getAddCommentButton().disabled).toBeTrue();
|
||||
});
|
||||
|
||||
it('should enable add button when comment is not empty', () => {
|
||||
component.commentControl.setValue('Some comment');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getAddCommentButton().disabled).toBeFalse();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -23,14 +23,23 @@ import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormControl, FormsModule, ReactiveFormsModule, ValidationErrors } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { CommentListComponent } from './comment-list';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-comments',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslateModule, MatFormFieldModule, MatInputModule, FormsModule, MatButtonModule, CommentListComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
FormsModule,
|
||||
MatButtonModule,
|
||||
CommentListComponent,
|
||||
ReactiveFormsModule
|
||||
],
|
||||
templateUrl: './comments.component.html',
|
||||
styleUrls: ['./comments.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
@ -49,11 +58,16 @@ export class CommentsComponent implements OnChanges {
|
||||
error = new EventEmitter<any>();
|
||||
|
||||
comments: CommentModel[] = [];
|
||||
message: string;
|
||||
beingAdded: boolean = false;
|
||||
|
||||
private commentsService = inject<CommentsService>(ADF_COMMENTS_SERVICE);
|
||||
|
||||
private readonly _commentControl = new FormControl('', [this.validateEmptyComment]);
|
||||
|
||||
get commentControl(): FormControl<string> {
|
||||
return this._commentControl;
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.id = null;
|
||||
|
||||
@ -95,10 +109,10 @@ export class CommentsComponent implements OnChanges {
|
||||
|
||||
this.beingAdded = true;
|
||||
|
||||
this.commentsService.add(this.id, this.message).subscribe({
|
||||
this.commentsService.add(this.id, this.commentControl.value).subscribe({
|
||||
next: (res) => {
|
||||
this.addToComments(res);
|
||||
this.resetMessage();
|
||||
this.commentControl.reset();
|
||||
},
|
||||
error: (err) => {
|
||||
this.error.emit(err);
|
||||
@ -111,19 +125,15 @@ export class CommentsComponent implements OnChanges {
|
||||
|
||||
clearMessage(event: Event): void {
|
||||
event.stopPropagation();
|
||||
this.resetMessage();
|
||||
this.commentControl.reset();
|
||||
}
|
||||
|
||||
private addToComments(comment: CommentModel): void {
|
||||
this.comments.unshift(comment);
|
||||
}
|
||||
|
||||
private resetMessage(): void {
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
private canAddComment(): boolean {
|
||||
return this.hasId() && this.message && this.message.trim() && !this.beingAdded;
|
||||
return this.hasId() && this.commentControl.value?.trim() && !this.beingAdded;
|
||||
}
|
||||
|
||||
private hasId(): boolean {
|
||||
@ -146,4 +156,8 @@ export class CommentsComponent implements OnChanges {
|
||||
private resetComments(): void {
|
||||
this.comments = [];
|
||||
}
|
||||
|
||||
private validateEmptyComment(commentControl: FormControl<string>): ValidationErrors {
|
||||
return commentControl.value?.trim() ? null : { emptyComment: true };
|
||||
}
|
||||
}
|
||||
|
@ -306,6 +306,7 @@
|
||||
"HEADER": "Comments ({{ count }})",
|
||||
"CREATED_BY_HEADER": "Created by",
|
||||
"MESSAGE_HEADER": "Message",
|
||||
"EMPTY_ERROR": "Comment can't be empty",
|
||||
"DIALOG": {
|
||||
"TITLE": "New comment",
|
||||
"LABELS": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user