[ACS-7688] Reduce the usage of LogService and TranslateModule (tests) (#9567)

This commit is contained in:
Denys Vuika
2024-04-19 12:14:33 -04:00
committed by GitHub
parent caa2166151
commit 54c3e12ad8
275 changed files with 4090 additions and 5551 deletions

View File

@@ -23,7 +23,6 @@ import { of, throwError } from 'rxjs';
import { defaultApp, deployedApps, nonDeployedApps } from '../mock/apps-list.mock';
import { AppsListComponent, APP_LIST_LAYOUT_GRID, APP_LIST_LAYOUT_LIST } from './apps-list.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { AppDefinitionRepresentationModel } from '../task-list';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
@@ -50,7 +49,7 @@ describe('AppsListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
declarations: [CustomEmptyAppListTemplateComponent]
});
fixture = TestBed.createComponent(AppsListComponent);

View File

@@ -22,10 +22,8 @@ import { OverlayContainer } from '@angular/cdk/overlay';
import { AppsProcessService } from './services/apps-process.service';
import { deployedApps } from '../mock/apps-list.mock';
import { of } from 'rxjs';
import { SelectAppsDialogComponent } from './select-apps-dialog.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-dialog-test',
@@ -59,10 +57,7 @@ describe('Select app dialog', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [DialogSelectAppTestComponent],
providers: [
{
@@ -89,9 +84,7 @@ describe('Select app dialog', () => {
service = TestBed.inject(AppsProcessService);
spyOn(service, 'getDeployedApplications').and.returnValue(
of(deployedApps)
);
spyOn(service, 'getDeployedApplications').and.returnValue(of(deployedApps));
});
describe('Dialog', () => {
@@ -102,16 +95,8 @@ describe('Select app dialog', () => {
it('should init title and dropdown', () => {
component.startProcessAction();
expect(
overlayContainerElement.querySelector(
'.adf-select-app-dialog-title'
)
).toBeDefined();
expect(
overlayContainerElement.querySelector(
'.adf-select-app-dialog-dropdown'
)
).toBeDefined();
expect(overlayContainerElement.querySelector('.adf-select-app-dialog-title')).toBeDefined();
expect(overlayContainerElement.querySelector('.adf-select-app-dialog-dropdown')).toBeDefined();
});
});
});

View File

@@ -19,20 +19,15 @@ import { TestBed } from '@angular/core/testing';
import { fakeApps } from '../mocks/apps-service.mock';
import { AppsProcessService } from './apps-process.service';
import { CoreTestingModule } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
declare let jasmine: any;
describe('AppsProcessService', () => {
let service: AppsProcessService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
service = TestBed.inject(AppsProcessService);
jasmine.Ajax.install();
@@ -43,19 +38,17 @@ describe('AppsProcessService', () => {
});
it('should get the deployed apps ', (done) => {
service.getDeployedApplications().subscribe(
(res: any) => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].name).toEqual('Sales-Fakes-App');
expect(res[0].description).toEqual('desc-fake1');
expect(res[0].deploymentId).toEqual('111');
expect(res[1].name).toEqual('health-care-Fake');
expect(res[1].description).toEqual('desc-fake2');
expect(res[1].deploymentId).toEqual('444');
done();
}
);
service.getDeployedApplications().subscribe((res: any) => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].name).toEqual('Sales-Fakes-App');
expect(res[0].description).toEqual('desc-fake1');
expect(res[0].deploymentId).toEqual('111');
expect(res[1].name).toEqual('health-care-Fake');
expect(res[1].description).toEqual('desc-fake2');
expect(res[1].deploymentId).toEqual('444');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
@@ -65,15 +58,13 @@ describe('AppsProcessService', () => {
});
it('should get the filter deployed app ', (done) => {
service.getDeployedApplicationsByName('health-care-Fake').subscribe(
(res: any) => {
expect(res).toBeDefined();
expect(res.name).toEqual('health-care-Fake');
expect(res.description).toEqual('desc-fake2');
expect(res.deploymentId).toEqual('444');
done();
}
);
service.getDeployedApplicationsByName('health-care-Fake').subscribe((res: any) => {
expect(res).toBeDefined();
expect(res.name).toEqual('health-care-Fake');
expect(res.description).toEqual('desc-fake2');
expect(res.deploymentId).toEqual('444');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
@@ -83,15 +74,13 @@ describe('AppsProcessService', () => {
});
it('should get the deployed app details by id ', (done) => {
service.getApplicationDetailsById(1).subscribe(
(app: any) => {
expect(app).toBeDefined();
expect(app.name).toEqual('Sales-Fakes-App');
expect(app.description).toEqual('desc-fake1');
expect(app.deploymentId).toEqual('111');
done();
}
);
service.getApplicationDetailsById(1).subscribe((app: any) => {
expect(app).toBeDefined();
expect(app.name).toEqual('Sales-Fakes-App');
expect(app.description).toEqual('desc-fake1');
expect(app.deploymentId).toEqual('111');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,

View File

@@ -19,12 +19,10 @@ import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CreateProcessAttachmentComponent } from './create-process-attachment.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
declare let jasmine: any;
describe('CreateProcessAttachmentComponent', () => {
let component: CreateProcessAttachmentComponent;
let fixture: ComponentFixture<CreateProcessAttachmentComponent>;
let element: HTMLElement;
@@ -49,10 +47,7 @@ describe('CreateProcessAttachmentComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(CreateProcessAttachmentComponent);
component = fixture.componentInstance;

View File

@@ -20,7 +20,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { AttachmentComponent } from './create-task-attachment.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { ProcessContentService } from '../form/services/process-content.service';
describe('AttachmentComponent', () => {
@@ -31,7 +30,7 @@ describe('AttachmentComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(AttachmentComponent);
component = fixture.componentInstance;

View File

@@ -21,7 +21,6 @@ import { By } from '@angular/platform-browser';
import { of, throwError } from 'rxjs';
import { ProcessAttachmentListComponent } from './process-attachment-list.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { mockEmittedProcessAttachments, mockProcessAttachments } from '../mock/process/process-attachments.mock';
import { ProcessContentService } from '../form/services/process-content.service';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -37,7 +36,7 @@ describe('ProcessAttachmentListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(ProcessAttachmentListComponent);
component = fixture.componentInstance;
@@ -255,7 +254,7 @@ describe('Custom CustomEmptyTemplateComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
declarations: [CustomEmptyTemplateComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});

View File

@@ -21,7 +21,6 @@ import { By } from '@angular/platform-browser';
import { of, throwError } from 'rxjs';
import { TaskAttachmentListComponent } from './task-attachment-list.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { mockEmittedTaskAttachments, mockTaskAttachments } from '../mock/task/task-attachments.mock';
import { ProcessContentService } from '../form/services/process-content.service';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -29,7 +28,6 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatMenuItemHarness } from '@angular/material/menu/testing';
describe('TaskAttachmentList', () => {
let component: TaskAttachmentListComponent;
let fixture: ComponentFixture<TaskAttachmentListComponent>;
let service: ProcessContentService;
@@ -42,10 +40,7 @@ describe('TaskAttachmentList', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(TaskAttachmentListComponent);
@@ -123,12 +118,14 @@ describe('TaskAttachmentList', () => {
});
it('should show the empty default message when has no custom template', async () => {
getTaskRelatedContentSpy.and.returnValue(of({
size: 0,
total: 0,
start: 0,
data: []
}));
getTaskRelatedContentSpy.and.returnValue(
of({
size: 0,
total: 0,
start: 0,
data: []
})
);
const change = new SimpleChange(null, '123', true);
component.ngOnChanges({ taskId: change });
component.hasCustomTemplate = false;
@@ -180,12 +177,14 @@ describe('TaskAttachmentList', () => {
});
it('should show the empty list component when the attachments list is empty', async () => {
getTaskRelatedContentSpy.and.returnValue(of({
size: 0,
total: 0,
start: 0,
data: []
}));
getTaskRelatedContentSpy.and.returnValue(
of({
size: 0,
total: 0,
start: 0,
data: []
})
);
const change = new SimpleChange(null, '123', true);
component.ngOnChanges({ taskId: change });
@@ -196,19 +195,23 @@ describe('TaskAttachmentList', () => {
});
it('should show the empty list component when the attachments list is empty for completed task', async () => {
getTaskRelatedContentSpy.and.returnValue(of({
size: 0,
total: 0,
start: 0,
data: []
}));
getTaskRelatedContentSpy.and.returnValue(
of({
size: 0,
total: 0,
start: 0,
data: []
})
);
const change = new SimpleChange(null, '123', true);
component.ngOnChanges({ taskId: change });
component.disabled = true;
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('div[adf-empty-list-header]').innerText.trim()).toEqual('ADF_TASK_LIST.ATTACHMENT.EMPTY.HEADER');
expect(fixture.nativeElement.querySelector('div[adf-empty-list-header]').innerText.trim()).toEqual(
'ADF_TASK_LIST.ATTACHMENT.EMPTY.HEADER'
);
});
});
@@ -229,7 +232,6 @@ describe('TaskAttachmentList', () => {
});
describe('change detection', () => {
let change: SimpleChange;
let nullChange: SimpleChange;
@@ -263,7 +265,6 @@ describe('TaskAttachmentList', () => {
});
describe('Delete attachments', () => {
beforeEach(() => {
component.taskId = '123';
fixture.whenStable();
@@ -289,18 +290,14 @@ describe('TaskAttachmentList', () => {
</adf-task-attachment-list>
`
})
class CustomEmptyTemplateComponent {
}
class CustomEmptyTemplateComponent {}
describe('Custom CustomEmptyTemplateComponent', () => {
let fixture: ComponentFixture<CustomEmptyTemplateComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [CustomEmptyTemplateComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});

View File

@@ -19,7 +19,6 @@ import { fakeAsync, TestBed } from '@angular/core/testing';
import { UserProcessModel } from '../models/user-process.model';
import { PeopleProcessService } from './people-process.service';
import { CoreTestingModule } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
declare let jasmine: any;
@@ -42,21 +41,16 @@ const fakeInvolveUserList: UserProcessModel[] = [firstInvolvedUser, secondInvolv
const errorResponse = { error: new Error('Unsuccessful HTTP response') };
describe('PeopleProcessService', () => {
let service: PeopleProcessService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
service = TestBed.inject(PeopleProcessService);
});
describe('when user is logged in', () => {
beforeEach(() => {
jasmine.Ajax.install();
});
@@ -66,36 +60,34 @@ describe('PeopleProcessService', () => {
});
it('should be able to retrieve people to involve in the task', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe(
(users: UserProcessModel[]) => {
expect(users).toBeDefined();
expect(users.length).toBe(2);
expect(users[0].id).toEqual(1);
expect(users[0].email).toEqual('fake-user1@fake.com');
expect(users[0].firstName).toEqual('fakeName1');
expect(users[0].lastName).toEqual('fakeLast1');
});
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users: UserProcessModel[]) => {
expect(users).toBeDefined();
expect(users.length).toBe(2);
expect(users[0].id).toEqual(1);
expect(users[0].email).toEqual('fake-user1@fake.com');
expect(users[0].firstName).toEqual('fakeName1');
expect(users[0].lastName).toEqual('fakeLast1');
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json',
responseText: {data: fakeInvolveUserList}
responseText: { data: fakeInvolveUserList }
});
}));
it('should be able to get people images for people retrieved', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe(
(users: UserProcessModel[]) => {
expect(users).toBeDefined();
expect(users.length).toBe(2);
expect(service.getUserImage(users[0])).toContain('/users/' + users[0].id + '/picture');
expect(service.getUserImage(users[1])).toContain('/users/' + users[1].id + '/picture');
});
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users: UserProcessModel[]) => {
expect(users).toBeDefined();
expect(users.length).toBe(2);
expect(service.getUserImage(users[0])).toContain('/users/' + users[0].id + '/picture');
expect(service.getUserImage(users[1])).toContain('/users/' + users[1].id + '/picture');
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json',
responseText: {data: fakeInvolveUserList}
responseText: { data: fakeInvolveUserList }
});
}));
@@ -106,11 +98,10 @@ describe('PeopleProcessService', () => {
});
it('should return empty list when there are no users to involve', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe(
(users: UserProcessModel[]) => {
expect(users).toBeDefined();
expect(users.length).toBe(0);
});
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users: UserProcessModel[]) => {
expect(users).toBeDefined();
expect(users.length).toBe(0);
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
@@ -120,10 +111,12 @@ describe('PeopleProcessService', () => {
}));
it('getWorkflowUsers catch errors call', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe(() => {
}, (error) => {
expect(error).toEqual(errorResponse);
});
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe(
() => {},
(error) => {
expect(error).toEqual(errorResponse);
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 403
@@ -131,11 +124,10 @@ describe('PeopleProcessService', () => {
}));
it('should be able to involve people in the task', fakeAsync(() => {
service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe(
() => {
expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT');
expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/involve');
});
service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe(() => {
expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT');
expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/involve');
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200
@@ -143,10 +135,12 @@ describe('PeopleProcessService', () => {
}));
it('involveUserWithTask catch errors call', fakeAsync(() => {
service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe(() => {
}, (error) => {
expect(error).toEqual(errorResponse);
});
service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe(
() => {},
(error) => {
expect(error).toEqual(errorResponse);
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 403
@@ -154,11 +148,10 @@ describe('PeopleProcessService', () => {
}));
it('should be able to remove involved people from task', fakeAsync(() => {
service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe(
() => {
expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT');
expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/remove-involved');
});
service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe(() => {
expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT');
expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/remove-involved');
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200
@@ -166,10 +159,12 @@ describe('PeopleProcessService', () => {
}));
it('removeInvolvedUser catch errors call', fakeAsync(() => {
service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe(() => {
}, (error) => {
expect(error).toEqual(errorResponse);
});
service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe(
() => {},
(error) => {
expect(error).toEqual(errorResponse);
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 403

View File

@@ -15,35 +15,32 @@
* limitations under the License.
*/
import {
SimpleChange,
ComponentFactoryResolver,
Injector,
NgModule,
Component,
ViewChild,
DebugElement
} from '@angular/core';
import { SimpleChange, ComponentFactoryResolver, Injector, NgModule, Component, ViewChild, DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { TaskRepresentation } from '@alfresco/js-api';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { Observable, of, throwError } from 'rxjs';
import {
FormFieldModel, FormFieldTypes, FormModel, FormOutcomeEvent, FormOutcomeModel,
FormService, WidgetVisibilityService, ContainerModel, fakeForm
FormFieldModel,
FormFieldTypes,
FormModel,
FormOutcomeEvent,
FormOutcomeModel,
FormService,
WidgetVisibilityService,
ContainerModel,
fakeForm
} from '@alfresco/adf-core';
import{ NodeMetadata, NodesApiService } from '@alfresco/adf-content-services';
import { NodeMetadata, NodesApiService } from '@alfresco/adf-content-services';
import { FormComponent } from './form.component';
import { ProcessFormRenderingService } from './process-form-rendering.service';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { TaskFormService } from './services/task-form.service';
import { TaskService } from './services/task.service';
import { EditorService } from './services/editor.service';
import { ModelService } from './services/model.service';
describe('FormComponent', () => {
let fixture: ComponentFixture<FormComponent>;
let formComponent: FormComponent;
@@ -60,7 +57,7 @@ describe('FormComponent', () => {
selector: 'adf-custom-widget',
template: '<div></div>'
})
// eslint-disable-next-line @angular-eslint/component-class-suffix
// eslint-disable-next-line @angular-eslint/component-class-suffix
class CustomWidget {
typeId = 'CustomWidget';
}
@@ -69,8 +66,7 @@ describe('FormComponent', () => {
declarations: [CustomWidget],
exports: [CustomWidget]
})
class CustomUploadModule {
}
class CustomUploadModule {}
const buildWidget = (type: string, injector: Injector): any => {
const resolver = formRenderingService.getComponentTypeResolver(type);
@@ -85,11 +81,7 @@ describe('FormComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule,
CustomUploadModule
]
imports: [ProcessTestingModule, CustomUploadModule]
});
visibilityService = TestBed.inject(WidgetVisibilityService);
spyOn(visibilityService, 'refreshVisibility').and.stub();
@@ -170,14 +162,14 @@ describe('FormComponent', () => {
it('should enable custom outcome buttons', () => {
const formModel = new FormModel();
formComponent.form = formModel;
const outcome = new FormOutcomeModel(formModel, {id: 'action1', name: 'Action 1'});
const outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' });
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
});
it('should allow controlling [complete] button visibility', () => {
const formModel = new FormModel();
formComponent.form = formModel;
const outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION});
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
formComponent.showSaveButton = true;
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
@@ -190,7 +182,7 @@ describe('FormComponent', () => {
const formModel = new FormModel();
formModel.readOnly = true;
formComponent.form = formModel;
const outcome = new FormOutcomeModel(formModel, {id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION});
const outcome = new FormOutcomeModel(formModel, { id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION });
formComponent.showCompleteButton = true;
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
@@ -200,23 +192,23 @@ describe('FormComponent', () => {
const formModel = new FormModel();
formModel.readOnly = true;
formComponent.form = formModel;
const outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION});
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
formComponent.showSaveButton = true;
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
});
it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => {
const formModel = new FormModel({selectedOutcome: 'custom-outcome'});
const formModel = new FormModel({ selectedOutcome: 'custom-outcome' });
formModel.readOnly = true;
formComponent.form = formModel;
let outcome = new FormOutcomeModel(formModel, {id: '$customoutome', name: 'custom-outcome'});
let outcome = new FormOutcomeModel(formModel, { id: '$customoutome', name: 'custom-outcome' });
formComponent.showCompleteButton = true;
formComponent.showSaveButton = true;
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
outcome = new FormOutcomeModel(formModel, {id: '$customoutome2', name: 'custom-outcome2'});
outcome = new FormOutcomeModel(formModel, { id: '$customoutome2', name: 'custom-outcome2' });
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy();
});
@@ -224,7 +216,7 @@ describe('FormComponent', () => {
const formModel = new FormModel();
formModel.readOnly = false;
formComponent.form = formModel;
const outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.COMPLETE_ACTION});
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION });
formComponent.showCompleteButton = true;
expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy();
@@ -287,7 +279,7 @@ describe('FormComponent', () => {
const taskId = '<task id>';
const change = new SimpleChange(null, taskId, true);
formComponent.ngOnChanges({taskId: change});
formComponent.ngOnChanges({ taskId: change });
expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId);
});
@@ -297,7 +289,7 @@ describe('FormComponent', () => {
const formId = '123';
const change = new SimpleChange(null, formId, true);
formComponent.ngOnChanges({formId: change});
formComponent.ngOnChanges({ formId: change });
expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId);
});
@@ -307,7 +299,7 @@ describe('FormComponent', () => {
const formName = '<form>';
const change = new SimpleChange(null, formName, true);
formComponent.ngOnChanges({formName: change});
formComponent.ngOnChanges({ formName: change });
expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName);
});
@@ -332,7 +324,7 @@ describe('FormComponent', () => {
spyOn(formComponent, 'getFormDefinitionByFormId').and.stub();
spyOn(formComponent, 'getFormDefinitionByFormName').and.stub();
formComponent.ngOnChanges({tag: new SimpleChange(null, 'hello world', true)});
formComponent.ngOnChanges({ tag: new SimpleChange(null, 'hello world', true) });
expect(formComponent.getFormByTaskId).not.toHaveBeenCalled();
expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled();
@@ -342,11 +334,11 @@ describe('FormComponent', () => {
it('should complete form on custom outcome click', () => {
const formModel = new FormModel();
const outcomeName = 'Custom Action';
const outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
const outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
let saved = false;
formComponent.form = formModel;
formComponent.formSaved.subscribe(() => saved = true);
formComponent.formSaved.subscribe(() => (saved = true));
spyOn(formComponent, 'completeTaskForm').and.stub();
const result = formComponent.onOutcomeClicked(outcome);
@@ -397,7 +389,7 @@ describe('FormComponent', () => {
let saved = false;
formComponent.form = formModel;
formComponent.formSaved.subscribe(() => saved = true);
formComponent.formSaved.subscribe(() => (saved = true));
const result = formComponent.onOutcomeClicked(outcome);
expect(result).toBeTruthy();
@@ -407,7 +399,7 @@ describe('FormComponent', () => {
it('should do nothing when clicking outcome for readonly form', () => {
const formModel = new FormModel();
const outcomeName = 'Custom Action';
const outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
const outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
formComponent.form = formModel;
spyOn(formComponent, 'completeTaskForm').and.stub();
@@ -426,7 +418,7 @@ describe('FormComponent', () => {
it('should require loaded form when clicking outcome', () => {
const formModel = new FormModel();
const outcomeName = 'Custom Action';
const outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName});
const outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName });
formComponent.readOnly = false;
formComponent.form = null;
@@ -435,7 +427,7 @@ describe('FormComponent', () => {
it('should not execute unknown system outcome', () => {
const formModel = new FormModel();
const outcome = new FormOutcomeModel(formModel, {id: 'unknown', name: 'Unknown', isSystem: true});
const outcome = new FormOutcomeModel(formModel, { id: 'unknown', name: 'Unknown', isSystem: true });
formComponent.form = formModel;
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
@@ -443,22 +435,25 @@ describe('FormComponent', () => {
it('should require custom action name to complete form', () => {
const formModel = new FormModel();
let outcome = new FormOutcomeModel(formModel, {id: 'custom'});
let outcome = new FormOutcomeModel(formModel, { id: 'custom' });
formComponent.form = formModel;
expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy();
outcome = new FormOutcomeModel(formModel, {id: 'custom', name: 'Custom'});
outcome = new FormOutcomeModel(formModel, { id: 'custom', name: 'Custom' });
spyOn(formComponent, 'completeTaskForm').and.stub();
expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy();
});
it('should fetch and parse form by task id', (done) => {
spyOn(taskService, 'getTask').and.returnValue(of({} as TaskRepresentation));
spyOn(taskFormService, 'getTaskForm').and.callFake((currentTaskId) => new Observable((observer) => {
observer.next({taskId: currentTaskId});
observer.complete();
}));
spyOn(taskFormService, 'getTaskForm').and.callFake(
(currentTaskId) =>
new Observable((observer) => {
observer.next({ taskId: currentTaskId });
observer.complete();
})
);
const taskId = '456';
formComponent.formLoaded.subscribe(() => {
@@ -487,10 +482,13 @@ describe('FormComponent', () => {
it('should apply readonly state when getting form by task id', (done) => {
spyOn(taskService, 'getTask').and.returnValue(of({} as TaskRepresentation));
spyOn(taskFormService, 'getTaskForm').and.callFake((taskId) => new Observable((observer) => {
observer.next({taskId});
observer.complete();
}));
spyOn(taskFormService, 'getTaskForm').and.callFake(
(taskId) =>
new Observable((observer) => {
observer.next({ taskId });
observer.complete();
})
);
formComponent.readOnly = true;
formComponent.getFormByTaskId('123').then(() => {
@@ -501,14 +499,17 @@ describe('FormComponent', () => {
});
it('should fetch and parse form definition by id', () => {
spyOn(editorService, 'getFormDefinitionById').and.callFake((currentFormId) => new Observable((observer) => {
observer.next({id: currentFormId});
observer.complete();
}));
spyOn(editorService, 'getFormDefinitionById').and.callFake(
(currentFormId) =>
new Observable((observer) => {
observer.next({ id: currentFormId });
observer.complete();
})
);
const formId = 456;
let loaded = false;
formComponent.formLoaded.subscribe(() => loaded = true);
formComponent.formLoaded.subscribe(() => (loaded = true));
expect(formComponent.form).toBeUndefined();
formComponent.getFormDefinitionByFormId(formId);
@@ -529,19 +530,25 @@ describe('FormComponent', () => {
});
it('should fetch and parse form definition by form name', () => {
spyOn(modelService, 'getFormDefinitionByName').and.callFake((currentFormName) => new Observable((observer) => {
observer.next(currentFormName);
observer.complete();
}));
spyOn(modelService, 'getFormDefinitionByName').and.callFake(
(currentFormName) =>
new Observable((observer) => {
observer.next(currentFormName);
observer.complete();
})
);
spyOn(editorService, 'getFormDefinitionById').and.callFake((currentFormName) => new Observable((observer) => {
observer.next({name: currentFormName});
observer.complete();
}));
spyOn(editorService, 'getFormDefinitionById').and.callFake(
(currentFormName) =>
new Observable((observer) => {
observer.next({ name: currentFormName });
observer.complete();
})
);
const formName = '<form>';
let loaded = false;
formComponent.formLoaded.subscribe(() => loaded = true);
formComponent.formLoaded.subscribe(() => (loaded = true));
expect(formComponent.form).toBeUndefined();
formComponent.getFormDefinitionByFormName(formName);
@@ -553,10 +560,13 @@ describe('FormComponent', () => {
});
it('should save task form and raise corresponding event', () => {
spyOn(taskFormService, 'saveTaskForm').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(taskFormService, 'saveTaskForm').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
let saved = false;
let savedForm = null;
@@ -567,10 +577,7 @@ describe('FormComponent', () => {
const formModel = new FormModel({
taskId: '123',
fields: [
{id: 'field1'},
{id: 'field2'}
]
fields: [{ id: 'field1' }, { id: 'field2' }]
});
formComponent.form = formModel;
formComponent.saveTaskForm();
@@ -585,7 +592,7 @@ describe('FormComponent', () => {
spyOn(taskFormService, 'saveTaskForm').and.callFake(() => throwError(error));
spyOn(formComponent, 'handleError').and.stub();
formComponent.form = new FormModel({taskId: '123'});
formComponent.form = new FormModel({ taskId: '123' });
formComponent.saveTaskForm();
expect(formComponent.handleError).toHaveBeenCalledWith(error);
@@ -616,21 +623,21 @@ describe('FormComponent', () => {
});
it('should complete form and raise corresponding event', () => {
spyOn(taskFormService, 'completeTaskForm').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(taskFormService, 'completeTaskForm').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
const outcome = 'complete';
let completed = false;
formComponent.formCompleted.subscribe(() => completed = true);
formComponent.formCompleted.subscribe(() => (completed = true));
const formModel = new FormModel({
taskId: '123',
fields: [
{id: 'field1'},
{id: 'field2'}
]
fields: [{ id: 'field1' }, { id: 'field2' }]
});
formComponent.form = formModel;
@@ -647,9 +654,7 @@ describe('FormComponent', () => {
it('should parse form from json', () => {
const form = formComponent.parseForm({
id: 1,
fields: [
{id: 'field1', type: FormFieldTypes.CONTAINER}
]
fields: [{ id: 'field1', type: FormFieldTypes.CONTAINER }]
});
expect(form).toBeDefined();
@@ -661,12 +666,11 @@ describe('FormComponent', () => {
it('should provide outcomes for form definition', () => {
spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough();
const form = formComponent.parseForm({id: 1});
const form = formComponent.parseForm({ id: 1 });
expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form);
});
it('should prevent default outcome execution', () => {
const outcome = new FormOutcomeModel(new FormModel(), {
id: FormComponent.CUSTOM_OUTCOME_ID,
name: 'Custom'
@@ -704,7 +708,6 @@ describe('FormComponent', () => {
});
it('should check visibility only if field with form provided', () => {
formComponent.checkVisibility(null);
expect(visibilityService.refreshVisibility).not.toHaveBeenCalled();
@@ -719,14 +722,12 @@ describe('FormComponent', () => {
it('should load form for ecm node', () => {
const metadata = {};
spyOn(nodeService, 'getNodeMetadata').and.returnValue(
of(new NodeMetadata(metadata, null))
);
spyOn(nodeService, 'getNodeMetadata').and.returnValue(of(new NodeMetadata(metadata, null)));
spyOn(formComponent, 'loadFormFromActiviti').and.stub();
const nodeId = '<id>';
const change = new SimpleChange(null, nodeId, false);
formComponent.ngOnChanges({nodeId: change});
formComponent.ngOnChanges({ nodeId: change });
expect(nodeService.getNodeMetadata).toHaveBeenCalledWith(nodeId);
expect(formComponent.loadFormFromActiviti).toHaveBeenCalled();
@@ -946,10 +947,10 @@ describe('FormComponent', () => {
id: 'option_2',
name: 'test2'
};
formValues.radio = {id: 'option_2', name: 'Option 2'};
formValues.radio = { id: 'option_2', name: 'Option 2' };
const change = new SimpleChange(null, formValues, false);
formComponent.data = formValues;
formComponent.ngOnChanges({data: change});
formComponent.ngOnChanges({ data: change });
formFields = formComponent.form.getFormFields();
dropdownField = formFields.find((field) => field.id === 'dropdownId');
@@ -969,7 +970,7 @@ describe('FormComponent', () => {
formValues.radio = 'option_3';
const change = new SimpleChange(null, formValues, false);
formComponent.data = formValues;
formComponent.ngOnChanges({data: change});
formComponent.ngOnChanges({ data: change });
formFields = formComponent.form.getFormFields();
radioFieldById = formFields.find((field) => field.id === 'radio');
@@ -979,55 +980,38 @@ describe('FormComponent', () => {
@Component({
selector: 'adf-form-with-custom-outcomes',
template: `
<adf-form #adfForm>
<adf-form-custom-outcomes>
<button mat-button id="adf-custom-outcome-1" (click)="onCustomButtonOneClick()">
CUSTOM-BUTTON-1
</button>
<button mat-button id="adf-custom-outcome-2" (click)="onCustomButtonTwoClick()">
CUSTOM-BUTTON-2
</button>
</adf-form-custom-outcomes>
</adf-form>`
template: ` <adf-form #adfForm>
<adf-form-custom-outcomes>
<button mat-button id="adf-custom-outcome-1" (click)="onCustomButtonOneClick()">CUSTOM-BUTTON-1</button>
<button mat-button id="adf-custom-outcome-2" (click)="onCustomButtonTwoClick()">CUSTOM-BUTTON-2</button>
</adf-form-custom-outcomes>
</adf-form>`
})
class FormWithCustomOutComesComponent {
@ViewChild('adfForm', {static: true})
@ViewChild('adfForm', { static: true })
adfForm: FormComponent;
onCustomButtonOneClick() {
}
onCustomButtonOneClick() {}
onCustomButtonTwoClick() {
}
onCustomButtonTwoClick() {}
}
describe('FormWithCustomOutComesComponent', () => {
let fixture: ComponentFixture<FormWithCustomOutComesComponent>;
let customComponent: FormWithCustomOutComesComponent;
let debugElement: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [FormWithCustomOutComesComponent]
});
fixture = TestBed.createComponent(FormWithCustomOutComesComponent);
customComponent = fixture.componentInstance;
debugElement = fixture.debugElement;
const formRepresentation = {
fields: [
{id: 'container1'}
],
outcomes: [
{id: 'outcome-1', name: 'outcome 1'}
]
fields: [{ id: 'container1' }],
outcomes: [{ id: 'outcome-1', name: 'outcome 1' }]
};
const form = new FormModel(formRepresentation);

View File

@@ -31,7 +31,6 @@ import {
} from '@alfresco/adf-core';
import { FormComponent } from './form.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { TaskService } from './services/task.service';
import { TaskFormService } from './services/task-form.service';
import { TaskRepresentation } from '@alfresco/js-api';
@@ -48,7 +47,7 @@ describe('FormComponent UI and visibility', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
fixture = TestBed.createComponent(FormComponent);

View File

@@ -15,10 +15,17 @@
* limitations under the License.
*/
import { AlfrescoApiService, LogService, ExternalContent } from '@alfresco/adf-core';
import { AlfrescoApiService, ExternalContent } from '@alfresco/adf-core';
import { SitesService } from '@alfresco/adf-content-services';
import { Injectable } from '@angular/core';
import { IntegrationAlfrescoOnPremiseApi, Node, RelatedContentRepresentation, ActivitiContentApi, AlfrescoEndpointRepresentation, AlfrescoContentRepresentation } from '@alfresco/js-api';
import {
IntegrationAlfrescoOnPremiseApi,
Node,
RelatedContentRepresentation,
ActivitiContentApi,
AlfrescoEndpointRepresentation,
AlfrescoContentRepresentation
} from '@alfresco/js-api';
import { Observable, from, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
@@ -42,7 +49,7 @@ export class ActivitiContentService {
return this._contentApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService, private sitesService: SitesService) {}
constructor(private apiService: AlfrescoApiService, private sitesService: SitesService) {}
/**
* Returns a list of child nodes below the specified folder
@@ -54,7 +61,7 @@ export class ActivitiContentService {
getAlfrescoNodes(accountId: string, folderId: string): Observable<AlfrescoContentRepresentation[]> {
const accountShortId = accountId.replace('alfresco-', '');
return from(this.integrationAlfrescoOnPremiseApi.getContentInFolder(accountShortId, folderId)).pipe(
map(res => res?.data || []),
map((res) => res?.data || []),
catchError((err) => this.handleError(err))
);
}
@@ -72,7 +79,7 @@ export class ActivitiContentService {
includeAccounts: includeAccount ? includeAccount : true
};
return from(this.integrationAlfrescoOnPremiseApi.getRepositories(opts)).pipe(
map(res => res?.data || []),
map((res) => res?.data || []),
catchError((err) => this.handleError(err))
);
}
@@ -95,7 +102,7 @@ export class ActivitiContentService {
sourceId: node.id + '@' + siteId
})
).pipe(
map(res => res || {}),
map((res) => res || {}),
catchError((err) => this.handleError(err))
);
}
@@ -110,7 +117,7 @@ export class ActivitiContentService {
link: node.isLink
};
return from(this.contentApi.createTemporaryRelatedContent(params)).pipe(
map(res => res || {}),
map((res) => res || {}),
catchError((err) => this.handleError(err))
);
}
@@ -124,7 +131,6 @@ export class ActivitiContentService {
? `${error.status} - ${error.statusText}`
: ActivitiContentService.GENERIC_ERROR_MESSAGE;
}
this.logService.error(errMsg);
return throwError(errMsg);
}
}

View File

@@ -19,7 +19,6 @@ import { Observable } from 'rxjs';
import { FormModel, CoreTestingModule } from '@alfresco/adf-core';
import { EcmModelService } from './ecm-model.service';
import { TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
declare let jasmine: any;
@@ -28,10 +27,7 @@ describe('EcmModelService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
service = TestBed.inject(EcmModelService);
jasmine.Ajax.install();
@@ -55,7 +51,6 @@ describe('EcmModelService', () => {
});
it('Should fetch ECM types', (done) => {
const modelName = 'modelTest';
service.getEcmType(modelName).subscribe(() => {
@@ -71,7 +66,6 @@ describe('EcmModelService', () => {
});
it('Should create ECM types', (done) => {
const typeName = 'typeTest';
service.createEcmType(typeName, EcmModelService.MODEL_NAME, EcmModelService.TYPE_MODEL).subscribe(() => {
@@ -90,7 +84,6 @@ describe('EcmModelService', () => {
});
it('Should create ECM types with a clean and preserve real name in the title', (done) => {
const typeName = 'typeTest:testName@#$*!';
const cleanName = 'testName';
@@ -110,7 +103,6 @@ describe('EcmModelService', () => {
});
it('Should add property to a type', (done) => {
const typeName = 'typeTest';
const formFields = {
values: {
@@ -120,24 +112,29 @@ describe('EcmModelService', () => {
};
service.addPropertyToAType(EcmModelService.MODEL_NAME, typeName, formFields).subscribe(() => {
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('1/cmm/' + EcmModelService.MODEL_NAME + '/types/' + typeName + '?select=props')).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).properties).toEqual([{
name: 'test',
title: 'test',
description: 'test',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
}, {
name: 'test2',
title: 'test2',
description: 'test2',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
}]);
expect(
jasmine.Ajax.requests.mostRecent().url.endsWith('1/cmm/' + EcmModelService.MODEL_NAME + '/types/' + typeName + '?select=props')
).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).properties).toEqual([
{
name: 'test',
title: 'test',
description: 'test',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
},
{
name: 'test2',
title: 'test2',
description: 'test2',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
}
]);
done();
});
@@ -149,7 +146,6 @@ describe('EcmModelService', () => {
});
it('Should add property to a type and clean name type', (done) => {
const typeName = 'typeTest:testName@#$*!';
const cleanName = 'testName';
const formFields = {
@@ -160,24 +156,29 @@ describe('EcmModelService', () => {
};
service.addPropertyToAType(EcmModelService.MODEL_NAME, typeName, formFields).subscribe(() => {
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('1/cmm/' + EcmModelService.MODEL_NAME + '/types/' + cleanName + '?select=props')).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).properties).toEqual([{
name: 'test',
title: 'test',
description: 'test',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
}, {
name: 'test2',
title: 'test2',
description: 'test2',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
}]);
expect(
jasmine.Ajax.requests.mostRecent().url.endsWith('1/cmm/' + EcmModelService.MODEL_NAME + '/types/' + cleanName + '?select=props')
).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).properties).toEqual([
{
name: 'test',
title: 'test',
description: 'test',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
},
{
name: 'test2',
title: 'test2',
description: 'test2',
dataType: 'd:text',
multiValued: false,
mandatory: false,
mandatoryEnforced: false
}
]);
done();
});
@@ -189,7 +190,6 @@ describe('EcmModelService', () => {
});
it('Should create ECM model', (done) => {
service.createEcmModel(EcmModelService.MODEL_NAME, EcmModelService.MODEL_NAMESPACE).subscribe(() => {
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('alfresco/versions/1/cmm')).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).status).toEqual('DRAFT');
@@ -204,9 +204,10 @@ describe('EcmModelService', () => {
});
it('Should activate ECM model', (done) => {
service.activeEcmModel(EcmModelService.MODEL_NAME).subscribe(() => {
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('alfresco/versions/1/cmm/' + EcmModelService.MODEL_NAME + '?select=status')).toBeTruthy();
expect(
jasmine.Ajax.requests.mostRecent().url.endsWith('alfresco/versions/1/cmm/' + EcmModelService.MODEL_NAME + '?select=status')
).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).status).toEqual('ACTIVE');
done();
});
@@ -219,15 +220,21 @@ describe('EcmModelService', () => {
});
it('Should create an ECM type with properties', (done) => {
spyOn(service, 'createEcmType').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'createEcmType').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
spyOn(service, 'addPropertyToAType').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'addPropertyToAType').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
service.createEcmTypeWithProperties('nameType', new FormModel()).subscribe(() => {
expect(service.createEcmType).toHaveBeenCalled();
@@ -237,15 +244,21 @@ describe('EcmModelService', () => {
});
it('Should return the already existing type', (done) => {
spyOn(service, 'searchEcmType').and.callFake(() => new Observable((observer) => {
observer.next({test: 'I-EXIST'});
observer.complete();
}));
spyOn(service, 'searchEcmType').and.callFake(
() =>
new Observable((observer) => {
observer.next({ test: 'I-EXIST' });
observer.complete();
})
);
spyOn(service, 'createEcmTypeWithProperties').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'createEcmTypeWithProperties').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
service.saveFomType('nameType', new FormModel()).subscribe(() => {
expect(service.searchEcmType).toHaveBeenCalled();
@@ -255,15 +268,21 @@ describe('EcmModelService', () => {
});
it('Should create an ECM type with properties if the ecm Type is not defined already', (done) => {
spyOn(service, 'searchEcmType').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'searchEcmType').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
spyOn(service, 'createEcmTypeWithProperties').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'createEcmTypeWithProperties').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
service.saveFomType('nameType', new FormModel()).subscribe(() => {
expect(service.searchEcmType).toHaveBeenCalled();
@@ -273,15 +292,21 @@ describe('EcmModelService', () => {
});
it('Should create an ECM model for the activiti if not defined already', (done) => {
spyOn(service, 'searchActivitiEcmModel').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'searchActivitiEcmModel').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
spyOn(service, 'createActivitiEcmModel').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'createActivitiEcmModel').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
service.createEcmTypeForActivitiForm('nameType', new FormModel()).subscribe(() => {
expect(service.searchActivitiEcmModel).toHaveBeenCalled();
@@ -291,15 +316,21 @@ describe('EcmModelService', () => {
});
it('If a model for the activiti is already define has to save the new type', (done) => {
spyOn(service, 'searchActivitiEcmModel').and.callFake(() => new Observable((observer) => {
observer.next({test: 'I-EXIST'});
observer.complete();
}));
spyOn(service, 'searchActivitiEcmModel').and.callFake(
() =>
new Observable((observer) => {
observer.next({ test: 'I-EXIST' });
observer.complete();
})
);
spyOn(service, 'saveFomType').and.callFake(() => new Observable((observer) => {
observer.next();
observer.complete();
}));
spyOn(service, 'saveFomType').and.callFake(
() =>
new Observable((observer) => {
observer.next();
observer.complete();
})
);
service.createEcmTypeForActivitiForm('nameType', new FormModel()).subscribe(() => {
expect(service.searchActivitiEcmModel).toHaveBeenCalled();

View File

@@ -15,8 +15,8 @@
* limitations under the License.
*/
import { AlfrescoApiService, LogService, FormModel } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { AlfrescoApiService, FormModel } from '@alfresco/adf-core';
import { EventEmitter, Injectable } from '@angular/core';
import { Observable, from } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { CustomModelApi } from '@alfresco/js-api';
@@ -29,13 +29,15 @@ export class EcmModelService {
public static MODEL_NAME: string = 'activitiFormsModel';
public static TYPE_MODEL: string = 'cm:folder';
error = new EventEmitter<any>();
private _customModelApi: CustomModelApi;
get customModelApi(): CustomModelApi {
this._customModelApi = this._customModelApi ?? new CustomModelApi(this.apiService.getInstance());
return this._customModelApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
constructor(private apiService: AlfrescoApiService) {}
public createEcmTypeForActivitiForm(formName: string, form: FormModel): Observable<any> {
return new Observable((observer) => {
@@ -67,11 +69,9 @@ export class EcmModelService {
createActivitiEcmModel(formName: string, form: FormModel): Observable<any> {
return new Observable((observer) => {
this.createEcmModel(EcmModelService.MODEL_NAME, EcmModelService.MODEL_NAMESPACE).subscribe(
(model) => {
this.logService.info('model created', model);
() => {
this.activeEcmModel(EcmModelService.MODEL_NAME).subscribe(
(modelActive) => {
this.logService.info('model active', modelActive);
() => {
this.createEcmTypeWithProperties(formName, form).subscribe((typeCreated) => {
observer.next(typeCreated);
observer.complete();
@@ -89,7 +89,6 @@ export class EcmModelService {
return new Observable((observer) => {
this.searchEcmType(formName, EcmModelService.MODEL_NAME).subscribe(
(ecmType) => {
this.logService.info('custom types', ecmType);
if (!ecmType) {
this.createEcmTypeWithProperties(formName, form).subscribe((typeCreated) => {
observer.next(typeCreated);
@@ -109,10 +108,8 @@ export class EcmModelService {
return new Observable((observer) => {
this.createEcmType(formName, EcmModelService.MODEL_NAME, EcmModelService.TYPE_MODEL).subscribe(
(typeCreated) => {
this.logService.info('type Created', typeCreated);
this.addPropertyToAType(EcmModelService.MODEL_NAME, formName, form).subscribe(
(propertyAdded) => {
this.logService.info('property Added', propertyAdded);
() => {
observer.next(typeCreated);
observer.complete();
},
@@ -206,6 +203,6 @@ export class EcmModelService {
}
private handleError(err: any): any {
this.logService.error(err);
this.error.next(err);
}
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { Observable, from, throwError } from 'rxjs';
import { FormModelsApi } from '@alfresco/js-api';
@@ -26,7 +26,6 @@ import { FormDefinitionModel } from '../model/form-definition.model';
providedIn: 'root'
})
export class EditorService {
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
static GENERIC_ERROR_MESSAGE: string = 'Server error';
@@ -36,8 +35,7 @@ export class EditorService {
return this._editorApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
}
constructor(private apiService: AlfrescoApiService) {}
/**
* Saves a form.
@@ -47,9 +45,7 @@ export class EditorService {
* @returns Data for the saved form
*/
saveForm(formId: number, formModel: FormDefinitionModel): Observable<any> {
return from(
this.editorApi.saveForm(formId, formModel)
);
return from(this.editorApi.saveForm(formId, formModel));
}
/**
@@ -59,11 +55,10 @@ export class EditorService {
* @returns Form definition
*/
getFormDefinitionById(formId: number): Observable<any> {
return from(this.editorApi.getForm(formId))
.pipe(
map(this.toJson),
catchError((err) => this.handleError(err))
);
return from(this.editorApi.getForm(formId)).pipe(
map(this.toJson),
catchError((err) => this.handleError(err))
);
}
/**
@@ -88,11 +83,8 @@ export class EditorService {
private handleError(error: any): Observable<any> {
let errMsg = EditorService.UNKNOWN_ERROR_MESSAGE;
if (error) {
errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : EditorService.GENERIC_ERROR_MESSAGE;
errMsg = error.message ? error.message : error.status ? `${error.status} - ${error.statusText}` : EditorService.GENERIC_ERROR_MESSAGE;
}
this.logService.error(errMsg);
return throwError(errMsg);
}
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { Observable, from, throwError } from 'rxjs';
import { ModelsApi } from '@alfresco/js-api';
@@ -34,7 +34,7 @@ export class ModelService {
return this._modelsApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
constructor(private apiService: AlfrescoApiService) {}
/**
* Create a Form.
@@ -141,7 +141,6 @@ export class ModelService {
if (error) {
errMsg = error.message ? error.message : error.status ? `${error.status} - ${error.statusText}` : ModelService.GENERIC_ERROR_MESSAGE;
}
this.logService.error(errMsg);
return throwError(errMsg);
}
}

View File

@@ -18,7 +18,6 @@
import { TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { ProcessContentService } from './process-content.service';
import { TranslateModule } from '@ngx-translate/core';
import { CoreTestingModule } from '@alfresco/adf-core';
declare let jasmine: any;
@@ -67,10 +66,7 @@ describe('ProcessContentService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
service = TestBed.inject(ProcessContentService);
});
@@ -108,7 +104,7 @@ describe('ProcessContentService', () => {
id: 8,
name: 'fake.zip',
created: 1494595697381,
createdBy: {id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com'},
createdBy: { id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com' },
relatedContent: true,
contentAvailable: true,
link: false,
@@ -121,7 +117,7 @@ describe('ProcessContentService', () => {
id: 9,
name: 'fake.jpg',
created: 1494595655381,
createdBy: {id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com'},
createdBy: { id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com' },
relatedContent: true,
contentAvailable: true,
link: false,

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { AlfrescoApiService, FormFieldOption, LogService } from '@alfresco/adf-core';
import { AlfrescoApiService, FormFieldOption } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { Observable, from, throwError } from 'rxjs';
import { ProcessDefinitionsApi } from '@alfresco/js-api';
@@ -35,7 +35,7 @@ export class ProcessDefinitionService {
return this._processDefinitionsApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
constructor(private apiService: AlfrescoApiService) {}
/**
* Gets values of fields populated by a REST backend using a process ID.
@@ -90,7 +90,6 @@ export class ProcessDefinitionService {
? `${error.status} - ${error.statusText}`
: ProcessDefinitionService.GENERIC_ERROR_MESSAGE;
}
this.logService.error(errMsg);
return throwError(errMsg);
}
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { AlfrescoApiService, FormFieldOption, FormValues, LogService, TaskProcessVariableModel } from '@alfresco/adf-core';
import { AlfrescoApiService, FormFieldOption, FormValues, TaskProcessVariableModel } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { from, Observable, throwError } from 'rxjs';
import { CompleteFormRepresentation, SaveFormRepresentation, TaskFormsApi } from '@alfresco/js-api';
@@ -35,7 +35,7 @@ export class TaskFormService {
return this._taskFormsApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
constructor(private apiService: AlfrescoApiService) {}
/**
* Saves a task form.
@@ -134,7 +134,6 @@ export class TaskFormService {
if (error) {
errMsg = error.message ? error.message : error.status ? `${error.status} - ${error.statusText}` : TaskFormService.GENERIC_ERROR_MESSAGE;
}
this.logService.error(errMsg);
return throwError(errMsg);
}
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { Observable, from, throwError } from 'rxjs';
import { TaskRepresentation, TasksApi } from '@alfresco/js-api';
@@ -25,7 +25,6 @@ import { catchError, map } from 'rxjs/operators';
providedIn: 'root'
})
export class TaskService {
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
static GENERIC_ERROR_MESSAGE: string = 'Server error';
@@ -35,9 +34,7 @@ export class TaskService {
return this._taskApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
}
constructor(private apiService: AlfrescoApiService) {}
/**
* Gets a task.
@@ -46,11 +43,10 @@ export class TaskService {
* @returns Task info
*/
getTask(taskId: string): Observable<TaskRepresentation> {
return from(this.taskApi.getTask(taskId))
.pipe(
map(this.toJson),
catchError((err) => this.handleError(err))
);
return from(this.taskApi.getTask(taskId)).pipe(
map(this.toJson),
catchError((err) => this.handleError(err))
);
}
/**
@@ -75,11 +71,8 @@ export class TaskService {
private handleError(error: any): Observable<any> {
let errMsg = TaskService.UNKNOWN_ERROR_MESSAGE;
if (error) {
errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : TaskService.GENERIC_ERROR_MESSAGE;
errMsg = error.message ? error.message : error.status ? `${error.status} - ${error.statusText}` : TaskService.GENERIC_ERROR_MESSAGE;
}
this.logService.error(errMsg);
return throwError(errMsg);
}
}

View File

@@ -19,14 +19,22 @@ import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import {
startFormDateWidgetMock, startFormDropdownDefinitionMock,
startFormTextDefinitionMock, startMockForm, startMockFormWithTab,
startFormAmountWidgetMock, startFormNumberWidgetMock, startFormRadioButtonWidgetMock,
taskFormSingleUploadMock, taskFormMultipleUploadMock, preselectedSingleNode, preselectedMultipleNodes
startFormDateWidgetMock,
startFormDropdownDefinitionMock,
startFormTextDefinitionMock,
startMockForm,
startMockFormWithTab,
startFormAmountWidgetMock,
startFormNumberWidgetMock,
startFormRadioButtonWidgetMock,
taskFormSingleUploadMock,
taskFormMultipleUploadMock,
preselectedSingleNode,
preselectedMultipleNodes
} from './start-form.component.mock';
import { StartFormComponent } from './start-form.component';
import { WidgetVisibilityService, FormModel, FormOutcomeModel } from '@alfresco/adf-core';
import { TranslateService, TranslateModule } from '@ngx-translate/core';
import { TranslateService } from '@ngx-translate/core';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { ProcessService } from '../process-list/services/process.service';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -36,7 +44,6 @@ import { MatCardHarness } from '@angular/material/card/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
describe('StartFormComponent', () => {
let component: StartFormComponent;
let fixture: ComponentFixture<StartFormComponent>;
let getStartFormSpy: jasmine.Spy;
@@ -50,10 +57,7 @@ describe('StartFormComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
fixture = TestBed.createComponent(StartFormComponent);
@@ -63,9 +67,11 @@ describe('StartFormComponent', () => {
visibilityService = TestBed.inject(WidgetVisibilityService);
translate = TestBed.inject(TranslateService);
getStartFormSpy = spyOn(processService, 'getStartFormDefinition').and.returnValue(of({
processDefinitionName: 'my:process'
}));
getStartFormSpy = spyOn(processService, 'getStartFormDefinition').and.returnValue(
of({
processDefinitionName: 'my:process'
})
);
spyOn(translate, 'instant').and.callFake((key) => key);
spyOn(translate, 'get').and.callFake((key) => of(key));
@@ -122,14 +128,18 @@ describe('StartFormComponent', () => {
});
it('should show outcome buttons by default', () => {
getStartFormSpy.and.returnValue(of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [{
id: 'approve',
name: 'Approve'
}]
}));
getStartFormSpy.and.returnValue(
of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [
{
id: 'approve',
name: 'Approve'
}
]
})
);
component.processDefinitionId = exampleId1;
component.ngOnInit();
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
@@ -138,14 +148,18 @@ describe('StartFormComponent', () => {
});
it('should show outcome buttons if showOutcomeButtons is true', () => {
getStartFormSpy.and.returnValue(of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [{
id: 'approve',
name: 'Approve'
}]
}));
getStartFormSpy.and.returnValue(
of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [
{
id: 'approve',
name: 'Approve'
}
]
})
);
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
@@ -164,7 +178,6 @@ describe('StartFormComponent', () => {
});
describe('Display widgets', () => {
it('should be able to display a textWidget from a process definition', async () => {
getStartFormSpy.and.returnValue(of(startFormTextDefinitionMock));
component.processDefinitionId = exampleId1;
@@ -387,7 +400,6 @@ describe('StartFormComponent', () => {
});
describe('OutCome Actions', () => {
it('should not enable outcome button when model missing', () => {
expect(component.isOutcomeButtonVisible(null, false)).toBeFalsy();
});

View File

@@ -26,11 +26,9 @@ import { AttachFileWidgetDialogComponentData } from './attach-file-widget-dialog
import { of, throwError } from 'rxjs';
import { By } from '@angular/platform-browser';
import { Node, SiteEntry, NodeEntry, SitePaging, SitePagingList } from '@alfresco/js-api';
import { TranslateModule } from '@ngx-translate/core';
import { OidcAuthenticationService } from 'lib/core/src/lib/auth/services/oidc-authentication.service';
describe('AttachFileWidgetDialogComponent', () => {
let widget: AttachFileWidgetDialogComponent;
let fixture: ComponentFixture<AttachFileWidgetDialogComponent>;
const data: AttachFileWidgetDialogComponentData = {
@@ -54,11 +52,7 @@ describe('AttachFileWidgetDialogComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentModule.forRoot(),
ProcessTestingModule
],
imports: [ContentModule.forRoot(), ProcessTestingModule],
providers: [
{ provide: OidcAuthenticationService, useValue: {} },
{ provide: MAT_DIALOG_DATA, useValue: data },
@@ -78,7 +72,9 @@ describe('AttachFileWidgetDialogComponent', () => {
spyOn(documentListService, 'getFolderNode').and.returnValue(of({ entry: { path: { elements: [] } } } as NodeEntry));
spyOn(documentListService, 'getFolder').and.returnValue(throwError('No results for test'));
spyOn(nodeService, 'getNode').and.returnValue(of(new Node({ id: 'fake-node', path: { elements: [{ nodeType: 'st:site', name: 'fake-site'}] } })));
spyOn(nodeService, 'getNode').and.returnValue(
of(new Node({ id: 'fake-node', path: { elements: [{ nodeType: 'st:site', name: 'fake-site' }] } }))
);
spyOn(siteService, 'getSite').and.returnValue(of(fakeSite));
spyOn(siteService, 'getSites').and.returnValue(of(new SitePaging({ list: new SitePagingList({ entries: [] }) })));
@@ -95,7 +91,6 @@ describe('AttachFileWidgetDialogComponent', () => {
});
describe('When is not logged in', () => {
beforeEach(() => {
fixture.detectChanges();
isLogged = false;
@@ -109,7 +104,7 @@ describe('AttachFileWidgetDialogComponent', () => {
});
it('should be able to login', (done) => {
spyOn(basicAlfrescoAuthService, 'login').and.returnValue(of({ type: 'type', ticket: 'ticket'}));
spyOn(basicAlfrescoAuthService, 'login').and.returnValue(of({ type: 'type', ticket: 'ticket' }));
isLogged = true;
let loginButton: HTMLButtonElement = element.querySelector('[data-automation-id="attach-file-dialog-actions-login"]');
const usernameInput: HTMLInputElement = element.querySelector('#username');
@@ -129,10 +124,9 @@ describe('AttachFileWidgetDialogComponent', () => {
done();
});
});
});
});
describe('When is logged in', () => {
let contentNodePanel;
beforeEach(() => {
@@ -154,7 +148,7 @@ describe('AttachFileWidgetDialogComponent', () => {
expect(nodeList[0].isFile).toBeTruthy();
done();
});
const fakeNode: Node = new Node({ id: 'fake', isFile: true});
const fakeNode: Node = new Node({ id: 'fake', isFile: true });
contentNodePanel.componentInstance.select.emit([fakeNode]);
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -164,10 +158,10 @@ describe('AttachFileWidgetDialogComponent', () => {
});
it('[C594015] should not be able to choose a folder', () => {
spyOn(widget,'onSelect');
const fakeFolderNode: Node = new Node({ id: 'fakeFolder', isFile: false, isFolder: true});
spyOn(widget, 'onSelect');
const fakeFolderNode: Node = new Node({ id: 'fakeFolder', isFile: false, isFolder: true });
contentNodePanel.componentInstance.onCurrentSelection([ { entry: fakeFolderNode }]);
contentNodePanel.componentInstance.onCurrentSelection([{ entry: fakeFolderNode }]);
fixture.detectChanges();
const chooseButton: HTMLButtonElement = element.querySelector('[data-automation-id="attach-file-dialog-actions-choose"]');
@@ -184,11 +178,11 @@ describe('AttachFileWidgetDialogComponent', () => {
expect(titleElement).not.toBeNull();
expect(titleElement.nativeElement.innerText).toBe('ATTACH-FILE.ACTIONS.CHOOSE_ITEM');
});
});
});
describe('login only', () => {
beforeEach(() => {
spyOn(basicAlfrescoAuthService, 'login').and.returnValue(of({ type: 'type', ticket: 'ticket'}));
spyOn(basicAlfrescoAuthService, 'login').and.returnValue(of({ type: 'type', ticket: 'ticket' }));
spyOn(matDialogRef, 'close').and.callThrough();
fixture.detectChanges();
widget.data.loginOnly = true;
@@ -223,9 +217,8 @@ describe('AttachFileWidgetDialogComponent', () => {
});
describe('Attach button', () => {
beforeEach(() => {
isLogged = true;
isLogged = true;
});
it('should be disabled by default', () => {

View File

@@ -20,11 +20,9 @@ import { MatDialog } from '@angular/material/dialog';
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
import { Subject, of } from 'rxjs';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { AlfrescoEndpointRepresentation } from '@alfresco/js-api';
describe('AttachFileWidgetDialogService', () => {
let service: AttachFileWidgetDialogService;
let materialDialog: MatDialog;
let spyOnDialogOpen: jasmine.Spy;
@@ -32,10 +30,7 @@ describe('AttachFileWidgetDialogService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
service = TestBed.inject(AttachFileWidgetDialogService);
materialDialog = TestBed.inject(MatDialog);
@@ -61,7 +56,7 @@ describe('AttachFileWidgetDialogService', () => {
});
it('should attach predicate on dialog opening which accepts only file nodes', () => {
const spyOnOpenLoginDialog = spyOn((service as any), 'openLoginDialog');
const spyOnOpenLoginDialog = spyOn(service as any, 'openLoginDialog');
service.openLogin(mockRepository, 'fake-action');

View File

@@ -23,7 +23,6 @@ import { ContentNodeDialogService, ContentModule } from '@alfresco/adf-content-s
import { of } from 'rxjs';
import { Node } from '@alfresco/js-api';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
import { ActivitiContentService } from '../../services/activiti-alfresco.service';
import { ProcessContentService } from '../../services/process-content.service';
@@ -145,7 +144,7 @@ describe('AttachFileWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule, ContentModule.forRoot()]
imports: [ProcessTestingModule, ContentModule.forRoot()]
});
fixture = TestBed.createComponent(AttachFileWidgetComponent);
widget = fixture.componentInstance;

View File

@@ -18,7 +18,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { AppConfigService, AppConfigValues, DownloadService, FormService, LogService, ThumbnailService } from '@alfresco/adf-core';
import { AppConfigService, AppConfigValues, DownloadService, FormService, ThumbnailService } from '@alfresco/adf-core';
import { ContentNodeDialogService, ContentService } from '@alfresco/adf-content-services';
import { AlfrescoEndpointRepresentation, Node, NodeChildAssociation, RelatedContentRepresentation } from '@alfresco/js-api';
import { from, of, Subject, zip } from 'rxjs';
@@ -53,7 +53,6 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
constructor(
public formService: FormService,
private logger: LogService,
public thumbnails: ThumbnailService,
public processContentService: ProcessContentService,
private activitiContentService: ActivitiContentService,
@@ -63,7 +62,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
private downloadService: DownloadService,
private attachDialogService: AttachFileWidgetDialogService
) {
super(formService, logger, thumbnails, processContentService);
super(formService, thumbnails, processContentService);
}
ngOnInit() {
@@ -152,7 +151,6 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
onAttachFileClicked(file: any) {
if (file.isExternal || !file.contentAvailable) {
this.logger.info(`The file ${file.name} comes from an external source and cannot be showed at this moment`);
return;
}
if (this.isTemporaryFile(file)) {
@@ -188,9 +186,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
(blob: Blob) => {
this.downloadService.downloadBlob(blob, file.name);
},
() => {
this.logger.error('Impossible retrieve content for download');
}
() => {}
);
}
}
@@ -248,9 +244,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
res['isExternal'] = isExternal;
filesSaved.push(res);
},
(error) => {
this.logger.error(error);
},
() => {},
() => {
const previousFiles = this.field.value ? this.field.value : [];
this.field.value = [...previousFiles, ...filesSaved];

View File

@@ -23,7 +23,6 @@ import { ContentNodeDialogService, NodesApiService } from '@alfresco/adf-content
import { of } from 'rxjs';
import { Node } from '@alfresco/js-api';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
const fakeNode = {
id: 'fake',
@@ -50,7 +49,7 @@ describe('AttachFolderWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(AttachFolderWidgetComponent);
widget = fixture.componentInstance;

View File

@@ -21,13 +21,11 @@ import { By } from '@angular/platform-browser';
import { ContentLinkModel, CoreTestingModule, DownloadService } from '@alfresco/adf-core';
import { of } from 'rxjs';
import { ContentWidgetComponent } from './content.widget';
import { TranslateModule } from '@ngx-translate/core';
import { ProcessContentService } from '../../services/process-content.service';
declare let jasmine: any;
describe('ContentWidgetComponent', () => {
let component: ContentWidgetComponent;
let fixture: ComponentFixture<ContentWidgetComponent>;
let element: HTMLElement;
@@ -37,33 +35,31 @@ describe('ContentWidgetComponent', () => {
const createFakeImageBlob = () => {
const data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==');
return new Blob([data], {type: 'image/png'});
return new Blob([data], { type: 'image/png' });
};
const createFakePdfBlob = (): Blob => {
const pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
return new Blob([pdfData], {type: 'application/pdf'});
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G'
);
return new Blob([pdfData], { type: 'application/pdf' });
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
downloadService = TestBed.inject(DownloadService);
processContentService = TestBed.inject(ProcessContentService);
@@ -110,7 +106,7 @@ describe('ContentWidgetComponent', () => {
const contentId = 1;
const change = new SimpleChange(null, contentId, true);
component.ngOnChanges({id: change});
component.ngOnChanges({ id: change });
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
@@ -121,7 +117,9 @@ describe('ContentWidgetComponent', () => {
created: 1490354907883,
createdBy: {
id: 2,
firstName: 'admin', lastName: 'admin', email: 'administrator@admin.com'
firstName: 'admin',
lastName: 'admin',
email: 'administrator@admin.com'
},
relatedContent: false,
contentAvailable: true,
@@ -150,7 +148,7 @@ describe('ContentWidgetComponent', () => {
const contentId = 1;
const change = new SimpleChange(null, contentId, true);
component.ngOnChanges({id: change});
component.ngOnChanges({ id: change });
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
@@ -161,7 +159,9 @@ describe('ContentWidgetComponent', () => {
created: 1490354907883,
createdBy: {
id: 2,
firstName: 'admin', lastName: 'admin', email: 'administrator@admin.com'
firstName: 'admin',
lastName: 'admin',
email: 'administrator@admin.com'
},
relatedContent: false,
contentAvailable: true,
@@ -175,10 +175,9 @@ describe('ContentWidgetComponent', () => {
}));
it('should show unsupported preview with unsupported file', fakeAsync(() => {
const contentId = 1;
const change = new SimpleChange(null, contentId, true);
component.ngOnChanges({id: change});
component.ngOnChanges({ id: change });
component.contentLoaded.subscribe(() => {
fixture.detectChanges();
@@ -196,7 +195,9 @@ describe('ContentWidgetComponent', () => {
created: 1490354907883,
createdBy: {
id: 2,
firstName: 'admin', lastName: 'admin', email: 'administrator@admin.com'
firstName: 'admin',
lastName: 'admin',
email: 'administrator@admin.com'
},
relatedContent: false,
contentAvailable: false,
@@ -220,7 +221,9 @@ describe('ContentWidgetComponent', () => {
created: 1490354907883,
createdBy: {
id: 2,
firstName: 'admin', lastName: 'admin', email: 'administrator@admin.com'
firstName: 'admin',
lastName: 'admin',
email: 'administrator@admin.com'
},
relatedContent: false,
contentAvailable: true,
@@ -255,7 +258,9 @@ describe('ContentWidgetComponent', () => {
created: 1490354907883,
createdBy: {
id: 2,
firstName: 'admin', lastName: 'admin', email: 'administrator@admin.com'
firstName: 'admin',
lastName: 'admin',
email: 'administrator@admin.com'
},
relatedContent: false,
contentAvailable: true,

View File

@@ -19,7 +19,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Observable, of } from 'rxjs';
import { WidgetVisibilityService, FormFieldOption, FormFieldModel, FormModel, FormFieldTypes, CoreTestingModule } from '@alfresco/adf-core';
import { DropdownWidgetComponent } from './dropdown.widget';
import { TranslateModule } from '@ngx-translate/core';
import { TaskFormService } from '../../services/task-form.service';
import { ProcessDefinitionService } from '../../services/process-definition.service';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -43,7 +42,7 @@ describe('DropdownWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), CoreTestingModule]
imports: [CoreTestingModule]
});
fixture = TestBed.createComponent(DropdownWidgetComponent);
widget = fixture.componentInstance;

View File

@@ -18,7 +18,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormService, FormFieldOption, WidgetComponent, LogService } from '@alfresco/adf-core';
import { FormService, FormFieldOption, WidgetComponent } from '@alfresco/adf-core';
import { ProcessDefinitionService } from '../../services/process-definition.service';
import { TaskFormService } from '../../services/task-form.service';
@@ -40,12 +40,7 @@ import { TaskFormService } from '../../services/task-form.service';
encapsulation: ViewEncapsulation.None
})
export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
constructor(
public formService: FormService,
public taskFormService: TaskFormService,
public processDefinitionService: ProcessDefinitionService,
private logService: LogService
) {
constructor(public formService: FormService, public taskFormService: TaskFormService, public processDefinitionService: ProcessDefinitionService) {
super(formService);
}
@@ -60,31 +55,27 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
}
getValuesByTaskId() {
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe(
(formFieldOption) => {
const options = [];
if (this.field.emptyOption) {
options.push(this.field.emptyOption);
}
this.field.options = options.concat(formFieldOption || []);
this.field.updateForm();
},
(err) => this.handleError(err)
);
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe((formFieldOption) => {
const options = [];
if (this.field.emptyOption) {
options.push(this.field.emptyOption);
}
this.field.options = options.concat(formFieldOption || []);
this.field.updateForm();
});
}
getValuesByProcessDefinitionId() {
this.processDefinitionService.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id).subscribe(
(formFieldOption) => {
this.processDefinitionService
.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id)
.subscribe((formFieldOption) => {
const options = [];
if (this.field.emptyOption) {
options.push(this.field.emptyOption);
}
this.field.options = options.concat(formFieldOption || []);
this.field.updateForm();
},
(err) => this.handleError(err)
);
});
}
getOptionValue(option: FormFieldOption, fieldValue: string): string {
@@ -97,10 +88,6 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
return optionValue;
}
handleError(error: any) {
this.logService.error(error);
}
isReadOnlyType(): boolean {
return this.field.type === 'readonly';
}

View File

@@ -16,24 +16,16 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {
FormFieldModel,
FormFieldTypes,
FormModel,
LogService,
FormService,
CoreTestingModule
} from '@alfresco/adf-core';
import { FormFieldModel, FormFieldTypes, FormModel, FormService, CoreTestingModule } from '@alfresco/adf-core';
import { DynamicTableColumn } from './editors/models/dynamic-table-column.model';
import { DynamicTableRow } from './editors/models/dynamic-table-row.model';
import { DynamicTableWidgetComponent } from './dynamic-table.widget';
import { DynamicTableModel } from './editors/models/dynamic-table.widget.model';
import { TranslateModule } from '@ngx-translate/core';
const fakeFormField = {
id: 'fake-dynamic-table',
name: 'fake-label',
value: [{1: 1, 2: 2, 3: 4}],
value: [{ 1: 1, 2: 2, 3: 4 }],
required: false,
readOnly: false,
overrideId: false,
@@ -72,23 +64,17 @@ const fakeFormField = {
};
describe('DynamicTableWidgetComponent', () => {
let widget: DynamicTableWidgetComponent;
let fixture: ComponentFixture<DynamicTableWidgetComponent>;
let element: HTMLElement;
let table: DynamicTableModel;
let logService: LogService;
let formService: FormService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
const field = new FormFieldModel(new FormModel());
logService = TestBed.inject(LogService);
formService = TestBed.inject(FormService);
table = new DynamicTableModel(field, formService);
const changeDetectorSpy = jasmine.createSpyObj('cd', ['detectChanges']);
@@ -109,7 +95,7 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should select row on click', () => {
const row = {selected: false} as DynamicTableRow;
const row = { selected: false } as DynamicTableRow;
widget.onRowClicked(row);
expect(row.selected).toBeTruthy();
@@ -117,7 +103,7 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should require table to select clicked row', () => {
const row = {selected: false} as DynamicTableRow;
const row = { selected: false } as DynamicTableRow;
widget.content = null;
widget.onRowClicked(row);
@@ -125,7 +111,7 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should reset selected row', () => {
const row = {selected: false} as DynamicTableRow;
const row = { selected: false } as DynamicTableRow;
widget.content.rows.push(row);
widget.content.selectedRow = row;
expect(widget.content.selectedRow).toBe(row);
@@ -137,7 +123,7 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should check selection', () => {
const row = {selected: false} as DynamicTableRow;
const row = { selected: false } as DynamicTableRow;
widget.content.rows.push(row);
widget.content.selectedRow = row;
expect(widget.hasSelection()).toBeTruthy();
@@ -215,7 +201,7 @@ describe('DynamicTableWidgetComponent', () => {
expect(widget.editMode).toBeFalsy();
expect(widget.editRow).toBeFalsy();
const row = {value: true} as DynamicTableRow;
const row = { value: true } as DynamicTableRow;
widget.content.selectedRow = row;
expect(widget.editSelection()).toBeTruthy();
@@ -225,7 +211,7 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should copy row', () => {
const row = {value: {opt: {key: '1', value: 1}}} as DynamicTableRow;
const row = { value: { opt: { key: '1', value: 1 } } } as DynamicTableRow;
const copy = widget.copyRow(row);
expect(copy.value).toEqual(row.value);
});
@@ -237,14 +223,14 @@ describe('DynamicTableWidgetComponent', () => {
it('should retrieve cell value', () => {
const value = '<value>';
const row = {value: {key: value}} as DynamicTableRow;
const column = {id: 'key'} as DynamicTableColumn;
const row = { value: { key: value } } as DynamicTableRow;
const column = { id: 'key' } as DynamicTableColumn;
expect(widget.getCellValue(row, column)).toBe(value);
});
it('should save changes and add new row', () => {
const row = {isNew: true, value: {key: 'value'}} as DynamicTableRow;
const row = { isNew: true, value: { key: 'value' } } as DynamicTableRow;
widget.editMode = true;
widget.editRow = row;
@@ -257,7 +243,7 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should save changes and update row', () => {
const row = {isNew: false, value: {key: 'value'}} as DynamicTableRow;
const row = { isNew: false, value: { key: 'value' } } as DynamicTableRow;
widget.editMode = true;
widget.editRow = row;
widget.content.selectedRow = row;
@@ -267,7 +253,6 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should require table to save changes', () => {
spyOn(logService, 'error').and.stub();
widget.editMode = true;
widget.content = null;
widget.onSaveChanges();
@@ -313,23 +298,22 @@ describe('DynamicTableWidgetComponent', () => {
});
it('should prepend default currency for amount columns', () => {
const row = {value: {key: '100'}} as DynamicTableRow;
const column = {id: 'key', type: 'Amount'} as DynamicTableColumn;
const row = { value: { key: '100' } } as DynamicTableRow;
const column = { id: 'key', type: 'Amount' } as DynamicTableColumn;
const actual = widget.getCellValue(row, column);
expect(actual).toBe('$ 100');
});
it('should prepend custom currency for amount columns', () => {
const row = {value: {key: '100'}} as DynamicTableRow;
const column = {id: 'key', type: 'Amount', amountCurrency: 'GBP'} as DynamicTableColumn;
const row = { value: { key: '100' } } as DynamicTableRow;
const column = { id: 'key', type: 'Amount', amountCurrency: 'GBP' } as DynamicTableColumn;
const actual = widget.getCellValue(row, column);
expect(actual).toBe('GBP 100');
});
describe('when template is ready', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({taskId: 'fake-task-id'}), fakeFormField);
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), fakeFormField);
widget.field.type = FormFieldTypes.DYNAMIC_TABLE;
fixture.detectChanges();

View File

@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { LogService, WidgetVisibilityService, WidgetComponent, FormService } from '@alfresco/adf-core';
import { WidgetVisibilityService, WidgetComponent, FormService } from '@alfresco/adf-core';
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewEncapsulation } from '@angular/core';
import { DynamicTableColumn } from './editors/models/dynamic-table-column.model';
import { DynamicTableRow } from './editors/models/dynamic-table-row.model';
@@ -41,8 +41,6 @@ import { DynamicTableModel } from './editors/models/dynamic-table.widget.model';
encapsulation: ViewEncapsulation.None
})
export class DynamicTableWidgetComponent extends WidgetComponent implements OnInit {
ERROR_MODEL_NOT_FOUND = 'Table model not found';
content: DynamicTableModel;
editMode: boolean = false;
@@ -54,7 +52,6 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
public formService: FormService,
public elementRef: ElementRef,
private visibilityService: WidgetVisibilityService,
private logService: LogService,
private cd: ChangeDetectorRef
) {
super(formService);
@@ -103,7 +100,7 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
}
}
private isEnterOrSpacePressed(keyCode) {
private isEnterOrSpacePressed(keyCode: number) {
return this.selectArrayCode.indexOf(keyCode) !== -1;
}
@@ -179,8 +176,6 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
this.content.selectedRow.value = this.copyObject(this.editRow.value);
}
this.content.flushValue();
} else {
this.logService.error(this.ERROR_MODEL_NOT_FOUND);
}
this.editMode = false;
this.forceFocusOnAddButton();

View File

@@ -22,7 +22,6 @@ import { DynamicTableRow } from '../models/dynamic-table-row.model';
import { DynamicTableModel } from '../models/dynamic-table.widget.model';
import { DateEditorComponent } from './date.editor';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
describe('DateEditorComponent', () => {
let component: DateEditorComponent;
@@ -33,16 +32,13 @@ describe('DateEditorComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
fixture = TestBed.createComponent(DateEditorComponent);
component = fixture.componentInstance;
row = {value: {date: '1879-03-14T00:00:00.000Z'}} as DynamicTableRow;
column = {id: 'date', type: 'Date'} as DynamicTableColumn;
row = { value: { date: '1879-03-14T00:00:00.000Z' } } as DynamicTableRow;
column = { id: 'date', type: 'Date' } as DynamicTableColumn;
const field = new FormFieldModel(new FormModel());
table = new DynamicTableModel(field, null);
table.rows.push(row);
@@ -54,7 +50,7 @@ describe('DateEditorComponent', () => {
describe('using Date Piker', () => {
it('should update row value on change', () => {
const input = {value: '2016-03-14'} as any;
const input = { value: '2016-03-14' } as any;
component.ngOnInit();
component.onDateChanged(input);
@@ -75,7 +71,6 @@ describe('DateEditorComponent', () => {
});
describe('user manual input', () => {
beforeEach(() => {
spyOn(component, 'onDateChanged').and.callThrough();
spyOn(table, 'flushValue').and.callThrough();

View File

@@ -21,7 +21,6 @@ import { DynamicTableColumn } from '../models/dynamic-table-column.model';
import { DynamicTableRow } from '../models/dynamic-table-row.model';
import { DynamicTableModel } from '../models/dynamic-table.widget.model';
import { DateTimeEditorComponent } from './datetime.editor';
import { TranslateModule } from '@ngx-translate/core';
describe('DateTimeEditorComponent', () => {
let component: DateTimeEditorComponent;
@@ -32,16 +31,13 @@ describe('DateTimeEditorComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
fixture = TestBed.createComponent(DateTimeEditorComponent);
component = fixture.componentInstance;
row = {value: {date: '1879-03-14T00:00:00.000Z'}} as DynamicTableRow;
column = {id: 'datetime', type: 'Datetime'} as DynamicTableColumn;
row = { value: { date: '1879-03-14T00:00:00.000Z' } } as DynamicTableRow;
column = { id: 'datetime', type: 'Datetime' } as DynamicTableColumn;
const field = new FormFieldModel(new FormModel());
table = new DynamicTableModel(field, null);
table.rows.push(row);

View File

@@ -16,8 +16,8 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Observable, of, throwError } from 'rxjs';
import { FormFieldModel, FormModel, FormService, TranslationMock, TranslationService } from '@alfresco/adf-core';
import { Observable, of } from 'rxjs';
import { FormFieldModel, FormModel, FormService } from '@alfresco/adf-core';
import { DynamicTableColumnOption } from '../models/dynamic-table-column-option.model';
import { DynamicTableColumn } from '../models/dynamic-table-column.model';
import { DynamicTableRow } from '../models/dynamic-table-row.model';
@@ -29,12 +29,10 @@ import { MatSelectHarness } from '@angular/material/select/testing';
import { FormModule } from '../../../../form.module';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { TranslateModule } from '@ngx-translate/core';
import { CommonModule } from '@angular/common';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MatSelectModule } from '@angular/material/select';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatOptionModule } from '@angular/material/core';
import { ProcessTestingModule } from '../../../../../testing/process.testing.module';
describe('DropdownEditorComponent', () => {
let fixture: ComponentFixture<DropdownEditorComponent>;
@@ -50,16 +48,7 @@ describe('DropdownEditorComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CommonModule,
NoopAnimationsModule,
MatFormFieldModule,
MatSelectModule,
MatOptionModule,
FormModule
],
providers: [{ provide: TranslationService, useClass: TranslationMock }]
imports: [ProcessTestingModule, MatFormFieldModule, MatSelectModule, MatOptionModule, FormModule]
});
formService = TestBed.inject(FormService);
taskFormService = TestBed.inject(TaskFormService);
@@ -166,31 +155,6 @@ describe('DropdownEditorComponent', () => {
expect(component.value).toBe(row.value[column.id]);
});
it('should handle REST error getting options with task id', () => {
column.optionType = 'rest';
const error = 'error';
spyOn(taskFormService, 'getRestFieldValuesColumn').and.returnValue(throwError(error));
spyOn(component, 'handleError').and.stub();
component.ngOnInit();
expect(component.handleError).toHaveBeenCalledWith(error);
});
it('should handle REST error getting option with processDefinitionId', () => {
column.optionType = 'rest';
const procForm = new FormModel({ processDefinitionId: '<process-definition-id>' });
const procTable = new DynamicTableModel(new FormFieldModel(procForm, { id: '<field-id>' }), formService);
component.table = procTable;
const error = 'error';
spyOn(processDefinitionService, 'getRestFieldValuesColumnByProcessId').and.returnValue(throwError(error));
spyOn(component, 'handleError').and.stub();
fixture.detectChanges();
expect(component.handleError).toHaveBeenCalledWith(error);
});
it('should update row on value change', () => {
const event = { value: 'two' };
component.onValueChanged(row, column, event);

View File

@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { LogService, FormService, FormFieldModel } from '@alfresco/adf-core';
import { FormService, FormFieldModel } from '@alfresco/adf-core';
import { Component, Input, OnInit } from '@angular/core';
import { DynamicTableColumnOption } from '../models/dynamic-table-column-option.model';
import { DynamicTableColumn } from '../models/dynamic-table-column.model';
@@ -47,8 +47,7 @@ export class DropdownEditorComponent implements OnInit {
constructor(
public formService: FormService,
private taskFormService: TaskFormService,
private processDefinitionService: ProcessDefinitionService,
private logService: LogService
private processDefinitionService: ProcessDefinitionService
) {}
ngOnInit() {
@@ -68,25 +67,21 @@ export class DropdownEditorComponent implements OnInit {
}
getValuesByTaskId(field: FormFieldModel) {
this.taskFormService.getRestFieldValuesColumn(field.form.taskId, field.id, this.column.id).subscribe(
(dynamicTableColumnOption) => {
this.column.options = dynamicTableColumnOption || [];
this.options = this.column.options;
this.value = this.table.getCellValue(this.row, this.column);
},
(err) => this.handleError(err)
);
this.taskFormService.getRestFieldValuesColumn(field.form.taskId, field.id, this.column.id).subscribe((dynamicTableColumnOption) => {
this.column.options = dynamicTableColumnOption || [];
this.options = this.column.options;
this.value = this.table.getCellValue(this.row, this.column);
});
}
getValuesByProcessDefinitionId(field: FormFieldModel) {
this.processDefinitionService.getRestFieldValuesColumnByProcessId(field.form.processDefinitionId, field.id, this.column.id).subscribe(
(dynamicTableColumnOption) => {
this.processDefinitionService
.getRestFieldValuesColumnByProcessId(field.form.processDefinitionId, field.id, this.column.id)
.subscribe((dynamicTableColumnOption) => {
this.column.options = dynamicTableColumnOption || [];
this.options = this.column.options;
this.value = this.table.getCellValue(this.row, this.column);
},
(err) => this.handleError(err)
);
});
}
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) {
@@ -94,8 +89,4 @@ export class DropdownEditorComponent implements OnInit {
value = column.options.find((opt) => opt.name === value);
row.value[column.id] = value;
}
handleError(error: any) {
this.logService.error(error);
}
}

View File

@@ -15,17 +15,11 @@
* limitations under the License.
*/
import {
FormFieldModel,
FormModel,
FormService,
CoreTestingModule
} from '@alfresco/adf-core';
import { FormFieldModel, FormModel, FormService, CoreTestingModule } from '@alfresco/adf-core';
import { DynamicTableColumn } from '../models/dynamic-table-column.model';
import { DynamicTableRow } from '../models/dynamic-table-row.model';
import { DynamicTableModel } from '../models/dynamic-table.widget.model';
import { RowEditorComponent } from './row.editor';
import { TranslateModule } from '@ngx-translate/core';
import { DynamicRowValidationSummary } from '../models/dynamic-row-validation-summary.model';
import { TestBed } from '@angular/core/testing';
@@ -34,10 +28,7 @@ describe('RowEditorComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
component = new RowEditorComponent();
const field = new FormFieldModel(new FormModel());
@@ -68,9 +59,7 @@ describe('RowEditorComponent', () => {
});
it('should emit [save] event', (done) => {
spyOn(component.table, 'validateRow').and.returnValue(
new DynamicRowValidationSummary({isValid: true, message: null})
);
spyOn(component.table, 'validateRow').and.returnValue(new DynamicRowValidationSummary({ isValid: true, message: null }));
component.save.subscribe((event) => {
expect(event.table).toBe(component.table);
expect(event.row).toBe(component.row);
@@ -81,11 +70,9 @@ describe('RowEditorComponent', () => {
});
it('should not emit [save] event for invalid row', () => {
spyOn(component.table, 'validateRow').and.returnValue(
new DynamicRowValidationSummary({isValid: false, message: 'error'})
);
spyOn(component.table, 'validateRow').and.returnValue(new DynamicRowValidationSummary({ isValid: false, message: 'error' }));
let raised = false;
component.save.subscribe(() => raised = true);
component.save.subscribe(() => (raised = true));
component.onSaveChanges();
expect(raised).toBeFalsy();
});

View File

@@ -16,16 +16,9 @@
*/
import { of, timer } from 'rxjs';
import {
FormFieldModel,
FormModel,
GroupModel,
CoreTestingModule,
FormFieldTypes
} from '@alfresco/adf-core';
import { FormFieldModel, FormModel, GroupModel, CoreTestingModule, FormFieldTypes } from '@alfresco/adf-core';
import { FunctionalGroupWidgetComponent } from './functional-group.widget';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { PeopleProcessService } from '../../../common/services/people-process.service';
describe('FunctionalGroupWidgetComponent', () => {
@@ -35,16 +28,13 @@ describe('FunctionalGroupWidgetComponent', () => {
let getWorkflowGroupsSpy: jasmine.Spy;
let element: HTMLElement;
const groups: GroupModel[] = [
{id: '1', name: 'group 1'},
{id: '2', name: 'group 2'}
{ id: '1', name: 'group 1' },
{ id: '2', name: 'group 2' }
];
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
peopleProcessService = TestBed.inject(PeopleProcessService);
getWorkflowGroupsSpy = spyOn(peopleProcessService, 'getWorkflowGroups').and.returnValue(of([]));
@@ -79,7 +69,7 @@ describe('FunctionalGroupWidgetComponent', () => {
};
it('should setup text from underlying field on init', async () => {
const group: GroupModel = {name: 'group-1'};
const group: GroupModel = { name: 'group-1' };
component.field.value = group;
component.ngOnInit();
@@ -96,7 +86,7 @@ describe('FunctionalGroupWidgetComponent', () => {
component.ngOnInit();
expect(component.groupId).toBeUndefined();
component.field.params = {restrictWithGroup: {id: '<id>'}};
component.field.params = { restrictWithGroup: { id: '<id>' } };
component.ngOnInit();
expect(component.groupId).toBe('<id>');
});
@@ -122,7 +112,7 @@ describe('FunctionalGroupWidgetComponent', () => {
await typeIntoInput('group');
const options: HTMLElement[] = Array.from(document.querySelectorAll('[id="adf-group-label-name"]'));
expect(options.map(option => option.innerText)).toEqual(['group 1', 'group 2']);
expect(options.map((option) => option.innerText)).toEqual(['group 1', 'group 2']);
expect(getWorkflowGroupsSpy).toHaveBeenCalledWith('group', 'parentGroup');
});
@@ -133,7 +123,7 @@ describe('FunctionalGroupWidgetComponent', () => {
await typeIntoInput('group');
let options: HTMLElement[] = Array.from(document.querySelectorAll('[id="adf-group-label-name"]'));
expect(options.map(option => option.innerText)).toEqual(['group 1', 'group 2']);
expect(options.map((option) => option.innerText)).toEqual(['group 1', 'group 2']);
await typeIntoInput('unknown-group');
@@ -154,9 +144,8 @@ describe('FunctionalGroupWidgetComponent', () => {
});
describe('when is required', () => {
beforeEach(() => {
component.field = new FormFieldModel(new FormModel({taskId: '<id>'}), {
component.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.FUNCTIONAL_GROUP,
required: true
});

View File

@@ -17,20 +17,14 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
FormFieldTypes,
FormFieldModel,
FormModel,
CoreTestingModule
} from '@alfresco/adf-core';
import { FormFieldTypes, FormFieldModel, FormModel, CoreTestingModule } from '@alfresco/adf-core';
import { Observable, of } from 'rxjs';
import { PeopleWidgetComponent } from './people.widget';
import { TranslateService, TranslateModule } from '@ngx-translate/core';
import { TranslateService } from '@ngx-translate/core';
import { PeopleProcessService } from '../../../common/services/people-process.service';
import { UserProcessModel } from '../../../common/models/user-process.model';
describe('PeopleWidgetComponent', () => {
let widget: PeopleWidgetComponent;
let fixture: ComponentFixture<PeopleWidgetComponent>;
let element: HTMLElement;
@@ -39,10 +33,7 @@ describe('PeopleWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
fixture = TestBed.createComponent(PeopleWidgetComponent);
peopleProcessService = TestBed.inject(PeopleProcessService);
@@ -70,12 +61,12 @@ describe('PeopleWidgetComponent', () => {
});
it('should skip first name for display name', () => {
const model = new UserProcessModel({firstName: null, lastName: 'Doe'});
const model = new UserProcessModel({ firstName: null, lastName: 'Doe' });
expect(widget.getDisplayName(model)).toBe('Doe');
});
it('should skip last name for display name', () => {
const model = new UserProcessModel({firstName: 'John', lastName: null});
const model = new UserProcessModel({ firstName: 'John', lastName: null });
expect(widget.getDisplayName(model)).toBe('John');
});
@@ -127,7 +118,7 @@ describe('PeopleWidgetComponent', () => {
widget.ngOnInit();
expect(widget.groupId).toBeUndefined();
widget.field.params = {restrictWithGroup: {id: '<id>'}};
widget.field.params = { restrictWithGroup: { id: '<id>' } };
widget.ngOnInit();
expect(widget.groupId).toBe('<id>');
});
@@ -157,9 +148,8 @@ describe('PeopleWidgetComponent', () => {
});
describe('when is required', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({taskId: '<id>'}), {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.PEOPLE,
required: true
});
@@ -189,17 +179,19 @@ describe('PeopleWidgetComponent', () => {
});
describe('when template is ready', () => {
const fakeUserResult = [
{id: 1001, firstName: 'Test01', lastName: 'Test01', email: 'test'},
{id: 1002, firstName: 'Test02', lastName: 'Test02', email: 'test2'}];
{ id: 1001, firstName: 'Test01', lastName: 'Test01', email: 'test' },
{ id: 1002, firstName: 'Test02', lastName: 'Test02', email: 'test2' }
];
beforeEach(() => {
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(new Observable((observer) => {
observer.next(fakeUserResult);
observer.complete();
}));
widget.field = new FormFieldModel(new FormModel({taskId: 'fake-task-id'}), {
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(
new Observable((observer) => {
observer.next(fakeUserResult);
observer.complete();
})
);
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
id: 'people-id',
name: 'people-name',
type: FormFieldTypes.PEOPLE,

View File

@@ -22,7 +22,6 @@ import { RadioButtonsWidgetComponent } from './radio-buttons.widget';
import { MatIconModule } from '@angular/material/icon';
import { MatRadioModule } from '@angular/material/radio';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { TaskFormService } from '../../services/task-form.service';
import { ProcessDefinitionService } from '../../services/process-definition.service';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -38,13 +37,13 @@ describe('RadioButtonsWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), CoreTestingModule, MatRadioModule, FormsModule, MatIconModule]
imports: [CoreTestingModule, MatRadioModule, FormsModule, MatIconModule]
});
taskFormService = TestBed.inject(TaskFormService);
processDefinitionService = TestBed.inject(ProcessDefinitionService);
formService = new FormService();
widget = new RadioButtonsWidgetComponent(formService, taskFormService, processDefinitionService, null);
widget = new RadioButtonsWidgetComponent(formService, taskFormService, processDefinitionService);
widget.field = new FormFieldModel(new FormModel(), { restUrl: '<url>' });
});

View File

@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { LogService, FormService, WidgetComponent } from '@alfresco/adf-core';
import { FormService, WidgetComponent } from '@alfresco/adf-core';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { TaskFormService } from '../../services/task-form.service';
import { ProcessDefinitionService } from '../../services/process-definition.service';
@@ -43,8 +43,7 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
constructor(
public formService: FormService,
private taskFormService: TaskFormService,
private processDefinitionService: ProcessDefinitionService,
private logService: LogService
private processDefinitionService: ProcessDefinitionService
) {
super(formService);
}
@@ -60,31 +59,23 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
}
getOptionsByTaskId() {
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe(
(formFieldOption) => {
this.field.options = formFieldOption || [];
this.field.updateForm();
},
(err) => this.handleError(err)
);
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe((formFieldOption) => {
this.field.options = formFieldOption || [];
this.field.updateForm();
});
}
getOptionsByProcessDefinitionId() {
this.processDefinitionService.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id).subscribe(
(formFieldOption) => {
this.processDefinitionService
.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id)
.subscribe((formFieldOption) => {
this.field.options = formFieldOption || [];
this.field.updateForm();
},
(err) => this.handleError(err)
);
});
}
onOptionClick(optionSelected: any) {
this.field.value = optionSelected;
this.fieldChanged.emit(this.field);
}
handleError(error: any) {
this.logService.error(error);
}
}

View File

@@ -16,24 +16,16 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Observable, of, throwError } from 'rxjs';
import { Observable, of } from 'rxjs';
import { By } from '@angular/platform-browser';
import {
FormService,
FormFieldOption,
FormFieldTypes,
FormFieldModel,
FormModel,
CoreTestingModule
} from '@alfresco/adf-core';
import { FormService, FormFieldOption, FormFieldTypes, FormFieldModel, FormModel, CoreTestingModule } from '@alfresco/adf-core';
import { TypeaheadWidgetComponent } from './typeahead.widget';
import { TranslateService, TranslateModule } from '@ngx-translate/core';
import { TranslateService } from '@ngx-translate/core';
import { TaskFormService } from '../../services/task-form.service';
import { ProcessDefinitionService } from '../../services/process-definition.service';
describe('TypeaheadWidgetComponent', () => {
let formService: FormService;
let widget: TypeaheadWidgetComponent;
let translationService: TranslateService;
@@ -42,10 +34,7 @@ describe('TypeaheadWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
translationService = TestBed.inject(TranslateService);
taskFormService = TestBed.inject(TaskFormService);
@@ -54,8 +43,8 @@ describe('TypeaheadWidgetComponent', () => {
spyOn(translationService, 'get').and.callFake((key) => of(key));
formService = new FormService();
widget = new TypeaheadWidgetComponent(formService, taskFormService, processDefinitionService, null);
widget.field = new FormFieldModel(new FormModel({taskId: 'task-id'}));
widget = new TypeaheadWidgetComponent(formService, taskFormService, processDefinitionService);
widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }));
widget.field.restUrl = 'whateverURL';
});
@@ -72,10 +61,12 @@ describe('TypeaheadWidgetComponent', () => {
restUrl: 'whateverURL'
});
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(new Observable((observer) => {
observer.next(null);
observer.complete();
}));
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
new Observable((observer) => {
observer.next(null);
observer.complete();
})
);
widget.ngOnInit();
expect(taskFormService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId);
});
@@ -97,58 +88,16 @@ describe('TypeaheadWidgetComponent', () => {
expect(taskFormService.getRestFieldValues).not.toHaveBeenCalled();
});
it('should handle error when requesting fields with task id', () => {
const taskId = '<form-id>';
const fieldId = '<field-id>';
const form = new FormModel({
taskId
});
widget.field = new FormFieldModel(form, {
id: fieldId,
restUrl: 'whateverURL'
});
const err = 'Error';
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(throwError(err));
spyOn(widget, 'handleError').and.stub();
widget.ngOnInit();
expect(taskFormService.getRestFieldValues).toHaveBeenCalled();
expect(widget.handleError).toHaveBeenCalledWith(err);
});
it('should handle error when requesting fields with process id', () => {
const processDefinitionId = '<process-id>';
const fieldId = '<field-id>';
const form = new FormModel({
processDefinitionId
});
widget.field = new FormFieldModel(form, {
id: fieldId,
restUrl: 'whateverURL'
});
const err = 'Error';
spyOn(processDefinitionService, 'getRestFieldValuesByProcessId').and.returnValue(throwError(err));
spyOn(widget, 'handleError').and.stub();
widget.ngOnInit();
expect(processDefinitionService.getRestFieldValuesByProcessId).toHaveBeenCalled();
expect(widget.handleError).toHaveBeenCalledWith(err);
});
it('should setup initial value', () => {
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(new Observable((observer) => {
observer.next([
{id: '1', name: 'One'},
{id: '2', name: 'Two'}
]);
observer.complete();
}));
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
new Observable((observer) => {
observer.next([
{ id: '1', name: 'One' },
{ id: '2', name: 'Two' }
]);
observer.complete();
})
);
widget.field.value = '2';
widget.field.restUrl = 'whateverURL';
widget.ngOnInit();
@@ -158,13 +107,15 @@ describe('TypeaheadWidgetComponent', () => {
});
it('should not setup initial value due to missing option', () => {
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(new Observable((observer) => {
observer.next([
{id: '1', name: 'One'},
{id: '2', name: 'Two'}
]);
observer.complete();
}));
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
new Observable((observer) => {
observer.next([
{ id: '1', name: 'One' },
{ id: '2', name: 'Two' }
]);
observer.complete();
})
);
widget.field.value = '3';
widget.field.restUrl = 'whateverURL';
@@ -176,24 +127,28 @@ describe('TypeaheadWidgetComponent', () => {
it('should setup field options on load', () => {
const options: FormFieldOption[] = [
{id: '1', name: 'One'},
{id: '2', name: 'Two'}
{ id: '1', name: 'One' },
{ id: '2', name: 'Two' }
];
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(new Observable((observer) => {
observer.next(options);
observer.complete();
}));
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
new Observable((observer) => {
observer.next(options);
observer.complete();
})
);
widget.ngOnInit();
expect(widget.field.options).toEqual(options);
});
it('should update form upon options setup', () => {
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(new Observable((observer) => {
observer.next([]);
observer.complete();
}));
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
new Observable((observer) => {
observer.next([]);
observer.complete();
})
);
widget.field.restUrl = 'whateverURL';
spyOn(widget.field, 'updateForm').and.callThrough();
@@ -203,8 +158,8 @@ describe('TypeaheadWidgetComponent', () => {
it('should get filtered options', () => {
const options: FormFieldOption[] = [
{id: '1', name: 'Item one'},
{id: '2', name: 'Item two'}
{ id: '1', name: 'Item one' },
{ id: '2', name: 'Item two' }
];
widget.field.options = options;
widget.value = 'tw';
@@ -216,8 +171,8 @@ describe('TypeaheadWidgetComponent', () => {
it('should be case insensitive when filtering options', () => {
const options: FormFieldOption[] = [
{id: '1', name: 'Item one'},
{id: '2', name: 'iTEM TWo'}
{ id: '1', name: 'Item one' },
{ id: '2', name: 'iTEM TWo' }
];
widget.field.options = options;
widget.value = 'tW';
@@ -232,13 +187,17 @@ describe('TypeaheadWidgetComponent', () => {
let fixture: ComponentFixture<TypeaheadWidgetComponent>;
let element: HTMLElement;
let stubProcessDefinitionService;
const fakeOptionList: FormFieldOption[] = [{
id: '1',
name: 'Fake Name 1 '
}, {
id: '2',
name: 'Fake Name 2'
}, {id: '3', name: 'Fake Name 3'}];
const fakeOptionList: FormFieldOption[] = [
{
id: '1',
name: 'Fake Name 1 '
},
{
id: '2',
name: 'Fake Name 2'
},
{ id: '3', name: 'Fake Name 3' }
];
beforeEach(() => {
fixture = TestBed.createComponent(TypeaheadWidgetComponent);
@@ -252,15 +211,16 @@ describe('TypeaheadWidgetComponent', () => {
});
describe('and typeahead is in readonly mode', () => {
it('should show typeahead value with input disabled', async () => {
typeaheadWidgetComponent.field = new FormFieldModel(
new FormModel({processVariables: [{name: 'typeahead-id_LABEL', value: 'FakeProcessValue'}]}), {
new FormModel({ processVariables: [{ name: 'typeahead-id_LABEL', value: 'FakeProcessValue' }] }),
{
id: 'typeahead-id',
name: 'typeahead-name',
type: 'readonly',
params: {field: {id: 'typeahead-id', name: 'typeahead-name', type: 'typeahead'}}
});
params: { field: { id: 'typeahead-id', name: 'typeahead-name', type: 'typeahead' } }
}
);
fixture.detectChanges();
await fixture.whenStable();
@@ -274,14 +234,12 @@ describe('TypeaheadWidgetComponent', () => {
afterEach(() => {
fixture.destroy();
});
});
describe('and typeahead is populated via taskId', () => {
beforeEach(() => {
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(of(fakeOptionList));
typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({taskId: 'fake-task-id'}), {
typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
id: 'typeahead-id',
name: 'typeahead-name',
type: FormFieldTypes.TYPEAHEAD,
@@ -355,17 +313,16 @@ describe('TypeaheadWidgetComponent', () => {
});
describe('and typeahead is populated via processDefinitionId', () => {
beforeEach(() => {
stubProcessDefinitionService = fixture.debugElement.injector.get(ProcessDefinitionService);
spyOn(stubProcessDefinitionService, 'getRestFieldValuesByProcessId').and.returnValue(of(fakeOptionList));
typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({processDefinitionId: 'fake-process-id'}), {
typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
id: 'typeahead-id',
name: 'typeahead-name',
type: FormFieldTypes.TYPEAHEAD,
readOnly: 'false'
});
typeaheadWidgetComponent.field.emptyOption = {id: 'empty', name: 'Choose one...'};
typeaheadWidgetComponent.field.emptyOption = { id: 'empty', name: 'Choose one...' };
typeaheadWidgetComponent.field.isVisible = true;
fixture.detectChanges();
});

View File

@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { LogService, FormService, FormFieldOption, WidgetComponent } from '@alfresco/adf-core';
import { FormService, FormFieldOption, WidgetComponent } from '@alfresco/adf-core';
import { ENTER, ESCAPE } from '@angular/cdk/keycodes';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { TaskFormService } from '../../services/task-form.service';
@@ -49,8 +49,7 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
constructor(
public formService: FormService,
private taskFormService: TaskFormService,
private processDefinitionService: ProcessDefinitionService,
private logService: LogService
private processDefinitionService: ProcessDefinitionService
) {
super(formService);
}
@@ -67,30 +66,26 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
}
getValuesByTaskId() {
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe(
(formFieldOption) => {
const options = formFieldOption || [];
this.field.options = options;
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe((formFieldOption) => {
const options = formFieldOption || [];
this.field.options = options;
const fieldValue = this.field.value;
if (fieldValue) {
const toSelect = options.find(
(item) => item.id === fieldValue || item.name.toLocaleLowerCase() === fieldValue.toLocaleLowerCase()
);
if (toSelect) {
this.value = toSelect.name;
}
const fieldValue = this.field.value;
if (fieldValue) {
const toSelect = options.find((item) => item.id === fieldValue || item.name.toLocaleLowerCase() === fieldValue.toLocaleLowerCase());
if (toSelect) {
this.value = toSelect.name;
}
this.onFieldChanged(this.field);
this.field.updateForm();
},
(err) => this.handleError(err)
);
}
this.onFieldChanged(this.field);
this.field.updateForm();
});
}
getValuesByProcessDefinitionId() {
this.processDefinitionService.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id).subscribe(
(formFieldOption) => {
this.processDefinitionService
.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id)
.subscribe((formFieldOption) => {
const options = formFieldOption || [];
this.field.options = options;
@@ -103,9 +98,7 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
}
this.onFieldChanged(this.field);
this.field.updateForm();
},
(err) => this.handleError(err)
);
});
}
getOptions(): FormFieldOption[] {
@@ -155,10 +148,6 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
return this.value !== null && this.value !== undefined;
}
handleError(error: any) {
this.logService.error(error);
}
isReadOnlyType(): boolean {
return this.field.type === 'readonly';
}

View File

@@ -19,15 +19,8 @@ import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { of } from 'rxjs';
import {
FormService,
FormFieldTypes,
FormModel,
FormFieldModel,
CoreTestingModule
} from '@alfresco/adf-core';
import { FormService, FormFieldTypes, FormModel, FormFieldModel, CoreTestingModule } from '@alfresco/adf-core';
import { UploadWidgetComponent } from './upload.widget';
import { TranslateModule } from '@ngx-translate/core';
import { RelatedContentRepresentation } from '@alfresco/js-api';
import { ProcessContentService } from '../../services/process-content.service';
@@ -35,7 +28,7 @@ const fakePngAnswer = new RelatedContentRepresentation({
id: 1155,
name: 'a_png_file.png',
created: new Date('2017-07-25T17:17:37.099Z'),
createdBy: {id: 1001, firstName: 'Admin', lastName: 'admin', email: 'admin'},
createdBy: { id: 1001, firstName: 'Admin', lastName: 'admin', email: 'admin' },
relatedContent: false,
contentAvailable: true,
link: false,
@@ -49,7 +42,7 @@ const fakeJpgAnswer = new RelatedContentRepresentation({
id: 1156,
name: 'a_jpg_file.jpg',
created: new Date('2017-07-25T17:17:37.118Z'),
createdBy: {id: 1001, firstName: 'Admin', lastName: 'admin', email: 'admin'},
createdBy: { id: 1001, firstName: 'Admin', lastName: 'admin', email: 'admin' },
relatedContent: false,
contentAvailable: true,
link: false,
@@ -60,12 +53,11 @@ const fakeJpgAnswer = new RelatedContentRepresentation({
});
describe('UploadWidgetComponent', () => {
const fakeCreationFile = (name: string, id: string | number) => ({
id,
name,
created: '2017-07-25T17:17:37.118Z',
createdBy: {id: 1001, firstName: 'Admin', lastName: 'admin', email: 'admin'},
createdBy: { id: 1001, firstName: 'Admin', lastName: 'admin', email: 'admin' },
relatedContent: false,
contentAvailable: true,
link: false,
@@ -77,15 +69,12 @@ describe('UploadWidgetComponent', () => {
let contentService: ProcessContentService;
const filePngFake = new File(['fakePng'], 'file-fake.png', {type: 'image/png'});
const filJpgFake = new File(['fakeJpg'], 'file-fake.jpg', {type: 'image/jpg'});
const filePngFake = new File(['fakePng'], 'file-fake.png', { type: 'image/png' });
const filJpgFake = new File(['fakeJpg'], 'file-fake.jpg', { type: 'image/jpg' });
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
});
@@ -111,9 +100,7 @@ describe('UploadWidgetComponent', () => {
uploadWidgetComponent.field = new FormFieldModel(null, {
type: FormFieldTypes.UPLOAD,
value: [
{name: encodedFileName}
]
value: [{ name: encodedFileName }]
});
uploadWidgetComponent.ngOnInit();
@@ -130,9 +117,7 @@ describe('UploadWidgetComponent', () => {
it('should reset field value', () => {
uploadWidgetComponent.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [
{name: 'filename'}
]
value: [{ name: 'filename' }]
});
uploadWidgetComponent.removeFile(uploadWidgetComponent.field.value[0]);
@@ -142,7 +127,7 @@ describe('UploadWidgetComponent', () => {
});
beforeEach(() => {
uploadWidgetComponent.field = new FormFieldModel(new FormModel({taskId: 'fake-upload-id'}), {
uploadWidgetComponent.field = new FormFieldModel(new FormModel({ taskId: 'fake-upload-id' }), {
id: 'upload-id',
name: 'upload-name',
value: '',
@@ -199,11 +184,10 @@ describe('UploadWidgetComponent', () => {
await fixture.whenStable();
const inputDebugElement = fixture.debugElement.query(By.css('#upload-id'));
inputDebugElement.triggerEventHandler('change', {target: {files: [filJpgFake]}});
inputDebugElement.triggerEventHandler('change', { target: { files: [filJpgFake] } });
const filesList = fixture.debugElement.query(By.css('#file-1156'));
expect(filesList).toBeDefined();
});
it('should update the form after deleted a file', async () => {
@@ -217,7 +201,7 @@ describe('UploadWidgetComponent', () => {
await fixture.whenStable();
const inputDebugElement = fixture.debugElement.query(By.css('#upload-id'));
inputDebugElement.triggerEventHandler('change', {target: {files: [filePngFake, filJpgFake]}});
inputDebugElement.triggerEventHandler('change', { target: { files: [filePngFake, filJpgFake] } });
fixture.detectChanges();
await fixture.whenStable();
@@ -247,7 +231,7 @@ describe('UploadWidgetComponent', () => {
await fixture.whenStable();
const inputDebugElement = fixture.debugElement.query(By.css('#upload-id'));
inputDebugElement.triggerEventHandler('change', {target: {files: [filePngFake, filJpgFake]}});
inputDebugElement.triggerEventHandler('change', { target: { files: [filePngFake, filJpgFake] } });
fixture.detectChanges();
await fixture.whenStable();
@@ -398,7 +382,6 @@ describe('UploadWidgetComponent', () => {
const fileJpegIcon = debugElement.query(By.css('#file-1156-icon'));
fileJpegIcon.nativeElement.dispatchEvent(new MouseEvent('click'));
});
});
});
});

View File

@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { LogService, ThumbnailService, FormService, ContentLinkModel, WidgetComponent } from '@alfresco/adf-core';
import { ThumbnailService, FormService, ContentLinkModel, WidgetComponent } from '@alfresco/adf-core';
import { Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { Observable, from } from 'rxjs';
import { ProcessContentService } from '../../services/process-content.service';
@@ -49,12 +49,7 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
@ViewChild('uploadFiles')
fileInput: ElementRef;
constructor(
public formService: FormService,
private logService: LogService,
private thumbnailService: ThumbnailService,
public processContentService: ProcessContentService
) {
constructor(public formService: FormService, private thumbnailService: ThumbnailService, public processContentService: ProcessContentService) {
super(formService);
}
@@ -84,7 +79,7 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
.pipe(mergeMap((file) => this.uploadRawContent(file)))
.subscribe(
(res) => filesSaved.push(res),
() => this.logService.error('Error uploading file. See console output for more details.'),
() => {},
() => {
this.field.value = filesSaved;
this.field.json.value = filesSaved;
@@ -97,7 +92,6 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
private uploadRawContent(file): Observable<any> {
return this.processContentService.createTemporaryRawRelatedContent(file).pipe(
map((response: any) => {
this.logService.info(response);
response.contentBlob = file;
return response;
})
@@ -137,14 +131,9 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
if (file.isTypeImage() || file.isTypePdf()) {
fetch = this.processContentService.getFileRawContent(file.id);
}
fetch.subscribe(
(blob: Blob) => {
file.contentBlob = blob;
this.formService.formContentClicked.next(file);
},
() => {
this.logService.error('Unable to send event for file ' + file.name);
}
);
fetch.subscribe((blob: Blob) => {
file.contentBlob = blob;
this.formService.formContentClicked.next(file);
});
}
}

View File

@@ -17,7 +17,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DataRowActionEvent, DataRowEvent, ObjectDataRow } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
import { UserEventModel } from '../../../task-list/models/user-event.model';
import { PeopleListComponent } from './people-list.component';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
@@ -31,16 +30,12 @@ const fakeUser: UserProcessModel = new UserProcessModel({
});
describe('PeopleListComponent', () => {
let peopleListComponent: PeopleListComponent;
let fixture: ComponentFixture<PeopleListComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(PeopleListComponent);
peopleListComponent = fixture.componentInstance;

View File

@@ -20,10 +20,8 @@ import { DebugElement } from '@angular/core';
import { PeopleSearchFieldComponent } from './people-search-field.component';
import { By } from '@angular/platform-browser';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
describe('PeopleSearchFieldComponent', () => {
let component: PeopleSearchFieldComponent;
let fixture: ComponentFixture<PeopleSearchFieldComponent>;
let debug: DebugElement;
@@ -31,10 +29,7 @@ describe('PeopleSearchFieldComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(PeopleSearchFieldComponent);
component = fixture.componentInstance;

View File

@@ -17,7 +17,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core';
import { PeopleSearchComponent } from './people-search.component';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { UserProcessModel } from '../../../common/models/user-process.model';
@@ -37,7 +36,6 @@ const fakeSecondUser: UserProcessModel = new UserProcessModel({
});
describe('PeopleSearchComponent', () => {
let peopleSearchComponent: PeopleSearchComponent;
let fixture: ComponentFixture<PeopleSearchComponent>;
let element: HTMLElement;
@@ -46,10 +44,7 @@ describe('PeopleSearchComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(PeopleSearchComponent);
peopleSearchComponent = fixture.componentInstance;

View File

@@ -16,25 +16,19 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LogService } from '@alfresco/adf-core';
import { PeopleSelectorComponent } from './people-selector.component';
import { of, throwError } from 'rxjs';
import { of } from 'rxjs';
import { By } from '@angular/platform-browser';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { PeopleProcessService } from '../../../common/services/people-process.service';
describe('PeopleSelectorComponent', () => {
let component: PeopleSelectorComponent;
let fixture: ComponentFixture<PeopleSelectorComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(PeopleSelectorComponent);
component = fixture.componentInstance;
@@ -45,7 +39,7 @@ describe('PeopleSelectorComponent', () => {
expect(component.placeholder).toBe('ADF_TASK_LIST.PEOPLE.ASSIGNEE');
});
it('should have the selected user\'s details as placeholder if one is set', () => {
it('should have the selected user details as placeholder if one is set', () => {
component.selectedUser = {
firstName: 'Max',
lastName: 'CaulField'
@@ -53,7 +47,7 @@ describe('PeopleSelectorComponent', () => {
expect(component.placeholder).toBe('Max CaulField');
});
it('should call the PeopleProcessService\'s getWorkflowUsers method on search', () => {
it('should call the PeopleProcessService getWorkflowUsers method on search', () => {
const peopleProcessService = TestBed.inject(PeopleProcessService);
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([]));
@@ -62,27 +56,13 @@ describe('PeopleSelectorComponent', () => {
expect(peopleProcessService.getWorkflowUsers).toHaveBeenCalledWith(undefined, 'Chloe Price');
});
it('should log error on getWorkflowUsers error', () => {
const peopleProcessService = TestBed.inject(PeopleProcessService);
const logService = TestBed.inject(LogService);
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(throwError(new Error()));
spyOn(logService, 'error');
component.performSearch('Chloe Price')
.subscribe((people) => {
expect(people).toEqual([]);
expect(logService.error).toHaveBeenCalledWith('getWorkflowUsers threw error');
});
});
it('should emit an event with the selected users id when userSelected method is invoked', (done) => {
component.peopleIdChange.subscribe((userId) => {
expect(userId).toBe(789);
done();
});
component.userSelected({id: 789});
component.userSelected({ id: 789 });
});
it('should emit an event with undefined when reset button is clicked', (done) => {

View File

@@ -17,7 +17,7 @@
import { Component, ViewChild, ViewEncapsulation, EventEmitter, Input, Output } from '@angular/core';
import { PerformSearchCallback } from '../../interfaces/perform-search-callback.interface';
import { LogService, TranslationService } from '@alfresco/adf-core';
import { TranslationService } from '@alfresco/adf-core';
import { PeopleSearchFieldComponent } from '../people-search-field/people-search-field.component';
import { getDisplayUser } from '../../helpers/get-display-user';
import { Observable, of } from 'rxjs';
@@ -49,14 +49,14 @@ export class PeopleSelectorComponent {
selectedUser: UserProcessModel;
defaultPlaceholder: string;
constructor(private peopleProcessService: PeopleProcessService, private logService: LogService, private translationService: TranslationService) {
constructor(private peopleProcessService: PeopleProcessService, private translationService: TranslationService) {
this.peopleIdChange = new EventEmitter();
this.performSearch = this.searchUser.bind(this);
this.defaultPlaceholder = this.translationService.instant(DEFAULT_ASSIGNEE_PLACEHOLDER);
}
searchUser(searchWord: string): Observable<any | UserProcessModel[]> {
return this.peopleProcessService.getWorkflowUsers(undefined, searchWord).pipe(catchError(this.onSearchUserError.bind(this)));
return this.peopleProcessService.getWorkflowUsers(undefined, searchWord).pipe(catchError(() => of([])));
}
userSelected(user: UserProcessModel): void {
@@ -67,11 +67,6 @@ export class PeopleSelectorComponent {
this.updateUserSelection(undefined);
}
private onSearchUserError(): Observable<UserProcessModel[]> {
this.logService.error('getWorkflowUsers threw error');
return of([]);
}
private updateUserSelection(user: UserProcessModel): void {
this.selectedUser = user;
this.peopleIdChange.emit(user?.id);

View File

@@ -16,13 +16,9 @@
*/
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { LogService } from '@alfresco/adf-core';
import { PeopleComponent } from './people.component';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { throwError } from 'rxjs';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { PeopleProcessService } from '../../../common/services/people-process.service';
declare let jasmine: any;
@@ -41,23 +37,15 @@ const fakeSecondUser = new UserProcessModel({
});
describe('PeopleComponent', () => {
let activitiPeopleComponent: PeopleComponent;
let fixture: ComponentFixture<PeopleComponent>;
let element: HTMLElement;
const userArray = [fakeUser, fakeSecondUser];
let logService: LogService;
let peopleProcessService: PeopleProcessService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
logService = TestBed.inject(LogService);
peopleProcessService = TestBed.inject(PeopleProcessService);
fixture = TestBed.createComponent(PeopleComponent);
activitiPeopleComponent = fixture.componentInstance;
element = fixture.nativeElement;
@@ -88,7 +76,6 @@ describe('PeopleComponent', () => {
});
describe('when there are involved people', () => {
beforeEach(() => {
activitiPeopleComponent.taskId = 'fake-task-id';
activitiPeopleComponent.people.push(...userArray);
@@ -117,13 +104,12 @@ describe('PeopleComponent', () => {
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200
});
fixture.whenStable()
.then(() => {
fixture.detectChanges();
const gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(1);
});
fixture.whenStable().then(() => {
fixture.detectChanges();
const gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(1);
});
}));
it('should involve people', fakeAsync(() => {
@@ -131,13 +117,12 @@ describe('PeopleComponent', () => {
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200
});
fixture.whenStable()
.then(() => {
fixture.detectChanges();
const gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(3);
});
fixture.whenStable().then(() => {
fixture.detectChanges();
const gatewayElement: any = element.querySelector('#assignment-people-list .adf-datatable-body');
expect(gatewayElement).not.toBeNull();
expect(gatewayElement.children.length).toBe(3);
});
}));
it('should return an observable with user search results', (done) => {
@@ -154,17 +139,20 @@ describe('PeopleComponent', () => {
status: 200,
contentType: 'json',
responseText: {
data: [{
id: 1,
firstName: 'fake-test-1',
lastName: 'fake-last-1',
email: 'fake-test-1@test.com'
}, {
id: 2,
firstName: 'fake-test-2',
lastName: 'fake-last-2',
email: 'fake-test-2@test.com'
}]
data: [
{
id: 1,
firstName: 'fake-test-1',
lastName: 'fake-last-1',
email: 'fake-test-1@test.com'
},
{
id: 2,
firstName: 'fake-test-2',
lastName: 'fake-last-2',
email: 'fake-test-2@test.com'
}
]
}
});
});
@@ -184,7 +172,6 @@ describe('PeopleComponent', () => {
});
describe('when there are errors on service call', () => {
beforeEach(() => {
jasmine.Ajax.install();
activitiPeopleComponent.people.push(...userArray);
@@ -195,16 +182,6 @@ describe('PeopleComponent', () => {
jasmine.Ajax.uninstall();
});
it('should log error message when search fails', async () => {
const logServiceErrorSpy = spyOn(logService, 'error');
const mockThrownError = { error: 'Could not load users'};
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(throwError(mockThrownError));
activitiPeopleComponent.searchUser('fake-search');
expect(logServiceErrorSpy).toHaveBeenCalledWith(mockThrownError);
});
it('should not remove user if remove involved user fail', async () => {
activitiPeopleComponent.removeInvolvedUser(fakeUser);
jasmine.Ajax.requests.mostRecent().respondWith({

View File

@@ -15,8 +15,7 @@
* limitations under the License.
*/
import { LogService } from '@alfresco/adf-core';
import { Component, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { Observable, Observer } from 'rxjs';
import { UserEventModel } from '../../../task-list/models/user-event.model';
import { PeopleSearchComponent } from '../people-search/people-search.component';
@@ -31,7 +30,6 @@ import { PeopleProcessService } from '../../../common/services/people-process.se
encapsulation: ViewEncapsulation.None
})
export class PeopleComponent {
/** The array of User objects to display. */
@Input()
people: UserProcessModel[] = [];
@@ -47,16 +45,16 @@ export class PeopleComponent {
@ViewChild('peopleSearch')
peopleSearch: PeopleSearchComponent;
@Output()
error = new EventEmitter<any>();
showAssignment: boolean = false;
peopleSearch$: Observable<UserProcessModel[]>;
private peopleSearchObserver: Observer<UserProcessModel[]>;
constructor(private logService: LogService, public peopleProcessService: PeopleProcessService) {
this.peopleSearch$ = new Observable<UserProcessModel[]>((observer) => this.peopleSearchObserver = observer)
.pipe(
share()
);
constructor(public peopleProcessService: PeopleProcessService) {
this.peopleSearch$ = new Observable<UserProcessModel[]>((observer) => (this.peopleSearchObserver = observer)).pipe(share());
}
involveUserAndCloseSearch() {
@@ -72,42 +70,41 @@ export class PeopleComponent {
}
searchUser(searchedWord: string) {
this.peopleProcessService.getWorkflowUsers(this.taskId, searchedWord)
.subscribe((users) => {
this.peopleProcessService.getWorkflowUsers(this.taskId, searchedWord).subscribe(
(users) => {
this.peopleSearchObserver.next(users);
}, (error) => this.logService.error(error));
},
(error) => this.error.emit(error)
);
}
involveUser(user: UserProcessModel) {
if (user?.id) {
this.peopleProcessService
.involveUserWithTask(this.taskId, user.id.toString())
.subscribe(
() => this.people = [...this.people, user],
() => this.logService.error('Impossible to involve user with task')
);
this.peopleProcessService.involveUserWithTask(this.taskId, user.id.toString()).subscribe(
() => (this.people = [...this.people, user]),
() => this.error.emit('Impossible to involve user with task')
);
}
}
removeInvolvedUser(user: UserProcessModel) {
this.peopleProcessService
.removeInvolvedUser(this.taskId, user.id.toString())
.subscribe(
() => {
this.people = this.people.filter(involvedUser => involvedUser.id !== user.id);
},
() => this.logService.error('Impossible to remove involved user from task'));
this.peopleProcessService.removeInvolvedUser(this.taskId, user.id.toString()).subscribe(
() => {
this.people = this.people.filter((involvedUser) => involvedUser.id !== user.id);
},
() => this.error.emit('Impossible to remove involved user from task')
);
}
getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string {
firstName = (firstName !== null ? firstName : '');
lastName = (lastName !== null ? lastName : '');
firstName = firstName !== null ? firstName : '';
lastName = lastName !== null ? lastName : '';
return firstName + delimiter + lastName;
}
getInitialUserName(firstName: string, lastName: string) {
firstName = (firstName !== null && firstName !== '' ? firstName[0] : '');
lastName = (lastName !== null && lastName !== '' ? lastName[0] : '');
firstName = firstName !== null && firstName !== '' ? firstName[0] : '';
lastName = lastName !== null && lastName !== '' ? lastName[0] : '';
return this.getDisplayUser(firstName, lastName, '');
}

View File

@@ -17,12 +17,10 @@
import { TestBed } from '@angular/core/testing';
import { ProcessNamePipe } from './process-name.pipe';
import { TranslateModule } from '@ngx-translate/core';
import { LocalizedDatePipe, CoreTestingModule } from '@alfresco/adf-core';
import { ProcessInstance } from '../process-list';
describe('ProcessNamePipe', () => {
let processNamePipe: ProcessNamePipe;
const defaultName = 'default-name';
const datetimeIdentifier = '%{datetime}';
@@ -32,14 +30,11 @@ describe('ProcessNamePipe', () => {
const nameWithProcessDefinitionIdentifier = `${defaultName} - ${processDefinitionIdentifier}`;
const nameWithDatetimeIdentifier = `${defaultName} - ${datetimeIdentifier}`;
const nameWithAllIdentifiers = `${defaultName} ${processDefinitionIdentifier} - ${datetimeIdentifier}`;
const fakeProcessInstanceDetails = new ProcessInstance({ processDefinitionName: 'fake-process-def-name'});
const fakeProcessInstanceDetails = new ProcessInstance({ processDefinitionName: 'fake-process-def-name' });
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
const localizedDatePipe = TestBed.inject(LocalizedDatePipe);
processNamePipe = new ProcessNamePipe(localizedDatePipe);
@@ -71,5 +66,4 @@ describe('ProcessNamePipe', () => {
const transformResult = processNamePipe.transform(nameWithProcessDefinitionIdentifier);
expect(transformResult).toEqual(`${defaultName} - `);
});
});

View File

@@ -22,10 +22,8 @@ import { CommentProcessService } from './services/comment-process.service';
import { ProcessCommentsComponent } from './process-comments.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { mockProcessInstanceComments } from '../mock/process/process-comments.mock';
import { TranslateModule } from '@ngx-translate/core';
describe('ProcessCommentsComponent', () => {
let component: ProcessCommentsComponent;
let fixture: ComponentFixture<ProcessCommentsComponent>;
let getCommentsSpy: jasmine.Spy;
@@ -33,10 +31,7 @@ describe('ProcessCommentsComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(ProcessCommentsComponent);
component = fixture.componentInstance;
@@ -121,7 +116,7 @@ describe('ProcessCommentsComponent', () => {
expect(fixture.nativeElement.querySelector('#comment-input')).toBeNull();
});
it('should display comments input when the process isn\'t readonly', async () => {
it('should display comments input when the process is not readonly', async () => {
component.readOnly = false;
fixture.detectChanges();

View File

@@ -21,19 +21,20 @@ import { of, throwError } from 'rxjs';
import { ProcessService } from './../services/process.service';
import { DownloadService } from '@alfresco/adf-core';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-basic-button',
template: `
<button id="auditButton"
template: ` <button
id="auditButton"
adf-process-audit
[process-id]="1234"
[download]="download"
[fileName]="fileName"
[format]="format"
(error)="onAuditError($event)"
(clicked)="onAuditClick($event)">My button
(clicked)="onAuditClick($event)"
>
My button
</button>`
})
class BasicButtonComponent {
@@ -46,7 +47,6 @@ class BasicButtonComponent {
}
describe('ProcessAuditDirective', () => {
let fixture: ComponentFixture<BasicButtonComponent>;
let component: BasicButtonComponent;
let service: ProcessService;
@@ -54,32 +54,28 @@ describe('ProcessAuditDirective', () => {
const createFakePdfBlob = (): Blob => {
const pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
return new Blob([pdfData], {type: 'application/pdf'});
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G'
);
return new Blob([pdfData], { type: 'application/pdf' });
};
const blob = createFakePdfBlob();
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
declarations: [
BasicButtonComponent
]
imports: [ProcessTestingModule],
declarations: [BasicButtonComponent]
});
fixture = TestBed.createComponent(BasicButtonComponent);
component = fixture.componentInstance;
@@ -145,22 +141,40 @@ describe('ProcessAuditDirective', () => {
component.format = 'json';
component.download = true;
const auditJson = {
processInstanceId: 42516, processInstanceName: 'Fake Process - August 3rd 2017',
processDefinitionName: 'Claim Approval Process', processDefinitionVersion: 1, processInstanceStartTime: 'Thu Aug 03 15:32:47 UTC 2017', processInstanceEndTime: null,
processInstanceId: 42516,
processInstanceName: 'Fake Process - August 3rd 2017',
processDefinitionName: 'Claim Approval Process',
processDefinitionVersion: 1,
processInstanceStartTime: 'Thu Aug 03 15:32:47 UTC 2017',
processInstanceEndTime: null,
// eslint-disable-next-line @cspell/spellchecker
processInstanceDurationInMillis: null,
processInstanceInitiator: 'MyName MyLastname',
entries: [{
index: 1, type: 'startForm',
selectedOutcome: null, formData: [{
fieldName: 'User Name',
fieldId: 'username', value: 'dsassd'
},
{ fieldName: 'Claim Amount', fieldId: 'claimamount', value: '22' }], taskName: null, taskAssignee: null, activityId: null,
// eslint-disable-next-line @cspell/spellchecker
activityName: null, activityType: null, startTime: null, endTime: null, durationInMillis: null
}
], decisionInfo: { calculatedValues: [], appliedRules: [] }
entries: [
{
index: 1,
type: 'startForm',
selectedOutcome: null,
formData: [
{
fieldName: 'User Name',
fieldId: 'username',
value: 'dsassd'
},
{ fieldName: 'Claim Amount', fieldId: 'claimamount', value: '22' }
],
taskName: null,
taskAssignee: null,
activityId: null,
// eslint-disable-next-line @cspell/spellchecker
activityName: null,
activityType: null,
startTime: null,
endTime: null,
durationInMillis: null
}
],
decisionInfo: { calculatedValues: [], appliedRules: [] }
};
spyOn(service, 'fetchProcessAuditJsonById').and.returnValue(of(auditJson));
spyOn(component, 'onAuditClick').and.callThrough();

View File

@@ -25,13 +25,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { fakeProcessFilters } from '../../mock/process/process-filters.mock';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { NavigationStart, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
describe('ProcessFiltersComponent', () => {
let filterList: ProcessFiltersComponent;
let fixture: ComponentFixture<ProcessFiltersComponent>;
let processFilterService: ProcessFilterService;
@@ -40,11 +38,7 @@ describe('ProcessFiltersComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule,
RouterTestingModule
],
imports: [ProcessTestingModule, RouterTestingModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
fixture = TestBed.createComponent(ProcessFiltersComponent);
@@ -64,7 +58,7 @@ describe('ProcessFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastValue: ProcessInstanceFilterRepresentation[];
filterList.success.subscribe((res) => lastValue = res);
filterList.success.subscribe((res) => (lastValue = res));
spyOn(filterList, 'getFiltersByAppId').and.callThrough();
@@ -106,7 +100,7 @@ describe('ProcessFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastValue: UserProcessInstanceFilterRepresentation;
filterList.filterSelected.subscribe((filter) => lastValue = filter);
filterList.filterSelected.subscribe((filter) => (lastValue = filter));
filterList.ngOnChanges({ appId: change });
fixture.detectChanges();
@@ -115,7 +109,7 @@ describe('ProcessFiltersComponent', () => {
expect(lastValue.name).toEqual('FakeCompleted');
});
it('should filterClicked emit when a filter is clicked from the UI', async () => {
it('should filterClicked emit when a filter is clicked from the UI', async () => {
filterList.filters = fakeProcessFilters;
spyOn(filterList.filterClicked, 'emit');
@@ -163,7 +157,7 @@ describe('ProcessFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastValue: any;
filterList.error.subscribe((err) => lastValue = err);
filterList.error.subscribe((err) => (lastValue = err));
filterList.ngOnChanges({ appId: change });
@@ -177,7 +171,7 @@ describe('ProcessFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastValue: any;
filterList.error.subscribe((err) => lastValue = err);
filterList.error.subscribe((err) => (lastValue = err));
filterList.ngOnChanges({ appName: change });
@@ -193,7 +187,7 @@ describe('ProcessFiltersComponent', () => {
});
let lastValue: UserProcessInstanceFilterRepresentation;
filterList.filterClicked.subscribe((filter) => lastValue = filter);
filterList.filterClicked.subscribe((filter) => (lastValue = filter));
filterList.selectFilter(currentFilter);
expect(lastValue).toBeDefined();

View File

@@ -27,13 +27,11 @@ import { ProcessService } from './../services/process.service';
import { ProcessInstanceDetailsComponent } from './process-instance-details.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { FormModule } from '../../form';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCardHarness } from '@angular/material/card/testing';
describe('ProcessInstanceDetailsComponent', () => {
let service: ProcessService;
let component: ProcessInstanceDetailsComponent;
let fixture: ComponentFixture<ProcessInstanceDetailsComponent>;
@@ -42,12 +40,7 @@ describe('ProcessInstanceDetailsComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule,
FormModule,
TaskListModule
],
imports: [ProcessTestingModule, FormModule, TaskListModule],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(ProcessInstanceDetailsComponent);
@@ -124,7 +117,6 @@ describe('ProcessInstanceDetailsComponent', () => {
});
describe('change detection', () => {
const change = new SimpleChange('123', '456', true);
const nullChange = new SimpleChange('123', null, true);

View File

@@ -15,7 +15,6 @@
* limitations under the License.
*/
import { LogService } from '@alfresco/adf-core';
import { DatePipe } from '@angular/common';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild } from '@angular/core';
import { TaskDetailsEvent } from '../../task-list';
@@ -67,7 +66,7 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
processInstanceDetails: ProcessInstance;
constructor(private activitiProcess: ProcessService, private logService: LogService) {}
constructor(private activitiProcess: ProcessService) {}
ngOnChanges(changes: SimpleChanges) {
const processInstanceId = changes['processInstanceId'];
@@ -130,8 +129,8 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
const datePipe = new DatePipe('en-US');
try {
return datePipe.transform(value, format);
} catch (err) {
this.logService.error(`ProcessListInstanceHeader: error parsing date ${value} to format ${format}`);
} catch {
return undefined;
}
}

View File

@@ -21,20 +21,15 @@ import { ProcessInstance } from '../models/process-instance.model';
import { exampleProcess } from '../../mock';
import { ProcessInstanceHeaderComponent } from './process-instance-header.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
describe('ProcessInstanceHeaderComponent', () => {
let component: ProcessInstanceHeaderComponent;
let fixture: ComponentFixture<ProcessInstanceHeaderComponent>;
let appConfigService: AppConfigService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(ProcessInstanceHeaderComponent);
component = fixture.componentInstance;
@@ -112,7 +107,7 @@ describe('ProcessInstanceHeaderComponent', () => {
});
it('should display started by', async () => {
component.processInstance.startedBy = {firstName: 'Admin', lastName: 'User'};
component.processInstance.startedBy = { firstName: 'Admin', lastName: 'User' };
component.ngOnChanges();
fixture.detectChanges();
await fixture.whenStable();
@@ -166,7 +161,6 @@ describe('ProcessInstanceHeaderComponent', () => {
});
describe('Config Filtering', () => {
it('should show only the properties from the configuration file', () => {
appConfigService.config['adf-process-instance-header'] = {
presets: {
@@ -196,5 +190,5 @@ describe('ProcessInstanceHeaderComponent', () => {
expect(propertyList[0].innerText).toContain('ADF_PROCESS_LIST.PROPERTIES.STATUS');
expect(propertyList[2].innerText).toContain('ADF_PROCESS_LIST.PROPERTIES.CATEGORY');
});
});
});
});

View File

@@ -25,7 +25,6 @@ import { ProcessInstance } from './../models/process-instance.model';
import { ProcessService } from './../services/process.service';
import { ProcessInstanceTasksComponent } from './process-instance-tasks.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatListItemHarness } from '@angular/material/list/testing';
@@ -40,7 +39,7 @@ describe('ProcessInstanceTasksComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(ProcessInstanceTasksComponent);
processService = TestBed.inject(ProcessService);

View File

@@ -15,7 +15,6 @@
* limitations under the License.
*/
import { LogService } from '@alfresco/adf-core';
import { DatePipe } from '@angular/common';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, OnDestroy } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
@@ -67,7 +66,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
private completedTaskObserver: Observer<TaskDetailsModel>;
private onDestroy$ = new Subject<boolean>();
constructor(private activitiProcess: ProcessService, private logService: LogService, private dialog: MatDialog) {
constructor(private processService: ProcessService, private dialog: MatDialog) {
this.task$ = new Observable<TaskDetailsModel>((observer) => (this.taskObserver = observer)).pipe(share());
this.completedTask$ = new Observable<TaskDetailsModel>((observer) => (this.completedTaskObserver = observer)).pipe(share());
}
@@ -98,7 +97,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
loadActive(processInstanceId: string) {
this.activeTasks = [];
if (processInstanceId) {
this.activitiProcess.getProcessTasks(processInstanceId, null).subscribe(
this.processService.getProcessTasks(processInstanceId, null).subscribe(
(res) => {
res.forEach((task) => {
this.taskObserver.next(task);
@@ -116,7 +115,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
loadCompleted(processInstanceId: string) {
this.completedTasks = [];
if (processInstanceId) {
this.activitiProcess.getProcessTasks(processInstanceId, 'completed').subscribe(
this.processService.getProcessTasks(processInstanceId, 'completed').subscribe(
(res) => {
res.forEach((task) => {
this.completedTaskObserver.next(task);
@@ -146,8 +145,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
const datePipe = new DatePipe('en-US');
try {
return datePipe.transform(value, format);
} catch (err) {
this.logService.error(`ProcessListInstanceTask: error parsing date ${value} to format ${format}`);
} catch {
return value;
}
}

View File

@@ -21,25 +21,24 @@ import { of, throwError, Subject } from 'rxjs';
import { By } from '@angular/platform-browser';
import { ProcessInstanceListComponent } from './process-list.component';
import {
AppConfigService, DataRow, DataColumn,
DataRowEvent, ObjectDataRow, ObjectDataTableAdapter, DataCellEvent, ObjectDataColumn
AppConfigService,
DataRow,
DataColumn,
DataRowEvent,
ObjectDataRow,
ObjectDataTableAdapter,
DataCellEvent,
ObjectDataColumn
} from '@alfresco/adf-core';
import {
fakeProcessInstance,
fakeProcessInstancesWithNoName,
fakeProcessInstancesEmpty,
fakeProcessColumnSchema
} from '../../mock';
import { fakeProcessInstance, fakeProcessInstancesWithNoName, fakeProcessInstancesEmpty, fakeProcessColumnSchema } from '../../mock';
import { ProcessService } from '../services/process.service';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
import { MatMenuItemHarness } from '@angular/material/menu/testing';
describe('ProcessInstanceListComponent', () => {
let fixture: ComponentFixture<ProcessInstanceListComponent>;
let component: ProcessInstanceListComponent;
let loader: HarnessLoader;
@@ -57,10 +56,7 @@ describe('ProcessInstanceListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(ProcessInstanceListComponent);
component = fixture.componentInstance;
@@ -87,12 +83,7 @@ describe('ProcessInstanceListComponent', () => {
});
it('should use the schemaColumn passed in input', () => {
component.data = new ObjectDataTableAdapter(
[],
[
{type: 'text', key: 'fake-id', title: 'Name'}
]
);
component.data = new ObjectDataTableAdapter([], [{ type: 'text', key: 'fake-id', title: 'Name' }]);
component.ngAfterContentInit();
expect(component.data.getColumns()).toBeDefined();
@@ -132,12 +123,7 @@ describe('ProcessInstanceListComponent', () => {
}));
it('should return the process instances list in original order when datalist passed non-existent columns', (done) => {
component.data = new ObjectDataTableAdapter(
[],
[
{type: 'text', key: 'fake-id', title: 'Name'}
]
);
component.data = new ObjectDataTableAdapter([], [{ type: 'text', key: 'fake-id', title: 'Name' }]);
component.appId = 1;
component.state = 'open';
component.success.subscribe((res) => {
@@ -170,11 +156,10 @@ describe('ProcessInstanceListComponent', () => {
});
it('should return selected true for the selected process', () => {
component.rows =
[
{ id: '999', name: 'Fake-name' },
{ id: '888', name: 'Fake-name-888' }
];
component.rows = [
{ id: '999', name: 'Fake-name' },
{ id: '888', name: 'Fake-name-888' }
];
component.selectFirst();
const dataRow = component.rows[0];
expect(dataRow).toBeDefined();
@@ -182,11 +167,10 @@ describe('ProcessInstanceListComponent', () => {
});
it('should not select first row when selectFirstRow is false', () => {
component.rows =
[
{ id: '999', name: 'Fake-name' },
{ id: '888', name: 'Fake-name-888' }
];
component.rows = [
{ id: '999', name: 'Fake-name' },
{ id: '888', name: 'Fake-name-888' }
];
component.selectFirstRow = false;
component.selectFirst();
const dataRow = component.rows;
@@ -216,14 +200,9 @@ describe('ProcessInstanceListComponent', () => {
}));
it('should reload processes when reload() is called', (done) => {
component.data = new ObjectDataTableAdapter(
[],
[
{type: 'text', key: 'fake-id', title: 'Name'}
]
);
component.data = new ObjectDataTableAdapter([], [{ type: 'text', key: 'fake-id', title: 'Name' }]);
component.state = 'open';
component.success.subscribe( (res) => {
component.success.subscribe((res) => {
expect(res).toBeDefined();
expect(component.rows).toBeDefined();
expect(component.isListEmpty()).not.toBeTruthy();
@@ -251,12 +230,14 @@ describe('ProcessInstanceListComponent', () => {
it('should emit row click event on Enter', (done) => {
let prevented = false;
const keyEvent = new CustomEvent('Keyboard event', { detail: {
keyboardEvent: { key: 'Enter' },
row: new ObjectDataRow({ id: '999' })
}});
const keyEvent = new CustomEvent('Keyboard event', {
detail: {
keyboardEvent: { key: 'Enter' },
row: new ObjectDataRow({ id: '999' })
}
});
spyOn(keyEvent, 'preventDefault').and.callFake(() => prevented = true);
spyOn(keyEvent, 'preventDefault').and.callFake(() => (prevented = true));
component.rowClick.subscribe((taskId: string) => {
expect(taskId).toEqual('999');
@@ -270,12 +251,14 @@ describe('ProcessInstanceListComponent', () => {
it('should NOT emit row click event on every other key', async () => {
let triggered = false;
const keyEvent = new CustomEvent('Keyboard event', { detail: {
keyboardEvent: { key: 'Space' },
row: new ObjectDataRow({ id: 999 })
}});
const keyEvent = new CustomEvent('Keyboard event', {
detail: {
keyboardEvent: { key: 'Space' },
row: new ObjectDataRow({ id: 999 })
}
});
component.rowClick.subscribe(() => triggered = true);
component.rowClick.subscribe(() => (triggered = true));
component.onRowKeyUp(keyEvent);
fixture.detectChanges();
@@ -309,14 +292,8 @@ describe('ProcessInstanceListComponent', () => {
});
describe('component changes', () => {
beforeEach(() => {
component.data = new ObjectDataTableAdapter(
[],
[
{type: 'text', key: 'fake-id', title: 'Name'}
]
);
component.data = new ObjectDataTableAdapter([], [{ type: 'text', key: 'fake-id', title: 'Name' }]);
});
it('should NOT reload the process list when no parameters changed', () => {
@@ -338,7 +315,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({appId: change});
component.ngOnChanges({ appId: change });
});
it('should reload the list when the state parameter changes', (done) => {
@@ -354,7 +331,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({state: change});
component.ngOnChanges({ state: change });
});
it('should reload the list when the sort parameter changes', (done) => {
@@ -370,7 +347,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({sort: change});
component.ngOnChanges({ sort: change });
});
it('should reload the process list when the processDefinitionId parameter changes', (done) => {
@@ -386,7 +363,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({processDefinitionId: change});
component.ngOnChanges({ processDefinitionId: change });
});
it('should reload the process list when the processDefinitionId parameter changes to null', (done) => {
@@ -402,7 +379,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({processDefinitionId: change});
component.ngOnChanges({ processDefinitionId: change });
});
it('should reload the process list when the processInstanceId parameter changes', (done) => {
@@ -418,7 +395,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({processInstanceId: change});
component.ngOnChanges({ processInstanceId: change });
});
it('should reload the process list when the processInstanceId parameter changes to null', (done) => {
@@ -434,7 +411,7 @@ describe('ProcessInstanceListComponent', () => {
done();
});
component.ngOnChanges({processInstanceId: change});
component.ngOnChanges({ processInstanceId: change });
});
it('should update the columns when presetColumn schema changes', () => {
@@ -461,22 +438,19 @@ describe('ProcessInstanceListComponent', () => {
});
@Component({
template: `
<adf-process-instance-list #processListComponentInstance>
template: ` <adf-process-instance-list #processListComponentInstance>
<data-columns>
<data-column key="name" title="ADF_PROCESS_LIST.PROPERTIES.NAME" class="adf-full-width adf-name-column" [order]="3"></data-column>
<data-column key="created" title="ADF_PROCESS_LIST.PROPERTIES.END_DATE" class="adf-hidden"></data-column>
<data-column key="startedBy" title="ADF_PROCESS_LIST.PROPERTIES.CREATED" class="adf-desktop-only dw-dt-col-3 adf-ellipsis-cell">
<ng-template let-entry="$implicit">
<div>{{entry.row.obj.startedBy | fullName}}</div>
<div>{{ entry.row.obj.startedBy | fullName }}</div>
</ng-template>
</data-column>
</data-columns>
</adf-process-instance-list>`
})
class CustomProcessListComponent {
@ViewChild(ProcessInstanceListComponent)
processList: ProcessInstanceListComponent;
}
@@ -487,10 +461,7 @@ describe('CustomProcessListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [CustomProcessListComponent]
});
fixture = TestBed.createComponent(CustomProcessListComponent);
@@ -510,25 +481,21 @@ describe('CustomProcessListComponent', () => {
@Component({
template: `
<adf-process-instance-list [appId]="1">
<adf-custom-empty-content-template>
<p id="custom-id"> No Process Instance</p>
</adf-custom-empty-content-template>
</adf-process-instance-list>
`
<adf-process-instance-list [appId]="1">
<adf-custom-empty-content-template>
<p id="custom-id">No Process Instance</p>
</adf-custom-empty-content-template>
</adf-process-instance-list>
`
})
class EmptyTemplateComponent {
}
class EmptyTemplateComponent {}
describe('Process List: Custom EmptyTemplateComponent', () => {
let fixture: ComponentFixture<EmptyTemplateComponent>;
let processService: ProcessService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [EmptyTemplateComponent]
});
fixture = TestBed.createComponent(EmptyTemplateComponent);
@@ -554,18 +521,18 @@ describe('Process List: Custom EmptyTemplateComponent', () => {
});
@Component({
template: `
<adf-process-instance-list
[appId]="appId"
[showContextMenu]="true"
(showRowContextMenu)="onShowRowContextMenu($event)"
#processListComponentInstance>
template: ` <adf-process-instance-list
[appId]="appId"
[showContextMenu]="true"
(showRowContextMenu)="onShowRowContextMenu($event)"
#processListComponentInstance
>
<data-columns>
<data-column key="name" title="ADF_PROCESS_LIST.PROPERTIES.NAME" class="adf-full-width adf-name-column"></data-column>
<data-column key="created" title="ADF_PROCESS_LIST.PROPERTIES.END_DATE" class="adf-hidden"></data-column>
<data-column key="startedBy" title="ADF_PROCESS_LIST.PROPERTIES.CREATED" class="adf-desktop-only dw-dt-col-3 adf-ellipsis-cell">
<ng-template let-entry="$implicit">
<div>{{entry.row.obj.startedBy | fullName}}</div>
<div>{{ entry.row.obj.startedBy | fullName }}</div>
</ng-template>
</data-column>
</data-columns>
@@ -587,8 +554,7 @@ class ProcessListContextMenuComponent implements OnInit {
event.value.actions = [
{
data: event.value.row['obj'],
model:
{
model: {
key: 'processDetails',
icon: 'open',
title: 'View Process Details',
@@ -598,8 +564,7 @@ class ProcessListContextMenuComponent implements OnInit {
},
{
data: event.value.row['obj'],
model:
{
model: {
key: 'cancel',
icon: 'open',
title: 'Cancel Process',
@@ -611,10 +576,9 @@ class ProcessListContextMenuComponent implements OnInit {
}
performContextActions() {
this.performAction$
.subscribe((action: any) => {
this.performAction$.subscribe((action: any) => {
this.contextAction.emit(action.data);
});
});
}
}
@@ -627,10 +591,7 @@ describe('ProcessListContextMenuComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [ProcessListContextMenuComponent]
});
fixture = TestBed.createComponent(ProcessListContextMenuComponent);
@@ -648,7 +609,7 @@ describe('ProcessListContextMenuComponent', () => {
});
it('Should be able to show context menu on process list', async () => {
const contextMenu = element.querySelector(`[data-automation-id="text_${fakeProcessInstance.data[0].name}"]`);
const contextMenu = element.querySelector(`[data-automation-id="text_${fakeProcessInstance.data[0].name}"]`);
const contextActionSpy = spyOn(customComponent.contextAction, 'emit').and.callThrough();
contextMenu.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }));
@@ -659,5 +620,5 @@ describe('ProcessListContextMenuComponent', () => {
await contextActions[0].click();
expect(contextActionSpy).toHaveBeenCalled();
});
});
});

View File

@@ -26,7 +26,6 @@ import { ProcessService } from '../services/process.service';
import { newProcess, taskFormMock, testProcessDef, testMultipleProcessDefs, testProcessDefWithForm, testProcessDefinitions } from '../../mock';
import { StartProcessInstanceComponent } from './start-process.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { deployedApps } from '../../mock/apps-list.mock';
import { ProcessNamePipe } from '../../pipes/process-name.pipe';
import { ProcessInstance } from '../models/process-instance.model';
@@ -52,7 +51,7 @@ describe('StartProcessComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
});
@@ -177,7 +176,9 @@ describe('StartProcessComponent', () => {
component.processDefinitionInput.setValue('My Default Name');
component.processNameInput.setValue('claim');
const inputLabels = await loader.getAllHarnesses(MatFormFieldHarness.with({ ancestor: '.adf-start-process', selector: '.adf-process-input-container' }));
const inputLabels = await loader.getAllHarnesses(
MatFormFieldHarness.with({ ancestor: '.adf-start-process', selector: '.adf-process-input-container' })
);
expect(inputLabels.length).toBe(2);
});

View File

@@ -20,7 +20,6 @@ import { fakeEcmUser, fakeEcmUserNoImage } from '@alfresco/adf-content-services'
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatMenuModule } from '@angular/material/menu';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { BpmUserModel } from '../common/models/bpm-user.model';
import { ProcessUserInfoComponent } from './process-user-info.component';
import { fakeBpmUser } from './mocks/bpm-user.service.mock';
@@ -51,11 +50,7 @@ describe('ProcessUserInfoComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
MatMenuModule
]
imports: [CoreTestingModule, MatMenuModule]
});
fixture = TestBed.createComponent(ProcessUserInfoComponent);
component = fixture.componentInstance;
@@ -82,7 +77,6 @@ describe('ProcessUserInfoComponent', () => {
});
describe('when user is logged on bpm', () => {
beforeEach(async () => {
component.bpmUser = fakeBpmUser;
component.isLoggedIn = true;
@@ -113,7 +107,7 @@ describe('ProcessUserInfoComponent', () => {
});
component.bpmUser = wrongBpmUser;
await whenFixtureReady();
const fullNameElement = (element.querySelector('#adf-userinfo-bpm-name-display'));
const fullNameElement = element.querySelector('#adf-userinfo-bpm-name-display');
fixture.detectChanges();
expect(element.querySelector('#userinfo_container')).toBeDefined();
expect(element.querySelector('#adf-userinfo-bpm-name-display')).not.toBeNull();
@@ -130,7 +124,6 @@ describe('ProcessUserInfoComponent', () => {
});
describe('when user is logged on bpm and ecm', () => {
beforeEach(async () => {
component.bpmUser = fakeBpmUser;
component.ecmUser = fakeEcmUser as any;
@@ -174,7 +167,9 @@ describe('ProcessUserInfoComponent', () => {
expect(ecmUsername).not.toBeNull();
expect(ecmImage).not.toBeNull();
expect(ecmImage.properties.src).toContain(profilePictureUrl);
expect(fixture.debugElement.query(By.css('#ecm-full-name')).nativeElement.textContent).toContain('fake-ecm-first-name fake-ecm-last-name');
expect(fixture.debugElement.query(By.css('#ecm-full-name')).nativeElement.textContent).toContain(
'fake-ecm-first-name fake-ecm-last-name'
);
expect(fixture.debugElement.query(By.css('#ecm-job-title')).nativeElement.textContent).toContain('job-ecm-test');
});

View File

@@ -18,7 +18,6 @@
import { TestBed } from '@angular/core/testing';
import { CommentModel, CoreTestingModule } from '@alfresco/adf-core';
import { fakeTasksComment, fakeUser1 } from '../mocks/task-comments.mock';
import { TranslateModule } from '@ngx-translate/core';
import { TaskCommentsService } from './task-comments.service';
declare let jasmine: any;
@@ -28,10 +27,7 @@ describe('TaskCommentsService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [CoreTestingModule]
});
service = TestBed.inject(TaskCommentsService);
});
@@ -45,26 +41,24 @@ describe('TaskCommentsService', () => {
});
describe('Task comments', () => {
it('should add a comment task ', (done) => {
service.add('999', 'fake-comment-message').subscribe(
(res: CommentModel) => {
expect(res).toBeDefined();
expect(res.id).not.toEqual(null);
expect(res.message).toEqual('fake-comment-message');
expect(res.created).not.toEqual(null);
expect(res.createdBy.email).toEqual('fake-email@dom.com');
expect(res.createdBy.firstName).toEqual('firstName');
expect(res.createdBy.lastName).toEqual('lastName');
done();
}
);
service.add('999', 'fake-comment-message').subscribe((res: CommentModel) => {
expect(res).toBeDefined();
expect(res.id).not.toEqual(null);
expect(res.message).toEqual('fake-comment-message');
expect(res.created).not.toEqual(null);
expect(res.createdBy.email).toEqual('fake-email@dom.com');
expect(res.createdBy.firstName).toEqual('firstName');
expect(res.createdBy.lastName).toEqual('lastName');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({
id: '111', message: 'fake-comment-message',
id: '111',
message: 'fake-comment-message',
createdBy: fakeUser1,
created: '2016-07-15T11:19:17.440+0000'
})
@@ -72,15 +66,13 @@ describe('TaskCommentsService', () => {
});
it('should return the tasks comments ', (done) => {
service.get('999').subscribe(
(res: CommentModel[]) => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].message).toEqual('fake-message-1');
expect(res[1].message).toEqual('fake-message-2');
done();
}
);
service.get('999').subscribe((res: CommentModel[]) => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].message).toEqual('fake-message-1');
expect(res[1].message).toEqual('fake-message-2');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,

View File

@@ -21,7 +21,6 @@ import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TaskListService } from './../services/tasklist.service';
import { of } from 'rxjs';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
describe('AttachFormComponent', () => {
let component: AttachFormComponent;
@@ -31,10 +30,7 @@ describe('AttachFormComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(AttachFormComponent);
component = fixture.componentInstance;
@@ -160,14 +156,14 @@ describe('AttachFormComponent', () => {
component.taskId = 1;
component.attachFormControl.setValue(10);
spyOn(taskService, 'attachFormToATask').and.returnValue(of(
{
spyOn(taskService, 'attachFormToATask').and.returnValue(
of({
id: 91,
name: 'fakeName',
formKey: 1204,
assignee: null
}
));
})
);
fixture.detectChanges();
await fixture.whenStable();

View File

@@ -15,7 +15,6 @@
* limitations under the License.
*/
import { LogService } from '@alfresco/adf-core';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { Form } from '../models/form.model';
import { TaskListService } from './../services/tasklist.service';
@@ -28,9 +27,7 @@ import { TaskFormService } from '../../form/services/task-form.service';
templateUrl: './attach-form.component.html',
styleUrls: ['./attach-form.component.scss']
})
export class AttachFormComponent implements OnInit, OnChanges {
/** Id of the task. */
@Input()
taskId: any;
@@ -59,14 +56,11 @@ export class AttachFormComponent implements OnInit, OnChanges {
attachFormControl: UntypedFormControl;
constructor(private taskService: TaskListService,
private logService: LogService,
private modelService: ModelService,
private taskFormService: TaskFormService) { }
constructor(private taskService: TaskListService, private modelService: ModelService, private taskFormService: TaskFormService) {}
ngOnInit() {
this.attachFormControl = new UntypedFormControl('', Validators.required);
this.attachFormControl.valueChanges.subscribe( (currentValue) => {
this.attachFormControl.valueChanges.subscribe((currentValue) => {
if (this.attachFormControl.valid) {
this.disableSubmit = this.formId === currentValue;
}
@@ -95,8 +89,8 @@ export class AttachFormComponent implements OnInit, OnChanges {
},
(err) => {
this.error.emit(err);
this.logService.error('An error occurred while trying to delete the form');
});
}
);
}
onAttachFormButtonClick(): void {
@@ -104,36 +98,39 @@ export class AttachFormComponent implements OnInit, OnChanges {
}
private loadFormsTask(): void {
this.taskService.getFormList().subscribe((form: Form[]) => {
this.taskService.getFormList().subscribe(
(form: Form[]) => {
this.forms = form;
},
(err) => {
this.error.emit(err);
this.logService.error('An error occurred while trying to get the forms');
});
}
);
}
private onFormAttached() {
this.taskFormService.getTaskForm(this.taskId)
.subscribe((res) => {
this.taskFormService.getTaskForm(this.taskId).subscribe(
(res) => {
this.modelService.getFormDefinitionByName(res.name).subscribe((formDef) => {
this.formId = this.selectedFormId = formDef;
});
}, (err) => {
},
(err) => {
this.error.emit(err);
this.logService.error('Could not load forms');
});
}
);
}
private attachForm(taskId: string, formId: number) {
if (taskId && formId) {
this.taskService.attachFormToATask(taskId, formId)
.subscribe(() => {
this.taskService.attachFormToATask(taskId, formId).subscribe(
() => {
this.success.emit();
}, (err) => {
},
(err) => {
this.error.emit(err);
this.logService.error('Could not attach form');
});
}
);
}
}
}

View File

@@ -22,10 +22,8 @@ import { ChecklistComponent } from './checklist.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TaskListService } from './../services/tasklist.service';
import { of } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core';
describe('ChecklistComponent', () => {
let checklistComponent: ChecklistComponent;
let fixture: ComponentFixture<ChecklistComponent>;
let element: HTMLElement;
@@ -34,16 +32,17 @@ describe('ChecklistComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
service = TestBed.inject(TaskListService);
spyOn(service, 'getTaskChecklist').and.returnValue(of([new TaskDetailsModel({
id: 'fake-check-changed-id',
name: 'fake-check-changed-name'
})]));
spyOn(service, 'getTaskChecklist').and.returnValue(
of([
new TaskDetailsModel({
id: 'fake-check-changed-id',
name: 'fake-check-changed-name'
})
])
);
fixture = TestBed.createComponent(ChecklistComponent);
checklistComponent = fixture.componentInstance;
@@ -63,13 +62,14 @@ describe('ChecklistComponent', () => {
});
describe('when is readonly mode', () => {
beforeEach(() => {
checklistComponent.taskId = 'fake-task-id';
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
checklistComponent.readOnly = true;
fixture.detectChanges();
@@ -86,14 +86,15 @@ describe('ChecklistComponent', () => {
});
describe('when is not in readonly mode', () => {
beforeEach(() => {
checklistComponent.taskId = 'fake-task-id';
checklistComponent.readOnly = false;
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
fixture.detectChanges();
showChecklistDialog = element.querySelector<HTMLElement>('#add-checklist');
@@ -109,7 +110,6 @@ describe('ChecklistComponent', () => {
});
describe('when interact with checklist dialog', () => {
beforeEach(() => {
checklistComponent.taskId = 'fake-task-id';
checklistComponent.checklist = [];
@@ -132,7 +132,6 @@ describe('ChecklistComponent', () => {
});
describe('when there are task checklist', () => {
beforeEach(() => {
checklistComponent.taskId = 'fake-task-id';
checklistComponent.checklist = [];
@@ -148,25 +147,31 @@ describe('ChecklistComponent', () => {
});
it('should show task checklist', () => {
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
fixture.detectChanges();
expect(element.querySelector('#check-fake-check-id')).not.toBeNull();
expect(element.querySelector('#check-fake-check-id').textContent).toContain('fake-check-name');
});
it('should not show delete icon when checklist task is completed', () => {
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-completed-id',
name: 'fake-completed-name',
endDate: '2018-05-23T11:25:14.552+0000'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-completed-id',
name: 'fake-completed-name',
endDate: '2018-05-23T11:25:14.552+0000'
})
);
fixture.detectChanges();
expect(element.querySelector('#remove-fake-check-id')).not.toBeNull();
expect(element.querySelector('#check-fake-completed-id')).not.toBeNull();
@@ -175,9 +180,14 @@ describe('ChecklistComponent', () => {
});
it('should add checklist', async () => {
spyOn(service, 'addTask').and.returnValue(of(new TaskDetailsModel({
id: 'fake-check-added-id', name: 'fake-check-added-name'
})));
spyOn(service, 'addTask').and.returnValue(
of(
new TaskDetailsModel({
id: 'fake-check-added-id',
name: 'fake-check-added-name'
})
)
);
showChecklistDialog.click();
const addButtonDialog = window.document.querySelector<HTMLElement>('#add-check');
@@ -194,10 +204,12 @@ describe('ChecklistComponent', () => {
spyOn(service, 'deleteTask').and.returnValue(of(null));
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
fixture.detectChanges();
await fixture.whenStable();
@@ -216,10 +228,12 @@ describe('ChecklistComponent', () => {
it('should send an event when the checklist is deleted', async () => {
spyOn(service, 'deleteTask').and.returnValue(of(null));
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
fixture.detectChanges();
await fixture.whenStable();
@@ -235,10 +249,12 @@ describe('ChecklistComponent', () => {
it('should show load task checklist on change', async () => {
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
fixture.detectChanges();
const change = new SimpleChange(null, 'new-fake-task-id', true);
checklistComponent.ngOnChanges({
@@ -254,10 +270,12 @@ describe('ChecklistComponent', () => {
it('should show empty checklist when task id is null', async () => {
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
}));
checklistComponent.checklist.push(
new TaskDetailsModel({
id: 'fake-check-id',
name: 'fake-check-name'
})
);
fixture.detectChanges();
await fixture.whenStable();

View File

@@ -19,12 +19,11 @@ import { NoTaskDetailsTemplateDirective } from './no-task-detail-template.direct
import { TaskDetailsComponent } from './task-details.component';
describe('NoTaskDetailsTemplateDirective', () => {
let component: NoTaskDetailsTemplateDirective;
let detailsComponent: TaskDetailsComponent;
beforeEach(() => {
detailsComponent = new TaskDetailsComponent(null, null, null, null, null);
detailsComponent = new TaskDetailsComponent(null, null, null, null);
component = new NoTaskDetailsTemplateDirective(detailsComponent);
});

View File

@@ -16,14 +16,12 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LogService } from '@alfresco/adf-core';
import { of, throwError } from 'rxjs';
import { TaskListService } from '../services/tasklist.service';
import { StartTaskComponent } from './start-task.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { taskDetailsMock } from '../../mock/task/task-details.mock';
import { TaskDetailsModel } from '../models/task-details.model';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatButtonHarness } from '@angular/material/button/testing';
@@ -33,11 +31,9 @@ describe('StartTaskComponent', () => {
let fixture: ComponentFixture<StartTaskComponent>;
let loader: HarnessLoader;
let service: TaskListService;
let logService: LogService;
let element: HTMLElement;
let getFormListSpy: jasmine.Spy;
let createNewTaskSpy: jasmine.Spy;
let logSpy: jasmine.Spy;
const fakeForms$ = [
{
@@ -54,7 +50,7 @@ describe('StartTaskComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(StartTaskComponent);
component = fixture.componentInstance;
@@ -62,7 +58,6 @@ describe('StartTaskComponent', () => {
loader = TestbedHarnessEnvironment.loader(fixture);
service = TestBed.inject(TaskListService);
logService = TestBed.inject(LogService);
getFormListSpy = spyOn(service, 'getFormList').and.returnValue(of(fakeForms$));
@@ -406,14 +401,6 @@ describe('StartTaskComponent', () => {
expect(name.valid).toBeTruthy();
});
it('should call logService when task name exceeds maximum length', () => {
logSpy = spyOn(logService, 'log').and.callThrough();
component.maxTaskNameLength = 300;
component.ngOnInit();
fixture.detectChanges();
expect(logSpy).toHaveBeenCalled();
});
it('should emit error when description have only white spaces', () => {
fixture.detectChanges();
const description = component.taskForm.controls['description'];

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { LogService, FormFieldModel, FormModel, DateFnsUtils, AdfDateFnsAdapter, ADF_DATE_FORMATS } from '@alfresco/adf-core';
import { FormFieldModel, FormModel, DateFnsUtils, AdfDateFnsAdapter, ADF_DATE_FORMATS } from '@alfresco/adf-core';
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation, OnDestroy } from '@angular/core';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { EMPTY, Observable, Subject } from 'rxjs';
@@ -36,7 +36,8 @@ const MAX_LENGTH = 255;
styleUrls: ['./start-task.component.scss'],
providers: [
{ provide: DateAdapter, useClass: AdfDateFnsAdapter },
{ provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS }],
{ provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS }
],
encapsulation: ViewEncapsulation.None
})
export class StartTaskComponent implements OnInit, OnDestroy {
@@ -71,10 +72,7 @@ export class StartTaskComponent implements OnInit, OnDestroy {
private onDestroy$ = new Subject<boolean>();
constructor(private taskService: TaskListService,
private formBuilder: UntypedFormBuilder,
private logService: LogService) {
}
constructor(private taskService: TaskListService, private formBuilder: UntypedFormBuilder) {}
ngOnInit() {
if (this.name) {
@@ -96,20 +94,22 @@ export class StartTaskComponent implements OnInit, OnDestroy {
buildForm(): void {
this.taskForm = this.formBuilder.group({
name: new UntypedFormControl(this.taskDetailsModel.name, [Validators.required, Validators.maxLength(this.maxTaskNameLength), this.whitespaceValidator]),
name: new UntypedFormControl(this.taskDetailsModel.name, [
Validators.required,
Validators.maxLength(this.maxTaskNameLength),
this.whitespaceValidator
]),
description: new UntypedFormControl('', [this.whitespaceValidator]),
formKey: new UntypedFormControl('')
});
this.taskForm.valueChanges
.pipe(takeUntil(this.onDestroy$))
.subscribe(taskFormValues => this.setTaskDetails(taskFormValues));
this.taskForm.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((taskFormValues) => this.setTaskDetails(taskFormValues));
}
whitespaceValidator(control: UntypedFormControl): any {
if (control.value) {
const isWhitespace = (control.value || '').trim().length === 0;
const isControlValid = control.value.length === 0 || !isWhitespace;
const isControlValid = control.value.length === 0 || !isWhitespace;
return isControlValid ? null : { whitespace: true };
}
return null;
@@ -130,15 +130,14 @@ export class StartTaskComponent implements OnInit, OnDestroy {
if (this.appId) {
this.taskDetailsModel.category = this.appId.toString();
}
this.taskService.createNewTask(this.taskDetailsModel)
this.taskService
.createNewTask(this.taskDetailsModel)
.pipe(
switchMap((createRes) =>
this.attachForm(createRes.id, this.taskDetailsModel.formKey).pipe(
defaultIfEmpty(createRes),
switchMap((attachRes) =>
this.assignTaskByUserId(createRes.id, this.assigneeId).pipe(
defaultIfEmpty(attachRes ? attachRes : createRes)
)
this.assignTaskByUserId(createRes.id, this.assigneeId).pipe(defaultIfEmpty(attachRes ? attachRes : createRes))
)
)
)
@@ -151,8 +150,8 @@ export class StartTaskComponent implements OnInit, OnDestroy {
(err) => {
this.loading = false;
this.error.emit(err);
this.logService.error('An error occurred while creating new task');
});
}
);
}
getAssigneeId(userId: number): void {
@@ -168,8 +167,8 @@ export class StartTaskComponent implements OnInit, OnDestroy {
}
getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string {
firstName = (firstName !== null ? firstName : '');
lastName = (lastName !== null ? lastName : '');
firstName = firstName !== null ? firstName : '';
lastName = lastName !== null ? lastName : '';
return firstName + delimiter + lastName;
}
@@ -199,7 +198,6 @@ export class StartTaskComponent implements OnInit, OnDestroy {
private validateMaxTaskNameLength() {
if (this.maxTaskNameLength > MAX_LENGTH) {
this.maxTaskNameLength = MAX_LENGTH;
this.logService.log(`the task name length cannot be greater than ${MAX_LENGTH}`);
}
}

View File

@@ -20,26 +20,25 @@ import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { TaskListService } from './../services/tasklist.service';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
declare let jasmine: any;
describe('TaskAuditDirective', () => {
@Component({
selector: 'adf-basic-button',
template: `
<button id="auditButton"
template: ` <button
id="auditButton"
adf-task-audit
[task-id]="currentTaskId"
[download]="download"
[fileName]="fileName"
[format]="format"
(clicked)="onAuditClick($event)">My button
(clicked)="onAuditClick($event)"
>
My button
</button>`
})
class BasicButtonComponent {
download: boolean = false;
fileName: string;
format: string;
@@ -54,27 +53,25 @@ describe('TaskAuditDirective', () => {
const createFakePdfBlob = (): Blob => {
const pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
return new Blob([pdfData], {type: 'application/pdf'});
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G'
);
return new Blob([pdfData], { type: 'application/pdf' });
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [ProcessTestingModule],
declarations: [BasicButtonComponent]
});
fixture = TestBed.createComponent(BasicButtonComponent);
@@ -105,7 +102,6 @@ describe('TaskAuditDirective', () => {
});
button.click();
}));
it('should fetch the json info when the format is json', fakeAsync(() => {
@@ -113,7 +109,14 @@ describe('TaskAuditDirective', () => {
component.format = 'json';
component.download = true;
const auditJson = { taskId: '77', taskName: 'Fake Task Name', assignee: 'FirstName LastName', formData: [], selectedOutcome: null, comments: [] };
const auditJson = {
taskId: '77',
taskName: 'Fake Task Name',
assignee: 'FirstName LastName',
formData: [],
selectedOutcome: null,
comments: []
};
spyOn(service, 'fetchTaskAuditJsonById').and.returnValue(of(auditJson));
spyOn(component, 'onAuditClick').and.callThrough();
@@ -127,7 +130,6 @@ describe('TaskAuditDirective', () => {
});
button.click();
}));
it('should fetch the pdf Blob as default when the format is UNKNOWN', fakeAsync(() => {
@@ -147,6 +149,5 @@ describe('TaskAuditDirective', () => {
});
button.click();
}));
});

View File

@@ -25,7 +25,6 @@ import { noDataMock, taskDetailsMock, taskFormMock, tasksMock, taskDetailsWithOu
import { TaskListService } from './../services/tasklist.service';
import { TaskDetailsComponent } from './task-details.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { TaskService } from '../../form/services/task.service';
import { TaskFormService } from '../../form/services/task-form.service';
import { TaskCommentsService } from '../../task-comments/services/task-comments.service';
@@ -65,7 +64,7 @@ describe('TaskDetailsComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
schemas: [NO_ERRORS_SCHEMA]
});
peopleProcessService = TestBed.inject(PeopleProcessService);

View File

@@ -23,7 +23,6 @@ import {
FormFieldValidator,
FormModel,
FormOutcomeEvent,
LogService,
UpdateNotification
} from '@alfresco/adf-core';
import {
@@ -191,7 +190,6 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
constructor(
private taskListService: TaskListService,
private peopleProcessService: PeopleProcessService,
private logService: LogService,
private cardViewUpdateService: CardViewUpdateService,
private dialog: MatDialog
) {}
@@ -310,13 +308,10 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
}
searchUser(searchedWord: string) {
this.peopleProcessService.getWorkflowUsers(null, searchedWord).subscribe(
(users) => {
users = users.filter((user) => user.id !== this.taskDetails.assignee.id);
this.peopleSearchObserver.next(users);
},
() => this.logService.error('Could not load users')
);
this.peopleProcessService.getWorkflowUsers(null, searchedWord).subscribe((users) => {
users = users.filter((user) => user.id !== this.taskDetails.assignee.id);
this.peopleSearchObserver.next(users);
});
}
onCloseSearch() {
@@ -325,7 +320,6 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
assignTaskToUser(selectedUser: UserProcessModel) {
this.taskListService.assignTask(this.taskDetails.id, selectedUser).subscribe(() => {
this.logService.info('Task Assigned to ' + selectedUser.email);
this.assignTask.emit();
});
this.showAssignee = false;

View File

@@ -26,13 +26,11 @@ import { TaskFilterService } from '../services/task-filter.service';
import { TaskFiltersComponent } from './task-filters.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { fakeTaskFilters } from '../../mock/task/task-filters.mock';
import { NavigationStart, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
describe('TaskFiltersComponent', () => {
let taskListService: TaskListService;
let taskFilterService: TaskFilterService;
let appsProcessService: AppsProcessService;
@@ -42,11 +40,7 @@ describe('TaskFiltersComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule,
RouterTestingModule
]
imports: [ProcessTestingModule, RouterTestingModule]
});
const appConfig: AppConfigService = TestBed.inject(AppConfigService);
appConfig.config.bpmHost = 'http://localhost:9876/bpm';
@@ -67,11 +61,11 @@ describe('TaskFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastError: any;
component.error.subscribe((err) => lastError = err);
component.error.subscribe((err) => (lastError = err));
component.ngOnChanges({ appId: change });
expect(lastError).toBeDefined();
});
});
it('should return the filter task list', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
@@ -79,7 +73,7 @@ describe('TaskFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastValue: any;
component.success.subscribe((res) => lastValue = res);
component.success.subscribe((res) => (lastValue = res));
component.ngOnChanges({ appId: change });
@@ -93,7 +87,7 @@ describe('TaskFiltersComponent', () => {
it('Should call the API to create the default task filters when no task filters exist', async () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of([]));
const filtersMock: any[] = [{ name: 'default-task-filter-1'}, { name: 'default-task-filter-2'}];
const filtersMock: any[] = [{ name: 'default-task-filter-1' }, { name: 'default-task-filter-2' }];
const createDefaultFiltersSpy = spyOn(taskFilterService, 'createDefaultFilters').and.returnValue(of(filtersMock));
const appId = '2';
const change = new SimpleChange(null, appId, true);
@@ -110,7 +104,7 @@ describe('TaskFiltersComponent', () => {
const change = new SimpleChange(null, 'test', true);
let lastValue: any;
component.success.subscribe((res) => lastValue = res);
component.success.subscribe((res) => (lastValue = res));
component.ngOnChanges({ appName: change });
@@ -123,7 +117,7 @@ describe('TaskFiltersComponent', () => {
component.filterParam = new FilterParamsModel({ name: 'FakeMyTasks1' });
let lastValue: any;
component.success.subscribe((res) => lastValue = res);
component.success.subscribe((res) => (lastValue = res));
const appId = '1';
const change = new SimpleChange(null, appId, true);
@@ -132,14 +126,14 @@ describe('TaskFiltersComponent', () => {
expect(lastValue).toBeDefined();
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeMyTasks1');
});
});
it('should select the task filter based on the input by index param', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
component.filterParam = new FilterParamsModel({ index: 2 });
let lastValue: any;
component.success.subscribe((res) => lastValue = res);
component.success.subscribe((res) => (lastValue = res));
const appId = '1';
const change = new SimpleChange(null, appId, true);
@@ -148,7 +142,7 @@ describe('TaskFiltersComponent', () => {
expect(lastValue).toBeDefined();
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeMyTasks2');
});
});
it('should select the task filter based on the input by id param', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
@@ -159,14 +153,14 @@ describe('TaskFiltersComponent', () => {
const change = new SimpleChange(null, appId, true);
let lastValue: any;
component.success.subscribe((res) => lastValue = res);
component.success.subscribe((res) => (lastValue = res));
component.ngOnChanges({ appId: change });
expect(lastValue).toBeDefined();
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeInvolvedTasks');
});
});
it('should emit the selected filter based on the filterParam input', () => {
spyOn(component.filterSelected, 'emit');
@@ -181,7 +175,7 @@ describe('TaskFiltersComponent', () => {
expect(component.filterSelected.emit).toHaveBeenCalledWith(fakeTaskFilters[0]);
});
it('should filterClicked emit when a filter is clicked from the UI', async () => {
it('should filterClicked emit when a filter is clicked from the UI', async () => {
component.filters = fakeTaskFilters;
spyOn(component.filterClicked, 'emit');
@@ -306,7 +300,7 @@ describe('TaskFiltersComponent', () => {
it('should reset selection when filterParam is a filter that does not exist', async () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
component.currentFilter = fakeTaskFilters[0];
component.filterParam = new FilterRepresentationModel( {name: 'non-existing-filter'});
component.filterParam = new FilterRepresentationModel({ name: 'non-existing-filter' });
const appId = '1';
const change = new SimpleChange(null, appId, true);
@@ -319,8 +313,7 @@ describe('TaskFiltersComponent', () => {
});
describe('Display Task Filters', () => {
it('Should be able to display default task filters', async () => {
it('Should be able to display default task filters', async () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of([]));
const defaultTaskFiltersMock: any = [
{ name: 'default-my-filter' },
@@ -349,7 +342,7 @@ describe('TaskFiltersComponent', () => {
spyOn(router.events, 'pipe').and.returnValue(of(navigationStartEvent));
fixture.detectChanges();
expect(component.isTaskActive).toBe(true);
});
});
it('should set isTaskActive to false when activeRoute does not include "tasks"', () => {
const navigationStartEvent = new NavigationStart(1, 'other-route');

View File

@@ -15,19 +15,11 @@
* limitations under the License.
*/
import {
Directive,
Input,
Output,
EventEmitter,
HostListener,
OnInit
} from '@angular/core';
import { Directive, Input, Output, EventEmitter, HostListener, OnInit } from '@angular/core';
import { TaskListService } from '../../services/tasklist.service';
import { LogService } from '@alfresco/adf-core';
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
// eslint-disable-next-line @angular-eslint/directive-selector
selector: '[adf-claim-task]'
})
export class ClaimTaskDirective implements OnInit {
@@ -45,9 +37,7 @@ export class ClaimTaskDirective implements OnInit {
invalidParams: string[] = [];
constructor(
private taskListService: TaskListService,
private logService: LogService) {}
constructor(private taskListService: TaskListService) {}
@HostListener('click')
onClick() {
@@ -68,9 +58,7 @@ export class ClaimTaskDirective implements OnInit {
}
if (this.invalidParams.length) {
throw new Error(
`Attribute ${this.invalidParams.join(', ')} is required`
);
throw new Error(`Attribute ${this.invalidParams.join(', ')} is required`);
}
}
@@ -81,10 +69,9 @@ export class ClaimTaskDirective implements OnInit {
private claimTask() {
this.taskListService.claimTask(this.taskId).subscribe(
() => {
this.logService.info('Task claimed');
this.success.emit(this.taskId);
},
error => this.error.emit(error)
(error) => this.error.emit(error)
);
}
}

View File

@@ -43,7 +43,6 @@ import {
} from '../../../mock/task/task-details.mock';
import { TaskDetailsModel } from '../../models/task-details.model';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { By } from '@angular/platform-browser';
import { TaskFormService } from '../../../form/services/task-form.service';
import { TaskService } from '../../../form/services/task.service';
@@ -63,7 +62,7 @@ describe('TaskFormComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(TaskFormComponent);

View File

@@ -15,16 +15,8 @@
* limitations under the License.
*/
import {
Directive,
HostListener,
Input,
Output,
EventEmitter,
OnInit
} from '@angular/core';
import { Directive, HostListener, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { TaskListService } from '../../services/tasklist.service';
import { LogService } from '@alfresco/adf-core';
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
@@ -45,9 +37,7 @@ export class UnclaimTaskDirective implements OnInit {
invalidParams: string[] = [];
constructor(
private taskListService: TaskListService,
private logService: LogService) {}
constructor(private taskListService: TaskListService) {}
@HostListener('click')
onClick() {
@@ -67,9 +57,7 @@ export class UnclaimTaskDirective implements OnInit {
this.invalidParams.push('taskId');
}
if (this.invalidParams.length) {
throw new Error(
`Attribute ${this.invalidParams.join(', ')} is required`
);
throw new Error(`Attribute ${this.invalidParams.join(', ')} is required`);
}
}
@@ -80,10 +68,9 @@ export class UnclaimTaskDirective implements OnInit {
private unclaimTask() {
this.taskListService.unclaimTask(this.taskId).subscribe(
() => {
this.logService.info('Task unclaimed');
this.success.emit(this.taskId);
},
error => this.error.emit(error)
(error) => this.error.emit(error)
);
}
}

View File

@@ -32,7 +32,6 @@ import { TaskDetailsModel } from '../models/task-details.model';
import { TaskListService } from './../services/tasklist.service';
import { TaskHeaderComponent } from './task-header.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { PeopleProcessService } from '../../common/services/people-process.service';
import { BpmUserModel } from '../../common/models/bpm-user.model';
@@ -59,7 +58,7 @@ describe('TaskHeaderComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(TaskHeaderComponent);
component = fixture.componentInstance;

View File

@@ -23,7 +23,7 @@ import { TaskListService } from '../services/tasklist.service';
import { TaskListComponent } from './task-list.component';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { fakeGlobalTask, fakeEmptyTask, paginatedTask, fakeColumnSchema, fakeCustomSchema } from '../../mock';
import { TranslateService, TranslateModule } from '@ngx-translate/core';
import { TranslateService } from '@ngx-translate/core';
import { of, Subject } from 'rxjs';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -93,7 +93,7 @@ describe('TaskListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule]
imports: [ProcessTestingModule]
});
appConfig = TestBed.inject(AppConfigService);
appConfig.config.bpmHost = 'http://localhost:9876/bpm';
@@ -651,7 +651,7 @@ describe('CustomTaskListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
declarations: [CustomTaskListComponent]
});
fixture = TestBed.createComponent(CustomTaskListComponent);
@@ -691,7 +691,7 @@ describe('Task List: Custom EmptyTemplateComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
declarations: [EmptyTemplateComponent]
});
translateService = TestBed.inject(TranslateService);
@@ -779,7 +779,7 @@ describe('TaskListContextMenuComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ProcessTestingModule],
imports: [ProcessTestingModule],
declarations: [TaskListContextMenuComponent]
});
fixture = TestBed.createComponent(TaskListContextMenuComponent);

View File

@@ -18,7 +18,6 @@
import { TaskStandaloneComponent } from './task-standalone.component';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core';
describe('TaskStandaloneComponent', () => {
let component: TaskStandaloneComponent;
@@ -27,10 +26,7 @@ describe('TaskStandaloneComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [ProcessTestingModule]
});
fixture = TestBed.createComponent(TaskStandaloneComponent);
component = fixture.componentInstance;