From 6dafcb44474dfb0be62a0ca252c71963ac222094 Mon Sep 17 00:00:00 2001 From: Shivangi Shree Date: Tue, 1 Jul 2025 13:54:07 +0530 Subject: [PATCH] [ADF-5580] emit commentAdded event from adf-comments component (#10966) * [ADF-5580] emit commentAdded event from adf-comments component * [ADF-5580] Emit commentAdded event from adf-comments and expose it in adf-node-comments * [ADF-5580] Emit commentAdded event from NodeCommentsComponent, add unit test, and update docs * [ADF-5580] Add unit test for commentAdded output in NodeCommentsComponent, update docs and create testing utils * [ADF-5580] Mark debugElement as readOnly * [ADF-5580] Add mock services and fix unit test setup * [ADF-5580] Reuse shared comment mocks across multiple test files * [ADF-5580] Align comments component documentation * [ADF-5580] Remove redundant setup and use ContentTestingModule in comment components tests --- .../components/node-comments.component.md | 17 +++-- docs/core/components/comments.component.md | 18 ++--- .../node-comments.component.html | 1 + .../node-comments.component.spec.ts | 65 +++++++++++++++++++ .../node-comments/node-comments.component.ts | 8 ++- .../lib/comments/comments.component.spec.ts | 27 ++++++++ .../src/lib/comments/comments.component.ts | 5 ++ 7 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 lib/content-services/src/lib/node-comments/node-comments.component.spec.ts diff --git a/docs/content-services/components/node-comments.component.md b/docs/content-services/components/node-comments.component.md index be3d23ac7b..a48be8d8e9 100644 --- a/docs/content-services/components/node-comments.component.md +++ b/docs/content-services/components/node-comments.component.md @@ -15,7 +15,8 @@ Displays comments from users involved in a specified content and allows an invol ```html + [readOnly]="YOUR_READ_ONLY_FLAG" + (commentAdded)="onCommentAdded($event)"> ``` @@ -23,7 +24,13 @@ Displays comments from users involved in a specified content and allows an invol ### Properties -| Name | Type | Default value | Description | -| ---- | ---- | ------------- | ----------- | -| nodeId | `string` | | nodeId of the document that has comments | -| readOnly | `boolean` | | make the [comments component](../../core/components/comments.component.md) readOnly | +| Name | Type | Default value | Description | +| -------- | --------- | ------------- | ----------------------------------------------------------------------------------- | +| nodeId | `string` | | nodeId of the document that has comments | +| readOnly | `boolean` | | make the [comments component](../../core/components/comments.component.md) readOnly | + +### Events + +| Name | Type | Description | +| ------------ | ------------------------------------------------------------------------ | ------------------------------------------------- | +| commentAdded | [`EventEmitter`](https://angular.io/api/core/EventEmitter) | Emitted when a new comment is successfully added. | diff --git a/docs/core/components/comments.component.md b/docs/core/components/comments.component.md index 87f023fab5..556e3c1d72 100644 --- a/docs/core/components/comments.component.md +++ b/docs/core/components/comments.component.md @@ -15,7 +15,8 @@ Displays comments from users involved in a specified environment and allows an i ```html + [readOnly]="YOUR_READ_ONLY_FLAG" + (commentAdded)="onCommentAdded($event)"> ``` @@ -23,13 +24,14 @@ Displays comments from users involved in a specified environment and allows an i ### Properties -| Name | Type | Default value | Description | -| ---- | ---- | ------------- | ----------- | -| id | `string` | | The numeric ID of the task. | -| readOnly | `boolean` | false | Are the comments read only? | +| Name | Type | Default value | Description | +| -------- | --------- | ------------- | --------------------------- | +| id | `string` | | The numeric ID of the task. | +| readOnly | `boolean` | false | Are the comments read only? | ### Events -| Name | Type | Description | -| ---- | ---- | ----------- | -| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when an error occurs while displaying/adding a comment. | +| Name | Type | Description | +| ------------ | --------------------------------------------------------------------------- | --------------------------------------------------------------- | +| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when an error occurs while displaying/adding a comment. | +| commentAdded | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when a new comment is successfully added. | diff --git a/lib/content-services/src/lib/node-comments/node-comments.component.html b/lib/content-services/src/lib/node-comments/node-comments.component.html index 12f01dd0e6..ac295b851e 100644 --- a/lib/content-services/src/lib/node-comments/node-comments.component.html +++ b/lib/content-services/src/lib/node-comments/node-comments.component.html @@ -1,4 +1,5 @@ \ No newline at end of file diff --git a/lib/content-services/src/lib/node-comments/node-comments.component.spec.ts b/lib/content-services/src/lib/node-comments/node-comments.component.spec.ts new file mode 100644 index 0000000000..df75805951 --- /dev/null +++ b/lib/content-services/src/lib/node-comments/node-comments.component.spec.ts @@ -0,0 +1,65 @@ +/*! + * @license + * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NodeCommentsComponent } from './node-comments.component'; +import { CommentsComponent } from '../../../../core/src/lib/comments/comments.component'; +import { CommentModel } from '../../../../core/src/lib/models'; +import { UnitTestingUtils } from '../../../../core/src/lib/testing/unit-testing-utils'; +import { ContentTestingModule } from '../testing/content.testing.module'; + +describe('NodeCommentsComponent', () => { + let fixture: ComponentFixture; + let component: NodeCommentsComponent; + let testingUtils: UnitTestingUtils; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [NodeCommentsComponent, ContentTestingModule] + }).compileComponents(); + + fixture = TestBed.createComponent(NodeCommentsComponent); + component = fixture.componentInstance; + testingUtils = new UnitTestingUtils(fixture.debugElement); + component.nodeId = 'test-node-id'; + fixture.detectChanges(); + }); + + it('should emit commentAdded when CommentsComponent emits', () => { + const mockComment: CommentModel = { + id: '123', + message: 'Sample comment', + created: new Date(), + createdBy: { + id: 'user1', + displayName: 'User 1', + avatarId: 'avatar-123' + }, + isSelected: false, + hasAvatarPicture: true, + userDisplayName: 'User 1', + userInitials: 'U1' + }; + + spyOn(component.commentAdded, 'emit'); + + const commentsComponent: CommentsComponent = testingUtils.getByDirective(CommentsComponent).componentInstance; + commentsComponent.commentAdded.emit(mockComment); + + expect(component.commentAdded.emit).toHaveBeenCalledWith(mockComment); + }); +}); diff --git a/lib/content-services/src/lib/node-comments/node-comments.component.ts b/lib/content-services/src/lib/node-comments/node-comments.component.ts index 4167a79332..cb3ba98f3b 100644 --- a/lib/content-services/src/lib/node-comments/node-comments.component.ts +++ b/lib/content-services/src/lib/node-comments/node-comments.component.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { Component, Input, ViewEncapsulation } from '@angular/core'; -import { ADF_COMMENTS_SERVICE, CommentsComponent } from '@alfresco/adf-core'; +import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'; +import { ADF_COMMENTS_SERVICE, CommentModel, CommentsComponent } from '@alfresco/adf-core'; import { NodeCommentsService } from './services/node-comments.service'; @Component({ @@ -40,4 +40,8 @@ export class NodeCommentsComponent { /** make the comments component readOnly */ @Input() readOnly: boolean; + + /** Emits when a new comment is added */ + @Output() + commentAdded = new EventEmitter(); } diff --git a/lib/core/src/lib/comments/comments.component.spec.ts b/lib/core/src/lib/comments/comments.component.spec.ts index 61a0844585..3c3dcb75c6 100644 --- a/lib/core/src/lib/comments/comments.component.spec.ts +++ b/lib/core/src/lib/comments/comments.component.spec.ts @@ -26,6 +26,7 @@ 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'; +import { CommentModel } from '../models'; describe('CommentsComponent', () => { let component: CommentsComponent; @@ -122,6 +123,32 @@ describe('CommentsComponent', () => { expect(testingUtils.getByCSS('#comment-input')).not.toBeNull(); }); + it('should emit commentAdded when a new comment is added successfully', () => { + const emitSpy = spyOn(component.commentAdded, 'emit'); + const mockComment: CommentModel = { + id: 'comment-123', + message: 'New test comment', + created: new Date(), + createdBy: { + id: 'user-1', + displayName: 'John Doe', + avatarId: 'avatar-001' + }, + isSelected: false, + hasAvatarPicture: false, + userDisplayName: 'John Doe', + userInitials: 'JD' + }; + + component.id = '123'; + component.commentControl.setValue('New test comment'); + addCommentSpy.and.returnValue(of(mockComment)); + + component.addComment(); + + expect(emitSpy).toHaveBeenCalledWith(mockComment); + }); + it('should not display comments input when the entity is readonly', async () => { component.readOnly = true; diff --git a/lib/core/src/lib/comments/comments.component.ts b/lib/core/src/lib/comments/comments.component.ts index 8633c6e8d8..46fd37a4b5 100644 --- a/lib/core/src/lib/comments/comments.component.ts +++ b/lib/core/src/lib/comments/comments.component.ts @@ -57,6 +57,10 @@ export class CommentsComponent implements OnChanges { @Output() error = new EventEmitter(); + /** Emits when a new comment is added */ + @Output() + commentAdded = new EventEmitter(); + comments: CommentModel[] = []; beingAdded: boolean = false; @@ -113,6 +117,7 @@ export class CommentsComponent implements OnChanges { next: (res) => { this.addToComments(res); this.commentControl.reset(); + this.commentAdded.emit(res); }, error: (err) => { this.error.emit(err);