diff --git a/src/app/dialogs/node-templates/create-from-template.dialog.spec.ts b/src/app/dialogs/node-templates/create-from-template.dialog.spec.ts new file mode 100644 index 000000000..0ff8ee84f --- /dev/null +++ b/src/app/dialogs/node-templates/create-from-template.dialog.spec.ts @@ -0,0 +1,140 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { CreateFileFromTemplateDialogComponent } from './create-from-template.dialog'; +import { TestBed, ComponentFixture } from '@angular/core/testing'; +import { AppTestingModule } from '../../testing/app-testing.module'; +import { CoreModule } from '@alfresco/adf-core'; +import { + MatDialogModule, + MatDialogRef, + MAT_DIALOG_DATA +} from '@angular/material/dialog'; + +function text(length: number) { + return new Array(length) + .fill( + Math.random() + .toString() + .substring(2, 3) + ) + .join(''); +} + +describe('CreateFileFromTemplateDialogComponent', () => { + let fixture: ComponentFixture; + let component: CreateFileFromTemplateDialogComponent; + let dialogRef: MatDialogRef; + + const data = { + id: 'node-id', + name: 'node-name', + properties: { + 'cm:title': 'node-title', + 'cm:description': '' + } + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [CoreModule.forRoot(), AppTestingModule, MatDialogModule], + declarations: [CreateFileFromTemplateDialogComponent], + providers: [ + { provide: MAT_DIALOG_DATA, useValue: data }, + { + provide: MatDialogRef, + useValue: { + close: jasmine.createSpy('close') + } + } + ] + }); + + fixture = TestBed.createComponent(CreateFileFromTemplateDialogComponent); + dialogRef = TestBed.get(MatDialogRef); + component = fixture.componentInstance; + + fixture.detectChanges(); + }); + + it('should populate form with provided dialog data', () => { + expect(component.form.controls.name.value).toBe(data.name); + expect(component.form.controls.title.value).toBe( + data.properties['cm:title'] + ); + expect(component.form.controls.description.value).toBe( + data.properties['cm:description'] + ); + }); + + it('should invalidate form if required `name` field is invalid', () => { + component.form.controls.name.setValue(''); + fixture.detectChanges(); + expect(component.form.invalid).toBe(true); + }); + + it('should invalidate form if required `name` field has `only spaces`', () => { + component.form.controls.name.setValue(' '); + fixture.detectChanges(); + expect(component.form.invalid).toBe(true); + }); + + it('should invalidate form if required `name` field has `ending dot`', () => { + component.form.controls.name.setValue('something.'); + fixture.detectChanges(); + expect(component.form.invalid).toBe(true); + }); + + it('should invalidate form if `title` text length is long', () => { + component.form.controls.title.setValue(text(260)); + fixture.detectChanges(); + expect(component.form.invalid).toBe(true); + }); + + it('should invalidate form if `description` text length is long', () => { + component.form.controls.description.setValue(text(520)); + fixture.detectChanges(); + expect(component.form.invalid).toBe(true); + }); + + it('should update data with form values', () => { + component.form.controls.name.setValue('new-node-name'); + component.form.controls.title.setValue('new-node-title'); + component.form.controls.description.setValue('new-node-description'); + + fixture.detectChanges(); + + component.onSubmit(); + + expect(dialogRef.close['calls'].argsFor(0)[0]).toEqual({ + id: 'node-id', + name: 'new-node-name', + properties: { + 'cm:title': 'new-node-title', + 'cm:description': 'new-node-description' + } + }); + }); +}); diff --git a/src/app/store/effects/template.effects.spec.ts b/src/app/store/effects/template.effects.spec.ts index 51e976b27..266656a88 100644 --- a/src/app/store/effects/template.effects.spec.ts +++ b/src/app/store/effects/template.effects.spec.ts @@ -36,12 +36,28 @@ import { CreateFileFromTemplateService } from '../../services/create-file-from-t import { of } from 'rxjs'; import { AlfrescoApiServiceMock, AlfrescoApiService } from '@alfresco/adf-core'; import { ContentManagementService } from '../../services/content-management.service'; +import { Node } from '@alfresco/js-api'; describe('TemplateEffects', () => { let store: Store; let createFileFromTemplateService: CreateFileFromTemplateService; let alfrescoApiService: AlfrescoApiService; let contentManagementService: ContentManagementService; + const node: Node = { + name: 'node-name', + id: 'node-id', + nodeType: 'cm:content', + isFolder: false, + isFile: true, + modifiedAt: null, + modifiedByUser: null, + createdAt: null, + createdByUser: null, + properties: { + 'cm:title': 'title', + 'cm:description': 'description' + } + }; beforeEach(() => { TestBed.configureTestingModule({ @@ -64,17 +80,27 @@ describe('TemplateEffects', () => { ); }); - it('should reload content on template copy', fakeAsync(() => { + it('should reload content on create file from template', fakeAsync(() => { spyOn(alfrescoApiService.getInstance().nodes, 'copyNode').and.returnValue( + of({ entry: { id: 'node-id' } }) + ); + + spyOn(alfrescoApiService.getInstance().nodes, 'updateNode').and.returnValue( of({}) ); + + spyOn( + createFileFromTemplateService, + 'createTemplateDialog' + ).and.returnValue({ afterClosed: () => of(node) }); + store.dispatch(new CreateFileFromTemplate()); - tick(); + tick(300); expect(contentManagementService.reload.next).toHaveBeenCalled(); })); - it('should raise error when copy template fails', fakeAsync(() => { + it('should raise error when copyNode api fails', fakeAsync(() => { spyOn(store, 'dispatch').and.callThrough(); spyOn(alfrescoApiService.getInstance().nodes, 'copyNode').and.returnValue( Promise.reject({ @@ -82,12 +108,54 @@ describe('TemplateEffects', () => { }) ); + spyOn( + createFileFromTemplateService, + 'createTemplateDialog' + ).and.returnValue({ afterClosed: () => of(node) }); + store.dispatch(new CreateFileFromTemplate()); - tick(); + tick(300); expect(contentManagementService.reload.next).not.toHaveBeenCalled(); expect(store.dispatch['calls'].argsFor(1)[0]).toEqual( new SnackbarErrorAction('APP.MESSAGES.ERRORS.GENERIC') ); })); + + it('should raise error when updateNode api fails', fakeAsync(() => { + spyOn(store, 'dispatch').and.callThrough(); + spyOn(alfrescoApiService.getInstance().nodes, 'copyNode').and.returnValue( + of({ entry: { id: 'node-id' } }) + ); + + spyOn(alfrescoApiService.getInstance().nodes, 'updateNode').and.returnValue( + Promise.reject({ + message: `{ "error": { "statusCode": 404 } } ` + }) + ); + + spyOn( + createFileFromTemplateService, + 'createTemplateDialog' + ).and.returnValue({ afterClosed: () => of(node) }); + + store.dispatch(new CreateFileFromTemplate()); + tick(300); + + expect(contentManagementService.reload.next).not.toHaveBeenCalled(); + expect(store.dispatch['calls'].argsFor(1)[0]).toEqual( + new SnackbarErrorAction('APP.MESSAGES.ERRORS.GENERIC') + ); + })); + + it('should update file from template with form data', () => { + spyOn(alfrescoApiService.getInstance().nodes, 'copyNode').and.returnValue( + of({ entry: { id: 'node-id' } }) + ); + + spyOn( + createFileFromTemplateService, + 'createTemplateDialog' + ).and.returnValue({ afterClosed: () => of(node) }); + }); });