mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
AAE-20141 Replace adf mat selectors process services (#9514)
* AAE-20141 removing mat from unit tests in process-services * AAE-20141 fix dropdown false-positives * AAE-20141 dropdown editor remake * AAE-20141 remove remaining selectors * AAE-20141 fix radio buttons selector
This commit is contained in:
@@ -24,6 +24,9 @@ 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';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatMenuItemHarness } from '@angular/material/menu/testing';
|
||||
|
||||
describe('TaskAttachmentList', () => {
|
||||
|
||||
@@ -35,6 +38,7 @@ describe('TaskAttachmentList', () => {
|
||||
let getFileRawContentSpy: jasmine.Spy;
|
||||
let getContentPreviewSpy: jasmine.Spy;
|
||||
let disposableSuccess: any;
|
||||
let loader: HarnessLoader;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -46,6 +50,7 @@ describe('TaskAttachmentList', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(TaskAttachmentListComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
||||
|
||||
service = TestBed.inject(ProcessContentService);
|
||||
|
||||
@@ -146,11 +151,12 @@ describe('TaskAttachmentList', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const actionMenu = window.document.querySelectorAll('button.mat-menu-item').length;
|
||||
|
||||
const actionMenuItems = await loader.getAllHarnesses(MatMenuItemHarness);
|
||||
expect(window.document.querySelector('[data-automation-id="ADF_TASK_LIST.MENU_ACTIONS.VIEW_CONTENT"]')).not.toBeNull();
|
||||
expect(window.document.querySelector('[data-automation-id="ADF_TASK_LIST.MENU_ACTIONS.REMOVE_CONTENT"]')).not.toBeNull();
|
||||
expect(window.document.querySelector('[data-automation-id="ADF_TASK_LIST.MENU_ACTIONS.DOWNLOAD_CONTENT"]')).not.toBeNull();
|
||||
expect(actionMenu).toBe(3);
|
||||
expect(actionMenuItems.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should not display remove action if attachments are read only', async () => {
|
||||
@@ -166,11 +172,11 @@ describe('TaskAttachmentList', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const actionMenu = window.document.querySelectorAll('button.mat-menu-item').length;
|
||||
const actionMenuItems = await loader.getAllHarnesses(MatMenuItemHarness);
|
||||
expect(window.document.querySelector('[data-automation-id="ADF_TASK_LIST.MENU_ACTIONS.VIEW_CONTENT"]')).not.toBeNull();
|
||||
expect(window.document.querySelector('[data-automation-id="ADF_TASK_LIST.MENU_ACTIONS.DOWNLOAD_CONTENT"]')).not.toBeNull();
|
||||
expect(window.document.querySelector('[data-automation-id="ADF_TASK_LIST.MENU_ACTIONS.REMOVE_CONTENT"]')).toBeNull();
|
||||
expect(actionMenu).toBe(2);
|
||||
expect(actionMenuItems.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should show the empty list component when the attachments list is empty', async () => {
|
||||
|
@@ -35,17 +35,16 @@ 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';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
|
||||
describe('FormComponent UI and visibility', () => {
|
||||
let component: FormComponent;
|
||||
let taskService: TaskService;
|
||||
let taskFormService: TaskFormService;
|
||||
let fixture: ComponentFixture<FormComponent>;
|
||||
|
||||
const openSelect = () => {
|
||||
const dropdown = fixture.debugElement.nativeElement.querySelector('.mat-select-trigger');
|
||||
dropdown.click();
|
||||
};
|
||||
let loader: HarnessLoader;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -54,6 +53,7 @@ describe('FormComponent UI and visibility', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(FormComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
taskService = TestBed.inject(TaskService);
|
||||
taskFormService = TestBed.inject(TaskFormService);
|
||||
});
|
||||
@@ -124,30 +124,23 @@ describe('FormComponent UI and visibility', () => {
|
||||
|
||||
const change = new SimpleChange(null, 1, true);
|
||||
component.ngOnChanges({ taskId: change });
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
openSelect();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
||||
const dropdown = await loader.getHarness(MatSelectHarness);
|
||||
await dropdown.open();
|
||||
const options = await dropdown.getOptions();
|
||||
|
||||
const optOne = options[1];
|
||||
const optTwo = options[2];
|
||||
const optThree = options[3];
|
||||
|
||||
expect(optOne.nativeElement.innerText.trim()).toEqual('united kingdom');
|
||||
expect(optTwo.nativeElement.innerText.trim()).toEqual('italy');
|
||||
expect(optThree.nativeElement.innerText.trim()).toEqual('france');
|
||||
expect((await optOne.getText()).trim()).toEqual('united kingdom');
|
||||
expect((await optTwo.getText()).trim()).toEqual('italy');
|
||||
expect((await optThree.getText()).trim()).toEqual('france');
|
||||
|
||||
optTwo.nativeElement.click();
|
||||
await optTwo.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const dropdown = fixture.debugElement.queryAll(By.css('#country'));
|
||||
expect(dropdown[0].nativeElement.innerText.trim()).toEqual('italy');
|
||||
const dropdownCountries = fixture.debugElement.queryAll(By.css('#country'));
|
||||
expect(dropdownCountries[0].nativeElement.innerText.trim()).toEqual('italy');
|
||||
});
|
||||
|
||||
describe('Visibility conditions', () => {
|
||||
|
@@ -29,6 +29,11 @@ import { WidgetVisibilityService, FormModel, FormOutcomeModel } from '@alfresco/
|
||||
import { TranslateService, TranslateModule } 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';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
import { MatCardHarness } from '@angular/material/card/testing';
|
||||
import { MatButtonHarness } from '@angular/material/button/testing';
|
||||
|
||||
describe('StartFormComponent', () => {
|
||||
|
||||
@@ -38,6 +43,7 @@ describe('StartFormComponent', () => {
|
||||
let visibilityService: WidgetVisibilityService;
|
||||
let translate: TranslateService;
|
||||
let processService: ProcessService;
|
||||
let loader: HarnessLoader;
|
||||
|
||||
const exampleId1 = 'my:process1';
|
||||
const exampleId2 = 'my:process2';
|
||||
@@ -52,6 +58,7 @@ describe('StartFormComponent', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(StartFormComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
processService = TestBed.inject(ProcessService);
|
||||
visibilityService = TestBed.inject(WidgetVisibilityService);
|
||||
translate = TestBed.inject(TranslateService);
|
||||
@@ -243,8 +250,8 @@ describe('StartFormComponent', () => {
|
||||
const dropdownField = formFields.find((field) => field.id === 'mockTypeDropDown');
|
||||
const dropdownWidget = fixture.debugElement.nativeElement.querySelector('dropdown-widget');
|
||||
const dropdownLabel = fixture.debugElement.nativeElement.querySelector('.adf-dropdown-widget .adf-label');
|
||||
const selectElement = fixture.debugElement.nativeElement.querySelector('.adf-select .mat-select-trigger');
|
||||
selectElement.click();
|
||||
const selectElement = await loader.getHarness(MatSelectHarness);
|
||||
await selectElement.open();
|
||||
|
||||
expect(selectElement).toBeTruthy();
|
||||
expect(dropdownWidget).toBeTruthy();
|
||||
@@ -300,7 +307,7 @@ describe('StartFormComponent', () => {
|
||||
|
||||
const formFieldsWidget = fixture.debugElement.nativeElement.querySelector('form-field');
|
||||
const inputElement = fixture.debugElement.nativeElement.querySelector('.adf-input');
|
||||
const inputLabelElement = fixture.debugElement.nativeElement.querySelector('.mat-form-field-infix > .adf-label');
|
||||
const inputLabelElement = fixture.debugElement.nativeElement.querySelector('.adf-label');
|
||||
const dateElement = fixture.debugElement.nativeElement.querySelector('#billdate');
|
||||
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#billdate-label');
|
||||
const selectElement = fixture.debugElement.nativeElement.querySelector('#claimtype');
|
||||
@@ -322,14 +329,9 @@ describe('StartFormComponent', () => {
|
||||
component.showOutcomeButtons = true;
|
||||
component.showRefreshButton = true;
|
||||
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const refreshElement = fixture.debugElement.nativeElement.querySelector('.mat-card-actions>button');
|
||||
refreshElement.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const refreshElement = await (await loader.getHarness(MatCardHarness)).getHarness(MatButtonHarness);
|
||||
await refreshElement.click();
|
||||
|
||||
/* cspell:disable-next-line */
|
||||
const selectElement = fixture.debugElement.nativeElement.querySelector('#claimtype');
|
||||
@@ -370,17 +372,17 @@ describe('StartFormComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const titleElement = fixture.debugElement.nativeElement.querySelector('mat-card-title>h2');
|
||||
const actionButtons = fixture.debugElement.nativeElement.querySelectorAll('.mat-button');
|
||||
const cardTitle = await loader.getHarness(MatCardHarness);
|
||||
const actionButtons = await loader.getAllHarnesses(MatButtonHarness);
|
||||
|
||||
expect(titleElement.innerText.trim()).toEqual('Mock Title');
|
||||
expect(await cardTitle.getTitleText()).toEqual('Mock Title');
|
||||
expect(actionButtons.length).toBe(4);
|
||||
expect(actionButtons[0].innerText.trim()).toBe('SAVE');
|
||||
expect(actionButtons[0].disabled).toBeFalsy();
|
||||
expect(actionButtons[1].innerText.trim()).toBe('APPROVE');
|
||||
expect(actionButtons[1].disabled).toBeTruthy();
|
||||
expect(actionButtons[2].innerText.trim()).toBe('COMPLETE');
|
||||
expect(actionButtons[2].disabled).toBeTruthy();
|
||||
expect(await actionButtons[0].getText()).toBe('SAVE');
|
||||
expect(await actionButtons[0].isDisabled()).toBeFalsy();
|
||||
expect(await actionButtons[1].getText()).toBe('APPROVE');
|
||||
expect(await actionButtons[1].isDisabled()).toBeTruthy();
|
||||
expect(await actionButtons[2].getText()).toBe('COMPLETE');
|
||||
expect(await actionButtons[2].isDisabled()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -16,46 +16,34 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import {
|
||||
WidgetVisibilityService,
|
||||
FormFieldOption,
|
||||
FormFieldModel,
|
||||
FormModel,
|
||||
FormFieldTypes,
|
||||
CoreTestingModule
|
||||
} from '@alfresco/adf-core';
|
||||
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';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
|
||||
describe('DropdownWidgetComponent', () => {
|
||||
|
||||
let taskFormService: TaskFormService;
|
||||
let processDefinitionService: ProcessDefinitionService;
|
||||
let widget: DropdownWidgetComponent;
|
||||
let visibilityService: WidgetVisibilityService;
|
||||
let fixture: ComponentFixture<DropdownWidgetComponent>;
|
||||
let element: HTMLElement;
|
||||
|
||||
const openSelect = () => {
|
||||
const dropdown = fixture.debugElement.nativeElement.querySelector('.mat-select-trigger');
|
||||
dropdown.click();
|
||||
};
|
||||
let loader: HarnessLoader;
|
||||
|
||||
const fakeOptionList: FormFieldOption[] = [
|
||||
{id: 'opt_1', name: 'option_1'},
|
||||
{id: 'opt_2', name: 'option_2'},
|
||||
{id: 'opt_3', name: 'option_3'}];
|
||||
{ id: 'opt_1', name: 'option_1' },
|
||||
{ id: 'opt_2', name: 'option_2' },
|
||||
{ id: 'opt_3', name: 'option_3' }
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), CoreTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(DropdownWidgetComponent);
|
||||
widget = fixture.componentInstance;
|
||||
@@ -64,6 +52,7 @@ describe('DropdownWidgetComponent', () => {
|
||||
visibilityService = TestBed.inject(WidgetVisibilityService);
|
||||
processDefinitionService = TestBed.inject(ProcessDefinitionService);
|
||||
widget.field = new FormFieldModel(new FormModel());
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
it('should require field with restUrl', () => {
|
||||
@@ -73,7 +62,7 @@ describe('DropdownWidgetComponent', () => {
|
||||
widget.ngOnInit();
|
||||
expect(taskFormService.getRestFieldValues).not.toHaveBeenCalled();
|
||||
|
||||
widget.field = new FormFieldModel(null, {restUrl: null});
|
||||
widget.field = new FormFieldModel(null, { restUrl: null });
|
||||
widget.ngOnInit();
|
||||
expect(taskFormService.getRestFieldValues).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -102,14 +91,17 @@ describe('DropdownWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should preserve empty option when loading fields', () => {
|
||||
const restFieldValue: FormFieldOption = {id: '1', name: 'Option1'} as FormFieldOption;
|
||||
spyOn(taskFormService, 'getRestFieldValues').and.callFake(() => new Observable((observer) => {
|
||||
observer.next([restFieldValue]);
|
||||
observer.complete();
|
||||
}));
|
||||
const restFieldValue: FormFieldOption = { id: '1', name: 'Option1' } as FormFieldOption;
|
||||
spyOn(taskFormService, 'getRestFieldValues').and.callFake(
|
||||
() =>
|
||||
new Observable((observer) => {
|
||||
observer.next([restFieldValue]);
|
||||
observer.complete();
|
||||
})
|
||||
);
|
||||
|
||||
const form = new FormModel({taskId: '<id>'});
|
||||
const emptyOption: FormFieldOption = {id: 'empty', name: 'Empty'} as FormFieldOption;
|
||||
const form = new FormModel({ taskId: '<id>' });
|
||||
const emptyOption: FormFieldOption = { id: 'empty', name: 'Empty' } as FormFieldOption;
|
||||
widget.field = new FormFieldModel(form, {
|
||||
id: '<id>',
|
||||
restUrl: '/some/url/address',
|
||||
@@ -125,9 +117,8 @@ describe('DropdownWidgetComponent', () => {
|
||||
});
|
||||
|
||||
describe('when is required', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
widget.field = new FormFieldModel(new FormModel({taskId: '<id>'}), {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
required: true
|
||||
});
|
||||
@@ -167,37 +158,31 @@ describe('DropdownWidgetComponent', () => {
|
||||
});
|
||||
|
||||
describe('when template is ready', () => {
|
||||
|
||||
describe('and dropdown is populated via taskId', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||
spyOn(taskFormService, 'getRestFieldValues').and.callFake(() => of(fakeOptionList));
|
||||
widget.field = new FormFieldModel(new FormModel({taskId: 'fake-task-id'}), {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: 'false',
|
||||
restUrl: 'fake-rest-url'
|
||||
});
|
||||
widget.field.emptyOption = {id: 'empty', name: 'Choose one...'};
|
||||
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
|
||||
widget.field.isVisible = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show visible dropdown widget', async () => {
|
||||
expect(element.querySelector('#dropdown-id')).toBeDefined();
|
||||
expect(element.querySelector('#dropdown-id')).not.toBeNull();
|
||||
const dropdown = await loader.getHarness(MatSelectHarness.with({ selector: '#dropdown-id' }));
|
||||
await dropdown.open();
|
||||
const options = await dropdown.getOptions();
|
||||
|
||||
openSelect();
|
||||
|
||||
const optOne = fixture.debugElement.queryAll(By.css('[id="mat-option-1"]'));
|
||||
const optTwo = fixture.debugElement.queryAll(By.css('[id="mat-option-2"]'));
|
||||
const optThree = fixture.debugElement.queryAll(By.css('[id="mat-option-3"]'));
|
||||
|
||||
expect(optOne).not.toBeNull();
|
||||
expect(optTwo).not.toBeNull();
|
||||
expect(optThree).not.toBeNull();
|
||||
expect(await options[0].getText()).toBe(widget.field.emptyOption.name);
|
||||
expect(await options[1].getText()).toBe(fakeOptionList[0].name);
|
||||
expect(await options[2].getText()).toBe(fakeOptionList[1].name);
|
||||
expect(await options[3].getText()).toBe(fakeOptionList[2].name);
|
||||
});
|
||||
|
||||
it('should select the default value when an option is chosen as default', async () => {
|
||||
@@ -216,13 +201,7 @@ describe('DropdownWidgetComponent', () => {
|
||||
widget.field.value = 'empty';
|
||||
widget.ngOnInit();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
openSelect();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await (await loader.getHarness(MatSelectHarness)).open();
|
||||
|
||||
const dropDownElement: any = element.querySelector('#dropdown-id');
|
||||
expect(dropDownElement.attributes['ng-reflect-model'].value).toBe('empty');
|
||||
@@ -230,35 +209,30 @@ describe('DropdownWidgetComponent', () => {
|
||||
});
|
||||
|
||||
describe('and dropdown is populated via processDefinitionId', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||
spyOn(processDefinitionService, 'getRestFieldValuesByProcessId').and.callFake(() => of(fakeOptionList));
|
||||
widget.field = new FormFieldModel(new FormModel({processDefinitionId: 'fake-process-id'}), {
|
||||
widget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: 'false',
|
||||
restUrl: 'fake-rest-url'
|
||||
});
|
||||
widget.field.emptyOption = {id: 'empty', name: 'Choose one...'};
|
||||
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
|
||||
widget.field.isVisible = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show visible dropdown widget', () => {
|
||||
expect(element.querySelector('#dropdown-id')).toBeDefined();
|
||||
expect(element.querySelector('#dropdown-id')).not.toBeNull();
|
||||
it('should show visible dropdown widget', async () => {
|
||||
const dropdown = await loader.getHarness(MatSelectHarness.with({ selector: '#dropdown-id' }));
|
||||
await dropdown.open();
|
||||
const options = await dropdown.getOptions();
|
||||
|
||||
openSelect();
|
||||
|
||||
const optOne = fixture.debugElement.queryAll(By.css('[id="mat-option-1"]'));
|
||||
const optTwo = fixture.debugElement.queryAll(By.css('[id="mat-option-2"]'));
|
||||
const optThree = fixture.debugElement.queryAll(By.css('[id="mat-option-3"]'));
|
||||
|
||||
expect(optOne).not.toBeNull();
|
||||
expect(optTwo).not.toBeNull();
|
||||
expect(optThree).not.toBeNull();
|
||||
expect(await options[0].getText()).toBe(widget.field.emptyOption.name);
|
||||
expect(await options[1].getText()).toBe(fakeOptionList[0].name);
|
||||
expect(await options[2].getText()).toBe(fakeOptionList[1].name);
|
||||
expect(await options[3].getText()).toBe(fakeOptionList[2].name);
|
||||
});
|
||||
|
||||
it('should select the default value when an option is chosen as default', async () => {
|
||||
@@ -276,21 +250,14 @@ describe('DropdownWidgetComponent', () => {
|
||||
it('should select the empty value when no default is chosen', async () => {
|
||||
widget.field.value = 'empty';
|
||||
widget.ngOnInit();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
openSelect();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await (await loader.getHarness(MatSelectHarness)).open();
|
||||
|
||||
const dropDownElement: any = element.querySelector('#dropdown-id');
|
||||
expect(dropDownElement.attributes['ng-reflect-model'].value).toBe('empty');
|
||||
});
|
||||
|
||||
it('should be disabled when the field is readonly', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel({processDefinitionId: 'fake-process-id'}), {
|
||||
widget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
@@ -307,25 +274,18 @@ describe('DropdownWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should show the option value when the field is readonly', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel({processDefinitionId: 'fake-process-id'}), {
|
||||
widget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'readonly',
|
||||
value: 'FakeValue',
|
||||
readOnly: true,
|
||||
params: {field: {name: 'date-name', type: 'dropdown'}}
|
||||
params: { field: { name: 'date-name', type: 'dropdown' } }
|
||||
});
|
||||
|
||||
openSelect();
|
||||
const select = await loader.getHarness(MatSelectHarness);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
||||
expect(options.length).toBe(1);
|
||||
|
||||
const option = options[0].nativeElement;
|
||||
expect(option.innerText).toEqual('FakeValue');
|
||||
expect(await select.getValueText()).toEqual('FakeValue');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -13,4 +13,5 @@
|
||||
<mat-option *ngFor="let opt of options" [value]="opt.name" [id]="opt.id">{{opt.name}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<span *ngFor="let opt of options" id="testme">{{opt | json}}</span>
|
||||
</div>
|
||||
|
@@ -16,31 +16,33 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
CoreTestingModule,
|
||||
FormFieldModel,
|
||||
FormModel,
|
||||
FormService
|
||||
} from '@alfresco/adf-core';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { FormFieldModel, FormModel, FormService, TranslationMock, TranslationService } 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';
|
||||
import { DynamicTableModel } from '../models/dynamic-table.widget.model';
|
||||
import { DropdownEditorComponent } from './dropdown.editor';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { TaskFormService } from '../../../../services/task-form.service';
|
||||
import { ProcessDefinitionService } from '../../../../services/process-definition.service';
|
||||
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';
|
||||
|
||||
describe('DropdownEditorComponent', () => {
|
||||
|
||||
let fixture: ComponentFixture<DropdownEditorComponent>;
|
||||
let component: DropdownEditorComponent;
|
||||
let loader: HarnessLoader;
|
||||
let formService: FormService;
|
||||
let taskFormService: TaskFormService;
|
||||
let processDefinitionService: ProcessDefinitionService;
|
||||
let alfrescoApiService: AlfrescoApiService;
|
||||
let form: FormModel;
|
||||
let table: DynamicTableModel;
|
||||
let column: DynamicTableColumn;
|
||||
@@ -50,254 +52,211 @@ describe('DropdownEditorComponent', () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule
|
||||
]
|
||||
CommonModule,
|
||||
NoopAnimationsModule,
|
||||
MatFormFieldModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
FormModule
|
||||
],
|
||||
providers: [{ provide: TranslationService, useClass: TranslationMock }]
|
||||
});
|
||||
alfrescoApiService = TestBed.inject(AlfrescoApiService);
|
||||
formService = TestBed.inject(FormService);
|
||||
taskFormService = TestBed.inject(TaskFormService);
|
||||
processDefinitionService = TestBed.inject(ProcessDefinitionService);
|
||||
|
||||
formService = new FormService();
|
||||
taskFormService = new TaskFormService(alfrescoApiService, null);
|
||||
processDefinitionService = new ProcessDefinitionService(alfrescoApiService, null);
|
||||
fixture = TestBed.createComponent(DropdownEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
row = {value: {dropdown: 'one'}} as DynamicTableRow;
|
||||
row = { value: { dropdown: 'one' } } as DynamicTableRow;
|
||||
column = {
|
||||
id: 'dropdown',
|
||||
options: [
|
||||
{id: '1', name: 'one'},
|
||||
{id: '2', name: 'two'}
|
||||
]
|
||||
{ id: '1', name: 'one' },
|
||||
{ id: '2', name: 'two' }
|
||||
],
|
||||
editable: true
|
||||
} as DynamicTableColumn;
|
||||
|
||||
form = new FormModel({taskId: '<task-id>'});
|
||||
table = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}), formService);
|
||||
form = new FormModel({ taskId: '<task-id>' });
|
||||
table = new DynamicTableModel(new FormFieldModel(form, { id: '<field-id>', isVisible: true }), formService);
|
||||
table.rows.push(row);
|
||||
table.columns.push(column);
|
||||
|
||||
component = new DropdownEditorComponent(formService, taskFormService, processDefinitionService, null);
|
||||
component.table = table;
|
||||
component.row = row;
|
||||
component.column = column;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
it('should require table field to setup', () => {
|
||||
table.field = null;
|
||||
component.ngOnInit();
|
||||
expect(component.value).toBeNull();
|
||||
expect(component.options).toEqual([]);
|
||||
});
|
||||
describe('dropdown is populated manually', () => {
|
||||
beforeEach(() => {
|
||||
column = {
|
||||
id: 'dropdown',
|
||||
options: [
|
||||
{ id: '1', name: 'one' },
|
||||
{ id: '2', name: 'two' }
|
||||
]
|
||||
} as DynamicTableColumn;
|
||||
|
||||
it('should setup with manual mode', () => {
|
||||
row.value[column.id] = 'two';
|
||||
component.ngOnInit();
|
||||
expect(component.options).toEqual(column.options);
|
||||
expect(component.value).toBe(row.value[column.id]);
|
||||
});
|
||||
component.column = column;
|
||||
});
|
||||
|
||||
it('should setup empty columns for manual mode', () => {
|
||||
column.options = null;
|
||||
component.ngOnInit();
|
||||
expect(component.options).toEqual([]);
|
||||
});
|
||||
|
||||
it('should setup with REST mode', () => {
|
||||
column.optionType = 'rest';
|
||||
row.value[column.id] = 'twelve';
|
||||
|
||||
const restResults: DynamicTableColumnOption[] = [
|
||||
{id: '11', name: 'eleven'},
|
||||
{id: '12', name: 'twelve'}
|
||||
];
|
||||
|
||||
spyOn(taskFormService, 'getRestFieldValuesColumn').and.returnValue(
|
||||
new Observable((observer) => {
|
||||
observer.next(restResults);
|
||||
observer.complete();
|
||||
})
|
||||
);
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(taskFormService.getRestFieldValuesColumn).toHaveBeenCalledWith(
|
||||
form.taskId,
|
||||
table.field.id,
|
||||
column.id
|
||||
);
|
||||
|
||||
expect(column.options).toEqual(restResults);
|
||||
expect(component.options).toEqual(restResults);
|
||||
expect(component.value).toBe(row.value[column.id]);
|
||||
});
|
||||
|
||||
it('should create empty options array on REST response', () => {
|
||||
column.optionType = 'rest';
|
||||
|
||||
spyOn(taskFormService, 'getRestFieldValuesColumn').and.returnValue(
|
||||
new Observable((observer) => {
|
||||
observer.next(null);
|
||||
observer.complete();
|
||||
})
|
||||
);
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(taskFormService.getRestFieldValuesColumn).toHaveBeenCalledWith(
|
||||
form.taskId,
|
||||
table.field.id,
|
||||
column.id
|
||||
);
|
||||
|
||||
expect(column.options).toEqual([]);
|
||||
expect(component.options).toEqual([]);
|
||||
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();
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.handleError).toHaveBeenCalledWith(error);
|
||||
});
|
||||
|
||||
it('should update row on value change', () => {
|
||||
const event = {value: 'two'};
|
||||
component.onValueChanged(row, column, event);
|
||||
expect(row.value[column.id]).toBe(column.options[1]);
|
||||
});
|
||||
|
||||
describe('when template is ready', () => {
|
||||
let dropDownEditorComponent: DropdownEditorComponent;
|
||||
let fixture: ComponentFixture<DropdownEditorComponent>;
|
||||
let element: HTMLElement;
|
||||
let dynamicTable: DynamicTableModel;
|
||||
|
||||
const openSelect = () => {
|
||||
const dropdown = fixture.debugElement.query(By.css('.mat-select-trigger'));
|
||||
dropdown.triggerEventHandler('click', null);
|
||||
it('should require table field to setup', () => {
|
||||
table.field = null;
|
||||
fixture.detectChanges();
|
||||
};
|
||||
expect(component.value).toBeNull();
|
||||
expect(component.options).toEqual([]);
|
||||
});
|
||||
|
||||
it('should setup with manual mode', () => {
|
||||
row.value[column.id] = 'two';
|
||||
fixture.detectChanges();
|
||||
expect(component.options).toEqual(column.options);
|
||||
expect(component.value).toBe(row.value[column.id]);
|
||||
});
|
||||
|
||||
it('should setup empty columns for manual mode', () => {
|
||||
column.options = null;
|
||||
fixture.detectChanges();
|
||||
expect(component.options).toEqual([]);
|
||||
});
|
||||
|
||||
it('should setup with REST mode', () => {
|
||||
column.optionType = 'rest';
|
||||
row.value[column.id] = 'twelve';
|
||||
|
||||
const restResults: DynamicTableColumnOption[] = [
|
||||
{ id: '11', name: 'eleven' },
|
||||
{ id: '12', name: 'twelve' }
|
||||
];
|
||||
|
||||
spyOn(taskFormService, 'getRestFieldValuesColumn').and.returnValue(
|
||||
new Observable((observer) => {
|
||||
observer.next(restResults);
|
||||
observer.complete();
|
||||
})
|
||||
);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(taskFormService.getRestFieldValuesColumn).toHaveBeenCalledWith(form.taskId, table.field.id, column.id);
|
||||
|
||||
expect(column.options).toEqual(restResults);
|
||||
expect(component.options).toEqual(restResults);
|
||||
expect(component.value).toBe(row.value[column.id]);
|
||||
});
|
||||
|
||||
it('should create empty options array on REST response', () => {
|
||||
column.optionType = 'rest';
|
||||
|
||||
spyOn(taskFormService, 'getRestFieldValuesColumn').and.returnValue(
|
||||
new Observable((observer) => {
|
||||
observer.next(null);
|
||||
observer.complete();
|
||||
})
|
||||
);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(taskFormService.getRestFieldValuesColumn).toHaveBeenCalledWith(form.taskId, table.field.id, column.id);
|
||||
|
||||
expect(column.options).toEqual([]);
|
||||
expect(component.options).toEqual([]);
|
||||
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);
|
||||
expect(row.value[column.id]).toBe(column.options[1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dropdown is populated via taskId', () => {
|
||||
let getRestFieldValuesColumnSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(async () => {
|
||||
form = new FormModel({ taskId: '<task-id>' });
|
||||
table = new DynamicTableModel(new FormFieldModel(form, { id: '<field-id>' }), formService);
|
||||
component.table = table;
|
||||
component.table.field = new FormFieldModel(form, {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: 'false',
|
||||
restUrl: 'fake-rest-url'
|
||||
});
|
||||
component.column.optionType = 'rest';
|
||||
component.table.field.isVisible = true;
|
||||
getRestFieldValuesColumnSpy = spyOn(taskFormService, 'getRestFieldValuesColumn').and.returnValue(of(column.options));
|
||||
});
|
||||
|
||||
it('should show visible dropdown widget', async () => {
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ selector: '#dropdown' }));
|
||||
await select.open();
|
||||
const options = await select.getOptions();
|
||||
|
||||
expect(getRestFieldValuesColumnSpy).toHaveBeenCalled();
|
||||
expect(component.options.length).toBe(2);
|
||||
expect(options.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dropdown is populated via processDefinitionId', () => {
|
||||
let getRestFieldValuesColumnByProcessId: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DropdownEditorComponent);
|
||||
dropDownEditorComponent = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
form = new FormModel({ processDefinitionId: '<proc-id>' });
|
||||
table = new DynamicTableModel(new FormFieldModel(form, { id: '<field-id>' }), formService);
|
||||
component.table = table;
|
||||
component.table.field = new FormFieldModel(form, {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: 'false',
|
||||
restUrl: 'fake-rest-url'
|
||||
});
|
||||
component.column.optionType = 'rest';
|
||||
component.table.field.isVisible = true;
|
||||
getRestFieldValuesColumnByProcessId = spyOn(processDefinitionService, 'getRestFieldValuesColumnByProcessId').and.returnValue(
|
||||
of(column.options)
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
it('should show visible dropdown widget', async () => {
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ selector: '#dropdown' }));
|
||||
await select.open();
|
||||
|
||||
describe('and dropdown is populated via taskId', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
row = {value: {dropdown: 'one'}} as DynamicTableRow;
|
||||
column = {
|
||||
id: 'column-id',
|
||||
optionType: 'rest',
|
||||
options: [
|
||||
{id: '1', name: 'one'},
|
||||
{id: '2', name: 'two'}
|
||||
]
|
||||
} as DynamicTableColumn;
|
||||
form = new FormModel({taskId: '<task-id>'});
|
||||
dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}), formService);
|
||||
dynamicTable.rows.push(row);
|
||||
dynamicTable.columns.push(column);
|
||||
dropDownEditorComponent.table = dynamicTable;
|
||||
dropDownEditorComponent.column = column;
|
||||
dropDownEditorComponent.row = row;
|
||||
dropDownEditorComponent.table.field = new FormFieldModel(form, {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: 'false',
|
||||
restUrl: 'fake-rest-url'
|
||||
});
|
||||
dropDownEditorComponent.table.field.isVisible = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show visible dropdown widget', () => {
|
||||
expect(element.querySelector('#column-id')).toBeDefined();
|
||||
expect(element.querySelector('#column-id')).not.toBeNull();
|
||||
|
||||
openSelect();
|
||||
|
||||
const optOne = fixture.debugElement.queryAll(By.css('[id="mat-option-1"]'));
|
||||
const optTwo = fixture.debugElement.queryAll(By.css('[id="mat-option-2"]'));
|
||||
const optThree = fixture.debugElement.queryAll(By.css('[id="mat-option-3"]'));
|
||||
|
||||
expect(optOne).not.toBeNull();
|
||||
expect(optTwo).not.toBeNull();
|
||||
expect(optThree).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('and dropdown is populated via processDefinitionId', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
row = {value: {dropdown: 'one'}} as DynamicTableRow;
|
||||
column = {
|
||||
id: 'column-id',
|
||||
optionType: 'rest',
|
||||
options: [
|
||||
{id: '1', name: 'one'},
|
||||
{id: '2', name: 'two'}
|
||||
]
|
||||
} as DynamicTableColumn;
|
||||
form = new FormModel({processDefinitionId: '<proc-id>'});
|
||||
dynamicTable = new DynamicTableModel(new FormFieldModel(form, {id: '<field-id>'}), formService);
|
||||
dynamicTable.rows.push(row);
|
||||
dynamicTable.columns.push(column);
|
||||
dropDownEditorComponent.table = dynamicTable;
|
||||
dropDownEditorComponent.column = column;
|
||||
dropDownEditorComponent.row = row;
|
||||
dropDownEditorComponent.table.field = new FormFieldModel(form, {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: 'false',
|
||||
restUrl: 'fake-rest-url'
|
||||
});
|
||||
dropDownEditorComponent.table.field.isVisible = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show visible dropdown widget', () => {
|
||||
expect(element.querySelector('#column-id')).toBeDefined();
|
||||
expect(element.querySelector('#column-id')).not.toBeNull();
|
||||
|
||||
openSelect();
|
||||
|
||||
const optOne = fixture.debugElement.queryAll(By.css('[id="mat-option-1"]'));
|
||||
const optTwo = fixture.debugElement.queryAll(By.css('[id="mat-option-2"]'));
|
||||
const optThree = fixture.debugElement.queryAll(By.css('[id="mat-option-3"]'));
|
||||
|
||||
expect(optOne).not.toBeNull();
|
||||
expect(optTwo).not.toBeNull();
|
||||
expect(optThree).not.toBeNull();
|
||||
});
|
||||
const options = await select.getOptions();
|
||||
expect(getRestFieldValuesColumnByProcessId).toHaveBeenCalled();
|
||||
expect(component.options.length).toBe(2);
|
||||
expect(options.length).toBe(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -17,15 +17,7 @@
|
||||
|
||||
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import {
|
||||
FormService,
|
||||
ContainerModel,
|
||||
FormFieldTypes,
|
||||
FormFieldOption,
|
||||
FormFieldModel,
|
||||
FormModel,
|
||||
CoreTestingModule
|
||||
} from '@alfresco/adf-core';
|
||||
import { FormService, ContainerModel, FormFieldTypes, FormFieldOption, FormFieldModel, FormModel, CoreTestingModule } from '@alfresco/adf-core';
|
||||
import { RadioButtonsWidgetComponent } from './radio-buttons.widget';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
@@ -33,9 +25,12 @@ 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';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatRadioButtonHarness, MatRadioGroupHarness } from '@angular/material/radio/testing';
|
||||
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
|
||||
|
||||
describe('RadioButtonsWidgetComponent', () => {
|
||||
|
||||
let formService: FormService;
|
||||
let widget: RadioButtonsWidgetComponent;
|
||||
let taskFormService: TaskFormService;
|
||||
@@ -43,20 +38,14 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule,
|
||||
MatRadioModule,
|
||||
FormsModule,
|
||||
MatIconModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), CoreTestingModule, MatRadioModule, FormsModule, MatIconModule]
|
||||
});
|
||||
taskFormService = TestBed.inject(TaskFormService);
|
||||
processDefinitionService = TestBed.inject(ProcessDefinitionService);
|
||||
|
||||
formService = new FormService();
|
||||
widget = new RadioButtonsWidgetComponent(formService, taskFormService, processDefinitionService, null);
|
||||
widget.field = new FormFieldModel(new FormModel(), {restUrl: '<url>'});
|
||||
widget.field = new FormFieldModel(new FormModel(), { restUrl: '<url>' });
|
||||
});
|
||||
|
||||
it('should request field values from service', () => {
|
||||
@@ -72,10 +61,12 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
restUrl: '<url>'
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
@@ -95,10 +86,12 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
const field = widget.field;
|
||||
spyOn(field, 'updateForm').and.stub();
|
||||
|
||||
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(field.updateForm).toHaveBeenCalled();
|
||||
});
|
||||
@@ -115,10 +108,12 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
id: fieldId,
|
||||
restUrl: '<url>'
|
||||
});
|
||||
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();
|
||||
})
|
||||
);
|
||||
|
||||
const field = widget.field;
|
||||
widget.field = null;
|
||||
@@ -146,6 +141,8 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
let radioButtonWidget: RadioButtonsWidgetComponent;
|
||||
let fixture: ComponentFixture<RadioButtonsWidgetComponent>;
|
||||
let element: HTMLElement;
|
||||
let loader: HarnessLoader;
|
||||
|
||||
const restOption: FormFieldOption[] = [
|
||||
{
|
||||
id: 'opt-1',
|
||||
@@ -154,12 +151,14 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
{
|
||||
id: 'opt-2',
|
||||
name: 'opt-name-2'
|
||||
}];
|
||||
}
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(RadioButtonsWidgetComponent);
|
||||
radioButtonWidget = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
it('should show radio buttons as text when is readonly', async () => {
|
||||
@@ -170,8 +169,7 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
readOnly: true
|
||||
});
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(element.querySelector('display-text-widget')).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -197,26 +195,21 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
options: restOption,
|
||||
restUrl: null
|
||||
});
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
const widgetLabel = element.querySelector('label');
|
||||
expect(widgetLabel.innerText).toBe('radio-name-label*');
|
||||
expect(radioButtonWidget.field.isValid).toBe(false);
|
||||
|
||||
const option = element.querySelector<HTMLElement>('#radio-id-opt-1 label');
|
||||
option.click();
|
||||
const option = await loader.getHarness(MatRadioButtonHarness.with({ selector: '#radio-id-opt-1' }));
|
||||
await option.check();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
const selectedOption = element.querySelector<HTMLElement>('[class*="mat-radio-checked"]');
|
||||
expect(selectedOption.innerText).toBe('opt-name-1');
|
||||
const selectedOption = await loader.getHarness(MatRadioButtonHarness.with({ checked: true }));
|
||||
expect(await selectedOption.getLabelText()).toBe('opt-name-1');
|
||||
expect(radioButtonWidget.field.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to set another Radio Button widget as required', () => {
|
||||
it('should be able to set another Radio Button widget as required', async () => {
|
||||
radioButtonWidget.field = new FormFieldModel(new FormModel({}), {
|
||||
id: 'radio-id',
|
||||
name: 'radio-name-label',
|
||||
@@ -228,10 +221,10 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
restUrl: null,
|
||||
value: 'opt-name-2'
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
const selectedOption = element.querySelector<HTMLElement>('[class*="mat-radio-checked"]');
|
||||
expect(selectedOption.innerText).toBe('opt-name-2');
|
||||
|
||||
const selectedOption = await loader.getHarness(MatRadioButtonHarness.with({ checked: true }));
|
||||
expect(await selectedOption.getLabelText()).toBe('opt-name-2');
|
||||
expect(radioButtonWidget.field.isValid).toBe(true);
|
||||
});
|
||||
|
||||
@@ -249,19 +242,16 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const radioButtonsElement: any = element.querySelector('#radio-id-opt-1');
|
||||
const tooltip = radioButtonsElement.getAttribute('ng-reflect-message');
|
||||
|
||||
expect(tooltip).toEqual(radioButtonWidget.field.tooltip);
|
||||
const tooltip = await loader.getHarness(MatTooltipHarness.with({ selector: '#radio-id-opt-1' }));
|
||||
await tooltip.show();
|
||||
expect(await tooltip.getTooltipText()).toEqual(radioButtonWidget.field.tooltip);
|
||||
});
|
||||
|
||||
describe('and radioButton is populated via taskId', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(taskFormService, 'getRestFieldValues').and.returnValue(of(restOption));
|
||||
radioButtonWidget.field = new FormFieldModel(new FormModel({taskId: 'task-id'}), {
|
||||
radioButtonWidget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }), {
|
||||
id: 'radio-id',
|
||||
name: 'radio-name',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
@@ -293,37 +283,38 @@ describe('RadioButtonsWidgetComponent', () => {
|
||||
}));
|
||||
|
||||
describe('and radioButton is readonly', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
radioButtonWidget.field.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show radio buttons disabled', () => {
|
||||
expect(element.querySelector('.mat-radio-disabled[ng-reflect-id="radio-id-opt-1"]')).toBeDefined();
|
||||
expect(element.querySelector('.mat-radio-disabled[ng-reflect-id="radio-id-opt-1"]')).not.toBeNull();
|
||||
expect(element.querySelector('.mat-radio-disabled[ng-reflect-id="radio-id-opt-2"]')).toBeDefined();
|
||||
expect(element.querySelector('.mat-radio-disabled[ng-reflect-id="radio-id-opt-2"]')).not.toBeNull();
|
||||
it('should show radio buttons disabled', async () => {
|
||||
const radioButtons = await (
|
||||
await loader.getHarness(MatRadioGroupHarness.with({ selector: '.adf-radio-group' }))
|
||||
).getRadioButtons();
|
||||
expect(await radioButtons[0].isDisabled()).toBe(true);
|
||||
expect(await radioButtons[1].isDisabled()).toBe(true);
|
||||
});
|
||||
|
||||
describe('and a value is selected', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
radioButtonWidget.field.value = restOption[0].id;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should check the selected value', () => {
|
||||
expect(element.querySelector('.mat-radio-checked')).toBe(element.querySelector('mat-radio-button[ng-reflect-id="radio-id-opt-1"]'));
|
||||
it('should check the selected value', async () => {
|
||||
const checkedRadioButton = await (
|
||||
await loader.getHarness(MatRadioGroupHarness.with({ selector: '.adf-radio-group' }))
|
||||
).getCheckedRadioButton();
|
||||
expect(await checkedRadioButton.getLabelText()).toBe(restOption[0].name);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and radioButton is populated via processDefinitionId', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
radioButtonWidget.field = new FormFieldModel(new FormModel({processDefinitionId: 'proc-id'}), {
|
||||
radioButtonWidget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'proc-id' }), {
|
||||
id: 'radio-id',
|
||||
name: 'radio-name',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DebugElement, NO_ERRORS_SCHEMA, SimpleChange } from '@angular/core';
|
||||
import { NO_ERRORS_SCHEMA, SimpleChange } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of } from 'rxjs';
|
||||
@@ -28,12 +28,16 @@ import { ProcessInstanceDetailsComponent } from './process-instance-details.comp
|
||||
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>;
|
||||
let loader: HarnessLoader;
|
||||
let getProcessSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -48,6 +52,7 @@ describe('ProcessInstanceDetailsComponent', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(ProcessInstanceDetailsComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
service = fixture.debugElement.injector.get(ProcessService);
|
||||
const commentService = fixture.debugElement.injector.get(CommentProcessService);
|
||||
|
||||
@@ -76,12 +81,8 @@ describe('ProcessInstanceDetailsComponent', () => {
|
||||
fixture.detectChanges();
|
||||
component.ngOnChanges({ processInstanceId: new SimpleChange(null, '123', true) });
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const headerEl: DebugElement = fixture.debugElement.query(By.css('.mat-card-title '));
|
||||
expect(headerEl).not.toBeNull();
|
||||
expect(headerEl.nativeElement.innerText).toBe('Process 123');
|
||||
const headerEl = await loader.getHarness(MatCardHarness);
|
||||
expect(await headerEl.getTitleText()).toBe('Process 123');
|
||||
});
|
||||
|
||||
it('should display default details when the process instance has no name', async () => {
|
||||
@@ -90,12 +91,8 @@ describe('ProcessInstanceDetailsComponent', () => {
|
||||
fixture.detectChanges();
|
||||
component.ngOnChanges({ processInstanceId: new SimpleChange(null, '123', true) });
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const headerEl: DebugElement = fixture.debugElement.query(By.css('.mat-card-title '));
|
||||
expect(headerEl).not.toBeNull();
|
||||
expect(headerEl.nativeElement.innerText).toBe('My Process - Nov 10, 2016, 3:37:30 AM');
|
||||
const headerEl = await loader.getHarness(MatCardHarness);
|
||||
expect(await headerEl.getTitleText()).toBe('My Process - Nov 10, 2016, 3:37:30 AM');
|
||||
});
|
||||
|
||||
it('should enable diagram button if the process is running', async () => {
|
||||
|
@@ -26,48 +26,42 @@ 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';
|
||||
|
||||
describe('ProcessInstanceTasksComponent', () => {
|
||||
|
||||
let component: ProcessInstanceTasksComponent;
|
||||
let fixture: ComponentFixture<ProcessInstanceTasksComponent>;
|
||||
let service: ProcessService;
|
||||
// let getProcessTasksSpy: jasmine.Spy;
|
||||
let loader: HarnessLoader;
|
||||
let processService: ProcessService;
|
||||
|
||||
const exampleProcessInstance = new ProcessInstance({ id: '123' });
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ProcessTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ProcessTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(ProcessInstanceTasksComponent);
|
||||
processService = TestBed.inject(ProcessService);
|
||||
component = fixture.componentInstance;
|
||||
service = TestBed.inject(ProcessService);
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
|
||||
spyOn(service, 'getProcessTasks').and.returnValue(of([new TaskDetailsModel(taskDetailsMock)]));
|
||||
spyOn(processService, 'getProcessTasks').and.returnValue(of([new TaskDetailsModel(taskDetailsMock)]));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should initially render message about no active tasks if no process instance ID provided', async () => {
|
||||
it('should initially render message about no active tasks if no process instance ID provided', () => {
|
||||
component.processInstanceDetails = undefined;
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const msgEl = fixture.debugElement.query(By.css('[data-automation-id="active-tasks-none"]'));
|
||||
expect(msgEl).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should initially render message about no completed tasks if no process instance ID provided', async () => {
|
||||
it('should initially render message about no completed tasks if no process instance ID provided', () => {
|
||||
component.processInstanceDetails = undefined;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const msgEl = fixture.debugElement.query(By.css('[data-automation-id="completed-tasks-none"]'));
|
||||
expect(msgEl).not.toBeNull();
|
||||
@@ -92,13 +86,8 @@ describe('ProcessInstanceTasksComponent', () => {
|
||||
fixture.detectChanges();
|
||||
component.ngOnChanges({ processInstanceDetails: change });
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
component.ngOnChanges({ processInstanceDetails: change });
|
||||
const listEl = fixture.debugElement.query(By.css('[data-automation-id="active-tasks"]'));
|
||||
expect(listEl).not.toBeNull();
|
||||
expect(listEl.queryAll(By.css('mat-list-item')).length).toBe(1);
|
||||
const items = await loader.getAllHarnesses(MatListItemHarness.with({ ancestor: '[data-automation-id="active-tasks"]' }));
|
||||
expect(items.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should display completed tasks', async () => {
|
||||
@@ -106,51 +95,42 @@ describe('ProcessInstanceTasksComponent', () => {
|
||||
fixture.detectChanges();
|
||||
component.ngOnChanges({ processInstanceDetails: change });
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const listEl = fixture.debugElement.query(By.css('[data-automation-id="completed-tasks"]'));
|
||||
expect(listEl).not.toBeNull();
|
||||
expect(listEl.queryAll(By.css('mat-list-item')).length).toBe(1);
|
||||
const items = await loader.getAllHarnesses(MatListItemHarness.with({ ancestor: '[data-automation-id="completed-tasks"]' }));
|
||||
expect(items.length).toBe(1);
|
||||
});
|
||||
|
||||
describe('task reloading', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.processInstanceDetails = exampleProcessInstance;
|
||||
});
|
||||
|
||||
it('should render a refresh button by default', async () => {
|
||||
it('should render a refresh button by default', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(fixture.debugElement.query(By.css('.process-tasks-refresh'))).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should render a refresh button if configured to', async () => {
|
||||
it('should render a refresh button if configured to', () => {
|
||||
component.showRefreshButton = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(fixture.debugElement.query(By.css('.process-tasks-refresh'))).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should NOT render a refresh button if configured not to', async () => {
|
||||
it('should NOT render a refresh button if configured not to', () => {
|
||||
component.showRefreshButton = false;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(fixture.debugElement.query(By.css('.process-tasks-refresh'))).toBeNull();
|
||||
});
|
||||
|
||||
it('should call service to get tasks when reload button clicked', async () => {
|
||||
it('should call service to get tasks when reload button clicked', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
component.onRefreshClicked();
|
||||
expect(service.getProcessTasks).toHaveBeenCalled();
|
||||
expect(processService.getProcessTasks).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -33,11 +33,16 @@ import {
|
||||
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;
|
||||
let service: ProcessService;
|
||||
let getProcessInstancesSpy: jasmine.Spy;
|
||||
let appConfig: AppConfigService;
|
||||
@@ -59,6 +64,7 @@ describe('ProcessInstanceListComponent', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(ProcessInstanceListComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
appConfig = TestBed.inject(AppConfigService);
|
||||
service = TestBed.inject(ProcessService);
|
||||
|
||||
@@ -68,11 +74,9 @@ describe('ProcessInstanceListComponent', () => {
|
||||
};
|
||||
});
|
||||
|
||||
it('should display loading spinner', () => {
|
||||
it('should display loading spinner', async () => {
|
||||
component.isLoading = true;
|
||||
|
||||
const spinner = fixture.debugElement.query(By.css('.mat-progress-spinner'));
|
||||
expect(spinner).toBeDefined();
|
||||
await loader.getHarness(MatProgressSpinnerHarness);
|
||||
});
|
||||
|
||||
it('should use the default schemaColumn as default', () => {
|
||||
@@ -619,6 +623,7 @@ describe('ProcessListContextMenuComponent', () => {
|
||||
let customComponent: ProcessListContextMenuComponent;
|
||||
let processService: ProcessService;
|
||||
let element: HTMLElement;
|
||||
let loader: HarnessLoader;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -631,6 +636,7 @@ describe('ProcessListContextMenuComponent', () => {
|
||||
fixture = TestBed.createComponent(ProcessListContextMenuComponent);
|
||||
customComponent = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
||||
processService = TestBed.inject(ProcessService);
|
||||
customComponent.appId = 12345;
|
||||
spyOn(processService, 'getProcesses').and.returnValue(of(fakeProcessInstance));
|
||||
@@ -645,15 +651,13 @@ describe('ProcessListContextMenuComponent', () => {
|
||||
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 }));
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const contextActions = document.querySelectorAll('.mat-menu-item');
|
||||
|
||||
const contextActions = await loader.getAllHarnesses(MatMenuItemHarness);
|
||||
expect(contextActions.length).toBe(2);
|
||||
expect(contextActions[0]['disabled']).toBe(false, 'View Process Details action not enabled');
|
||||
expect(contextActions[1]['disabled']).toBe(false, 'Cancel Process action not enabled');
|
||||
contextActions[0].dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
expect(await contextActions[0].isDisabled()).toBe(false, 'View Process Details action not enabled');
|
||||
expect(await contextActions[1].isDisabled()).toBe(false, 'Cancel Process action not enabled');
|
||||
|
||||
await contextActions[0].click();
|
||||
expect(contextActionSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DebugElement, SimpleChange } from '@angular/core';
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
@@ -26,18 +26,22 @@ 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 { By } from '@angular/platform-browser';
|
||||
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';
|
||||
import { ActivitiContentService } from '../../form/services/activiti-alfresco.service';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing';
|
||||
|
||||
describe('StartProcessComponent', () => {
|
||||
let appConfig: AppConfigService;
|
||||
let activitiContentService: ActivitiContentService;
|
||||
let component: StartProcessInstanceComponent;
|
||||
let fixture: ComponentFixture<StartProcessInstanceComponent>;
|
||||
let loader: HarnessLoader;
|
||||
let processService: ProcessService;
|
||||
let appsProcessService: AppsProcessService;
|
||||
let getDefinitionsSpy: jasmine.Spy;
|
||||
@@ -52,16 +56,13 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
const selectOptionByName = (name: string) => {
|
||||
const selectOptionByName = async (name: string) => {
|
||||
const selectElement = fixture.nativeElement.querySelector('button#adf-select-process-dropdown');
|
||||
selectElement.click();
|
||||
fixture.detectChanges();
|
||||
const options: any = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
||||
const currentOption = options.find((option: DebugElement) => option.nativeElement.innerHTML.trim() === name);
|
||||
|
||||
if (currentOption) {
|
||||
currentOption.nativeElement.click();
|
||||
}
|
||||
const autocompleteDropdown = await loader.getHarness(MatAutocompleteHarness);
|
||||
const options = await autocompleteDropdown.getOptions({ text: name });
|
||||
expect(options.length).toBe(1);
|
||||
await options[0].click();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -80,6 +81,7 @@ describe('StartProcessComponent', () => {
|
||||
activitiContentService = TestBed.inject(ActivitiContentService);
|
||||
fixture = TestBed.createComponent(StartProcessInstanceComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
processService = TestBed.inject(ProcessService);
|
||||
appsProcessService = TestBed.inject(AppsProcessService);
|
||||
|
||||
@@ -175,11 +177,8 @@ describe('StartProcessComponent', () => {
|
||||
component.processDefinitionInput.setValue('My Default Name');
|
||||
component.processNameInput.setValue('claim');
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const inputLabelsNodes = document.querySelectorAll('.adf-start-process .adf-process-input-container mat-label');
|
||||
expect(inputLabelsNodes.length).toBe(2);
|
||||
const inputLabels = await loader.getAllHarnesses(MatFormFieldHarness.with({ ancestor: '.adf-start-process', selector: '.adf-process-input-container' }));
|
||||
expect(inputLabels.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should have floating labels for process name and type', async () => {
|
||||
@@ -313,13 +312,10 @@ describe('StartProcessComponent', () => {
|
||||
const selectElement = fixture.nativeElement.querySelector('button#adf-select-process-dropdown');
|
||||
selectElement.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const options: any = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
||||
|
||||
const options = await (await loader.getHarness(MatAutocompleteHarness)).getOptions();
|
||||
expect(options.length).toBe(2);
|
||||
expect(options[0].nativeElement.innerText).toBe('My Process 1');
|
||||
expect(options[1].nativeElement.innerText).toBe('My Process 2');
|
||||
expect(await options[0].getText()).toBe('My Process 1');
|
||||
expect(await options[1].getText()).toBe('My Process 2');
|
||||
});
|
||||
|
||||
it('should show no process available message when no process definition is loaded', async () => {
|
||||
@@ -511,24 +507,21 @@ describe('StartProcessComponent', () => {
|
||||
expect(startProcessEmitterSpy).toHaveBeenCalledWith(newProcess);
|
||||
});
|
||||
|
||||
it('should emit processDefinitionSelection event when a process definition is selected', () => {
|
||||
it('should emit processDefinitionSelection event when a process definition is selected', async () => {
|
||||
const processDefinitionSelectionSpy = spyOn(component.processDefinitionSelection, 'emit');
|
||||
fixture.detectChanges();
|
||||
selectOptionByName(testProcessDef.name);
|
||||
await selectOptionByName(testProcessDef.name);
|
||||
|
||||
expect(processDefinitionSelectionSpy).toHaveBeenCalledWith(testProcessDef);
|
||||
});
|
||||
|
||||
it('should set the process name using the processName pipe when a process definition gets selected', () => {
|
||||
it('should set the process name using the processName pipe when a process definition gets selected', async () => {
|
||||
const processNamePipe = TestBed.inject(ProcessNamePipe);
|
||||
const processNamePipeTransformSpy = spyOn(processNamePipe, 'transform').and.returnValue('fake-transformed-name');
|
||||
const expectedProcessInstanceDetails = new ProcessInstance({ processDefinitionName: testProcessDef.name });
|
||||
getDefinitionsSpy = getDefinitionsSpy.and.returnValue(of(testMultipleProcessDefs));
|
||||
|
||||
changeAppId(123);
|
||||
fixture.detectChanges();
|
||||
|
||||
selectOptionByName(testProcessDef.name);
|
||||
await selectOptionByName(testProcessDef.name);
|
||||
|
||||
expect(processNamePipeTransformSpy).toHaveBeenCalledWith(component.name, expectedProcessInstanceDetails);
|
||||
expect(component.nameController.dirty).toBe(true);
|
||||
@@ -570,16 +563,16 @@ describe('StartProcessComponent', () => {
|
||||
getDeployedApplicationsSpy = spyOn(appsProcessService, 'getDeployedApplications').and.returnValue(of(deployedApps));
|
||||
});
|
||||
|
||||
it('Should be able to show application drop-down if showSelectApplicationDropdown set to true', () => {
|
||||
it('Should be able to show application drop-down if showSelectApplicationDropdown set to true', async () => {
|
||||
getDefinitionsSpy.and.returnValue(of(testMultipleProcessDefs));
|
||||
changeAppId(3);
|
||||
fixture.detectChanges();
|
||||
|
||||
const appsSelector = fixture.nativeElement.querySelector('[data-automation-id="adf-start-process-apps-drop-down"]');
|
||||
const labelElement = fixture.nativeElement.querySelector('.adf-start-process-app-list .mat-form-field-label');
|
||||
const labelText = await (await loader.getHarness(MatFormFieldHarness.with({ selector: '.adf-start-process-app-list' }))).getLabel();
|
||||
|
||||
expect(appsSelector).not.toBeNull();
|
||||
expect(labelElement.innerText).toEqual('ADF_PROCESS_LIST.START_PROCESS.FORM.LABEL.SELECT_APPLICATION');
|
||||
expect(labelText).toEqual('ADF_PROCESS_LIST.START_PROCESS.FORM.LABEL.SELECT_APPLICATION');
|
||||
|
||||
expect(getDeployedApplicationsSpy).toHaveBeenCalled();
|
||||
expect(component.applications.length).toBe(6);
|
||||
|
@@ -22,15 +22,18 @@ 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';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatTabGroupHarness, MatTabHarness } from '@angular/material/tabs/testing';
|
||||
|
||||
describe('ProcessUserInfoComponent', () => {
|
||||
const profilePictureUrl = 'alfresco-logo.svg';
|
||||
|
||||
let component: ProcessUserInfoComponent;
|
||||
let fixture: ComponentFixture<ProcessUserInfoComponent>;
|
||||
let loader: HarnessLoader;
|
||||
let element: HTMLElement;
|
||||
|
||||
const openUserInfo = () => {
|
||||
@@ -56,6 +59,7 @@ describe('ProcessUserInfoComponent', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(ProcessUserInfoComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
||||
element = fixture.nativeElement;
|
||||
|
||||
spyOn(window, 'requestAnimationFrame').and.returnValue(1);
|
||||
@@ -120,9 +124,8 @@ describe('ProcessUserInfoComponent', () => {
|
||||
it('should not show the tabs', async () => {
|
||||
await whenFixtureReady();
|
||||
openUserInfo();
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('#tab-group-env')).classes['adf-hide-tab']).toBeTruthy();
|
||||
const tabGroupHost = await (await loader.getHarness(MatTabGroupHarness.with({ selector: '#tab-group-env' }))).host();
|
||||
expect(await tabGroupHost.hasClass('adf-hide-tab')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -138,19 +141,16 @@ describe('ProcessUserInfoComponent', () => {
|
||||
it('should show the tabs', async () => {
|
||||
await whenFixtureReady();
|
||||
openUserInfo();
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('#tab-group-env')).classes['adf-hide-tab']).toBeFalsy();
|
||||
const tabGroupHost = await (await loader.getHarness(MatTabGroupHarness.with({ selector: '#tab-group-env' }))).host();
|
||||
expect(await tabGroupHost.hasClass('adf-hide-tab')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should get the bpm user information', async () => {
|
||||
spyOn(component, 'getBpmUserImage').and.returnValue(profilePictureUrl);
|
||||
await whenFixtureReady();
|
||||
openUserInfo();
|
||||
const bpmTab = fixture.debugElement.queryAll(By.css('#tab-group-env .mat-tab-labels .mat-tab-label'))[1];
|
||||
bpmTab.triggerEventHandler('click', null);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const bpmTab = await loader.getHarness(MatTabHarness.with({ label: 'USER_PROFILE.TAB.PS' }));
|
||||
await bpmTab.select();
|
||||
const bpmUsername = fixture.debugElement.query(By.css('#bpm-username'));
|
||||
const bpmImage = fixture.debugElement.query(By.css('#bpm-user-detail-image'));
|
||||
expect(element.querySelector('#userinfo_container')).not.toBeNull();
|
||||
@@ -198,24 +198,19 @@ describe('ProcessUserInfoComponent', () => {
|
||||
it('should show the tabs for the env', async () => {
|
||||
await whenFixtureReady();
|
||||
openUserInfo();
|
||||
const tabGroup = fixture.debugElement.query(By.css('#tab-group-env'));
|
||||
const tabs = fixture.debugElement.queryAll(By.css('#tab-group-env .mat-tab-labels .mat-tab-label'));
|
||||
const tabGroup = await loader.getHarness(MatTabGroupHarness.with({ selector: '#tab-group-env' }));
|
||||
const tabs = await tabGroup.getTabs();
|
||||
|
||||
expect(tabGroup).not.toBeNull();
|
||||
expect(tabGroup.classes['adf-hide-tab']).toBeFalsy();
|
||||
expect(await (await tabGroup.host()).hasClass('adf-hide-tab')).toBeFalsy();
|
||||
expect(tabs.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should not close the menu when a tab is clicked', async () => {
|
||||
await whenFixtureReady();
|
||||
openUserInfo();
|
||||
const tabGroup = fixture.debugElement.query(By.css('#tab-group-env'));
|
||||
const bpmTab = await loader.getHarness(MatTabHarness.with({ label: 'USER_PROFILE.TAB.PS' }));
|
||||
|
||||
const tabs = fixture.debugElement.queryAll(By.css('#tab-group-env .mat-tab-labels .mat-tab-label'));
|
||||
|
||||
expect(tabGroup).not.toBeNull();
|
||||
tabs[1].triggerEventHandler('click', null);
|
||||
fixture.detectChanges();
|
||||
bpmTab.select();
|
||||
expect(fixture.debugElement.query(By.css('#user-profile-lists'))).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
@@ -24,11 +24,14 @@ 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';
|
||||
|
||||
describe('StartTaskComponent', () => {
|
||||
|
||||
let component: StartTaskComponent;
|
||||
let fixture: ComponentFixture<StartTaskComponent>;
|
||||
let loader: HarnessLoader;
|
||||
let service: TaskListService;
|
||||
let logService: LogService;
|
||||
let element: HTMLElement;
|
||||
@@ -51,14 +54,12 @@ describe('StartTaskComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ProcessTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ProcessTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(StartTaskComponent);
|
||||
component = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
|
||||
service = TestBed.inject(TaskListService);
|
||||
logService = TestBed.inject(LogService);
|
||||
@@ -81,16 +82,15 @@ describe('StartTaskComponent', () => {
|
||||
});
|
||||
|
||||
describe('create task', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
createNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(of(
|
||||
{
|
||||
createNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: null,
|
||||
assignee: null
|
||||
} as any
|
||||
));
|
||||
} as any)
|
||||
);
|
||||
});
|
||||
|
||||
it('should create new task when start is clicked', () => {
|
||||
@@ -140,25 +140,25 @@ describe('StartTaskComponent', () => {
|
||||
|
||||
describe('attach form', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service, 'createNewTask').and.returnValue(of(
|
||||
{
|
||||
spyOn(service, 'createNewTask').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: null,
|
||||
assignee: null
|
||||
} as any
|
||||
));
|
||||
} as any)
|
||||
);
|
||||
});
|
||||
|
||||
it('should attach form to the task when a form is selected', () => {
|
||||
spyOn(service, 'attachFormToATask').and.returnValue(of(
|
||||
{
|
||||
spyOn(service, 'attachFormToATask').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: 1204,
|
||||
assignee: null
|
||||
}
|
||||
));
|
||||
})
|
||||
);
|
||||
const successSpy = spyOn(component.success, 'emit');
|
||||
component.taskForm.controls['name'].setValue('fakeName');
|
||||
component.taskForm.controls['formKey'].setValue(1204);
|
||||
@@ -176,14 +176,14 @@ describe('StartTaskComponent', () => {
|
||||
});
|
||||
|
||||
it('should not attach form to the task when a no form is selected', () => {
|
||||
spyOn(service, 'attachFormToATask').and.returnValue(of(
|
||||
{
|
||||
spyOn(service, 'attachFormToATask').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: null,
|
||||
assignee: null
|
||||
}
|
||||
));
|
||||
})
|
||||
);
|
||||
const successSpy = spyOn(component.success, 'emit');
|
||||
component.taskForm.controls['name'].setValue('fakeName');
|
||||
component.taskForm.controls['formKey'].setValue(null);
|
||||
@@ -203,30 +203,30 @@ describe('StartTaskComponent', () => {
|
||||
|
||||
describe('assign user', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service, 'createNewTask').and.returnValue(of(
|
||||
{
|
||||
spyOn(service, 'createNewTask').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: null,
|
||||
assignee: null
|
||||
} as any
|
||||
));
|
||||
spyOn(service, 'attachFormToATask').and.returnValue(of(
|
||||
{
|
||||
} as any)
|
||||
);
|
||||
spyOn(service, 'attachFormToATask').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: 1204,
|
||||
assignee: null
|
||||
}
|
||||
));
|
||||
spyOn(service, 'assignTaskByUserId').and.returnValue(of(
|
||||
{
|
||||
})
|
||||
);
|
||||
spyOn(service, 'assignTaskByUserId').and.returnValue(
|
||||
of({
|
||||
id: 91,
|
||||
name: 'fakeName',
|
||||
formKey: 1204,
|
||||
assignee: testUser
|
||||
} as any
|
||||
));
|
||||
} as any)
|
||||
);
|
||||
});
|
||||
|
||||
it('should assign task when an assignee is selected', () => {
|
||||
@@ -285,7 +285,7 @@ describe('StartTaskComponent', () => {
|
||||
|
||||
it('should not attach a form when a form id is not selected', () => {
|
||||
const attachFormToATask = spyOn(service, 'attachFormToATask').and.returnValue(of([]));
|
||||
spyOn(service, 'createNewTask').and.returnValue(of(new TaskDetailsModel({ id: 'task-id'})));
|
||||
spyOn(service, 'createNewTask').and.returnValue(of(new TaskDetailsModel({ id: 'task-id' })));
|
||||
component.taskForm.controls['name'].setValue('fakeName');
|
||||
fixture.detectChanges();
|
||||
const createTaskButton = element.querySelector<HTMLElement>('#button-start');
|
||||
@@ -301,9 +301,11 @@ describe('StartTaskComponent', () => {
|
||||
expect(element.querySelector('#button-start').textContent).toContain('ADF_TASK_LIST.START_TASK.FORM.ACTION.START');
|
||||
});
|
||||
|
||||
it('should render start task button with primary color', () => {
|
||||
it('should render start task button with primary color', async () => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('#button-start').classList.contains('mat-primary')).toBeTruthy();
|
||||
|
||||
const buttonEl = await (await loader.getHarness(MatButtonHarness.with({ selector: '#button-start' }))).host();
|
||||
expect(await buttonEl.getAttribute('color')).toBe('primary');
|
||||
});
|
||||
|
||||
it('should render task buttons with uppercase text', () => {
|
||||
|
@@ -21,13 +21,7 @@ import { By } from '@angular/platform-browser';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { FormModel, FormOutcomeEvent, FormOutcomeModel, CommentModel, User } from '@alfresco/adf-core';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import {
|
||||
noDataMock,
|
||||
taskDetailsMock,
|
||||
taskFormMock,
|
||||
tasksMock,
|
||||
taskDetailsWithOutAssigneeMock
|
||||
} from '../../mock';
|
||||
import { noDataMock, taskDetailsMock, taskFormMock, tasksMock, taskDetailsWithOutAssigneeMock } from '../../mock';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import { TaskDetailsComponent } from './task-details.component';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
@@ -37,6 +31,9 @@ import { TaskFormService } from '../../form/services/task-form.service';
|
||||
import { TaskCommentsService } from '../../task-comments/services/task-comments.service';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
import { PeopleProcessService } from '../../common/services/people-process.service';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { MatDialogHarness } from '@angular/material/dialog/testing';
|
||||
|
||||
const fakeUser = new UserProcessModel({
|
||||
id: 'fake-id',
|
||||
@@ -58,6 +55,7 @@ describe('TaskDetailsComponent', () => {
|
||||
let taskFormService: TaskFormService;
|
||||
let component: TaskDetailsComponent;
|
||||
let fixture: ComponentFixture<TaskDetailsComponent>;
|
||||
let loader: HarnessLoader;
|
||||
let getTaskDetailsSpy: jasmine.Spy;
|
||||
let getCommentsSpy: jasmine.Spy;
|
||||
let getTasksSpy: jasmine.Spy;
|
||||
@@ -67,10 +65,7 @@ describe('TaskDetailsComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ProcessTestingModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ProcessTestingModule],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
});
|
||||
peopleProcessService = TestBed.inject(PeopleProcessService);
|
||||
@@ -92,15 +87,18 @@ describe('TaskDetailsComponent', () => {
|
||||
assignTaskSpy = spyOn(taskListService, 'assignTask').and.returnValue(of(fakeTaskAssignResponse));
|
||||
taskCommentsService = TestBed.inject(TaskCommentsService);
|
||||
|
||||
getCommentsSpy = spyOn(taskCommentsService, 'get').and.returnValue(of([
|
||||
new CommentModel({ message: 'Test1', created: new Date(), createdBy: new User({ firstName: 'Admin', lastName: 'User' }) }),
|
||||
new CommentModel({ message: 'Test2', created: new Date(), createdBy: new User({ firstName: 'Admin', lastName: 'User' }) }),
|
||||
new CommentModel({ message: 'Test3', created: new Date(), createdBy: new User({ firstName: 'Admin', lastName: 'User' }) })
|
||||
]));
|
||||
getCommentsSpy = spyOn(taskCommentsService, 'get').and.returnValue(
|
||||
of([
|
||||
new CommentModel({ message: 'Test1', created: new Date(), createdBy: new User({ firstName: 'Admin', lastName: 'User' }) }),
|
||||
new CommentModel({ message: 'Test2', created: new Date(), createdBy: new User({ firstName: 'Admin', lastName: 'User' }) }),
|
||||
new CommentModel({ message: 'Test3', created: new Date(), createdBy: new User({ firstName: 'Admin', lastName: 'User' }) })
|
||||
])
|
||||
);
|
||||
|
||||
fixture = TestBed.createComponent(TaskDetailsComponent);
|
||||
peopleProcessService = TestBed.inject(PeopleProcessService);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -122,7 +120,7 @@ describe('TaskDetailsComponent', () => {
|
||||
|
||||
it('should send a claim task event when a task is claimed', () => {
|
||||
let lastValue: string;
|
||||
component.claimedTask.subscribe((taskId) => lastValue = taskId);
|
||||
component.claimedTask.subscribe((taskId) => (lastValue = taskId));
|
||||
component.onClaimAction('FAKE-TASK-CLAIM');
|
||||
expect(lastValue).toBe('FAKE-TASK-CLAIM');
|
||||
});
|
||||
@@ -182,7 +180,6 @@ describe('TaskDetailsComponent', () => {
|
||||
}));
|
||||
|
||||
describe('change detection', () => {
|
||||
|
||||
let change;
|
||||
let nullChange;
|
||||
|
||||
@@ -209,7 +206,6 @@ describe('TaskDetailsComponent', () => {
|
||||
});
|
||||
|
||||
describe('Form events', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
@@ -289,15 +285,13 @@ describe('TaskDetailsComponent', () => {
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should display a dialog to the user when a form error occurs', () => {
|
||||
let dialogEl = window.document.querySelector('mat-dialog-content');
|
||||
it('should display a dialog to the user when a form error occurs', async () => {
|
||||
const dialogEl = await loader.getHarnessOrNull(MatDialogHarness);
|
||||
expect(dialogEl).toBeNull();
|
||||
|
||||
component.onFormError({});
|
||||
fixture.detectChanges();
|
||||
|
||||
dialogEl = window.document.querySelector('mat-dialog-content');
|
||||
expect(dialogEl).not.toBeNull();
|
||||
await loader.getHarness(MatDialogHarness);
|
||||
});
|
||||
|
||||
it('should emit a task created event when checklist task is created', () => {
|
||||
@@ -306,10 +300,9 @@ describe('TaskDetailsComponent', () => {
|
||||
component.onChecklistTaskCreated(mockTask);
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Comments', () => {
|
||||
|
||||
it('should comments be readonly if the task is complete and no user are involved', () => {
|
||||
component.showComments = true;
|
||||
component.showHeaderContent = true;
|
||||
@@ -381,27 +374,31 @@ describe('TaskDetailsComponent', () => {
|
||||
});
|
||||
|
||||
describe('assign task to user', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should return an observable with user search results', () => {
|
||||
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([{
|
||||
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'
|
||||
}]));
|
||||
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(
|
||||
of([
|
||||
{
|
||||
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'
|
||||
}
|
||||
])
|
||||
);
|
||||
|
||||
let lastValue: UserProcessModel[];
|
||||
component.peopleSearch.subscribe((users) => lastValue = users);
|
||||
component.peopleSearch.subscribe((users) => (lastValue = users));
|
||||
component.searchUser('fake-search-word');
|
||||
|
||||
expect(lastValue.length).toBe(2);
|
||||
@@ -415,7 +412,7 @@ describe('TaskDetailsComponent', () => {
|
||||
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([]));
|
||||
|
||||
let lastValue: UserProcessModel[];
|
||||
component.peopleSearch.subscribe((users) => lastValue = users);
|
||||
component.peopleSearch.subscribe((users) => (lastValue = users));
|
||||
component.searchUser('fake-search-word');
|
||||
|
||||
expect(lastValue.length).toBe(0);
|
||||
|
@@ -30,12 +30,17 @@ import {
|
||||
} from '../../mock';
|
||||
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
|
||||
import { MatMenuItemHarness } from '@angular/material/menu/testing';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
describe('TaskListComponent', () => {
|
||||
let component: TaskListComponent;
|
||||
let fixture: ComponentFixture<TaskListComponent>;
|
||||
let loader: HarnessLoader;
|
||||
let appConfig: AppConfigService;
|
||||
let taskListService: TaskListService;
|
||||
|
||||
@@ -71,27 +76,19 @@ describe('TaskListComponent', () => {
|
||||
component.selectionMode = selectionMode;
|
||||
}
|
||||
component.ngOnChanges({ sort: state });
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const selectTask1 = fixture.nativeElement.querySelector('[data-automation-id="datatable-row-0"] .mat-checkbox-inner-container');
|
||||
const selectTask2 = fixture.nativeElement.querySelector('[data-automation-id="datatable-row-1"] .mat-checkbox-inner-container');
|
||||
selectTask1.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
selectTask1.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
selectTask2.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const selectTask1 = await loader.getHarness(MatCheckboxHarness.with({ ancestor: '[data-automation-id="datatable-row-0"]' }));
|
||||
const selectTask2 = await loader.getHarness(MatCheckboxHarness.with({ ancestor: '[data-automation-id="datatable-row-1"]' }));
|
||||
await selectTask1.toggle();
|
||||
await selectTask1.toggle();
|
||||
await selectTask2.toggle();
|
||||
|
||||
let selectRow1 = fixture.nativeElement.querySelector('[class*="adf-is-selected"][data-automation-id="datatable-row-0"]');
|
||||
let selectRow2 = fixture.nativeElement.querySelector('[class*="adf-is-selected"][data-automation-id="datatable-row-1"]');
|
||||
expect(selectRow1).toBeDefined();
|
||||
expect(selectRow2).toBeDefined();
|
||||
expect(component.selectedInstances.length).toBe(2);
|
||||
selectTask2.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await selectTask2.toggle();
|
||||
|
||||
expect(component.selectedInstances.length).toBe(1);
|
||||
selectRow1 = fixture.nativeElement.querySelector('[class*="adf-is-selected"][data-automation-id="datatable-row-0"]');
|
||||
@@ -112,6 +109,7 @@ describe('TaskListComponent', () => {
|
||||
|
||||
fixture = TestBed.createComponent(TaskListComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
||||
taskListService = TestBed.inject(TaskListService);
|
||||
|
||||
appConfig.config = Object.assign(appConfig.config, {
|
||||
@@ -135,25 +133,16 @@ describe('TaskListComponent', () => {
|
||||
it('should display loading spinner', () => {
|
||||
component.isLoading = true;
|
||||
|
||||
const spinner = fixture.debugElement.query(By.css('.mat-progress-spinner'));
|
||||
const spinner = fixture.debugElement.query(By.css('.adf-task-list-loading-margin'));
|
||||
expect(spinner).toBeDefined();
|
||||
});
|
||||
|
||||
it('should hide loading spinner upon loading complete', async () => {
|
||||
component.isLoading = true;
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
let spinner = fixture.debugElement.query(By.css('.mat-progress-spinner'));
|
||||
expect(spinner).toBeDefined();
|
||||
expect(fixture.debugElement.query(By.css('.adf-task-list-loading-margin'))).toBeDefined();
|
||||
|
||||
component.isLoading = false;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
spinner = fixture.debugElement.query(By.css('.mat-progress-spinner'));
|
||||
expect(spinner).toBeNull();
|
||||
expect(fixture.debugElement.query(By.css('.adf-task-list-loading-margin'))).toBeNull();
|
||||
});
|
||||
|
||||
it('should use the default schemaColumn as default', () => {
|
||||
@@ -579,23 +568,14 @@ describe('TaskListComponent', () => {
|
||||
|
||||
component.ngOnChanges({ sort: state });
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const selectAllCheckbox = fixture.nativeElement.querySelector('div[class*="adf-datatable-cell-header adf-datatable-checkbox"] .mat-checkbox-inner-container');
|
||||
selectAllCheckbox.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const selectAllCheckbox = await loader.getHarness(MatCheckboxHarness.with({ ancestor: '.adf-datatable-cell-header' }));
|
||||
await selectAllCheckbox.toggle();
|
||||
|
||||
expect(component.selectedInstances.length).toBe(2);
|
||||
expect(component.selectedInstances[0].obj.name).toBe('nameFake1');
|
||||
expect(component.selectedInstances[1].obj.description).toBe('descriptionFake2');
|
||||
|
||||
selectAllCheckbox.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await selectAllCheckbox.toggle();
|
||||
|
||||
expect(component.selectedInstances.length).toBe(0);
|
||||
});
|
||||
@@ -622,16 +602,13 @@ describe('TaskListComponent', () => {
|
||||
component.selectionMode = 'single';
|
||||
|
||||
component.ngOnChanges({ sort: state });
|
||||
fixture.detectChanges();
|
||||
|
||||
const selectTask1 = fixture.nativeElement.querySelector('[data-automation-id="datatable-row-0"] .mat-checkbox-inner-container');
|
||||
const selectTask2 = fixture.nativeElement.querySelector('[data-automation-id="datatable-row-1"] .mat-checkbox-inner-container');
|
||||
selectTask1.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
selectTask1.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
selectTask2.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
const selectTask1 = await loader.getHarness(MatCheckboxHarness.with({ ancestor: '[data-automation-id="datatable-row-0"]' }));
|
||||
const selectTask2 = await loader.getHarness(MatCheckboxHarness.with({ ancestor: '[data-automation-id="datatable-row-1"]' }));
|
||||
await selectTask1.toggle();
|
||||
await selectTask1.toggle();
|
||||
await selectTask2.toggle();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
expect(component.selectedInstances.length).toBe(2);
|
||||
});
|
||||
|
||||
@@ -825,6 +802,7 @@ class TaskListContextMenuComponent implements OnInit {
|
||||
describe('TaskListContextMenuComponent', () => {
|
||||
let fixture: ComponentFixture<TaskListContextMenuComponent>;
|
||||
let customComponent: TaskListContextMenuComponent;
|
||||
let loader: HarnessLoader;
|
||||
let taskListService: TaskListService;
|
||||
let element: HTMLElement;
|
||||
|
||||
@@ -840,6 +818,7 @@ describe('TaskListContextMenuComponent', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(TaskListContextMenuComponent);
|
||||
customComponent = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
||||
element = fixture.nativeElement;
|
||||
taskListService = TestBed.inject(TaskListService);
|
||||
spyOn(taskListService, 'findTasksByState').and.returnValues(of(fakeGlobalTask));
|
||||
@@ -854,15 +833,12 @@ describe('TaskListContextMenuComponent', () => {
|
||||
const contextMenu = element.querySelector(`[data-automation-id="text_${fakeGlobalTask.data[0].name}"]`);
|
||||
const contextActionSpy = spyOn(customComponent.contextAction, 'emit').and.callThrough();
|
||||
contextMenu.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }));
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const contextActions = document.querySelectorAll('.mat-menu-item');
|
||||
const contextActions = await loader.getAllHarnesses(MatMenuItemHarness);
|
||||
|
||||
expect(contextActions.length).toBe(2);
|
||||
expect(contextActions[0]['disabled']).toBe(false, 'View Task Details action not enabled');
|
||||
expect(contextActions[1]['disabled']).toBe(false, 'Cancel Task action not enabled');
|
||||
contextActions[0].dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
expect(await contextActions[0].isDisabled()).toBe(false, 'View Task Details action not enabled');
|
||||
expect(await contextActions[1].isDisabled()).toBe(false, 'Cancel Task action not enabled');
|
||||
await contextActions[0].click();
|
||||
expect(contextActionSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user