From 1c59b2fb15570a497db8cb022469cecbb464c6a5 Mon Sep 17 00:00:00 2001 From: Dominik Iwanek <141320833+dominikiwanekhyland@users.noreply.github.com> Date: Mon, 26 Jan 2026 13:32:48 +0100 Subject: [PATCH] [ACS-10307] SR: Personal files: No confirmation announced when creating new folder or document (#11549) --- .../lib/dialogs/folder/folder.dialog.spec.ts | 109 +++++++++--------- .../src/lib/dialogs/folder/folder.dialog.ts | 8 +- lib/core/src/lib/i18n/en.json | 4 +- 3 files changed, 66 insertions(+), 55 deletions(-) diff --git a/lib/content-services/src/lib/dialogs/folder/folder.dialog.spec.ts b/lib/content-services/src/lib/dialogs/folder/folder.dialog.spec.ts index 5a4ae1dc43..8a527721bb 100644 --- a/lib/content-services/src/lib/dialogs/folder/folder.dialog.spec.ts +++ b/lib/content-services/src/lib/dialogs/folder/folder.dialog.spec.ts @@ -15,17 +15,19 @@ * limitations under the License. */ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { MatDialogRef } from '@angular/material/dialog'; import { NodesApiService } from '../../common/services/nodes-api.service'; import { FolderDialogComponent } from './folder.dialog'; -import { BehaviorSubject, throwError } from 'rxjs'; +import { of, throwError } from 'rxjs'; import { By } from '@angular/platform-browser'; +import { NotificationService } from '@alfresco/adf-core'; describe('FolderDialogComponent', () => { let fixture: ComponentFixture; let component: FolderDialogComponent; let nodesApi: NodesApiService; + let notificationService: NotificationService; let submitButton: HTMLButtonElement; const dialogRef = { @@ -34,29 +36,26 @@ describe('FolderDialogComponent', () => { let updateNodeSpy: jasmine.Spy; let createFolderSpy: jasmine.Spy; - const updateNode$ = new BehaviorSubject(null); - let createFolderNode$ = null; - beforeEach(() => { + const notificationServiceMock = { + showInfo: jasmine.createSpy('showInfo') + }; + TestBed.configureTestingModule({ imports: [], - providers: [{ provide: MatDialogRef, useValue: dialogRef }] + providers: [{ provide: MatDialogRef, useValue: dialogRef }, { provide: NotificationService, useValue: notificationServiceMock }] }); dialogRef.close.calls.reset(); fixture = TestBed.createComponent(FolderDialogComponent); component = fixture.componentInstance; nodesApi = TestBed.inject(NodesApiService); - createFolderNode$ = new BehaviorSubject(null); + notificationService = TestBed.inject(NotificationService); - createFolderSpy = spyOn(nodesApi, 'createFolder').and.returnValue(createFolderNode$); - updateNodeSpy = spyOn(nodesApi, 'updateNode').and.returnValue(updateNode$); + createFolderSpy = spyOn(nodesApi, 'createFolder'); + updateNodeSpy = spyOn(nodesApi, 'updateNode'); submitButton = fixture.nativeElement.querySelector('#adf-folder-create-button'); }); - afterEach(() => { - fixture.destroy(); - }); - const getTitle = () => fixture.debugElement.query(By.css('[data-automation-id="adf-folder-dialog-title"]')); describe('Edit', () => { @@ -95,7 +94,8 @@ describe('FolderDialogComponent', () => { }); it('should submit updated values if form is valid', () => { - updateNode$.next(null); + const updatedFolder: any = { name: 'folder-name-update' }; + updateNodeSpy.and.returnValue(of(updatedFolder)); setFormValues(); @@ -128,36 +128,40 @@ describe('FolderDialogComponent', () => { expect(updateNodeSpy).not.toHaveBeenCalled(); }); - describe('when submit is successfully', () => { - const folder: any = { data: 'folder-data' }; + it('should show edit success notification with folder name when folder is updated', () => { + const updatedFolder: any = { name: 'updated-folder' }; + updateNodeSpy.and.returnValue(of(updatedFolder)); - beforeAll(() => { - updateNode$.next(folder); - }); + component.form.controls['name'].setValue('updated-folder'); + component.submit(); + + expect(notificationService.showInfo).toHaveBeenCalledWith('CORE.FOLDER_DIALOG.FOLDER_UPDATED_SUCCESS'); + }); + + describe('when submit is successfully', () => { + const folder: any = { data: 'folder-data', name: 'folder-data' }; it('should call dialog to close with form data', () => { + updateNodeSpy.and.returnValue(of(folder)); component.submit(); expect(dialogRef.close).toHaveBeenCalledWith(folder); }); - it('should emit success output event with folder', async () => { - let expectedNode = null; - + it('should emit success output event with folder', fakeAsync(() => { + updateNodeSpy.and.returnValue(of(folder)); + let emittedNode: any; component.success.subscribe((node) => { - expectedNode = node; + emittedNode = node; }); component.submit(); - - fixture.detectChanges(); - await fixture.whenStable(); - - expect(expectedNode).toBe(folder); - }); + tick(); + expect(emittedNode).toBe(folder); + })); }); it('should not call dialog to close if submit fails', () => { - updateNode$.error(throwError('error')); + updateNodeSpy.and.returnValue(throwError(() => 'error')); spyOn(component, 'handleError').and.callFake((val) => val); component.submit(); @@ -196,11 +200,13 @@ describe('FolderDialogComponent', () => { describe('when form is valid', () => { beforeEach(() => { - createFolderNode$.next(null); setFormValues(); }); it('should submit updated values', () => { + const createdFolder: any = { name: 'folder-name-update' }; + createFolderSpy.and.returnValue(of(createdFolder)); + component.submit(); expect(component.disableSubmitButton).toBeTrue(); @@ -215,6 +221,8 @@ describe('FolderDialogComponent', () => { }); it('should submit updated values (with custom nodeType)', () => { + const createdFolder: any = { name: 'folder-name-update' }; + createFolderSpy.and.returnValue(of(createdFolder)); component.nodeType = 'cm:sushi'; fixture.detectChanges(); @@ -236,14 +244,10 @@ describe('FolderDialogComponent', () => { }); it('should call dialog to close with form data when submit is successfully', () => { - const folder: any = { - data: 'folder-data' - }; + const folder: any = { data: 'folder-data', name: 'folder-data' }; + createFolderSpy.and.returnValue(of(folder)); setFormValues(); - - createFolderNode$.next(folder); - component.submit(); expect(dialogRef.close).toHaveBeenCalledWith(folder); @@ -259,7 +263,7 @@ describe('FolderDialogComponent', () => { }); it('should not call dialog to close if submit fails', () => { - createFolderNode$.error(throwError('error')); + createFolderSpy.and.returnValue(throwError(() => 'error')); spyOn(component, 'handleError').and.callFake((val) => val); component.form.controls['name'].setValue('name'); @@ -271,23 +275,24 @@ describe('FolderDialogComponent', () => { expect(dialogRef.close).not.toHaveBeenCalled(); }); + it('should show success notification with folder name when folder is created', () => { + const createdFolder: any = { name: 'new-folder' }; + createFolderSpy.and.returnValue(of(createdFolder)); + + component.form.controls['name'].setValue('new-folder'); + component.submit(); + + expect(notificationService.showInfo).toHaveBeenCalledWith('CORE.FOLDER_DIALOG.FOLDER_CREATED_SUCCESS'); + }); + describe('Error events', () => { - let errorSubscriber = null; - - afterEach(() => { - createFolderNode$.next(null); - if (errorSubscriber) { - errorSubscriber.complete(); - } - }); - it('should raise error for 409', (done) => { const error = { message: '{ "error": { "statusCode" : 409 } }' }; - createFolderNode$.error(error); + createFolderSpy.and.returnValue(throwError(() => error)); - errorSubscriber = component.error.subscribe((message) => { + component.error.subscribe((message) => { expect(message).toBe('CORE.MESSAGES.ERRORS.EXISTENT_FOLDER'); done(); }); @@ -302,9 +307,9 @@ describe('FolderDialogComponent', () => { const error = { message: '{ "error": { "statusCode" : 123 } }' }; - createFolderNode$.error(error); + createFolderSpy.and.returnValue(throwError(() => error)); - errorSubscriber = component.error.subscribe((message) => { + component.error.subscribe((message) => { expect(message).toBe('CORE.MESSAGES.ERRORS.GENERIC'); done(); }); @@ -316,7 +321,7 @@ describe('FolderDialogComponent', () => { }); it('should enable submit button after changing name field when previous value caused error', () => { - createFolderNode$.error(throwError('error')); + createFolderSpy.and.returnValue(throwError(() => 'error')); spyOn(component, 'handleError').and.callFake((val) => val); component.form.controls['name'].setValue(''); component.submit(); diff --git a/lib/content-services/src/lib/dialogs/folder/folder.dialog.ts b/lib/content-services/src/lib/dialogs/folder/folder.dialog.ts index 21fd4de484..90ed573002 100644 --- a/lib/content-services/src/lib/dialogs/folder/folder.dialog.ts +++ b/lib/content-services/src/lib/dialogs/folder/folder.dialog.ts @@ -20,7 +20,7 @@ import { Component, DestroyRef, EventEmitter, inject, Inject, OnInit, Optional, import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { Node } from '@alfresco/js-api'; -import { TranslationService } from '@alfresco/adf-core'; +import { TranslationService, NotificationService } from '@alfresco/adf-core'; import { NodesApiService } from '../../common/services/nodes-api.service'; import { forbidEndingDot, forbidOnlySpaces, forbidSpecialCharacters } from './folder-name.validators'; import { CommonModule } from '@angular/common'; @@ -94,6 +94,7 @@ export class FolderDialogComponent implements OnInit { } private readonly destroyRef = inject(DestroyRef); + private readonly notificationService = inject(NotificationService) constructor( private formBuilder: UntypedFormBuilder, @@ -116,7 +117,6 @@ export class FolderDialogComponent implements OnInit { let name = ''; let title = ''; let description = ''; - if (folder) { const { properties } = folder; @@ -143,6 +143,10 @@ export class FolderDialogComponent implements OnInit { (this.editing ? this.edit() : this.create()).subscribe( (folder: Node) => { + const messageKey = this.editing ? 'CORE.FOLDER_DIALOG.FOLDER_UPDATED_SUCCESS' : 'CORE.FOLDER_DIALOG.FOLDER_CREATED_SUCCESS'; + const message = this.translation.instant(messageKey, { name: folder.name }); + + this.notificationService.showInfo(message); this.success.emit(folder); this.dialog.close(folder); }, diff --git a/lib/core/src/lib/i18n/en.json b/lib/core/src/lib/i18n/en.json index 5c1ad1a1ad..f77ec47585 100644 --- a/lib/core/src/lib/i18n/en.json +++ b/lib/core/src/lib/i18n/en.json @@ -214,7 +214,9 @@ }, "CANCEL_BUTTON": { "LABEL": "Cancel" - } + }, + "FOLDER_CREATED_SUCCESS": "Folder '{{ name }}' created successfully", + "FOLDER_UPDATED_SUCCESS": "Folder '{{ name }}' updated successfully" }, "MESSAGES": { "ERRORS": {