[ACS-6140] reduce access to internal material classes (#9053)

* cleanup login (demo shell)

* cleanup e2e from useless calls

* [ci:force] cleanup e2e from useless calls

* [ci:force] cleanup e2e from useless calls

* [ci:force] improved uploader selectors

* [ci:force] remove useless selectors when automation id provided

* [ci:force] improved tests and selectors

* [ci:force] improved tests and selectors

* [ci:force] improved tests and selectors

* [ci:force] improved tests and selectors

* [ci:force] improved tests and selectors

* [ci:force] improved tests and selectors

* [ci:force] switch edit task filter to angular harness

* [ci:force] switch edit process filter to angular harness

* [ci:force] switch search chip list to angular harness

* [ci:force] switch search panel to angular harness

* [ci:force] switch search radio to angular harness

* [ci:force] switch search text to angular harness

* [ci:force] search logical filter

* [ci:force] search form component

* [ci:force] search filter container

* [ci:force] fix viewer test

* [ci:force] search facet chip harness

* [ci:force] search facet chip harness

* [ci:force] dropdown breadcrumb

* [ci:force] search check list

* [ci:force] folder dialog

* [ci:force] search filter component

* [ci:force] json cell

* [ci:force] amount widget

* [ci:force] checkbox widget

* [ci:force] multiline-text widget

* [ci:force] number widget

* [ci:force] text widget

* [ci:force] card view array item

* add permission dialog

* permission container component

* permission list component

* card view components

* search widget chip

* search facet chip

* edit service task filter

* card view components

* sites dropdown

* share dialog

* header component

* datetime widget

* remove comments
This commit is contained in:
Denys Vuika
2023-11-03 06:05:34 -04:00
committed by GitHub
parent 9278d9296f
commit 93fd0bec6c
62 changed files with 2323 additions and 2648 deletions
@@ -26,7 +26,6 @@ import { of } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core';
describe('DropdownBreadcrumb', () => {
let component: DropdownBreadcrumbComponent;
let fixture: ComponentFixture<DropdownBreadcrumbComponent>;
let documentList: DocumentListComponent;
@@ -34,10 +33,7 @@ describe('DropdownBreadcrumb', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
imports: [TranslateModule.forRoot(), ContentTestingModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [{ provide: DocumentListService, useValue: documentListService }]
});
@@ -64,7 +60,7 @@ describe('DropdownBreadcrumb', () => {
};
const clickOnTheFirstOption = () => {
const option: any = document.querySelector('[id^="mat-option"]');
const option: any = document.querySelector(`[data-automation-class="dropdown-breadcrumb-path-option"]`);
option.click();
};
@@ -75,7 +71,6 @@ describe('DropdownBreadcrumb', () => {
triggerComponentChange(fakeNodeWithCreatePermissionInstance);
fixture.whenStable().then(() => {
openSelect();
const currentFolder = fixture.debugElement.query(By.css('[data-automation-id="current-folder"]'));
@@ -99,7 +94,6 @@ describe('DropdownBreadcrumb', () => {
triggerComponentChange(fakeNodeWithCreatePermissionInstance);
fixture.whenStable().then(() => {
openSelect();
const path = fixture.debugElement.query(By.css('[data-automation-id="dropdown-breadcrumb-path"]'));
@@ -110,7 +104,6 @@ describe('DropdownBreadcrumb', () => {
});
});
it('should update document list when clicking on an option', async () => {
component.target = documentList;
const fakeNodeWithCreatePermissionInstance = JSON.parse(JSON.stringify(fakeNodeWithCreatePermission));
@@ -607,7 +607,7 @@ describe('ContentMetadataComponent', () => {
it('should hide metadata fields if displayDefaultProperties is set to false', () => {
component.displayDefaultProperties = false;
fixture.detectChanges();
const metadataContainer = fixture.debugElement.query(By.css('mat-expansion-panel[data-automation-id="adf-metadata-group-properties"]'));
const metadataContainer = fixture.debugElement.query(By.css('[data-automation-id="adf-metadata-group-properties"]'));
fixture.detectChanges();
expect(metadataContainer).toBeNull();
});
@@ -615,7 +615,7 @@ describe('ContentMetadataComponent', () => {
it('should display metadata fields if displayDefaultProperties is set to true', () => {
component.displayDefaultProperties = true;
fixture.detectChanges();
const metadataContainer = fixture.debugElement.query(By.css('mat-expansion-panel[data-automation-id="adf-metadata-group-properties"]'));
const metadataContainer = fixture.debugElement.query(By.css('[data-automation-id="adf-metadata-group-properties"]'));
fixture.detectChanges();
expect(metadataContainer).toBeDefined();
});
@@ -24,7 +24,6 @@ import { By } from '@angular/platform-browser';
import { FileModel } from '../common/models/file.model';
import { FileUploadEvent } from '../common/events/file.event';
import { UploadService } from '../common/services/upload.service';
import { of } from 'rxjs';
import { ContentTestingModule } from '../testing/content.testing.module';
import { DocumentListService } from '../document-list/services/document-list.service';
@@ -58,12 +57,7 @@ describe('ContentNodeSelectorComponent', () => {
};
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule,
MatDialogModule,
UploadModule
],
imports: [TranslateModule.forRoot(), ContentTestingModule, MatDialogModule, UploadModule],
providers: [
{ provide: MAT_DIALOG_DATA, useValue: data },
{
@@ -118,6 +112,8 @@ describe('ContentNodeSelectorComponent', () => {
fixture.destroy();
});
const getTabInfoButton = () => fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
const enableLocalUpload = () => {
component.data.showLocalUploadButton = true;
component.hasAllowableOperations = true;
@@ -125,15 +121,16 @@ describe('ContentNodeSelectorComponent', () => {
component.isLoading = false;
};
const getTabLabel = (idx: number) => fixture.debugElement.queryAll(By.css('.mat-tab-label'))[idx];
const selectTabByIndex = (tabIndex: number) => {
const uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[tabIndex];
const uploadFromLocalTab = getTabLabel(tabIndex);
const attributes = uploadFromLocalTab.nativeNode.attributes as NamedNodeMap;
const tabPositionInSet = Number(attributes.getNamedItem('aria-posinset').value) - 1;
component.onTabSelectionChange(tabPositionInSet);
};
describe('Data injecting with the "Material dialog way"', () => {
it('should show the INJECTED title', () => {
const titleElement = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-title"]'));
expect(titleElement).not.toBeNull();
@@ -149,101 +146,105 @@ describe('ContentNodeSelectorComponent', () => {
it('should pass through the injected currentFolderId to the documentList', () => {
const documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
expect(documentList).not.toBeNull('Document list should be shown');
expect(documentList).not.toBeNull();
expect(documentList.componentInstance.currentFolderId).toBe('cat-girl-nuku-nuku');
});
it('should pass through the injected rowFilter to the documentList', () => {
const documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
expect(documentList).not.toBeNull('Document list should be shown');
expect(documentList.componentInstance.rowFilter({
node: {
entry: new Node({
name: 'impossible-name',
id: 'name'
})
}
}))
.toBe(data.rowFilter({
expect(documentList).not.toBeNull();
expect(
documentList.componentInstance.rowFilter({
node: {
entry: new Node({
name: 'impossible-name',
id: 'name'
})
}
}));
})
).toBe(
data.rowFilter({
node: {
entry: new Node({
name: 'impossible-name',
id: 'name'
})
}
})
);
});
it('should pass through the injected imageResolver to the documentList', () => {
const documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
expect(documentList).not.toBeNull('Document list should be shown');
expect(documentList).not.toBeNull();
expect(documentList.componentInstance.imageResolver).toBe(data.imageResolver);
});
});
});
describe('Cancel button', () => {
const getCancelButton = () => fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-cancel"]'));
it('should not be shown if dialogRef is NOT injected', () => {
const closeButton = fixture.debugElement.query(By.css('[content-node-selector-actions-cancel]'));
expect(closeButton).toBeNull();
});
it('should close the dialog', () => {
let cancelButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-cancel"]'));
let cancelButton = getCancelButton();
cancelButton.triggerEventHandler('click', {});
expect(dialog.close).toHaveBeenCalled();
fixture.detectChanges();
cancelButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-cancel"]'));
cancelButton = getCancelButton();
expect(cancelButton).not.toBeNull();
});
});
describe('Action button for the chosen node', () => {
const getActionButton = () =>
fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'))?.nativeElement as HTMLButtonElement;
it('should be disabled by default', () => {
fixture.detectChanges();
const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
expect(actionButton.nativeElement.disabled).toBeTruthy();
const actionButton = getActionButton();
expect(actionButton.disabled).toBeTruthy();
});
it('should be enabled when a node is chosen', () => {
component.onSelect([new Node({ id: 'fake' })]);
fixture.detectChanges();
const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
expect(actionButton.nativeElement.disabled).toBeFalsy();
const actionButton = getActionButton();
expect(actionButton.disabled).toBeFalsy();
});
it('should be disabled when no node chosen', () => {
component.onSelect([new Node({ id: 'fake' })]);
fixture.detectChanges();
const actionButtonWithNodeSelected = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
expect(actionButtonWithNodeSelected.nativeElement.disabled).toBe(false);
const actionButtonWithNodeSelected = getActionButton();
expect(actionButtonWithNodeSelected.disabled).toBe(false);
component.onSelect([]);
fixture.detectChanges();
const actionButtonWithoutNodeSelected = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
expect(actionButtonWithoutNodeSelected.nativeElement.disabled).toBe(true);
const actionButtonWithoutNodeSelected = getActionButton();
expect(actionButtonWithoutNodeSelected.disabled).toBe(true);
});
it('should close the dialog when action button is clicked', async () => {
it('should close the dialog when action button is clicked', () => {
component.onSelect([new Node({ id: 'fake' })]);
fixture.detectChanges();
const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
await actionButton.nativeElement.click();
const actionButton = getActionButton();
actionButton.click();
expect(dialog.close).toHaveBeenCalled();
});
});
describe('Title', () => {
it('should be updated when a site is chosen', () => {
const fakeSiteTitle = 'My fake site';
const contentNodePanel = fixture.debugElement.query(By.directive(ContentNodeSelectorPanelComponent));
@@ -253,17 +254,18 @@ describe('ContentNodeSelectorComponent', () => {
const titleElement = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-title"]'));
expect(titleElement).not.toBeNull();
expect(titleElement.nativeElement.innerText).toBe('NODE_SELECTOR.CHOOSE_ITEM');
});
});
});
});
describe('Upload button', () => {
const getUploadButton = () => fixture.debugElement.query(By.css('adf-upload-button button'))?.nativeElement as HTMLButtonElement;
it('Should not be able to upload a file whilst a search is still running', () => {
enableLocalUpload();
fixture.detectChanges();
let infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
let uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
let infoMatIcon = getTabInfoButton();
let uploadFromLocalTab = getTabLabel(1);
expect(uploadFromLocalTab.nativeElement.getAttribute('aria-disabled')).toBe('false');
expect(infoMatIcon).toBeFalsy();
@@ -271,8 +273,8 @@ describe('ContentNodeSelectorComponent', () => {
component.showingSearch = true;
fixture.detectChanges();
uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
uploadFromLocalTab = getTabLabel(1);
infoMatIcon = getTabInfoButton();
expect(uploadFromLocalTab.nativeElement.getAttribute('aria-disabled')).toBe('true');
expect(infoMatIcon).toBeTruthy();
@@ -281,8 +283,8 @@ describe('ContentNodeSelectorComponent', () => {
component.showingSearch = false;
fixture.detectChanges();
uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
uploadFromLocalTab = getTabLabel(1);
infoMatIcon = getTabInfoButton();
expect(uploadFromLocalTab.nativeElement.getAttribute('aria-disabled')).toBe('false');
expect(infoMatIcon).toBeFalsy();
@@ -305,10 +307,10 @@ describe('ContentNodeSelectorComponent', () => {
component.hasAllowableOperations = true;
fixture.detectChanges();
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
const adfUploadButton = getUploadButton();
expect(adfUploadButton).not.toBeNull();
expect(adfUploadButton.nativeElement.disabled).toBe(true);
expect(adfUploadButton.disabled).toBe(true);
});
it('should be able to enable UploadButton if showingSearch set to false', () => {
@@ -317,10 +319,10 @@ describe('ContentNodeSelectorComponent', () => {
component.hasAllowableOperations = true;
fixture.detectChanges();
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
const adfUploadButton = getUploadButton();
expect(adfUploadButton).not.toBeNull();
expect(adfUploadButton.nativeElement.disabled).toBe(false);
expect(adfUploadButton.disabled).toBe(false);
});
it('should be able to show warning message while searching', () => {
@@ -330,7 +332,7 @@ describe('ContentNodeSelectorComponent', () => {
selectTabByIndex(1);
fixture.detectChanges();
const infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
const infoMatIcon = getTabInfoButton();
const iconTooltipMessage = infoMatIcon.attributes['ng-reflect-message'];
const expectedMessage = 'NODE_SELECTOR.UPLOAD_BUTTON_SEARCH_WARNING_MESSAGE';
@@ -354,10 +356,10 @@ describe('ContentNodeSelectorComponent', () => {
selectTabByIndex(1);
fixture.detectChanges();
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
const adfUploadButton = getUploadButton();
expect(adfUploadButton).not.toBeNull();
expect(adfUploadButton.nativeElement.disabled).toBe(true);
expect(adfUploadButton.disabled).toBe(true);
});
it('should be able to enable UploadButton if user has allowable operations', () => {
@@ -365,10 +367,10 @@ describe('ContentNodeSelectorComponent', () => {
component.hasAllowableOperations = true;
fixture.detectChanges();
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
const adfUploadButton = getUploadButton();
expect(adfUploadButton).not.toBeNull();
expect(adfUploadButton.nativeElement.disabled).toBe(false);
expect(adfUploadButton.disabled).toBe(false);
});
it('should not be able to show warning message if user has allowable operations', () => {
@@ -388,7 +390,7 @@ describe('ContentNodeSelectorComponent', () => {
selectTabByIndex(1);
fixture.detectChanges();
const infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
const infoMatIcon = getTabInfoButton();
const iconTooltipMessage = infoMatIcon.attributes['ng-reflect-message'];
const expectedMessage = 'NODE_SELECTOR.UPLOAD_BUTTON_PERMISSION_WARNING_MESSAGE';
@@ -424,11 +426,11 @@ describe('ContentNodeSelectorComponent', () => {
});
it('should tabs be headless when local upload is not enabled', () => {
component.data.showLocalUploadButton = false;
fixture.detectChanges();
const tabGroup = fixture.debugElement.queryAll(By.css('.adf-content-node-selector-headless-tabs'))[0];
component.data.showLocalUploadButton = false;
fixture.detectChanges();
const tabGroup = fixture.debugElement.queryAll(By.css('.adf-content-node-selector-headless-tabs'))[0];
expect(tabGroup).not.toBe(undefined);
expect(tabGroup).not.toBe(undefined);
});
it('should tabs show headers when local upload is enabled', () => {
@@ -441,12 +443,14 @@ describe('ContentNodeSelectorComponent', () => {
});
describe('Drag and drop area', () => {
const getEmptyList = () => fixture.nativeElement.querySelector('[data-automation-id="adf-empty-list"]');
it('should uploadStarted be false by default', () => {
expect(component.uploadStarted).toBe(false);
});
it('should uploadStarted become true when the first upload gets started', () => {
const fileUploadEvent = new FileUploadEvent(new FileModel({ name: 'fake-name', size: 100 } as File));
const fileUploadEvent = new FileUploadEvent(new FileModel({ name: 'fake-name', size: 100 } as File));
uploadService.fileUploadStarting.next(fileUploadEvent);
expect(component.uploadStarted).toBe(true);
@@ -454,12 +458,13 @@ describe('ContentNodeSelectorComponent', () => {
it('should show drag and drop area with the empty list template when no upload has started', async () => {
enableLocalUpload();
const uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
const uploadFromLocalTab = getTabLabel(1);
uploadFromLocalTab.nativeElement.click();
fixture.detectChanges();
await fixture.whenRenderingDone();
const emptyListTemplate = fixture.nativeElement.querySelector('[data-automation-id="adf-empty-list"]');
const emptyListTemplate = getEmptyList();
const dragAndDropArea = fixture.debugElement.query(By.css('.adf-upload-drag-area'));
expect(emptyListTemplate).not.toBeNull();
@@ -468,19 +473,21 @@ describe('ContentNodeSelectorComponent', () => {
it('should not show the empty list template when an upload has started', async () => {
enableLocalUpload();
const uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
const uploadFromLocalTab = getTabLabel(1);
uploadFromLocalTab.nativeElement.click();
component.uploadStarted = true;
fixture.detectChanges();
await fixture.whenRenderingDone();
const emptyListTemplate = fixture.nativeElement.querySelector('[data-automation-id="adf-empty-list"]');
const emptyListTemplate = getEmptyList();
expect(emptyListTemplate).toBeNull();
});
});
describe('Selected nodes counter', () => {
const getNodeCounter = () => fixture.debugElement.nativeElement.querySelector('adf-node-counter');
it('should getSelectedCount return 0 by default', () => {
expect(component.getSelectedCount()).toBe(0);
});
@@ -494,19 +501,19 @@ describe('ContentNodeSelectorComponent', () => {
it('should show the counter depending on the action', () => {
component.action = NodeAction.ATTACH;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).not.toBe(null);
expect(getNodeCounter()).not.toBe(null);
component.action = NodeAction.CHOOSE;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).not.toBe(null);
expect(getNodeCounter()).not.toBe(null);
component.action = NodeAction.COPY;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).toBe(null);
expect(getNodeCounter()).toBe(null);
component.action = NodeAction.MOVE;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).toBe(null);
expect(getNodeCounter()).toBe(null);
});
});
});
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { TestBed, fakeAsync, ComponentFixture, tick } from '@angular/core/testing';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
import { of } from 'rxjs';
import { NotificationService, AppConfigService } from '@alfresco/adf-core';
@@ -28,8 +28,12 @@ import { TranslateModule } from '@ngx-translate/core';
import { format, endOfDay } from 'date-fns';
import { By } from '@angular/platform-browser';
import { NodeEntry } from '@alfresco/js-api';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing';
describe('ShareDialogComponent', () => {
let loader: HarnessLoader;
let node: NodeEntry;
let matDialog: MatDialog;
const notificationServiceMock = {
@@ -45,8 +49,6 @@ describe('ShareDialogComponent', () => {
const shareToggleId = '[data-automation-id="adf-share-toggle"]';
const expireToggle = '[data-automation-id="adf-expire-toggle"]';
const getShareToggleLinkedClasses = (): DOMTokenList => fixture.nativeElement.querySelector(shareToggleId).classList;
const fillInDatepickerInput = (value: string) => {
const input = fixture.debugElement.query(By.css('.adf-share-link__input')).nativeElement;
input.value = value;
@@ -55,10 +57,6 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
};
const clickExpireToggleButton = () => fixture.nativeElement.querySelector(`${expireToggle} label`).dispatchEvent(new MouseEvent('click'));
const clickShareToggleButton = () => fixture.nativeElement.querySelector(`${shareToggleId} label`).dispatchEvent(new MouseEvent('click'));
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ContentTestingModule],
@@ -99,6 +97,7 @@ describe('ShareDialogComponent', () => {
};
spyOn(nodesApiService, 'updateNode').and.returnValue(of(null));
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -133,7 +132,7 @@ describe('ShareDialogComponent', () => {
});
});
it(`should toggle share action when property 'sharedId' does not exists`, () => {
it(`should toggle share action when property 'sharedId' does not exists`, async () => {
spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue(
of({
entry: { id: 'sharedId', sharedId: 'sharedId' }
@@ -151,7 +150,9 @@ describe('ShareDialogComponent', () => {
expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalled();
expect(renditionService.getNodeRendition).toHaveBeenCalled();
expect(fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]').value).toBe('some-url/sharedId');
expect(getShareToggleLinkedClasses()).toContain('mat-checked');
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
expect(await toggle.isChecked()).toBe(true);
});
it(`should not toggle share action when file has 'sharedId' property`, async () => {
@@ -176,10 +177,12 @@ describe('ShareDialogComponent', () => {
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
expect(fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]').value).toBe('some-url/sharedId');
expect(getShareToggleLinkedClasses()).toContain('mat-checked');
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
expect(await toggle.isChecked()).toBe(true);
});
it('should open a confirmation dialog when unshare button is triggered', () => {
it('should open a confirmation dialog when unshare button is triggered', async () => {
spyOn(matDialog, 'open').and.returnValue({ beforeClosed: () => of(false) } as any);
spyOn(sharedLinksApiService, 'deleteSharedLink').and.callThrough();
@@ -192,14 +195,13 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
clickShareToggleButton();
fixture.detectChanges();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
await toggle.toggle();
expect(matDialog.open).toHaveBeenCalled();
});
it('should unshare file when confirmation dialog returns true', fakeAsync(() => {
it('should unshare file when confirmation dialog returns true', async () => {
spyOn(matDialog, 'open').and.returnValue({ beforeClosed: () => of(true) } as any);
spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue(of({}));
node.entry.properties['qshare:sharedId'] = 'sharedId';
@@ -211,14 +213,13 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
clickShareToggleButton();
fixture.detectChanges();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
await toggle.toggle();
expect(sharedLinksApiService.deleteSharedLink).toHaveBeenCalled();
}));
});
it('should not unshare file when confirmation dialog returns false', fakeAsync(() => {
it('should not unshare file when confirmation dialog returns false', async () => {
spyOn(matDialog, 'open').and.returnValue({ beforeClosed: () => of(false) } as any);
spyOn(sharedLinksApiService, 'deleteSharedLink').and.callThrough();
node.entry.properties['qshare:sharedId'] = 'sharedId';
@@ -230,14 +231,13 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
clickShareToggleButton();
fixture.detectChanges();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
await toggle.toggle();
expect(sharedLinksApiService.deleteSharedLink).not.toHaveBeenCalled();
}));
});
it('should not allow unshare when node has no update permission', () => {
it('should not allow unshare when node has no update permission', async () => {
node.entry.properties['qshare:sharedId'] = 'sharedId';
node.entry.allowableOperations = [];
@@ -248,7 +248,8 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
expect(getShareToggleLinkedClasses()).toContain('mat-disabled');
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
expect(await toggle.isChecked()).toBe(true);
});
it('should delete the current link generated with expiry date and generate a new link without expiry date when toggle is unchecked', async () => {
@@ -266,9 +267,9 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
component.form.controls['time'].setValue(new Date());
fixture.detectChanges();
clickExpireToggleButton();
fixture.detectChanges();
await fixture.whenStable();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
await toggle.toggle();
expect(sharedLinksApiService.deleteSharedLink).toHaveBeenCalled();
expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalledWith('nodeId', undefined);
@@ -286,7 +287,9 @@ describe('ShareDialogComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
expect(fixture.nativeElement.querySelector('.mat-slide-toggle[data-automation-id="adf-expire-toggle"]').classList).toContain('mat-disabled');
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: `[data-automation-id="adf-expire-toggle"]` }));
expect(await toggle.isDisabled()).toBe(true);
expect(fixture.nativeElement.querySelector('[data-automation-id="adf-slide-toggle-checked"]').style.display).toEqual('none');
});
@@ -303,18 +306,19 @@ describe('ShareDialogComponent', () => {
};
});
it('should update node with input date and end of day time when type is `date`', fakeAsync(() => {
it('should update node with input date and end of day time when type is `date`', async () => {
const dateTimePickerType = 'date';
const date = new Date('2525-01-01');
spyOn(appConfigService, 'get').and.callFake(() => dateTimePickerType as any);
fixture.detectChanges();
clickExpireToggleButton();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
await toggle.toggle();
fixture.componentInstance.time.setValue(date);
component.onTimeChanged();
fixture.detectChanges();
tick(500);
const expiryDate = format(endOfDay(date as Date), `yyyy-MM-dd'T'HH:mm:ss.SSSxx`);
@@ -323,11 +327,14 @@ describe('ShareDialogComponent', () => {
nodeId: 'nodeId',
expiresAt: expiryDate
});
}));
});
it('should not update node when provided date is less than minDate', () => {
it('should not update node when provided date is less than minDate', async () => {
fixture.detectChanges();
clickExpireToggleButton();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
await toggle.toggle();
fillInDatepickerInput('01.01.2010');
expect(component.form.invalid).toBeTrue();
@@ -335,9 +342,12 @@ describe('ShareDialogComponent', () => {
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
});
it('should not accept alphabets in the datepicker input', () => {
it('should not accept alphabets in the datepicker input', async () => {
fixture.detectChanges();
clickExpireToggleButton();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
await toggle.toggle();
fillInDatepickerInput('test');
expect(component.form.invalid).toBeTrue();
@@ -346,7 +356,10 @@ describe('ShareDialogComponent', () => {
it('should show an error if provided date is invalid', async () => {
fixture.detectChanges();
clickExpireToggleButton();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
await toggle.toggle();
fillInDatepickerInput('incorrect');
fixture.detectChanges();
@@ -358,9 +371,12 @@ describe('ShareDialogComponent', () => {
expect(component.time.hasError('invalidDate')).toBeTrue();
});
it('should not show an error when provided date is valid', () => {
it('should not show an error when provided date is valid', async () => {
fixture.detectChanges();
clickExpireToggleButton();
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
await toggle.toggle();
fillInDatepickerInput('12.12.2525');
const error = fixture.debugElement.query(By.css('[data-automation-id="adf-share-link-input-warning"]'));
@@ -1,4 +1,4 @@
<h2 mat-dialog-title>
<h2 data-automation-id="adf-folder-dialog-title" mat-dialog-title>
{{ (editing ? editTitle : createTitle) | translate }}
</h2>
@@ -35,13 +35,8 @@ describe('FolderDialogComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
providers: [
{ provide: MatDialogRef, useValue: dialogRef }
]
imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [{ provide: MatDialogRef, useValue: dialogRef }]
});
dialogRef.close.calls.reset();
fixture = TestBed.createComponent(FolderDialogComponent);
@@ -54,7 +49,6 @@ describe('FolderDialogComponent', () => {
});
describe('Edit', () => {
beforeEach(() => {
component.data = {
folder: {
@@ -100,16 +94,13 @@ describe('FolderDialogComponent', () => {
component.submit();
expect(nodesApi.updateNode).toHaveBeenCalledWith(
'node-id',
{
name: 'folder-name-update',
properties: {
'cm:title': 'folder-title-update',
'cm:description': 'folder-description-update'
}
expect(nodesApi.updateNode).toHaveBeenCalledWith('node-id', {
name: 'folder-name-update',
properties: {
'cm:title': 'folder-title-update',
'cm:description': 'folder-description-update'
}
);
});
});
it('should call dialog to close with form data when submit is successfully', () => {
@@ -174,10 +165,10 @@ describe('FolderDialogComponent', () => {
});
it('should have the proper title', () => {
const title = fixture.debugElement.query(By.css('[mat-dialog-title]'));
const title = fixture.debugElement.query(By.css(`[data-automation-id="adf-folder-dialog-title"]`));
expect(title === null).toBe(false);
expect(title.nativeElement.innerText.trim()).toBe('CORE.FOLDER_DIALOG.CREATE_FOLDER_TITLE');
});
});
it('should init form with empty inputs', () => {
expect(component.name).toBe('');
@@ -201,17 +192,14 @@ describe('FolderDialogComponent', () => {
component.submit();
expect(nodesApi.createFolder).toHaveBeenCalledWith(
'parentNodeId',
{
name: 'folder-name-update',
properties: {
'cm:title': 'folder-title-update',
'cm:description': 'folder-description-update'
},
nodeType: 'cm:folder'
}
);
expect(nodesApi.createFolder).toHaveBeenCalledWith('parentNodeId', {
name: 'folder-name-update',
properties: {
'cm:title': 'folder-title-update',
'cm:description': 'folder-description-update'
},
nodeType: 'cm:folder'
});
});
it('should submit updated values if form is valid (with custom nodeType)', () => {
@@ -224,17 +212,14 @@ describe('FolderDialogComponent', () => {
component.submit();
expect(nodesApi.createFolder).toHaveBeenCalledWith(
'parentNodeId',
{
name: 'folder-name-update',
properties: {
'cm:title': 'folder-title-update',
'cm:description': 'folder-description-update'
},
nodeType: 'cm:sushi'
}
);
expect(nodesApi.createFolder).toHaveBeenCalledWith('parentNodeId', {
name: 'folder-name-update',
properties: {
'cm:title': 'folder-title-update',
'cm:description': 'folder-description-update'
},
nodeType: 'cm:sushi'
});
});
it('should call dialog to close with form data when submit is successfully', () => {
@@ -315,5 +300,5 @@ describe('FolderDialogComponent', () => {
component.submit();
});
});
});
});
});
@@ -26,9 +26,12 @@ import { ContentTestingModule } from '../../../testing/content.testing.module';
import { AddPermissionDialogComponent } from './add-permission-dialog.component';
import { AddPermissionDialogData } from './add-permission-dialog-data.interface';
import { fakeAuthorityResults } from '../../../mock/add-permission.component.mock';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
describe('AddPermissionDialog', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<AddPermissionDialogComponent>;
let component: AddPermissionDialogComponent;
let element: HTMLElement;
@@ -53,7 +56,7 @@ describe('AddPermissionDialog', () => {
role: 'Consumer'
}
],
confirm: new Subject<PermissionElement[]> ()
confirm: new Subject<PermissionElement[]>()
};
const dialogRef = {
close: jasmine.createSpy('close')
@@ -61,10 +64,7 @@ describe('AddPermissionDialog', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [
{ provide: MatDialogRef, useValue: dialogRef },
{ provide: MAT_DIALOG_DATA, useValue: data }
@@ -74,12 +74,15 @@ describe('AddPermissionDialog', () => {
component = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
fixture.destroy();
});
const getConfirmButton = () => element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
it('should show the INJECTED title', () => {
const titleElement = fixture.debugElement.query(By.css('#add-permission-dialog-title'));
expect(titleElement).not.toBeNull();
@@ -94,27 +97,31 @@ describe('AddPermissionDialog', () => {
});
it('should disable the confirm button when no selection is applied', () => {
const confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
const confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBeTruthy();
});
it('should enable the button when a selection is done', async () => {
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
By.directive(AddPermissionPanelComponent)
).componentInstance;
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
let confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBeTruthy();
fixture.detectChanges();
await fixture.whenStable();
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(false);
});
it('should update the role after selection', async () => {
spyOn(component, 'onMemberUpdate').and.callThrough();
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
By.directive(AddPermissionPanelComponent)
).componentInstance;
let confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(true);
addPermissionPanelComponent.select.emit([fakeAuthorityResults[0]]);
@@ -127,17 +134,12 @@ describe('AddPermissionDialog', () => {
fixture.detectChanges();
await fixture.whenStable();
const selectBox = fixture.debugElement.query(By.css(('[id="adf-select-role-permission"] .mat-select-trigger')));
selectBox.nativeElement.dispatchEvent(new Event('click'));
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
await select.open();
const options = fixture.debugElement.queryAll(By.css('mat-option'));
expect(options).not.toBeNull();
const options = await select.getOptions();
expect(options.length).toBe(2);
options[0].triggerEventHandler('click', {});
fixture.detectChanges();
await fixture.whenStable();
await options[0].click();
expect(component.onMemberUpdate).toHaveBeenCalled();
@@ -147,7 +149,7 @@ describe('AddPermissionDialog', () => {
currentSelection = selection;
});
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(false);
confirmButton.click();
@@ -156,8 +158,10 @@ describe('AddPermissionDialog', () => {
it('should update all the user role on header column update', async () => {
spyOn(component, 'onBulkUpdate').and.callThrough();
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
By.directive(AddPermissionPanelComponent)
).componentInstance;
let confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(true);
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
@@ -170,19 +174,12 @@ describe('AddPermissionDialog', () => {
fixture.detectChanges();
await fixture.whenStable();
const selectBox = fixture.debugElement.query(By.css(('[id="adf-bulk-select-role-permission"] .mat-select-trigger')));
selectBox.nativeElement.dispatchEvent(new Event('click'));
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-bulk-select-role-permission` }));
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options = fixture.debugElement.queryAll(By.css('mat-option'));
expect(options).not.toBeNull();
const options = await select.getOptions();
expect(options.length).toBe(2);
options[0].triggerEventHandler('click', {});
fixture.detectChanges();
await fixture.whenStable();
await options[0].click();
expect(component.onBulkUpdate).toHaveBeenCalled();
@@ -190,7 +187,7 @@ describe('AddPermissionDialog', () => {
expect(selection.length).toBe(3);
});
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(false);
confirmButton.click();
});
@@ -198,8 +195,10 @@ describe('AddPermissionDialog', () => {
it('should delete the user after selection', async () => {
spyOn(component, 'onMemberUpdate').and.callThrough();
spyOn(component, 'onMemberDelete').and.callThrough();
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
By.directive(AddPermissionPanelComponent)
).componentInstance;
let confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(true);
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
@@ -212,22 +211,16 @@ describe('AddPermissionDialog', () => {
fixture.detectChanges();
await fixture.whenStable();
const selectBox = fixture.debugElement.query(By.css(('[id="adf-select-role-permission"] .mat-select-trigger')));
selectBox.nativeElement.dispatchEvent(new Event('click'));
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options = fixture.debugElement.queryAll(By.css('mat-option'));
expect(options).not.toBeNull();
const options = await select.getOptions();
expect(options.length).toBe(2);
options[0].triggerEventHandler('click', {});
fixture.detectChanges();
await fixture.whenStable();
await options[0].click();
expect(component.onMemberUpdate).toHaveBeenCalled();
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
confirmButton = getConfirmButton();
expect(confirmButton.disabled).toBe(true);
const deleteButton = element.querySelectorAll('[data-automation-id="adf-delete-permission-button"]') as any;
deleteButton[1].click();
@@ -246,7 +239,9 @@ describe('AddPermissionDialog', () => {
});
it('should stream the confirmed selection on the confirm subject', async () => {
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
By.directive(AddPermissionPanelComponent)
).componentInstance;
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
fixture.detectChanges();
@@ -255,7 +250,7 @@ describe('AddPermissionDialog', () => {
let authorityResult = fixture.debugElement.query(By.css('[data-automation-id="datatable-row-0"]'));
expect(authorityResult).toBeNull();
const confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
const confirmButton = getConfirmButton();
confirmButton.click();
fixture.detectChanges();
@@ -16,23 +16,23 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { PermissionContainerComponent } from './permission-container.component';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
describe('PermissionContainerComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<PermissionContainerComponent>;
let component: PermissionContainerComponent;
let element: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(PermissionContainerComponent);
component = fixture.componentInstance;
@@ -60,6 +60,7 @@ describe('PermissionContainerComponent', () => {
];
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -72,26 +73,24 @@ describe('PermissionContainerComponent', () => {
expect(element.querySelector('#adf-select-role-permission').textContent).toContain('consumer');
});
it('should emit update event on role change', () => {
it('should emit update event on role change', async () => {
spyOn(component.update, 'emit');
const selectBox = fixture.debugElement.query(By.css(('[id="adf-select-role-permission"] .mat-select-trigger')));
selectBox.triggerEventHandler('click', null);
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
await select.open();
const options = fixture.debugElement.queryAll(By.css('mat-option'));
expect(options).not.toBeNull();
const options = await select.getOptions();
expect(options.length).toBe(2);
options[0].triggerEventHandler('click', {});
fixture.detectChanges();
await options[0].click();
expect(component.update.emit).toHaveBeenCalledWith({ role: 'Test', permission: component.permissions[0] });
});
it('should delete update event on row delete', () => {
it('should delete update event on row delete', async () => {
spyOn(component.delete, 'emit');
const deleteButton: HTMLButtonElement = element.querySelector('[data-automation-id="adf-delete-permission-button-GROUP_EVERYONE"]');
deleteButton.click();
fixture.detectChanges();
const deleteButton = await loader.getHarness(
MatButtonHarness.with({ selector: `[data-automation-id="adf-delete-permission-button-GROUP_EVERYONE"]` })
);
await deleteButton.click();
expect(component.delete.emit).toHaveBeenCalledWith(component.permissions[0]);
});
});
@@ -16,7 +16,6 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { of, throwError } from 'rxjs';
import { SearchService } from '../../../search/services/search.service';
@@ -36,8 +35,13 @@ import {
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { Node } from '@alfresco/js-api';
import { NodesApiService } from '../../../common/services/nodes-api.service';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing';
import { MatSelectHarness } from '@angular/material/select/testing';
describe('PermissionListComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<PermissionListComponent>;
let component: PermissionListComponent;
let element: HTMLElement;
@@ -64,6 +68,7 @@ describe('PermissionListComponent', () => {
searchQuerySpy = spyOn(searchApiService, 'searchByQueryBody').and.returnValue(of(fakeEmptyResponse));
component.nodeId = 'fake-node-id';
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -117,7 +122,9 @@ describe('PermissionListComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
const toggle = await loader.getHarness(MatSlideToggleHarness);
expect(await toggle.isChecked()).toBe(true);
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
);
@@ -127,10 +134,11 @@ describe('PermissionListComponent', () => {
it('should toggle the inherited button', async () => {
getNodeSpy.and.returnValue(of(fakeNodeInheritedOnly));
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
const toggle = await loader.getHarness(MatSlideToggleHarness);
expect(await toggle.isChecked()).toBe(true);
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
);
@@ -138,12 +146,8 @@ describe('PermissionListComponent', () => {
spyOn(nodeService, 'updateNode').and.returnValue(of(fakeLocalPermission));
const slider = fixture.debugElement.query(By.css('mat-slide-toggle'));
slider.triggerEventHandler('change', { source: { checked: false } });
await toggle.uncheck();
fixture.detectChanges();
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBe(null);
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.OFF'
);
@@ -157,7 +161,9 @@ describe('PermissionListComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
const toggle = await loader.getHarness(MatSlideToggleHarness);
expect(await toggle.isChecked()).toBe(true);
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
);
@@ -165,13 +171,8 @@ describe('PermissionListComponent', () => {
spyOn(nodeService, 'updateNode').and.returnValue(of(fakeLocalPermission));
const slider = fixture.debugElement.query(By.css('mat-slide-toggle'));
slider.triggerEventHandler('change', { source: { checked: false } });
await toggle.uncheck();
fixture.detectChanges();
await fixture.whenStable();
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
);
@@ -206,17 +207,16 @@ describe('PermissionListComponent', () => {
expect(element.querySelector('adf-user-name-column').textContent).toContain('GROUP_EVERYONE');
expect(element.querySelector('#adf-select-role-permission').textContent).toContain('Contributor');
const selectBox = fixture.debugElement.query(By.css('[id="adf-select-role-permission"] .mat-select-trigger'));
selectBox.triggerEventHandler('click', null);
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
await select.open();
const options = fixture.debugElement.queryAll(By.css('mat-option'));
expect(options).not.toBeNull();
const options = await select.getOptions();
expect(options.length).toBe(4);
expect(options[0].nativeElement.innerText).toContain('ADF.ROLES.SITECOLLABORATOR');
expect(options[1].nativeElement.innerText).toContain('ADF.ROLES.SITECONSUMER');
expect(options[2].nativeElement.innerText).toContain('ADF.ROLES.SITECONTRIBUTOR');
expect(options[3].nativeElement.innerText).toContain('ADF.ROLES.SITEMANAGER');
expect(await options[0].getText()).toContain('ADF.ROLES.SITECOLLABORATOR');
expect(await options[1].getText()).toContain('ADF.ROLES.SITECONSUMER');
expect(await options[2].getText()).toContain('ADF.ROLES.SITECONTRIBUTOR');
expect(await options[3].getText()).toContain('ADF.ROLES.SITEMANAGER');
});
it('should show readonly member for site manager to toggle the inherit permission', async () => {
@@ -247,14 +247,12 @@ describe('PermissionListComponent', () => {
expect(element.querySelector('adf-user-name-column').textContent).toContain('GROUP_EVERYONE');
expect(element.querySelector('#adf-select-role-permission').textContent).toContain('Contributor');
const selectBox = fixture.debugElement.query(By.css('[id="adf-select-role-permission"] .mat-select-trigger'));
selectBox.triggerEventHandler('click', null);
fixture.detectChanges();
const options = fixture.debugElement.queryAll(By.css('mat-option'));
expect(options).not.toBeNull();
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
await select.open();
const options = await select.getOptions();
expect(options.length).toBe(5);
options[3].triggerEventHandler('click', {});
fixture.detectChanges();
await options[3].click();
expect(nodeService.updateNode).toHaveBeenCalledWith('f472543f-7218-403d-917b-7a5861257244', {
permissions: { locallySet: [{ accessStatus: 'ALLOWED', name: 'Editor', authorityId: 'GROUP_EVERYONE' }] }
});
@@ -22,35 +22,33 @@ import { UserIconColumnComponent } from './user-icon-column.component';
import { NodeEntry } from '@alfresco/js-api';
describe('UserIconColumnComponent', () => {
let fixture: ComponentFixture<UserIconColumnComponent>;
let component: UserIconColumnComponent;
let element: HTMLElement;
const person = {
const person = {
firstName: 'fake',
lastName: 'user',
email: 'fake@test.com'
};
const group = {
const group = {
id: 'fake-id',
displayName: 'fake authority'
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(UserIconColumnComponent);
fixture = TestBed.createComponent(UserIconColumnComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
});
describe('person initial', () => {
const getInitials = () => element.querySelector('[data-automation-id="user-initials-image"]')?.textContent;
it('should render person value from context', () => {
component.context = {
row: {
@@ -61,7 +59,7 @@ describe('UserIconColumnComponent', () => {
};
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('fu');
expect(getInitials()).toContain('fu');
});
it('should render person value from node', () => {
@@ -69,8 +67,8 @@ describe('UserIconColumnComponent', () => {
entry: {
nodeType: 'cm:person',
properties: {
'cm:firstName': 'Fake',
'cm:lastName': 'User',
'cm:firstName': 'Fake',
'cm:lastName': 'User',
'cm:email': 'fake-user@test.com',
'cm:userName': 'fake-user'
}
@@ -78,11 +76,13 @@ describe('UserIconColumnComponent', () => {
} as NodeEntry;
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('FU');
expect(getInitials()).toContain('FU');
});
});
describe('group initial', () => {
const getGroupIcon = () => element.querySelector('[id="group-icon"] .adf-group-icon');
it('should render group value from context', () => {
component.context = {
row: {
@@ -93,8 +93,8 @@ describe('UserIconColumnComponent', () => {
};
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('[id="group-icon"] mat-icon')).toBeDefined();
expect(element.querySelector('[id="group-icon"] mat-icon').textContent).toContain('people_alt_outline');
expect(getGroupIcon()).toBeDefined();
expect(getGroupIcon().textContent).toContain('people_alt_outline');
});
it('should render person value from node', () => {
@@ -102,14 +102,14 @@ describe('UserIconColumnComponent', () => {
entry: {
nodeType: 'cm:authorityContainer',
properties: {
'cm:authorityName': 'Fake authorityN'
'cm:authorityName': 'Fake authorityN'
}
}
} as NodeEntry;
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('[id="group-icon"] mat-icon')).toBeDefined();
expect(element.querySelector('[id="group-icon"] mat-icon').textContent).toContain('people_alt_outline');
expect(getGroupIcon()).toBeDefined();
expect(getGroupIcon().textContent).toContain('people_alt_outline');
});
});
@@ -20,22 +20,24 @@ import { SearchFilterList } from '../../models/search-filter-list.model';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { sizeOptions, stepOne, stepThree } from '../../../mock';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader, TestKey } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
describe('SearchCheckListComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchCheckListComponent>;
let component: SearchCheckListComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchCheckListComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should setup options from settings', () => {
@@ -49,7 +51,7 @@ describe('SearchCheckListComponent', () => {
expect(component.options.items).toEqual(options);
});
it('should handle enter key as click on checkboxes', () => {
it('should handle enter key as click on checkboxes', async () => {
component.options = new SearchFilterList<SearchListOption>([
{ name: 'Folder', value: `TYPE:'cm:folder'`, checked: false },
{ name: 'Document', value: `TYPE:'cm:content'`, checked: false }
@@ -58,13 +60,13 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
const option = await loader.getHarness(MatCheckboxHarness);
optionElements[0].triggerEventHandler('keydown.enter', {});
expect(component.options.items[0].checked).toBeTruthy();
await (await option.host()).sendKeys(TestKey.ENTER);
expect(await option.isChecked()).toBe(true);
optionElements[0].triggerEventHandler('keydown.enter', {});
expect(component.options.items[0].checked).toBeFalsy();
await (await option.host()).sendKeys(TestKey.ENTER);
expect(await option.isChecked()).toBe(false);
});
it('should setup operator from the settings', () => {
@@ -95,21 +97,13 @@ describe('SearchCheckListComponent', () => {
spyOn(component.context, 'update').and.stub();
component.changeHandler(
{ checked: true } as any,
component.options.items[0]
);
component.changeHandler({ checked: true } as any, component.options.items[0]);
expect(component.context.queryFragments[component.id]).toEqual(`TYPE:'cm:folder'`);
component.changeHandler(
{ checked: true } as any,
component.options.items[1]
);
component.changeHandler({ checked: true } as any, component.options.items[1]);
expect(component.context.queryFragments[component.id]).toEqual(
`TYPE:'cm:folder' OR TYPE:'cm:content'`
);
expect(component.context.queryFragments[component.id]).toEqual(`TYPE:'cm:folder' OR TYPE:'cm:content'`);
});
it('should reset selected boxes', () => {
@@ -147,7 +141,7 @@ describe('SearchCheckListComponent', () => {
});
describe('Pagination', () => {
it('should show 5 items when pageSize not defined', () => {
it('should show 5 items when pageSize not defined', async () => {
component.id = 'checklist';
component.context = {
queryFragments: {
@@ -160,13 +154,14 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
expect(optionElements.length).toEqual(5);
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
const options = await loader.getAllHarnesses(MatCheckboxHarness);
expect(options.length).toBe(5);
const labels = await Promise.all(options.map((element) => element.getLabelText()));
expect(labels).toEqual(stepOne);
});
it('should show all items when pageSize is high', () => {
it('should show all items when pageSize is high', async () => {
component.id = 'checklist';
component.context = {
queryFragments: {
@@ -178,14 +173,15 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
expect(optionElements.length).toEqual(13);
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
const options = await loader.getAllHarnesses(MatCheckboxHarness);
expect(options.length).toBe(13);
const labels = await Promise.all(options.map((element) => element.getLabelText()));
expect(labels).toEqual(stepThree);
});
});
it('should able to check/reset the checkbox', () => {
it('should able to check/reset the checkbox', async () => {
component.id = 'checklist';
component.context = {
queryFragments: {
@@ -198,16 +194,15 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.query(By.css('mat-checkbox'));
optionElements.triggerEventHandler('change', { checked: true });
const option = await loader.getHarness(MatCheckboxHarness);
await option.check();
expect(component.submitValues).toHaveBeenCalled();
const clearAllElement = fixture.debugElement.query(By.css('button[title="SEARCH.FILTER.ACTIONS.CLEAR-ALL"]'));
clearAllElement.triggerEventHandler('click', {} );
fixture.detectChanges();
const clearButton = await loader.getHarness(MatButtonHarness.with({ selector: `[title="SEARCH.FILTER.ACTIONS.CLEAR-ALL"]` }));
await clearButton.click();
const selectedElements = fixture.debugElement.queryAll(By.css('.mat-checkbox-checked'));
expect(selectedElements.length).toBe(0);
const checkedElements = await loader.getAllHarnesses(MatCheckboxHarness.with({ checked: true }));
expect(checkedElements.length).toBe(0);
});
});
@@ -21,15 +21,13 @@ import { By } from '@angular/platform-browser';
import { SearchFacetFiltersService } from '../../services/search-facet-filters.service';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness, MatChipRemoveHarness } from '@angular/material/chips/testing';
@Component({
selector: 'adf-test-component',
template: `
<adf-search-chip-list
[searchFilter]="searchFilter"
[clearAll]="allowClear">
</adf-search-chip-list>
`
template: ` <adf-search-chip-list [searchFilter]="searchFilter" [clearAll]="allowClear"> </adf-search-chip-list> `
})
class TestComponent {
allowClear = true;
@@ -40,23 +38,22 @@ class TestComponent {
}
describe('SearchChipListComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<TestComponent>;
let component: TestComponent;
let searchFacetFiltersService: SearchFacetFiltersService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
declarations: [
TestComponent
]
imports: [TranslateModule.forRoot(), ContentTestingModule],
declarations: [TestComponent]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
searchFacetFiltersService = TestBed.inject(SearchFacetFiltersService);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should display clear button only when entries present', () => {
@@ -65,24 +62,26 @@ describe('SearchChipListComponent', () => {
let clearButton = fixture.debugElement.query(By.css(`[data-automation-id="reset-filter"]`));
expect(clearButton).toBeNull();
searchFacetFiltersService.selectedBuckets = [{
bucket: {
count: 1,
label: 'test',
filterQuery: 'query'
},
field: null
}];
searchFacetFiltersService.selectedBuckets = [
{
bucket: {
count: 1,
label: 'test',
filterQuery: 'query'
},
field: null
}
];
fixture.detectChanges();
clearButton = fixture.debugElement.query(By.css(`[data-automation-id="reset-filter"]`));
expect(clearButton).toBeDefined();
});
it('should reflect changes in the search filter', () => {
it('should reflect changes in the search filter', async () => {
const selectedBuckets = searchFacetFiltersService.selectedBuckets;
fixture.detectChanges();
let chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"]`));
let chips = await loader.getAllHarnesses(MatChipHarness.with({ selector: '[data-automation-id="chip-list-entry"]' }));
expect(chips.length).toBe(0);
selectedBuckets.push({
@@ -95,7 +94,7 @@ describe('SearchChipListComponent', () => {
});
fixture.detectChanges();
chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"]`));
chips = await loader.getAllHarnesses(MatChipHarness.with({ selector: '[data-automation-id="chip-list-entry"]' }));
expect(chips.length).toBe(1);
});
@@ -115,32 +114,30 @@ describe('SearchChipListComponent', () => {
fixture.detectChanges();
const chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"] .mat-chip-remove`));
chips[0].nativeElement.click();
const removeButton = await loader.getHarness(MatChipRemoveHarness.with({ ancestor: `[data-automation-id="chip-list-entry"]` }));
await removeButton.click();
await fixture.whenStable();
expect(searchFacetFiltersService.unselectFacetBucket).toHaveBeenCalled();
});
it('should remove items from the search filter on clear button click', () => {
it('should remove items from the search filter on clear button click', async () => {
spyOn(searchFacetFiltersService, 'unselectFacetBucket').and.stub();
const selectedBucket1: any = { field: { id: 1 }, bucket: {label: 'bucket1'} };
const selectedBucket2: any = { field: { id: 2 }, bucket: {label: 'bucket2'} };
const selectedBucket1: any = { field: { id: 1 }, bucket: { label: 'bucket1' } };
const selectedBucket2: any = { field: { id: 2 }, bucket: { label: 'bucket2' } };
searchFacetFiltersService.selectedBuckets = [selectedBucket1, selectedBucket2];
fixture.detectChanges();
const closeButtons = fixture.debugElement.nativeElement.querySelectorAll('.mat-chip-remove');
const closeButtons = await loader.getAllHarnesses(MatChipRemoveHarness);
expect(closeButtons.length).toBe(2);
closeButtons[0].click();
fixture.detectChanges();
await closeButtons[0].click();
expect(searchFacetFiltersService.unselectFacetBucket).toHaveBeenCalledWith(selectedBucket1.field, selectedBucket1.bucket);
});
it('should disable clear mode via input properties', () => {
it('should disable clear mode via input properties', async () => {
spyOn(component.searchFilter, 'unselectFacetBucket').and.callThrough();
component.allowClear = false;
@@ -157,10 +154,10 @@ describe('SearchChipListComponent', () => {
fixture.detectChanges();
const chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"] .mat-chip-remove`));
expect(chips.length).toBe(1);
const closeButtons = await loader.getAllHarnesses(MatChipRemoveHarness.with({ ancestor: `[data-automation-id="chip-list-entry"]` }));
expect(closeButtons.length).toBe(1);
const clearButton = fixture.debugElement.query(By.css(`[data-automation-id="reset-filter"]`));
expect(clearButton).toBeNull();
const hasClearButton = await loader.hasHarness(MatChipRemoveHarness.with({ selector: `[data-automation-id="reset-filter"]` }));
expect(hasClearButton).toBe(false);
});
});
@@ -32,10 +32,7 @@ describe('SearchDateRangeComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchDateRangeComponent);
component = fixture.componentInstance;
@@ -43,6 +40,9 @@ describe('SearchDateRangeComponent', () => {
afterEach(() => fixture.destroy());
const getFromInput = () => fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const getToInput = () => fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-to-input"]');
it('should setup form elements on init', () => {
fixture.detectChanges();
@@ -74,7 +74,6 @@ describe('SearchDateRangeComponent', () => {
});
it('should reset form', () => {
fixture.detectChanges();
component.form.setValue({ from: fromDate, to: toDate });
@@ -129,10 +128,13 @@ describe('SearchDateRangeComponent', () => {
spyOn(context, 'update').and.stub();
fixture.detectChanges();
component.apply({
from: fromDate,
to: toDate
}, true);
component.apply(
{
from: fromDate,
to: toDate
},
true
);
const startDate = startOfDay(fromDate).toISOString();
const endDate = endOfDay(toDate).toISOString();
@@ -146,7 +148,7 @@ describe('SearchDateRangeComponent', () => {
it('should show date-format error when Invalid found', async () => {
fixture.detectChanges();
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const input = getFromInput();
input.value = '10-f-18';
input.dispatchEvent(new Event('input'));
@@ -159,7 +161,7 @@ describe('SearchDateRangeComponent', () => {
it('should hide date-format error when correcting input', async () => {
fixture.detectChanges();
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const input = getFromInput();
input.value = '10-f-18';
input.dispatchEvent(new Event('input'));
@@ -181,7 +183,7 @@ describe('SearchDateRangeComponent', () => {
component.settings = { field: 'cm:created', maxDate: 'today' };
fixture.detectChanges();
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const input = getFromInput();
input.value = format(addDays(new Date(), 1), 'dd-MM-yyyy');
input.dispatchEvent(new Event('input'));
@@ -194,11 +196,11 @@ describe('SearchDateRangeComponent', () => {
it('should show error for required constraint', async () => {
fixture.detectChanges();
const fromInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const fromInput = getFromInput();
fromInput.value = '';
fromInput.dispatchEvent(new Event('input'));
const toInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-to-input"]');
const toInput = getToInput();
toInput.value = '';
toInput.dispatchEvent(new Event('input'));
@@ -212,11 +214,11 @@ describe('SearchDateRangeComponent', () => {
it('should show error for incorrect date range', async () => {
fixture.detectChanges();
const fromInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const fromInput = getFromInput();
fromInput.value = '11-10-2018';
fromInput.dispatchEvent(new Event('input'));
const toInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-to-input"]');
const toInput = getToInput();
toInput.value = '10-10-2018';
toInput.dispatchEvent(new Event('input'));
@@ -230,7 +232,7 @@ describe('SearchDateRangeComponent', () => {
it('should not show date-format error when valid found', async () => {
fixture.detectChanges();
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
const input = getFromInput();
input.value = '10-10-2018';
input.dispatchEvent(new Event('input'));
@@ -23,8 +23,13 @@ import { SearchFilterList } from '../../../models/search-filter-list.model';
import { SearchFacetChipTabbedComponent } from './search-facet-chip-tabbed.component';
import { FacetField } from '../../../models/facet-field.interface';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { HarnessLoader, TestKey } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness } from '@angular/material/chips/testing';
import { MatIconHarness } from '@angular/material/icon/testing';
describe('SearchFacetChipTabbedComponent', () => {
let loader: HarnessLoader;
let component: SearchFacetChipTabbedComponent;
let fixture: ComponentFixture<SearchFacetChipTabbedComponent>;
@@ -48,17 +53,9 @@ describe('SearchFacetChipTabbedComponent', () => {
}
};
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
/**
* Open the facet
*/
function openFacet() {
const chip = fixture.debugElement.query(By.css('mat-chip'));
chip.triggerEventHandler('click', {});
fixture.detectChanges();
}
/**
* Get the filter display value
*
@@ -90,71 +87,92 @@ describe('SearchFacetChipTabbedComponent', () => {
expect(displayValue).toBe('SEARCH.FILTER.ANY');
});
it('should display remove icon and disable facet when no items are loaded', () => {
const chip = fixture.debugElement.query(By.css('mat-chip'));
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(chip.classes['mat-chip-disabled']).toBeTrue();
expect(icon).toEqual('remove');
it('should display remove icon and disable facet when no items are loaded', async () => {
const chip = await loader.getHarness(MatChipHarness);
const icon = await chip.getHarness(MatIconHarness);
expect(await chip.isDisabled()).toBe(true);
expect(await icon.getName()).toEqual('remove');
});
it('should not open context menu when no items are loaded', () => {
it('should not open context menu when no items are loaded', async () => {
spyOn(component.menuTrigger, 'openMenu');
const chip = fixture.debugElement.query(By.css('mat-chip')).nativeElement;
chip.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' }));
const chip = await loader.getHarness(MatChipHarness);
const host = await chip.host();
await host.sendKeys(TestKey.ENTER);
expect(component.menuTrigger.openMenu).not.toHaveBeenCalled();
});
it('should display correct title when facet is opened', () => {
openFacet();
it('should display correct title when facet is opened', async () => {
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
const title = fixture.debugElement.query(By.css('.adf-search-filter-title')).nativeElement.innerText.split('\n')[0];
expect(title).toBe(component.tabbedFacet.label);
});
it('should display adf-search-facet-tabbed-content component', () => {
openFacet();
it('should display adf-search-facet-tabbed-content component', async () => {
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
const activeTabLabel = fixture.debugElement.query(By.css('adf-search-facet-tabbed-content'));
expect(activeTabLabel).toBeTruthy();
});
it('should display arrow down icon and not disable the chip when items are loaded', () => {
it('should display arrow down icon and not disable the chip when items are loaded', async () => {
component.isPopulated = true;
fixture.detectChanges();
const chip = fixture.debugElement.query(By.css('mat-chip'));
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(chip.classes['mat-chip-disabled']).toBeUndefined();
expect(icon).toEqual('keyboard_arrow_down');
const chip = await loader.getHarness(MatChipHarness);
const icon = await chip.getHarness(MatIconHarness);
expect(await chip.isDisabled()).toBe(false);
expect(await icon.getName()).toBe('keyboard_arrow_down');
});
it('should display arrow up icon when menu is opened', async () => {
openFacet();
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
emitChildEvent('isPopulated', true);
await fixture.whenStable();
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(icon).toEqual('keyboard_arrow_up');
const icon = await chip.getHarness(MatIconHarness);
expect(await icon.getName()).toBe('keyboard_arrow_up');
});
it('should update display value when new displayValue$ emitted', () => {
it('should update display value when new displayValue$ emitted', async () => {
const displayValue = 'field_LABEL: test, test2';
openFacet();
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
emitChildEvent('displayValue$', displayValue);
fixture.detectChanges();
expect(getDisplayValue()).toBe(displayValue);
});
it('should call onApply and close modal when apply btn is clicked', () => {
it('should call onApply and close modal when apply btn is clicked', async () => {
spyOn(component.menuTrigger, 'closeMenu').and.callThrough();
spyOn(component, 'onApply').and.callThrough();
openFacet();
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
applyButton.triggerEventHandler('click', {});
expect(component.menuTrigger.closeMenu).toHaveBeenCalled();
expect(component.onApply).toHaveBeenCalled();
});
it('should call onRemove and close modal when cancel btn is clicked', () => {
it('should call onRemove and close modal when cancel btn is clicked', async () => {
spyOn(component.menuTrigger, 'closeMenu').and.callThrough();
spyOn(component, 'onRemove').and.callThrough();
openFacet();
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
const applyButton = fixture.debugElement.query(By.css('#cancel-filter-button'));
applyButton.triggerEventHandler('click', {});
expect(component.menuTrigger.closeMenu).toHaveBeenCalled();
@@ -5,7 +5,7 @@
[disabled]="!isPopulated()"
tabIndex="0"
[matMenuTriggerFor]="menu"
(onMenuOpen)="onMenuOpen()"
(menuOpened)="onMenuOpen()"
(keydown.enter)="onEnterKeydown()"
(keydown.escape)="onEscKeydown()"
[attr.title]="facetField.displayValue$ | async"
@@ -19,77 +19,85 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SearchFacetChipComponent } from './search-facet-chip.component';
import { ContentTestingModule } from '../../../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { By } from '@angular/platform-browser';
import { SearchQueryBuilderService } from '../../../services/search-query-builder.service';
import { SearchFilterList } from '../../../models/search-filter-list.model';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatMenuHarness } from '@angular/material/menu/testing';
import { HarnessLoader, TestKey } from '@angular/cdk/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatIconHarness } from '@angular/material/icon/testing';
describe('SearchFacetChipComponent', () => {
let component: SearchFacetChipComponent;
let fixture: ComponentFixture<SearchFacetChipComponent>;
let queryBuilder: SearchQueryBuilderService;
let loader: HarnessLoader;
let component: SearchFacetChipComponent;
let fixture: ComponentFixture<SearchFacetChipComponent>;
let queryBuilder: SearchQueryBuilderService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
fixture = TestBed.createComponent(SearchFacetChipComponent);
component = fixture.componentInstance;
queryBuilder = TestBed.inject(SearchQueryBuilderService);
spyOn(queryBuilder, 'update').and.stub();
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchFacetChipComponent);
component = fixture.componentInstance;
queryBuilder = TestBed.inject(SearchQueryBuilderService);
spyOn(queryBuilder, 'update').and.stub();
component.field = { type: 'field', label: 'f2', field: 'f2', buckets: new SearchFilterList() };
fixture.detectChanges();
});
it('should update search query on apply click', () => {
const chip = fixture.debugElement.query(By.css('mat-chip'));
chip.triggerEventHandler('click', { stopPropagation: () => null });
component.field = { type: 'field', label: 'f2', field: 'f2', buckets: new SearchFilterList() };
fixture.detectChanges();
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
applyButton.triggerEventHandler('click', {});
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should update search query on apply click', async () => {
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
const applyButton = await menu.getHarness(MatButtonHarness.with({ selector: '#apply-filter-button' }));
await applyButton.click();
expect(queryBuilder.update).toHaveBeenCalled();
});
it('should update search query on cancel click', () => {
const chip = fixture.debugElement.query(By.css('mat-chip'));
chip.triggerEventHandler('click', { stopPropagation: () => null });
fixture.detectChanges();
const applyButton = fixture.debugElement.query(By.css('#cancel-filter-button'));
applyButton.triggerEventHandler('click', {});
it('should update search query on cancel click', async () => {
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
const cancelButton = await menu.getHarness(MatButtonHarness.with({ selector: '#cancel-filter-button' }));
await cancelButton.click();
expect(queryBuilder.update).toHaveBeenCalled();
});
it('should display arrow down icon and not disable the chip when items are loaded', () => {
it('should display arrow down icon and not disable the chip when items are loaded', async () => {
component.field.buckets.items = [{ count: 1, label: 'test', filterQuery: '' }];
fixture.detectChanges();
const chip = fixture.debugElement.query(By.css('mat-chip'));
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(chip.classes['mat-chip-disabled']).toBeUndefined();
expect(icon).toEqual('keyboard_arrow_down');
const menu = await loader.getHarness(MatMenuHarness);
expect(await menu.isDisabled()).toBe(false);
const icon = await loader.getHarness(MatIconHarness);
expect(await icon.getName()).toBe('keyboard_arrow_down');
});
it('should display arrow up icon when menu is opened', () => {
it('should display arrow up icon when menu is opened', async () => {
component.field.buckets.items = [{ count: 1, label: 'test', filterQuery: '' }];
component.onMenuOpen();
fixture.detectChanges();
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(icon).toEqual('keyboard_arrow_up');
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
const icon = await loader.getHarness(MatIconHarness);
expect(await icon.getName()).toBe('keyboard_arrow_up');
});
it('should display remove icon and disable facet when no items are loaded', () => {
const chip = fixture.debugElement.query(By.css('mat-chip'));
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(chip.classes['mat-chip-disabled']).toBeTrue();
expect(icon).toEqual('remove');
it('should display remove icon and disable facet when no items are loaded', async () => {
const menu = await loader.getHarness(MatMenuHarness);
expect(await menu.isDisabled()).toBe(true);
const icon = await loader.getHarness(MatIconHarness);
expect(await icon.getName()).toBe('remove');
});
it('should not open context menu when no items are loaded', () => {
spyOn(component.menuTrigger, 'openMenu');
const chip = fixture.debugElement.query(By.css('mat-chip')).nativeElement;
chip.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' }));
expect(component.menuTrigger.openMenu).not.toHaveBeenCalled();
it('should not open context menu when no items are loaded', async () => {
const menu = await loader.getHarness(MatMenuHarness);
await (await menu.host()).sendKeys(TestKey.ENTER);
expect(await menu.isOpen()).toBe(false);
});
});
@@ -4,7 +4,7 @@
[class.adf-search-toggle-chip]="(widget.getDisplayValue() | async) || menuTrigger.menuOpen"
tabIndex="0"
[matMenuTriggerFor]="menu"
(onMenuOpen)="onMenuOpen()"
(menuOpened)="onMenuOpen()"
(keydown.enter)="onEnterKeydown()"
(keydown.escape)="onEscKeydown()"
[attr.title]="widget.getDisplayValue() | async"
@@ -23,19 +23,20 @@ import { ContentTestingModule } from '../../../../testing/content.testing.module
import { MatMenuModule } from '@angular/material/menu';
import { By } from '@angular/platform-browser';
import { SearchQueryBuilderService } from '../../../services/search-query-builder.service';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness } from '@angular/material/chips/testing';
import { MatIconHarness } from '@angular/material/icon/testing';
describe('SearchWidgetChipComponent', () => {
let loader: HarnessLoader;
let component: SearchWidgetChipComponent;
let fixture: ComponentFixture<SearchWidgetChipComponent>;
let queryBuilder: SearchQueryBuilderService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
MatMenuModule,
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [MatMenuModule, TranslateModule.forRoot(), ContentTestingModule]
});
queryBuilder = TestBed.inject(SearchQueryBuilderService);
fixture = TestBed.createComponent(SearchWidgetChipComponent);
@@ -44,35 +45,40 @@ describe('SearchWidgetChipComponent', () => {
component.category = simpleCategories[1];
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should update search query on apply click', () => {
const chip = fixture.debugElement.query(By.css('mat-chip'));
chip.triggerEventHandler('click', { stopPropagation: () => null });
fixture.detectChanges();
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
applyButton.triggerEventHandler('click', {});
expect(queryBuilder.update).toHaveBeenCalled();
it('should update search query on apply click', async () => {
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
applyButton.triggerEventHandler('click', {});
expect(queryBuilder.update).toHaveBeenCalled();
});
it('should update search query on cancel click', () => {
const chip = fixture.debugElement.query(By.css('mat-chip'));
chip.triggerEventHandler('click', { stopPropagation: () => null });
fixture.detectChanges();
const applyButton = fixture.debugElement.query(By.css('#cancel-filter-button'));
applyButton.triggerEventHandler('click', {});
expect(queryBuilder.update).toHaveBeenCalled();
it('should update search query on cancel click', async () => {
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
const applyButton = fixture.debugElement.query(By.css('#cancel-filter-button'));
applyButton.triggerEventHandler('click', {});
expect(queryBuilder.update).toHaveBeenCalled();
});
it('should display arrow down icon', () => {
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(icon).toEqual('keyboard_arrow_down');
it('should display arrow down icon', async () => {
const chip = await loader.getHarness(MatChipHarness);
const icon = await chip.getHarness(MatIconHarness);
expect(await icon.getName()).toBe('keyboard_arrow_down');
});
it('should display arrow up icon when menu is opened', () => {
component.onMenuOpen();
fixture.detectChanges();
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
expect(icon).toEqual('keyboard_arrow_up');
it('should display arrow up icon when menu is opened', async () => {
component.onMenuOpen();
fixture.detectChanges();
const chip = await loader.getHarness(MatChipHarness);
const icon = await chip.getHarness(MatIconHarness);
expect(await icon.getName()).toBe('keyboard_arrow_up');
});
});
@@ -24,8 +24,13 @@ import { ContentTestingModule } from '../../../testing/content.testing.module';
import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
import { By } from '@angular/platform-browser';
import { SearchFilterContainerComponent } from './search-filter-container.component';
import { MatMenuTrigger } from '@angular/material/menu';
import { SearchCategory } from '../../models/search-category.interface';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatMenuHarness } from '@angular/material/menu/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatBadgeHarness } from '@angular/material/badge/testing';
const mockCategory: SearchCategory = {
id: 'queryName',
@@ -44,6 +49,7 @@ const mockCategory: SearchCategory = {
};
describe('SearchFilterContainerComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchFilterContainerComponent>;
let component: SearchFilterContainerComponent;
let queryBuilder: SearchHeaderQueryBuilderService;
@@ -54,10 +60,7 @@ describe('SearchFilterContainerComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [
{ provide: SearchService, useValue: searchMock },
{ provide: SEARCH_QUERY_SERVICE_TOKEN, useClass: SearchHeaderQueryBuilderService }
@@ -66,9 +69,10 @@ describe('SearchFilterContainerComponent', () => {
fixture = TestBed.createComponent(SearchFilterContainerComponent);
component = fixture.componentInstance;
queryBuilder = fixture.componentInstance['searchFilterQueryBuilder'];
component.col = {key: '123', type: 'text'};
component.col = { key: '123', type: 'text' };
spyOn(queryBuilder, 'getCategoryForColumn').and.returnValue(mockCategory);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -86,26 +90,23 @@ describe('SearchFilterContainerComponent', () => {
});
it('should set/update the active filter after the Apply button is clicked', async () => {
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
component.widgetContainer.componentRef.instance.value = 'searchText';
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
applyButton.triggerEventHandler('click', {});
fixture.detectChanges();
await fixture.whenStable();
const applyButton = await menu.getHarness(MatButtonHarness.with({ selector: '#apply-filter-button' }));
await applyButton.click();
expect(queryBuilder.getActiveFilters().length).toBe(1);
expect(queryBuilder.getActiveFilters()[0].key).toBe('name');
expect(queryBuilder.getActiveFilters()[0].value).toBe('searchText');
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
await menu.open();
component.widgetContainer.componentRef.instance.value = 'updated text';
applyButton.triggerEventHandler('click', {});
fixture.detectChanges();
await fixture.whenStable();
await applyButton.click();
expect(queryBuilder.getActiveFilters().length).toBe(1);
expect(queryBuilder.getActiveFilters()[0].key).toBe('name');
expect(queryBuilder.getActiveFilters()[0].value).toBe('updated text');
@@ -113,16 +114,15 @@ describe('SearchFilterContainerComponent', () => {
it('should remove active filter after the Clear button is clicked', async () => {
queryBuilder.setActiveFilter('name', 'searchText');
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
component.widgetContainer.componentRef.instance.value = 'searchText';
const fakeEvent = jasmine.createSpyObj('event', ['stopPropagation']);
const clearButton = fixture.debugElement.query(By.css('#clear-filter-button'));
clearButton.triggerEventHandler('click', fakeEvent);
fixture.detectChanges();
await fixture.whenStable();
const clearButton = await menu.getHarness(MatButtonHarness.with({ selector: '#clear-filter-button' }));
await clearButton.click();
expect(queryBuilder.getActiveFilters().length).toBe(0);
});
@@ -133,15 +133,13 @@ describe('SearchFilterContainerComponent', () => {
component.filterChange.subscribe(() => {
eventRaised = true;
});
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
component.widgetContainer.componentRef.instance.value = 'searchText';
const widgetContainer = fixture.debugElement.query(By.css('adf-search-widget-container'));
widgetContainer.triggerEventHandler('keypress', {key: 'Enter'});
widgetContainer.triggerEventHandler('keypress', { key: 'Enter' });
fixture.detectChanges();
await fixture.whenStable();
@@ -150,39 +148,33 @@ describe('SearchFilterContainerComponent', () => {
});
it('should hide the red dot after the filter is cleared', async () => {
const badge: HTMLElement = fixture.nativeElement.querySelector(`[data-automation-id="filter-menu-button"] .mat-badge-content`);
expect(window.getComputedStyle(badge).display).toBe('none');
const badge = await loader.getHarness(MatBadgeHarness);
expect(await badge.isHidden()).toBe(true);
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
component.widgetContainer.componentRef.instance.value = 'searchText';
const widgetContainer = fixture.debugElement.query(By.css('adf-search-widget-container'));
widgetContainer.triggerEventHandler('keypress', {key: 'Enter'});
widgetContainer.triggerEventHandler('keypress', { key: 'Enter' });
fixture.detectChanges();
await fixture.whenStable();
expect(window.getComputedStyle(badge).display).not.toBe('none');
expect(await badge.isHidden()).toBe(false);
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
const fakeEvent = jasmine.createSpyObj('event', ['stopPropagation']);
const clearButton = fixture.debugElement.query(By.css('#clear-filter-button'));
clearButton.triggerEventHandler('click', fakeEvent);
fixture.detectChanges();
await fixture.whenStable();
expect(window.getComputedStyle(badge).display).toBe('none');
await menu.open();
const clearButton = await menu.getHarness(MatButtonHarness.with({ selector: '#clear-filter-button' }));
await clearButton.click();
expect(await badge.isHidden()).toBe(true);
});
describe('Accessibility', () => {
it('should set up a focus trap on the filter when the menu is opened', async () => {
expect(component.focusTrap).toBeUndefined();
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
fixture.detectChanges();
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
expect(component.focusTrap).toBeDefined();
// eslint-disable-next-line no-underscore-dangle
@@ -190,32 +182,19 @@ describe('SearchFilterContainerComponent', () => {
});
it('should focus the input element when the menu is opened', async () => {
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
fixture.detectChanges();
await fixture.whenStable();
const inputElement = fixture.debugElement.query(By.css('.mat-input-element'));
expect(document.activeElement).toBe(inputElement.nativeElement);
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
const input = await menu.getHarness(MatInputHarness);
expect(await input.isFocused()).toBe(true);
});
it('should focus the menu trigger when the menu is closed', async () => {
const menuButton: HTMLButtonElement = fixture.nativeElement.querySelector('[data-automation-id="filter-menu-button"]');
menuButton.click();
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
fixture.detectChanges();
await fixture.whenStable();
const matMenuTrigger = fixture.debugElement.query(By.directive(MatMenuTrigger)).injector.get(MatMenuTrigger);
matMenuTrigger.closeMenu();
fixture.detectChanges();
await fixture.whenStable();
const matMenuButton = fixture.debugElement.query(By.css('[data-automation-id="filter-menu-button"]'));
expect(document.activeElement).toBe(matMenuButton.nativeElement);
await menu.close();
expect(await menu.isFocused()).toBe(true);
});
});
});
@@ -18,7 +18,7 @@
import { SearchFilterComponent } from './search-filter.component';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { AppConfigService, TranslationService } from '@alfresco/adf-core';
import { SearchService } from '../../services/search.service';
import { SearchService } from '../../services/search.service';
import { Subject } from 'rxjs';
import { SearchFilterList } from '../../models/search-filter-list.model';
import { ComponentFixture, TestBed } from '@angular/core/testing';
@@ -40,8 +40,15 @@ import {
import { TranslateModule } from '@ngx-translate/core';
import { SearchFacetFiltersService } from '../../services/search-facet-filters.service';
import { SearchFacetFieldComponent } from '../search-facet-field/search-facet-field.component';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatInputHarness } from '@angular/material/input/testing';
describe('SearchFilterComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchFilterComponent>;
let component: SearchFilterComponent;
let queryBuilder: SearchQueryBuilderService;
@@ -53,21 +60,17 @@ describe('SearchFilterComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
providers: [
{ provide: SearchService, useValue: searchMock }
]
imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [{ provide: SearchService, useValue: searchMock }]
});
searchFacetFiltersService = TestBed.inject(SearchFacetFiltersService);
queryBuilder = TestBed.inject(SearchQueryBuilderService);
fixture = TestBed.createComponent(SearchFilterComponent);
appConfigService = TestBed.inject(AppConfigService);
const translationService = fixture.debugElement.injector.get(TranslationService);
spyOn(translationService, 'instant').and.callFake((key) => key ? `${key}_translated` : null);
spyOn(translationService, 'instant').and.callFake((key) => (key ? `${key}_translated` : null));
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => fixture.destroy());
@@ -79,27 +82,41 @@ describe('SearchFilterComponent', () => {
spyOn(queryBuilder, 'execute').and.stub();
queryBuilder.config = {
categories: [],
facetFields: { fields: [
facetFields: {
fields: [
{ label: 'f1', field: 'f1' },
{ label: 'f2', field: 'f2' }
]},
]
},
facetQueries: {
queries: []
}
};
searchFacetFiltersService.responseFacets = [
{ type: 'field', label: 'f1', field: 'f1', buckets: new SearchFilterList([
{ label: 'b1', count: 10, filterQuery: 'filter', checked: true },
{ label: 'b2', count: 1, filterQuery: 'filter2' }]) },
{
type: 'field',
label: 'f1',
field: 'f1',
buckets: new SearchFilterList([
{ label: 'b1', count: 10, filterQuery: 'filter', checked: true },
{ label: 'b2', count: 1, filterQuery: 'filter2' }
])
},
{ type: 'field', label: 'f2', field: 'f2', buckets: new SearchFilterList([]) }
];
queryBuilder.addUserFacetBucket('f1', searchFacetFiltersService.responseFacets[0].buckets.items[0]);
const serverResponseFields: any = [
{ type: 'field', label: 'f1', field: 'f1', buckets: [
{ label: 'b1', metrics: [{value: {count: 6}}], filterQuery: 'filter' },
{ label: 'b2', metrics: [{value: {count: 1}}], filterQuery: 'filter2' }] },
{
type: 'field',
label: 'f1',
field: 'f1',
buckets: [
{ label: 'b1', metrics: [{ value: { count: 6 } }], filterQuery: 'filter' },
{ label: 'b2', metrics: [{ value: { count: 1 } }], filterQuery: 'filter2' }
]
},
{ type: 'field', label: 'f2', field: 'f2', buckets: [] }
];
const data = {
@@ -123,27 +140,41 @@ describe('SearchFilterComponent', () => {
spyOn(queryBuilder, 'execute').and.stub();
queryBuilder.config = {
categories: [],
facetFields: { fields: [
facetFields: {
fields: [
{ label: 'f1', field: 'f1' },
{ label: 'f2', field: 'f2' }
]},
]
},
facetQueries: {
queries: []
}
};
searchFacetFiltersService.responseFacets = [
{ type: 'field', label: 'f1', field: 'f1', buckets: new SearchFilterList([
{ label: 'b1', count: 10, filterQuery: 'filter', checked: true },
{ label: 'b2', count: 1, filterQuery: 'filter2' }]) },
{
type: 'field',
label: 'f1',
field: 'f1',
buckets: new SearchFilterList([
{ label: 'b1', count: 10, filterQuery: 'filter', checked: true },
{ label: 'b2', count: 1, filterQuery: 'filter2' }
])
},
{ type: 'field', label: 'f2', field: 'f2', buckets: new SearchFilterList([]) }
];
searchFacetFiltersService.queryBuilder.addUserFacetBucket('f1', searchFacetFiltersService.responseFacets[0].buckets.items[0]);
const serverResponseFields: any = [
{ type: 'field', label: 'f1', field: 'f1', buckets: [
{ label: 'b1', metrics: [{value: {count: 6}}], filterQuery: 'filter' },
{ label: 'b2', metrics: [{value: {count: 1}}], filterQuery: 'filter2' }] },
{
type: 'field',
label: 'f1',
field: 'f1',
buckets: [
{ label: 'b1', metrics: [{ value: { count: 6 } }], filterQuery: 'filter' },
{ label: 'b2', metrics: [{ value: { count: 1 } }], filterQuery: 'filter2' }
]
},
{ type: 'field', label: 'f2', field: 'f2', buckets: [] }
];
const data = {
@@ -167,19 +198,27 @@ describe('SearchFilterComponent', () => {
spyOn(queryBuilder, 'execute').and.stub();
queryBuilder.config = {
categories: [],
facetFields: { fields: [
facetFields: {
fields: [
{ label: 'f1', field: 'f1' },
{ label: 'f2', field: 'f2' }
]},
]
},
facetQueries: {
queries: []
}
};
searchFacetFiltersService.responseFacets = [
{ type: 'field', label: 'f1', field: 'f1', buckets: new SearchFilterList([
{ label: 'b1', count: 10, filterQuery: 'filter', checked: true },
{ label: 'b2', count: 1, filterQuery: 'filter2' }]) },
{
type: 'field',
label: 'f1',
field: 'f1',
buckets: new SearchFilterList([
{ label: 'b1', count: 10, filterQuery: 'filter', checked: true },
{ label: 'b2', count: 1, filterQuery: 'filter2' }
])
},
{ type: 'field', label: 'f2', field: 'f2', buckets: new SearchFilterList() }
];
searchFacetFiltersService.queryBuilder.addUserFacetBucket('f1', searchFacetFiltersService.responseFacets[0].buckets.items[0]);
@@ -205,9 +244,10 @@ describe('SearchFilterComponent', () => {
const queryResponse = {
label: 'query response',
buckets: new SearchFilterList([
{ label: 'q1', query: 'q1', checked: true, metrics: [{value: {count: 1}}] },
{ label: 'q2', query: 'q2', checked: false, metrics: [{value: {count: 1}}] },
{ label: 'q3', query: 'q3', checked: true, metrics: [{value: {count: 1}}] }])
{ label: 'q1', query: 'q1', checked: true, metrics: [{ value: { count: 1 } }] },
{ label: 'q2', query: 'q2', checked: false, metrics: [{ value: { count: 1 } }] },
{ label: 'q3', query: 'q3', checked: true, metrics: [{ value: { count: 1 } }] }
])
} as any;
searchFacetFiltersService.responseFacets = [queryResponse];
@@ -222,10 +262,9 @@ describe('SearchFilterComponent', () => {
expect(entry.checked).toEqual(false);
}
});
});
});
describe('widgets', () => {
it('should have expandable categories', async () => {
fixture.detectChanges();
await fixture.whenStable();
@@ -235,24 +274,8 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
const panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(1);
const element: HTMLElement = panels[0].nativeElement;
(element.childNodes[0] as HTMLElement).click();
fixture.detectChanges();
await fixture.whenStable();
expect(element.classList.contains('mat-expanded')).toBeTruthy();
(element.childNodes[0] as HTMLElement).click();
fixture.detectChanges();
await fixture.whenStable();
expect(element.classList.contains('mat-expanded')).toEqual(false);
});
it('should not show the disabled widget', async () => {
@@ -262,7 +285,7 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
const panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(0);
});
@@ -273,21 +296,11 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
const panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(1);
const title = fixture.debugElement.query(By.css('.mat-expansion-panel-header-title'));
expect(title.nativeElement.innerText.trim()).toBe('Type');
const element: HTMLElement = panels[0].nativeElement;
expect(element.classList.contains('mat-expanded')).toBeTruthy();
(element.childNodes[0] as HTMLElement).click();
fixture.detectChanges();
await fixture.whenStable();
expect(element.classList.contains('mat-expanded')).toEqual(false);
expect(await panels[0].getTitle()).toBe('Type');
expect(await panels[0].isExpanded()).toBe(true);
});
it('should show the widgets only if configured', async () => {
@@ -297,11 +310,11 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
const panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(2);
const titleElements = fixture.debugElement.queryAll(By.css('.mat-expansion-panel-header-title'));
expect(titleElements.map(title => title.nativeElement.innerText.trim())).toEqual(['Name', 'Type']);
expect(await panels[0].getTitle()).toBe('Name');
expect(await panels[1].getTitle()).toBe('Type');
});
it('should be update the search query when name changed', async () => {
@@ -311,17 +324,19 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
let panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
let panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(6);
const inputElement = fixture.debugElement.query(By.css('[data-automation-id="expansion-panel-Name"] input'));
inputElement.triggerEventHandler('change', { target: { value: '*' } });
expect(queryBuilder.update).toHaveBeenCalled();
queryBuilder.executed.next(mockSearchResult);
fixture.detectChanges();
panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(8);
});
@@ -332,19 +347,20 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const inputElement = fixture.debugElement.query(By.css('[data-automation-id="expansion-panel-Name"] input'));
inputElement.triggerEventHandler('change', { target: { value: '*' } });
const input = await loader.getHarness(MatInputHarness);
await input.setValue('*');
queryBuilder.executed.next(getMockSearchResultWithResponseBucket());
fixture.detectChanges();
const panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
const panels = await loader.getAllHarnesses(MatExpansionPanelHarness);
expect(panels.length).toBe(9);
});
it('should show the long facet options list with pagination', () => {
const panel = '[data-automation-id="expansion-panel-Size facet queries"]';
it('should show the long facet options list with pagination', async () => {
const showMoreButton = MatButtonHarness.with({ selector: `[title="SEARCH.FILTER.ACTIONS.SHOW-MORE"]` });
const showLessButton = MatButtonHarness.with({ selector: `[title="SEARCH.FILTER.ACTIONS.SHOW-LESS"]` });
appConfigService.config.search = searchFilter;
queryBuilder.resetToDefaults();
@@ -352,58 +368,51 @@ describe('SearchFilterComponent', () => {
queryBuilder.executed.next(mockSearchResult);
fixture.detectChanges();
let sizes = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(sizes).toEqual(stepOne);
const panel = await loader.getHarness(
MatExpansionPanelHarness.with({
selector: `[data-automation-id="expansion-panel-Size facet queries"]`
})
);
let moreButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-MORE"]`));
let lessButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-LESS"]`));
let sizes = await panel.getAllHarnesses(MatCheckboxHarness);
let sizeLabels = await Promise.all(sizes.map((element) => element.getLabelText()));
expect(sizeLabels).toEqual(stepOne);
expect(lessButton).toEqual(null);
expect(moreButton).toBeDefined();
let moreButton = await loader.getHarness(showMoreButton);
expect(await loader.hasHarness(showLessButton)).toBe(false);
moreButton.triggerEventHandler('click', {});
fixture.detectChanges();
await moreButton.click();
sizes = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(sizes).toEqual(stepTwo);
sizes = await panel.getAllHarnesses(MatCheckboxHarness);
sizeLabels = await Promise.all(sizes.map((element) => element.getLabelText()));
expect(sizeLabels).toEqual(stepTwo);
moreButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-MORE"]`));
lessButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-LESS"]`));
expect(lessButton).toBeDefined();
expect(moreButton).toBeDefined();
moreButton = await loader.getHarness(showMoreButton);
expect(await loader.hasHarness(showLessButton)).toBe(true);
await moreButton.click();
moreButton.triggerEventHandler('click', {});
fixture.detectChanges();
sizes = getAllMenus(`${panel} mat-checkbox`, fixture);
sizes = await panel.getAllHarnesses(MatCheckboxHarness);
sizeLabels = await Promise.all(sizes.map((element) => element.getLabelText()));
expect(sizeLabels).toEqual(stepThree);
expect(sizes).toEqual(stepThree);
expect(await loader.hasHarness(showMoreButton)).toBe(false);
let lessButton = await loader.getHarness(showLessButton);
await lessButton.click();
moreButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-MORE"]`));
lessButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-LESS"]`));
expect(lessButton).toBeDefined();
expect(moreButton).toEqual(null);
sizes = await panel.getAllHarnesses(MatCheckboxHarness);
sizeLabels = await Promise.all(sizes.map((element) => element.getLabelText()));
expect(sizeLabels).toEqual(stepTwo);
lessButton.triggerEventHandler('click', {});
fixture.detectChanges();
expect(await loader.hasHarness(showMoreButton)).toBe(true);
lessButton = await loader.getHarness(showLessButton);
await lessButton.click();
sizes = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(sizes).toEqual(stepTwo);
sizes = await panel.getAllHarnesses(MatCheckboxHarness);
sizeLabels = await Promise.all(sizes.map((element) => element.getLabelText()));
expect(sizeLabels).toEqual(stepOne);
moreButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-MORE"]`));
lessButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-LESS"]`));
expect(lessButton).toBeDefined();
expect(moreButton).toBeDefined();
lessButton.triggerEventHandler('click', {});
fixture.detectChanges();
sizes = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(sizes).toEqual(stepOne);
moreButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-MORE"]`));
lessButton = fixture.debugElement.query(By.css(`${panel} button[title="SEARCH.FILTER.ACTIONS.SHOW-LESS"]`));
expect(lessButton).toEqual(null);
expect(moreButton).toBeDefined();
expect(await loader.hasHarness(showMoreButton)).toBe(true);
expect(await loader.hasHarness(showLessButton)).toBe(false);
});
it('should not show facets if filter is not available', () => {
@@ -422,8 +431,8 @@ describe('SearchFilterComponent', () => {
expect(facetElement).toEqual(null);
});
it('should search the facets options and select it', () => {
const panel = '[data-automation-id="expansion-panel-Size facet queries"]';
it('should search the facets options and select it', async () => {
const panelSelector = '[data-automation-id="expansion-panel-Size facet queries"]';
appConfigService.config.search = searchFilter;
queryBuilder.resetToDefaults();
fixture.detectChanges();
@@ -432,41 +441,39 @@ describe('SearchFilterComponent', () => {
spyOn(queryBuilder, 'update').and.stub();
const inputElement = fixture.debugElement.query(By.css(`${panel} input`));
inputElement.nativeElement.value = 'Extra';
inputElement.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
const panel = await loader.getHarness(
MatExpansionPanelHarness.with({
selector: panelSelector
})
);
let filteredMenu = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(filteredMenu).toEqual(['Extra Small (10239)']);
const input = await panel.getHarness(MatInputHarness);
await input.setValue('Extra');
inputElement.nativeElement.value = 'my';
inputElement.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
let checkboxes = await panel.getAllHarnesses(MatCheckboxHarness);
expect(checkboxes.length).toBe(1);
expect(await checkboxes[0].getLabelText()).toBe('Extra Small (10239)');
filteredMenu = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(filteredMenu).toEqual(filteredResult);
await input.setValue('my');
const clearButton = fixture.debugElement.query(By.css(`${panel} mat-form-field button`));
clearButton.triggerEventHandler('click', {});
fixture.detectChanges();
checkboxes = await panel.getAllHarnesses(MatCheckboxHarness);
let labels = await Promise.all(checkboxes.map((element) => element.getLabelText()));
expect(labels).toEqual(filteredResult);
filteredMenu = getAllMenus(`${panel} mat-checkbox`, fixture);
expect(filteredMenu).toEqual(stepOne);
const clearButton = await panel.getHarness(MatButtonHarness.with({ selector: '[title="SEARCH.FILTER.BUTTONS.CLEAR"]' }));
await clearButton.click();
const firstOption = fixture.debugElement.query(By.css(`${panel} mat-checkbox`));
firstOption.triggerEventHandler('change', { checked: true });
fixture.detectChanges();
const checkedOption = fixture.debugElement.query(By.css(`${panel} mat-checkbox.mat-checkbox-checked`));
expect(checkedOption.nativeElement.innerText).toEqual('Extra Small (10239)');
checkboxes = await panel.getAllHarnesses(MatCheckboxHarness);
labels = await Promise.all(checkboxes.map((element) => element.getLabelText()));
expect(labels).toEqual(stepOne);
await checkboxes[0].check();
expect(queryBuilder.update).toHaveBeenCalledTimes(1);
});
it('should preserve the filter state if other fields edited', () => {
const panel1 = '[data-automation-id="expansion-panel-Size facet queries"]';
const panel2 = '[data-automation-id="expansion-panel-Type facet queries"]';
it('should preserve the filter state if other fields edited', async () => {
const panel1Selector = '[data-automation-id="expansion-panel-Size facet queries"]';
const panel2selector = '[data-automation-id="expansion-panel-Type facet queries"]';
appConfigService.config.search = searchFilter;
queryBuilder.resetToDefaults();
fixture.detectChanges();
@@ -474,39 +481,39 @@ describe('SearchFilterComponent', () => {
fixture.detectChanges();
spyOn(queryBuilder, 'update').and.stub();
const inputElement = fixture.debugElement.query(By.css(`${panel1} input`));
const inputElement = fixture.debugElement.query(By.css(`${panel1Selector} input`));
inputElement.nativeElement.value = 'my';
inputElement.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
let filteredMenu = getAllMenus(`${panel1} mat-checkbox`, fixture);
expect(filteredMenu).toEqual(filteredResult);
const panel1 = await loader.getHarness(MatExpansionPanelHarness.with({ selector: panel1Selector }));
const firstOption = fixture.debugElement.query(By.css(`${panel1} mat-checkbox`));
firstOption.triggerEventHandler('change', { checked: true });
fixture.detectChanges();
let checkboxes = await panel1.getAllHarnesses(MatCheckboxHarness);
let labels = await Promise.all(checkboxes.map((element) => element.getLabelText()));
expect(labels).toEqual(filteredResult);
let panel1CheckedOption = fixture.debugElement.query(By.css(`${panel1} mat-checkbox.mat-checkbox-checked`));
expect(panel1CheckedOption.nativeElement.innerText).toEqual('my1 (806)');
await checkboxes[0].check();
expect(await checkboxes[0].isChecked()).toBe(true);
expect(await checkboxes[0].getLabelText()).toBe('my1 (806)');
const panel2Options = fixture.debugElement.query(By.css(`${panel2} mat-checkbox`));
panel2Options.triggerEventHandler('change', { checked: true });
fixture.detectChanges();
const panel2 = await loader.getHarness(MatExpansionPanelHarness.with({ selector: panel2selector }));
checkboxes = await panel2.getAllHarnesses(MatCheckboxHarness);
await checkboxes[0].check();
expect(await checkboxes[0].isChecked()).toBe(true);
expect(await checkboxes[0].getLabelText()).toBe('SEARCH.FACET_QUERIES.MIMETYPE (13)');
const panel2CheckedOption = fixture.debugElement.query(By.css(`${panel2} mat-checkbox.mat-checkbox-checked`));
expect(panel2CheckedOption.nativeElement.innerText).toEqual('SEARCH.FACET_QUERIES.MIMETYPE (13)');
checkboxes = await panel1.getAllHarnesses(MatCheckboxHarness);
labels = await Promise.all(checkboxes.map((element) => element.getLabelText()));
expect(labels).toEqual(filteredResult);
filteredMenu = getAllMenus(`${panel1} mat-checkbox`, fixture);
expect(filteredMenu).toEqual(filteredResult);
panel1CheckedOption = fixture.debugElement.query(By.css(`${panel1} mat-checkbox.mat-checkbox-checked`));
expect(panel1CheckedOption.nativeElement.innerText).toEqual('my1 (806)');
const checkedOption = await panel1.getHarness(MatCheckboxHarness.with({ checked: true }));
expect(await checkedOption.getLabelText()).toBe('my1 (806)');
expect(queryBuilder.update).toHaveBeenCalledTimes(2);
});
it('should reset the query fragments when reset All is clicked', () => {
component.queryBuilder.queryFragments = { fragment1 : 'value1'};
component.queryBuilder.queryFragments = { fragment1: 'value1' };
appConfigService.config.search = searchFilter;
searchFacetFiltersService.responseFacets = [];
component.displayResetButton = true;
@@ -519,11 +526,10 @@ describe('SearchFilterComponent', () => {
expect(component.queryBuilder.queryFragments).toEqual({});
expect(queryBuilder.resetToDefaults).toHaveBeenCalled();
});
});
});
export const getAllMenus = (regex, fixture: ComponentFixture<any>): string[] => {
const elements = fixture.debugElement.queryAll(By.css(regex));
return Array.from(elements).map(element => element.nativeElement.innerText);
return Array.from(elements).map((element) => element.nativeElement.innerText);
};
@@ -23,8 +23,13 @@ import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchForm } from '../../models/search-form.interface';
import { By } from '@angular/platform-browser';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatMenuHarness } from '@angular/material/menu/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
describe('SearchFormComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchFormComponent>;
let component: SearchFormComponent;
let queryBuilder: SearchQueryBuilderService;
@@ -36,62 +41,62 @@ describe('SearchFormComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
providers: [
{ provide: SEARCH_QUERY_SERVICE_TOKEN, useClass: SearchQueryBuilderService }
]
imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [{ provide: SEARCH_QUERY_SERVICE_TOKEN, useClass: SearchQueryBuilderService }]
});
fixture = TestBed.createComponent(SearchFormComponent);
component = fixture.componentInstance;
queryBuilder = TestBed.inject<SearchQueryBuilderService>(SEARCH_QUERY_SERVICE_TOKEN);
queryBuilder.searchForms.next(mockSearchForms);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
const getTitle = () => fixture.debugElement.query(By.css('.adf-search-form-title'))?.nativeElement as HTMLSpanElement;
it('should show search forms', () => {
const title = fixture.debugElement.query(By.css('.adf-search-form-title'));
expect(title.nativeElement.innerText).toContain(mockSearchForms[1].name);
const title = getTitle();
expect(title.innerText).toContain(mockSearchForms[1].name);
});
it('should emit on form change', (done) => {
it('should emit on form change', async () => {
spyOn(queryBuilder, 'updateSelectedConfiguration').and.stub();
component.formChange.subscribe((form) => {
expect(form).toEqual(mockSearchForms[2]);
expect(queryBuilder.updateSelectedConfiguration).toHaveBeenCalled();
done();
});
const button = fixture.debugElement.query(By.css('.adf-search-form')).nativeElement;
button.click();
fixture.detectChanges();
let changedForm: SearchForm;
component.formChange.subscribe((form) => (changedForm = form));
const matOption = fixture.debugElement.queryAll(By.css('.mat-menu-item'))[2].nativeElement;
matOption.click();
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();
const menuItems = await menu.getItems();
expect(menuItems.length).toEqual(3);
await menuItems[2].click();
expect(changedForm).toEqual(mockSearchForms[2]);
expect(queryBuilder.updateSelectedConfiguration).toHaveBeenCalled();
});
it('should not show menu if only one config found', () => {
it('should not show menu if only one config found', async () => {
queryBuilder.searchForms.next([{ name: 'one', selected: true, default: true, index: 0 }]);
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('.adf-search-form')).nativeElement;
button.click();
const button = await loader.getHarness(MatButtonHarness.with({ selector: '.adf-search-form' }));
await button.click();
const title = fixture.debugElement.query(By.css('.adf-search-form-title'));
expect(title.nativeElement.innerText).toContain('one');
const title = getTitle();
expect(title.innerText).toContain('one');
fixture.detectChanges();
const matOption = fixture.debugElement.query(By.css('.mat-menu-item'));
expect(matOption).toBe(null, 'should not show mat menu');
const hasMenu = await loader.hasHarness(MatMenuHarness);
expect(hasMenu).toBe(false);
});
it('should not display search form if no form configured', () => {
queryBuilder.searchForms.next([]);
fixture.detectChanges();
const field = fixture.debugElement.query(By.css('.adf-search-form-title'));
expect(field).toEqual(null, 'search form displayed for empty configuration');
const field = getTitle();
expect(field).toBeUndefined();
});
});
@@ -1,6 +1,6 @@
<div class="adf-search-logical-filter-container">
<div *ngFor="let field of fields" class="adf-search-input">
<mat-label>{{('SEARCH.LOGICAL_SEARCH.' + field + '_LABEL') | translate}}</mat-label>
<mat-label data-automation-id="adf-search-input-label">{{('SEARCH.LOGICAL_SEARCH.' + field + '_LABEL') | translate}}</mat-label>
<input type="text"
[(ngModel)]="searchCondition[LogicalSearchFields[field]]"
placeholder="{{ ('SEARCH.LOGICAL_SEARCH.' + field + '_HINT') | translate }}"
@@ -28,10 +28,7 @@ describe('SearchLogicalFilterComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SearchLogicalFilterComponent],
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchLogicalFilterComponent);
@@ -62,7 +59,7 @@ describe('SearchLogicalFilterComponent', () => {
* @returns list of labels
*/
function getInputsLabels(): string[] {
return fixture.debugElement.queryAll(By.css('.adf-search-input mat-label')).map((label) => label.nativeElement.innerText);
return fixture.debugElement.queryAll(By.css(`[data-automation-id="adf-search-input-label"]`)).map((label) => label.nativeElement.innerText);
}
/**
@@ -164,7 +161,9 @@ describe('SearchLogicalFilterComponent', () => {
enterNewPhrase('test5 test6 ', 2);
component.submitValues();
expect(component.context.update).toHaveBeenCalled();
expect(component.context.queryFragments[component.id]).toBe('((NOT field1:"test5" AND NOT field1:"test6") AND (NOT field2:"test5" AND NOT field2:"test6"))');
expect(component.context.queryFragments[component.id]).toBe(
'((NOT field1:"test5" AND NOT field1:"test6") AND (NOT field2:"test5" AND NOT field2:"test6"))'
);
});
it('should form correct query from match exact field and trim it', () => {
@@ -20,22 +20,26 @@ import { SearchFilterList } from '../../models/search-filter-list.model';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { sizeOptions, stepOne, stepThree } from '../../../mock';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader, TestKey } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { By } from '@angular/platform-browser';
describe('SearchCheckListComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchCheckListComponent>;
let component: SearchCheckListComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchCheckListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should setup options from settings', () => {
@@ -49,7 +53,7 @@ describe('SearchCheckListComponent', () => {
expect(component.options.items).toEqual(options);
});
it('should handle enter key as click on checkboxes', () => {
it('should handle enter key as click on checkboxes', async () => {
component.options = new SearchFilterList<SearchListOption>([
{ name: 'Folder', value: `TYPE:'cm:folder'`, checked: false },
{ name: 'Document', value: `TYPE:'cm:content'`, checked: false }
@@ -58,13 +62,12 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
const options = await loader.getAllHarnesses(MatCheckboxHarness);
await (await options[0].host()).sendKeys(TestKey.ENTER);
expect(await options[0].isChecked()).toBe(true);
optionElements[0].triggerEventHandler('keydown.enter', {});
expect(component.options.items[0].checked).toBeTruthy();
optionElements[0].triggerEventHandler('keydown.enter', {});
expect(component.options.items[0].checked).toBeFalsy();
await (await options[0].host()).sendKeys(TestKey.ENTER);
expect(await options[0].isChecked()).toBe(false);
});
it('should setup operator from the settings', () => {
@@ -95,21 +98,13 @@ describe('SearchCheckListComponent', () => {
spyOn(component.context, 'update').and.stub();
component.changeHandler(
{ checked: true } as any,
component.options.items[0]
);
component.changeHandler({ checked: true } as any, component.options.items[0]);
expect(component.context.queryFragments[component.id]).toEqual(`TYPE:'cm:folder'`);
component.changeHandler(
{ checked: true } as any,
component.options.items[1]
);
component.changeHandler({ checked: true } as any, component.options.items[1]);
expect(component.context.queryFragments[component.id]).toEqual(
`TYPE:'cm:folder' OR TYPE:'cm:content'`
);
expect(component.context.queryFragments[component.id]).toEqual(`TYPE:'cm:folder' OR TYPE:'cm:content'`);
});
it('should reset selected boxes', () => {
@@ -147,7 +142,7 @@ describe('SearchCheckListComponent', () => {
});
describe('Pagination', () => {
it('should show 5 items when pageSize not defined', () => {
it('should show 5 items when pageSize not defined', async () => {
component.id = 'checklist';
component.context = {
queryFragments: {
@@ -160,13 +155,14 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
expect(optionElements.length).toEqual(5);
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
const options = await loader.getAllHarnesses(MatCheckboxHarness);
expect(options.length).toEqual(5);
const labels = await Promise.all(Array.from(options).map(async (element) => element.getLabelText()));
expect(labels).toEqual(stepOne);
});
it('should show all items when pageSize is high', () => {
it('should show all items when pageSize is high', async () => {
component.id = 'checklist';
component.context = {
queryFragments: {
@@ -178,14 +174,15 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
expect(optionElements.length).toEqual(13);
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
const options = await loader.getAllHarnesses(MatCheckboxHarness);
expect(options.length).toEqual(13);
const labels = await Promise.all(Array.from(options).map(async (element) => element.getLabelText()));
expect(labels).toEqual(stepThree);
});
});
it('should able to check/reset the checkbox', () => {
it('should able to check/reset the checkbox', async () => {
component.id = 'checklist';
component.context = {
queryFragments: {
@@ -198,16 +195,15 @@ describe('SearchCheckListComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.query(By.css('mat-checkbox'));
optionElements.triggerEventHandler('change', { checked: true });
const checkbox = await loader.getHarness(MatCheckboxHarness);
await checkbox.check();
expect(component.submitValues).toHaveBeenCalled();
const clearAllElement = fixture.debugElement.query(By.css('button[title="SEARCH.FILTER.ACTIONS.CLEAR-ALL"]'));
clearAllElement.triggerEventHandler('click', {} );
clearAllElement.triggerEventHandler('click', {});
fixture.detectChanges();
const selectedElements = fixture.debugElement.queryAll(By.css('.mat-checkbox-checked'));
expect(selectedElements.length).toBe(0);
expect(await checkbox.isChecked()).toBe(false);
});
});
@@ -16,29 +16,31 @@
*/
import { sizeOptions, stepOne, stepThree } from '../../../mock';
import { By } from '@angular/platform-browser';
import { SearchRadioComponent } from './search-radio.component';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatRadioButtonHarness, MatRadioGroupHarness } from '@angular/material/radio/testing';
describe('SearchRadioComponent', () => {
let fixture: ComponentFixture<SearchRadioComponent>;
let component: SearchRadioComponent;
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchRadioComponent>;
let component: SearchRadioComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
fixture = TestBed.createComponent(SearchRadioComponent);
component = fixture.componentInstance;
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchRadioComponent);
component = fixture.componentInstance;
describe('Pagination', () => {
it('should show 5 items when pageSize not defined', () => {
loader = TestbedHarnessEnvironment.loader(fixture);
});
describe('Pagination', () => {
it('should show 5 items when pageSize not defined', async () => {
component.id = 'radio';
component.context = {
queryFragments: {
@@ -51,13 +53,14 @@ describe('SearchRadioComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-radio-button'));
expect(optionElements.length).toEqual(5);
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
const options = await loader.getAllHarnesses(MatRadioButtonHarness);
expect(options.length).toEqual(5);
const labels = await Promise.all(Array.from(options).map(async (element) => element.getLabelText()));
expect(labels).toEqual(stepOne);
});
it('should show all items when pageSize is high', () => {
it('should show all items when pageSize is high', async () => {
component.id = 'radio';
component.context = {
queryFragments: {
@@ -69,14 +72,15 @@ describe('SearchRadioComponent', () => {
component.ngOnInit();
fixture.detectChanges();
const optionElements = fixture.debugElement.queryAll(By.css('mat-radio-button'));
expect(optionElements.length).toEqual(13);
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
const options = await loader.getAllHarnesses(MatRadioButtonHarness);
expect(options.length).toEqual(13);
const labels = await Promise.all(Array.from(options).map(async (element) => element.getLabelText()));
expect(labels).toEqual(stepThree);
});
});
it('should able to check the radio button', async () => {
it('should able to check the radio button', async () => {
component.id = 'radio';
component.context = {
queryFragments: {
@@ -85,15 +89,10 @@ describe('SearchRadioComponent', () => {
update: () => {}
} as any;
component.settings = { options: sizeOptions } as any;
spyOn(component.context, 'update').and.stub();
fixture.detectChanges();
await fixture.whenStable();
const optionElements = fixture.debugElement.query(By.css('mat-radio-group'));
optionElements.triggerEventHandler('change', { value: sizeOptions[0].value });
fixture.detectChanges();
const group = await loader.getHarness(MatRadioGroupHarness);
await group.checkRadioButton({ selector: `[data-automation-id="search-radio-${sizeOptions[0].name}"]` });
expect(component.context.update).toHaveBeenCalled();
expect(component.context.queryFragments[component.id]).toBe(sizeOptions[0].value);
});
});
@@ -19,17 +19,19 @@ import { SearchTextComponent } from './search-text.component';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
describe('SearchTextComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchTextComponent>;
let component: SearchTextComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(SearchTextComponent);
component = fixture.componentInstance;
@@ -44,6 +46,8 @@ describe('SearchTextComponent', () => {
queryFragments: {},
update: () => {}
} as any;
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should parse value from the context at startup', () => {
@@ -100,16 +104,19 @@ describe('SearchTextComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
expect(component.value).toEqual('secret.pdf');
const input = fixture.debugElement.nativeElement.querySelector('.mat-form-field-infix input');
expect(input.value).toEqual('secret.pdf');
const input = await loader.getHarness(MatInputHarness);
expect(await input.getValue()).toBe('secret.pdf');
});
it('should be able to reset by clicking clear button', async () => {
it('should be able to reset by clicking clear button', async () => {
component.context.queryFragments[component.id] = `cm:name:'secret.pdf'`;
fixture.detectChanges();
await fixture.whenStable();
const clearElement = fixture.debugElement.nativeElement.querySelector('button');
clearElement.click();
const clearButton = await loader.getHarness(MatButtonHarness);
await clearButton.click();
expect(component.value).toBe('');
expect(component.context.queryFragments[component.id]).toBe('');
});
@@ -15,13 +15,12 @@
* limitations under the License.
*/
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DropdownSitesComponent, Relations } from './sites-dropdown.component';
import { AuthenticationService } from '@alfresco/adf-core';
import { of } from 'rxjs';
import { getFakeSitePaging,
import {
getFakeSitePaging,
getFakeSitePagingNoMoreItems,
getFakeSitePagingFirstPage,
getFakeSitePagingLastPage,
@@ -30,6 +29,10 @@ import { getFakeSitePaging,
import { ContentTestingModule } from '../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { SitesService } from '../common/services/sites.service';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
import { SiteEntry } from '@alfresco/js-api';
const customSiteList = {
list: {
@@ -51,70 +54,57 @@ const customSiteList = {
};
describe('DropdownSitesComponent', () => {
let loader: HarnessLoader;
let component: any;
let fixture: ComponentFixture<DropdownSitesComponent>;
let debug: DebugElement;
let element: HTMLElement;
let siteService: SitesService;
let authService: AuthenticationService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
});
describe('Rendering tests', () => {
describe('Infinite Loading', () => {
beforeEach(() => {
siteService = TestBed.inject(SitesService);
fixture = TestBed.createComponent(DropdownSitesComponent);
debug = fixture.debugElement;
element = fixture.nativeElement;
component = fixture.componentInstance;
spyOn(siteService, 'getSites').and.returnValue(of(getFakeSitePaging()));
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('Should show loading item if there are more itemes', async () => {
it('Should show loading item if there are more items', async () => {
fixture.detectChanges();
await fixture.whenStable();
expect(element.querySelector('[data-automation-id="site-loading"]')).toBeDefined();
});
it('Should not show loading item if there are more itemes', async () => {
it('Should not show loading item if there are more items', async () => {
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();
expect(element.querySelector('[data-automation-id="site-loading"]')).toBeNull();
});
});
describe('Sites', () => {
beforeEach(() => {
siteService = TestBed.inject(SitesService);
spyOn(siteService, 'getSites').and.returnValue(of(getFakeSitePagingNoMoreItems()));
fixture = TestBed.createComponent(DropdownSitesComponent);
debug = fixture.debugElement;
element = fixture.nativeElement;
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
const openSelectBox = () => {
const selectBox = debug.query(By.css(('[data-automation-id="site-my-files-option"] .mat-select-trigger')));
selectBox.triggerEventHandler('click', null);
};
it('Dropdown sites should be rendered', async () => {
fixture.detectChanges();
await fixture.whenStable();
@@ -131,13 +121,11 @@ describe('DropdownSitesComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
const select = await loader.getHarness(MatSelectHarness);
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options: any = debug.queryAll(By.css('mat-option'));
expect(options[0].nativeElement.innerText).toContain('DROPDOWN.MY_FILES_OPTION');
const options = await select.getOptions();
expect(await options[0].getText()).toContain('DROPDOWN.MY_FILES_OPTION');
});
it('should hide the "My files" option if the developer desires that way', async () => {
@@ -146,23 +134,19 @@ describe('DropdownSitesComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
const select = await loader.getHarness(MatSelectHarness);
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options: any = debug.queryAll(By.css('mat-option'));
expect(options[0].nativeElement.innerText).not.toContain('DROPDOWN.MY_FILES_OPTION');
const options = await select.getOptions();
expect(await options[0].getText()).not.toContain('DROPDOWN.MY_FILES_OPTION');
});
it('should show the default placeholder label by default', async () => {
fixture.detectChanges();
await fixture.whenStable();
openSelectBox();
fixture.detectChanges();
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
expect(fixture.nativeElement.innerText.trim()).toContain('NODE_SELECTOR.LOCATION');
});
@@ -173,10 +157,8 @@ describe('DropdownSitesComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
openSelectBox();
fixture.detectChanges();
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
expect(fixture.nativeElement.innerText.trim()).toContain('NODE_SELECTOR.LOCATION');
});
@@ -187,51 +169,42 @@ describe('DropdownSitesComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
openSelectBox();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options = await select.getOptions();
const options = debug.queryAll(By.css('mat-option'));
options[0].triggerEventHandler('click', null);
fixture.detectChanges();
await fixture.whenStable();
expect(options[0].nativeElement.innerText).toContain('PERSONAL_FILES');
expect(options[1].nativeElement.innerText).toContain('FILE_LIBRARIES');
expect(await options[0].getText()).toContain('PERSONAL_FILES');
expect(await options[1].getText()).toContain('FILE_LIBRARIES');
});
it('should load sites by default', async () => {
fixture.detectChanges();
await fixture.whenStable();
debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const options = await select.getOptions();
expect(await options[1].getText()).toContain('fake-test-site');
expect(await options[2].getText()).toContain('fake-test-2');
});
it('should raise an event when a site is selected', async () => {
fixture.detectChanges();
await fixture.whenStable();
const options: any = debug.queryAll(By.css('mat-option'));
expect(options[1].nativeElement.innerText).toContain('fake-test-site');
expect(options[2].nativeElement.innerText).toContain('fake-test-2');
});
let site: SiteEntry;
component.change.subscribe((value) => (site = value));
it('should raise an event when a site is selected', (done) => {
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
fixture.whenStable().then(() => {
fixture.detectChanges();
debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
fixture.detectChanges();
const options: any = debug.queryAll(By.css('mat-option'));
options[1].nativeElement.click();
fixture.detectChanges();
});
const options = await select.getOptions();
await options[1].click();
component.change.subscribe((site) => {
expect(site.entry.guid).toBe('fake-1');
done();
});
expect(site.entry.guid).toBe('fake-1');
});
it('should be possible to select the default value', async () => {
@@ -245,13 +218,13 @@ describe('DropdownSitesComponent', () => {
});
describe('Default value', () => {
beforeEach(() => {
siteService = TestBed.inject(SitesService);
spyOn(siteService, 'getSites').and.returnValues(of(getFakeSitePagingFirstPage()), of(getFakeSitePagingLastPage()));
fixture = TestBed.createComponent(DropdownSitesComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should load new sites if default value is not in the first page', (done) => {
@@ -277,15 +250,14 @@ describe('DropdownSitesComponent', () => {
});
describe('Sites with members', () => {
beforeEach(() => {
siteService = TestBed.inject(SitesService);
spyOn(siteService, 'getSites').and.returnValue(of(getFakeSitePagingWithMembers()));
fixture = TestBed.createComponent(DropdownSitesComponent);
debug = fixture.debugElement;
element = fixture.nativeElement;
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -293,28 +265,23 @@ describe('DropdownSitesComponent', () => {
});
describe('No relations', () => {
beforeEach(() => {
component.relations = Relations.Members;
authService = TestBed.inject(AuthenticationService);
});
it('should show only sites which logged user is member of when member relation is set', (done) => {
it('should show only sites which logged user is member of when member relation is set', async () => {
spyOn(authService, 'getEcmUsername').and.returnValue('test');
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
fixture.detectChanges();
fixture.whenStable().then(() => {
const options: any = debug.queryAll(By.css('mat-option'));
expect(options[1].nativeElement.innerText).toContain('FAKE-SITE-PUBLIC');
expect(options[2].nativeElement.innerText).toContain('FAKE-PRIVATE-SITE-MEMBER');
expect(options[3]).toBeUndefined();
done();
});
});
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const options = await select.getOptions();
expect(await options[1].getText()).toContain('FAKE-SITE-PUBLIC');
expect(await options[2].getText()).toContain('FAKE-PRIVATE-SITE-MEMBER');
});
});
@@ -324,22 +291,19 @@ describe('DropdownSitesComponent', () => {
authService = TestBed.inject(AuthenticationService);
});
it('should show all the sites if no relation is set', (done) => {
it('should show all the sites if no relation is set', async () => {
spyOn(authService, 'getEcmUsername').and.returnValue('test');
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null);
fixture.detectChanges();
fixture.whenStable().then(() => {
const options: any = debug.queryAll(By.css('mat-option'));
expect(options[1].nativeElement.innerText).toContain('FAKE-MODERATED-SITE');
expect(options[2].nativeElement.innerText).toContain('FAKE-SITE-PUBLIC');
expect(options[3].nativeElement.innerText).toContain('FAKE-PRIVATE-SITE-MEMBER');
done();
});
});
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const options = await select.getOptions();
expect(await options[1].getText()).toContain('FAKE-MODERATED-SITE');
expect(await options[2].getText()).toContain('FAKE-SITE-PUBLIC');
expect(await options[3].getText()).toContain('FAKE-PRIVATE-SITE-MEMBER');
});
});
});
@@ -8,6 +8,7 @@
<header class="adf-upload-dialog__header">
<button
mat-button
[attr.data-automation-id]="'adf-upload-dialog__toggle-minimize'"
[attr.aria-label]="(isDialogMinimized ?
'ADF_FILE_UPLOAD.ARIA-LABEL.DIALOG_MAXIMIZE':
'ADF_FILE_UPLOAD.ARIA-LABEL.DIALOG_MINIMIZE') | translate"
@@ -29,15 +29,15 @@ describe('FileUploadingListRowComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
imports: [TranslateModule.forRoot(), ContentTestingModule]
});
fixture = TestBed.createComponent(FileUploadingListRowComponent);
component = fixture.componentInstance;
});
const getCancelButton = () =>
fixture.debugElement.query(By.css('[data-automation-id="cancel-upload-progress"]'))?.nativeElement as HTMLButtonElement;
describe('events', () => {
beforeEach(() => {
component.file = file;
@@ -58,9 +58,7 @@ describe('FileUploadingListRowComponent', () => {
fixture.detectChanges();
expect(fixture.nativeElement.querySelector(
'.adf-file-uploading-row__version'
).textContent).toContain('1');
expect(fixture.nativeElement.querySelector('.adf-file-uploading-row__version').textContent).toContain('1');
});
it('should show cancel button when upload is in progress', async () => {
@@ -71,7 +69,7 @@ describe('FileUploadingListRowComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const cancelButton = fixture.debugElement.query(By.css('[data-automation-id="cancel-upload-progress"]'));
const cancelButton = getCancelButton();
expect(cancelButton).not.toBeNull();
});
@@ -83,7 +81,7 @@ describe('FileUploadingListRowComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const cancelButton = fixture.debugElement.query(By.css('[data-automation-id="cancel-upload-progress"]'));
const cancelButton = getCancelButton();
expect(cancelButton).not.toBeNull();
});
@@ -95,8 +93,8 @@ describe('FileUploadingListRowComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const cancelButton = fixture.debugElement.query(By.css('[data-automation-id="cancel-upload-progress"]'));
expect(cancelButton).toBeNull();
const cancelButton = getCancelButton();
expect(cancelButton).toBeUndefined();
});
it('should provide tooltip for the cancel button', async () => {
@@ -107,7 +105,7 @@ describe('FileUploadingListRowComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const cancelButton: HTMLDivElement = fixture.debugElement.query(By.css('[data-automation-id="cancel-upload-progress"]')).nativeElement;
const cancelButton = getCancelButton();
expect(cancelButton.title).toBe('ADF_FILE_UPLOAD.BUTTON.STOP_FILE');
});
});
@@ -178,6 +178,9 @@ describe('AlfrescoViewerComponent', () => {
fixture.destroy();
});
const getNextButton = () => element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const getPrevButton = () => element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
describe('Extension Type Test', () => {
it('should use external viewer to display node by id', fakeAsync(() => {
const extension: ViewerExtensionRef = {
@@ -482,10 +485,10 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const nextButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const nextButton = getNextButton();
expect(nextButton).not.toBeNull();
const prevButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
const prevButton = getPrevButton();
expect(prevButton).toBeNull();
});
@@ -497,7 +500,7 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const nextButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const nextButton = getNextButton();
expect(nextButton.title).toBe('ADF_VIEWER.ACTIONS.NEXT_FILE');
});
@@ -509,10 +512,10 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const nextButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const nextButton = getNextButton();
expect(nextButton).toBeNull();
const prevButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
const prevButton = getPrevButton();
expect(prevButton).not.toBeNull();
});
@@ -524,7 +527,7 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const prevButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
const prevButton = getPrevButton();
expect(prevButton.title).toBe('ADF_VIEWER.ACTIONS.PREV_FILE');
});
@@ -536,10 +539,10 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const nextButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const nextButton = getNextButton();
expect(nextButton).not.toBeNull();
const prevButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
const prevButton = getPrevButton();
expect(prevButton).not.toBeNull();
});
@@ -549,10 +552,10 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const nextButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const nextButton = getNextButton();
expect(nextButton).toBeNull();
const prevButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
const prevButton = getPrevButton();
expect(prevButton).toBeNull();
});
@@ -564,10 +567,10 @@ describe('AlfrescoViewerComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const nextButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-next-file"]');
const nextButton = getNextButton();
expect(nextButton).toBeNull();
const prevButton = element.querySelector<HTMLButtonElement>('[data-automation-id="adf-toolbar-pref-file"]');
const prevButton = getPrevButton();
expect(prevButton).toBeNull();
});
@@ -787,21 +790,13 @@ describe('AlfrescoViewerComponent', () => {
});
});
it('should not close the viewer on Escape event if dialog was opened', (done) => {
it('should not close the viewer on Escape event if dialog was opened', async () => {
const event = new KeyboardEvent('keydown', {
bubbles: true,
keyCode: 27
key: 'Escape'
} as KeyboardEventInit);
const dialogRef = dialog.open(DummyDialogComponent);
dialogRef.afterClosed().subscribe(() => {
EventMock.keyDown(27);
fixture.detectChanges();
expect(element.querySelector('.adf-viewer-content')).toBeNull();
done();
});
dialog.open(DummyDialogComponent);
fixture.detectChanges();
document.body.dispatchEvent(event);
@@ -23,8 +23,14 @@ import { CardViewArrayItemModel, CardViewArrayItem } from '../../models/card-vie
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { CardViewUpdateService } from '../../services/card-view-update.service';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness, MatChipListHarness } from '@angular/material/chips/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatIconHarness } from '@angular/material/icon/testing';
describe('CardViewArrayItemComponent', () => {
let loader: HarnessLoader;
let component: CardViewArrayItemComponent;
let fixture: ComponentFixture<CardViewArrayItemComponent>;
let service: CardViewUpdateService;
@@ -52,6 +58,7 @@ describe('CardViewArrayItemComponent', () => {
service = TestBed.inject(CardViewUpdateService);
component = fixture.componentInstance;
component.property = new CardViewArrayItemModel(mockDefaultProps);
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -69,23 +76,25 @@ describe('CardViewArrayItemComponent', () => {
fixture.detectChanges();
});
it('should call service on chip click', () => {
const chip: HTMLElement = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Zlatan"]');
chip.dispatchEvent(new Event('click'));
it('should call service on chip click', async () => {
const chip = await loader.getHarness(MatChipHarness);
await (await chip.host()).click();
expect(serviceSpy).toHaveBeenCalled();
});
it('should call service on edit icon click', () => {
const editIcon: HTMLElement = fixture.nativeElement.querySelector('[data-automation-id="card-array-item-clickable-icon-array"]');
editIcon.dispatchEvent(new Event('click'));
it('should call service on edit icon click', async () => {
const button = await loader.getHarness(
MatButtonHarness.with({ selector: `[data-automation-id="card-array-item-clickable-icon-array"]` })
);
await button.click();
expect(serviceSpy).toHaveBeenCalled();
});
it('should NOT call service on chip list container click', () => {
const chipListContainer: HTMLElement = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-list-container"]');
chipListContainer.dispatchEvent(new Event('click'));
it('should NOT call service on chip list container click', async () => {
const chipList = await loader.getHarness(MatChipListHarness);
await (await chipList.host()).click();
expect(serviceSpy).not.toHaveBeenCalled();
});
@@ -116,7 +125,7 @@ describe('CardViewArrayItemComponent', () => {
expect(chip2.innerText).toEqual('Lionel Messi');
});
it('should render chip with defined icon', () => {
it('should render chip with defined icon', async () => {
component.property = new CardViewArrayItemModel({
...mockDefaultProps,
editable: true
@@ -125,15 +134,16 @@ describe('CardViewArrayItemComponent', () => {
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chip1 = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Zlatan"] span');
const chip1Icon = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Zlatan"] mat-icon');
const chip1Icon = await loader.getHarness(MatIconHarness.with({ ancestor: `[data-automation-id="card-arrayitem-chip-Zlatan"]` }));
const chip2 = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Lionel Messi"] span');
const chip2Icon = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Lionel Messi"] mat-icon');
const chip2Icon = await loader.getHarness(MatIconHarness.with({ ancestor: `[data-automation-id="card-arrayitem-chip-Lionel Messi"]` }));
expect(chipListContainer).not.toBeNull();
expect(chip1.innerText).toEqual('Zlatan');
expect(chip1Icon.innerText).toEqual('person');
expect(await chip1Icon.getName()).toBe('person');
expect(chip2.innerText).toEqual('Lionel Messi');
expect(chip2Icon.innerText).toEqual('group');
expect(await chip2Icon.getName()).toBe('group');
});
it('should render defined icon if clickable set to true', () => {
@@ -147,41 +157,41 @@ describe('CardViewArrayItemComponent', () => {
expect(editIcon.innerText).toBe('edit');
});
it('should not render defined icon if clickable set to false', () => {
it('should not render defined icon if clickable set to false', async () => {
component.property = new CardViewArrayItemModel({
...mockDefaultProps,
clickable: false
});
fixture.detectChanges();
const editIcon = fixture.nativeElement.querySelector('[data-automation-id="card-array-item-clickable-icon-array"]');
expect(editIcon).toBeNull();
const editExists = await loader.hasHarness(
MatButtonHarness.with({ selector: `[data-automation-id="card-array-item-clickable-icon-array"]` })
);
expect(editExists).toBe(false);
});
it('should render all values if noOfItemsToDisplay is not defined', () => {
it('should render all values if noOfItemsToDisplay is not defined', async () => {
fixture.detectChanges();
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const moreElement = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-more-chip"]'));
const chip = fixture.nativeElement.querySelectorAll('mat-chip');
const chipList = await loader.getHarness(MatChipListHarness);
const chips = await chipList.getChips();
expect(chipListContainer).not.toBeNull();
const moreElement = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-more-chip"]'));
expect(moreElement).toBeNull();
expect(chip.length).toBe(4);
expect(chips.length).toBe(4);
});
it('should render only two values along with more item chip if noOfItemsToDisplay is set to 2', () => {
it('should render only two values along with more item chip if noOfItemsToDisplay is set to 2', async () => {
component.property = new CardViewArrayItemModel({
...mockDefaultProps,
noOfItemsToDisplay: 2
});
fixture.detectChanges();
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chip = fixture.debugElement.queryAll(By.css('mat-chip'));
const chipList = await loader.getHarness(MatChipListHarness);
const chips = await chipList.getChips();
expect(chipListContainer).not.toBeNull();
expect(chip.length).toBe(3);
expect(chip[2].nativeElement.innerText).toBe('2 CORE.CARDVIEW.MORE');
expect(chips.length).toBe(3);
expect(await chips[2].getText()).toBe('2 CORE.CARDVIEW.MORE');
});
});
});
@@ -26,19 +26,19 @@ import { CardViewDatetimeItemModel } from '../../models/card-view-datetimeitem.m
import { TranslateModule } from '@ngx-translate/core';
import { AppConfigService } from '@alfresco/adf-core';
import { MatDatetimepickerInputEvent } from '@mat-datetimepicker/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness } from '@angular/material/chips/testing';
describe('CardViewDateItemComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<CardViewDateItemComponent>;
let component: CardViewDateItemComponent;
let appConfigService: AppConfigService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
appConfigService = TestBed.inject(AppConfigService);
appConfigService.config.dateValues = {
@@ -57,6 +57,8 @@ describe('CardViewDateItemComponent', () => {
format: '',
editable: false
});
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => fixture.destroy());
@@ -235,7 +237,9 @@ describe('CardViewDateItemComponent', () => {
component.property.value = new Date('Jul 10 2017');
fixture.detectChanges();
const datePickerClearToggle = fixture.debugElement.query(By.css(`[data-automation-id="datepicker-date-clear-${component.property.key}"]`));
const datePickerClearToggle = fixture.debugElement.query(
By.css(`[data-automation-id="datepicker-date-clear-${component.property.key}"]`)
);
expect(datePickerClearToggle).not.toBeNull('Clean Icon should be in DOM');
});
@@ -245,7 +249,9 @@ describe('CardViewDateItemComponent', () => {
component.property.value = null;
fixture.detectChanges();
const datePickerClearToggle = fixture.debugElement.query(By.css(`[data-automation-id="datepicker-date-clear--${component.property.key}"]`));
const datePickerClearToggle = fixture.debugElement.query(
By.css(`[data-automation-id="datepicker-date-clear--${component.property.key}"]`)
);
expect(datePickerClearToggle).toBeNull('Clean Icon should not be in DOM');
});
@@ -256,7 +262,9 @@ describe('CardViewDateItemComponent', () => {
component.property.value = new Date('Jul 10 2017');
fixture.detectChanges();
const datePickerClearToggle = fixture.debugElement.query(By.css(`[data-automation-id="datepicker-date-clear--${component.property.key}"]`));
const datePickerClearToggle = fixture.debugElement.query(
By.css(`[data-automation-id="datepicker-date-clear--${component.property.key}"]`)
);
expect(datePickerClearToggle).toBeNull('Clean Icon should not be in DOM');
});
@@ -341,12 +349,12 @@ describe('CardViewDateItemComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const valueChips = fixture.debugElement.queryAll(By.css(`mat-chip`));
expect(valueChips).not.toBeNull();
expect(valueChips.length).toBe(3);
expect(valueChips[0].nativeElement.innerText.trim()).toBe('Jul 10, 2017');
expect(valueChips[1].nativeElement.innerText.trim()).toBe('Jul 11, 2017');
expect(valueChips[2].nativeElement.innerText.trim()).toBe('Jul 12, 2017');
const chips = await loader.getAllHarnesses(MatChipHarness);
expect(chips.length).toBe(3);
expect(await chips[0].getText()).toBe('Jul 10, 2017');
expect(await chips[1].getText()).toBe('Jul 11, 2017');
expect(await chips[2].getText()).toBe('Jul 12, 2017');
});
it('should render chips for multivalue datetimes when chips are enabled', async () => {
@@ -360,11 +368,11 @@ describe('CardViewDateItemComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const valueChips = fixture.debugElement.queryAll(By.css(`mat-chip`));
expect(valueChips).not.toBeNull();
expect(valueChips.length).toBe(3);
expect(valueChips[0].nativeElement.innerText.trim()).toBe('Jul 10, 2017, 0:01');
expect(valueChips[1].nativeElement.innerText.trim()).toBe('Jul 11, 2017, 0:01');
expect(valueChips[2].nativeElement.innerText.trim()).toBe('Jul 12, 2017, 0:01');
const chips = await loader.getAllHarnesses(MatChipHarness);
expect(chips.length).toBe(3);
expect(await chips[0].getText()).toBe('Jul 10, 2017, 0:01');
expect(await chips[1].getText()).toBe('Jul 11, 2017, 0:01');
expect(await chips[2].getText()).toBe('Jul 12, 2017, 0:01');
});
});
@@ -16,7 +16,6 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OverlayContainer } from '@angular/cdk/overlay';
import { By } from '@angular/platform-browser';
import { CardViewSelectItemModel } from '../../models/card-view-selectitem.model';
import { CardViewSelectItemComponent } from './card-view-selectitem.component';
@@ -24,14 +23,25 @@ import { CoreTestingModule } from '../../../testing/core.testing.module';
import { of } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core';
import { AppConfigService } from '../../../app-config/app-config.service';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
describe('CardViewSelectItemComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<CardViewSelectItemComponent>;
let component: CardViewSelectItemComponent;
let overlayContainer: OverlayContainer;
let appConfig: AppConfigService;
const mockData = [{ key: 'one', label: 'One' }, { key: 'two', label: 'Two' }, { key: 'three', label: 'Three' }];
const mockDataNumber = [{ key: 1, label: 'One' }, { key: 2, label: 'Two' }, { key: 3, label: 'Three' }];
const mockData = [
{ key: 'one', label: 'One' },
{ key: 'two', label: 'Two' },
{ key: 'three', label: 'Three' }
];
const mockDataNumber = [
{ key: 1, label: 'One' },
{ key: 2, label: 'Two' },
{ key: 3, label: 'Three' }
];
const mockDefaultProps = {
label: 'Select box label',
value: 'two',
@@ -49,16 +59,13 @@ describe('CardViewSelectItemComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
fixture = TestBed.createComponent(CardViewSelectItemComponent);
component = fixture.componentInstance;
overlayContainer = TestBed.inject(OverlayContainer);
appConfig = TestBed.inject(AppConfigService);
component.property = new CardViewSelectItemModel(mockDefaultProps);
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -90,7 +97,7 @@ describe('CardViewSelectItemComponent', () => {
expect(selectBox).toBeNull();
});
it('should be possible edit selectBox item', () => {
it('should be possible edit selectBox item', async () => {
component.property = new CardViewSelectItemModel({
...mockDefaultProps,
editable: true
@@ -102,19 +109,18 @@ describe('CardViewSelectItemComponent', () => {
expect(component.value).toEqual('two');
expect(component.isEditable()).toBe(true);
const selectBox = fixture.debugElement.query(By.css('.mat-select-trigger'));
selectBox.triggerEventHandler('click', {});
fixture.detectChanges();
const optionsElement = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
expect(optionsElement.length).toEqual(4);
optionsElement[1].dispatchEvent(new Event('click'));
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const options = await select.getOptions();
expect(options.length).toEqual(4);
await options[1].click();
expect(component.value).toEqual('one');
});
it('should be possible edit selectBox item with numbers', () => {
it('should be possible edit selectBox item with numbers', async () => {
component.property = new CardViewSelectItemModel({
...mockDefaultNumbersProps,
editable: true
@@ -126,19 +132,19 @@ describe('CardViewSelectItemComponent', () => {
expect(component.value).toEqual(2);
expect(component.isEditable()).toBe(true);
const selectBox = fixture.debugElement.query(By.css('.mat-select-trigger'));
selectBox.triggerEventHandler('click', {});
fixture.detectChanges();
const optionsElement = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
expect(optionsElement.length).toEqual(4);
optionsElement[1].dispatchEvent(new Event('click'));
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const options = await select.getOptions();
expect(options.length).toEqual(4);
await options[1].click();
expect(component.value).toEqual(1);
});
it('should be able to enable None option', () => {
it('should be able to enable None option', async () => {
component.property = new CardViewSelectItemModel({
...mockDefaultProps,
editable: true
@@ -149,25 +155,23 @@ describe('CardViewSelectItemComponent', () => {
fixture.detectChanges();
expect(component.isEditable()).toBe(true);
const selectBox = fixture.debugElement.query(By.css('.mat-select-trigger'));
selectBox.triggerEventHandler('click', {});
fixture.detectChanges();
const noneElement: HTMLElement = overlayContainer.getContainerElement().querySelector('mat-option');
expect(noneElement).toBeDefined();
expect(noneElement.innerText).toEqual('CORE.CARDVIEW.NONE');
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const options = await select.getOptions();
expect(await options[0].getText()).toBe('CORE.CARDVIEW.NONE');
});
it('should render select box if editable property is TRUE', () => {
it('should render select box if editable property is TRUE', async () => {
component.ngOnChanges();
component.editable = true;
fixture.detectChanges();
const selectBox = fixture.debugElement.query(By.css('[data-automation-class="select-box"]'));
expect(selectBox).not.toBeNull();
expect(await loader.hasHarness(MatSelectHarness)).toBe(true);
});
it('should not have label twice', () => {
it('should not have label twice', async () => {
component.ngOnChanges();
component.editable = true;
fixture.detectChanges();
@@ -178,11 +182,10 @@ describe('CardViewSelectItemComponent', () => {
});
describe('Filter', () => {
it('should render a list of filtered options', () => {
it('should render a list of filtered options', async () => {
appConfig.config['content-metadata'] = {
selectFilterLimit: 0
};
let optionsElement: any[];
component.property = new CardViewSelectItemModel({
...mockDefaultProps,
editable: true
@@ -192,24 +195,22 @@ describe('CardViewSelectItemComponent', () => {
component.ngOnChanges();
fixture.detectChanges();
const selectBox = fixture.debugElement.query(By.css('.mat-select-trigger'));
selectBox.triggerEventHandler('click', {});
const select = await loader.getHarness(MatSelectHarness);
await select.open();
fixture.detectChanges();
optionsElement = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
expect(optionsElement.length).toBe(3);
let options = await select.getOptions();
expect(options.length).toBe(3);
const filterInput = fixture.debugElement.query(By.css('.adf-select-filter-input input'));
filterInput.nativeElement.value = mockData[0].label;
filterInput.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
optionsElement = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
expect(optionsElement.length).toBe(1);
expect(optionsElement[0].innerText).toEqual(mockData[0].label);
options = await select.getOptions();
expect(options.length).toBe(1);
expect(await options[0].getText()).toEqual(mockData[0].label);
});
it('should hide filter if options are less then limit', () => {
it('should hide filter if options are less then limit', async () => {
appConfig.config['content-metadata'] = {
selectFilterLimit: mockData.length + 1
};
@@ -222,15 +223,14 @@ describe('CardViewSelectItemComponent', () => {
component.ngOnChanges();
fixture.detectChanges();
const selectBox = fixture.debugElement.query(By.css('.mat-select-trigger'));
selectBox.triggerEventHandler('click', {});
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const filterInput = fixture.debugElement.query(By.css('.adf-select-filter-input'));
expect(filterInput).toBe(null);
});
it('should show filter if options are greater then limit', () => {
it('should show filter if options are greater then limit', async () => {
appConfig.config['content-metadata'] = {
selectFilterLimit: mockData.length - 1
};
@@ -243,9 +243,8 @@ describe('CardViewSelectItemComponent', () => {
component.ngOnChanges();
fixture.detectChanges();
const selectBox = fixture.debugElement.query(By.css('.mat-select-trigger'));
selectBox.triggerEventHandler('click', {});
fixture.detectChanges();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const filterInput = fixture.debugElement.query(By.css('.adf-select-filter-input'));
expect(filterInput).not.toBe(null);
@@ -30,9 +30,12 @@ import { ClipboardService } from '../../../clipboard/clipboard.service';
import { SimpleChange } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
import { CardViewItemValidator } from '../../interfaces/card-view-item-validator.interface';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatChipHarness, MatChipListHarness } from '@angular/material/chips/testing';
describe('CardViewTextItemComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<CardViewTextItemComponent>;
let component: CardViewTextItemComponent;
@@ -63,7 +66,7 @@ describe('CardViewTextItemComponent', () => {
ctrlKey: ctrlKeyValue,
code: codeValue,
metaKey: metaKeyValue
} as KeyboardEventInit );
} as KeyboardEventInit);
component.undoText(event);
if (flag) {
expect(component.textInput.value).toBe('');
@@ -72,32 +75,35 @@ describe('CardViewTextItemComponent', () => {
}
};
const renderChipsForMultiValuedProperties = async (cardViewTextItemObject, flag: boolean, length: number,
param1: string, param2: string, param3: string) => {
const renderChipsForMultiValuedProperties = async (
cardViewTextItemObject,
flag: boolean,
length: number,
param1: string,
param2: string,
param3: string
) => {
component.property = new CardViewTextItemModel(cardViewTextItemObject);
component.useChipsForMultiValueProperty = flag;
component.ngOnChanges({ property: new SimpleChange(null, null, true) });
fixture.detectChanges();
await fixture.whenStable();
const valueChips = fixture.debugElement.queryAll(By.css(`mat-chip`));
expect(valueChips).not.toBeNull();
const valueChips = await loader.getAllHarnesses(MatChipHarness);
expect(valueChips.length).toBe(length);
expect(valueChips[0].nativeElement.innerText.trim()).toBe(param1);
expect(valueChips[1].nativeElement.innerText.trim()).toBe(param2);
expect(valueChips[2].nativeElement.innerText.trim()).toBe(param3);
expect(await valueChips[0].getText()).toBe(param1);
expect(await valueChips[1].getText()).toBe(param2);
expect(await valueChips[2].getText()).toBe(param3);
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
MatChipsModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, MatChipsModule]
});
fixture = TestBed.createComponent(CardViewTextItemComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -105,7 +111,6 @@ describe('CardViewTextItemComponent', () => {
});
describe('Rendering', () => {
beforeEach(() => {
component.property = new CardViewTextItemModel({
label: 'Text label',
@@ -182,7 +187,6 @@ describe('CardViewTextItemComponent', () => {
await fixture.whenStable();
const value = getTextFieldValue(component.property.key);
expect(value).toBe('Lorem ipsum');
});
it('should render the edit icon in case of editable:true', () => {
@@ -211,7 +215,6 @@ describe('CardViewTextItemComponent', () => {
await fixture.whenStable();
const editIcon = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-edit-icon-${component.property.key}"]`));
expect(editIcon).toBeNull('Edit icon should NOT be shown');
});
it('should render chips for multivalue properties when chips are enabled', async () => {
@@ -224,7 +227,6 @@ describe('CardViewTextItemComponent', () => {
multivalued: true
};
renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, 'item1', 'item2', 'item3');
});
it('should render chips for multivalue integers when chips are enabled', async () => {
@@ -236,7 +238,6 @@ describe('CardViewTextItemComponent', () => {
multivalued: true
};
renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, '1', '2', '3');
});
it('should render chips for multivalue decimal numbers when chips are enabled', async () => {
@@ -248,7 +249,6 @@ describe('CardViewTextItemComponent', () => {
multivalued: true
};
renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, '1.1', '2.2', '3.3');
});
it('should render string for multivalue properties when chips are disabled', async () => {
@@ -266,10 +266,9 @@ describe('CardViewTextItemComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const valueChips = fixture.debugElement.query(By.css(`mat-chip-list`));
const value = getTextFieldValue(component.property.key);
expect(value).toBe('item1,item2,item3');
expect(valueChips).toBeNull();
expect(await loader.hasHarness(MatChipListHarness)).toBe(false);
});
it('should display the label for multi-valued chips if displayLabelForChips is true', async () => {
@@ -358,7 +357,6 @@ describe('CardViewTextItemComponent', () => {
fixture.detectChanges();
const value = fixture.debugElement.query(By.css('.adf-textitem-edit-icon'));
expect(value).toBeNull();
});
it('should not render the clickable icon in case editable set to false', async () => {
@@ -372,7 +370,6 @@ describe('CardViewTextItemComponent', () => {
const value = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-clickable-icon-${component.property.key}"]`));
expect(value).toBeNull('icon should NOT be shown');
});
it('should render the defined clickable icon in case of clickable true and editable input set to true', async () => {
@@ -388,7 +385,6 @@ describe('CardViewTextItemComponent', () => {
const value = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-clickable-icon-${component.property.key}"]`));
expect(value).not.toBeNull();
expect(value.nativeElement.innerText).toBe('FAKE_ICON');
});
it('should not render clickable icon in case of clickable true and icon undefined', async () => {
@@ -413,7 +409,6 @@ describe('CardViewTextItemComponent', () => {
const value = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-edit-icon-${component.property.icon}"]`));
expect(value).toBeNull('Edit icon should NOT be shown');
});
it('should call back function when clickable property enabled', async () => {
@@ -490,7 +485,10 @@ describe('CardViewTextItemComponent', () => {
doubleClickEl.triggerEventHandler('dblclick', new MouseEvent('dblclick'));
fixture.detectChanges();
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith('myValueToCopy', 'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith(
'myValueToCopy',
'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE'
);
});
it('should clear value when clear value icon is clicked', async () => {
@@ -516,7 +514,6 @@ describe('CardViewTextItemComponent', () => {
});
describe('Update', () => {
beforeEach(() => {
component.property = new CardViewTextItemModel({
label: 'Text label',
@@ -655,7 +652,6 @@ describe('CardViewTextItemComponent', () => {
value = getTextFieldValue(component.property.key);
expect(value).toEqual(expectedText);
expect(component.property.value).toBe(expectedText);
});
it('should render the default as value if the value is empty, clickable is true and displayEmpty is true', () => {
@@ -885,26 +881,20 @@ describe('CardViewTextItemComponent', () => {
});
describe('events', () => {
it('should perform undo action by clearing the text that we enter in the text field using undo keyboard shortcut', async () => {
checkCtrlZActions(true, 'KeyZ', false, 'UNDO TEST', true);
});
it('should not perform undo action when we hit any other shortcut instead of using undo keyboard shortcut', async () => {
checkCtrlZActions(true, 'KeyH', false, 'DO NOT DO UNDO', false);
});
it('should not perform undo action when control key is not pressed even if the keycode is correct', async () => {
checkCtrlZActions(false, 'KeyZ', false, 'DO NOT DO UNDO', false);
});
it('should perform undo action in MacOS by clearing the text that we enter in the text field using undo keyboard shortcut', async () => {
checkCtrlZActions(false, 'KeyZ', true, 'UNDO TEST FOR MACOS', true);
});
});
});
@@ -27,9 +27,12 @@ import { of } from 'rxjs';
import { CardViewSelectItemOption } from '../../interfaces/card-view-selectitem-properties.interface';
import { CardViewItem } from '../../interfaces/card-view-item.interface';
import { CardViewItemDispatcherComponent } from '../card-view-item-dispatcher/card-view-item-dispatcher.component';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
describe('CardViewComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<CardViewComponent>;
let component: CardViewComponent;
@@ -40,6 +43,7 @@ describe('CardViewComponent', () => {
fixture = TestBed.createComponent(CardViewComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -63,12 +67,14 @@ describe('CardViewComponent', () => {
it('should pass through editable property to the items', () => {
component.editable = true;
component.properties = [new CardViewDateItemModel({
label: 'My date label',
value: '2017-06-14',
key: 'some-key',
editable: true
})];
component.properties = [
new CardViewDateItemModel({
label: 'My date label',
value: '2017-06-14',
key: 'some-key',
editable: true
})
];
fixture.detectChanges();
@@ -77,12 +83,14 @@ describe('CardViewComponent', () => {
});
it('should render the date in the correct format', async () => {
component.properties = [new CardViewDateItemModel({
label: 'My date label',
value: '2017-06-14',
key: 'some key',
format: 'short'
})];
component.properties = [
new CardViewDateItemModel({
label: 'My date label',
value: '2017-06-14',
key: 'some key',
format: 'short'
})
];
fixture.detectChanges();
await fixture.whenStable();
@@ -97,13 +105,15 @@ describe('CardViewComponent', () => {
});
it('should render the default value if the value is empty, not editable and displayEmpty is true', async () => {
component.properties = [new CardViewTextItemModel({
label: 'My default label',
value: null,
default: 'default value',
key: 'some-key',
editable: false
})];
component.properties = [
new CardViewTextItemModel({
label: 'My default label',
value: null,
default: 'default value',
key: 'some-key',
editable: false
})
];
component.editable = true;
component.displayEmpty = true;
@@ -120,13 +130,15 @@ describe('CardViewComponent', () => {
});
it('should render the default value if the value is empty and is editable', async () => {
component.properties = [new CardViewTextItemModel({
label: 'My default label',
value: null,
default: 'default value',
key: 'some-key',
editable: true
})];
component.properties = [
new CardViewTextItemModel({
label: 'My default label',
value: null,
default: 'default value',
key: 'some-key',
editable: true
})
];
component.editable = true;
component.displayEmpty = false;
@@ -143,95 +155,104 @@ describe('CardViewComponent', () => {
});
it('should render the select element with the None option when not set in the properties', async () => {
const options: CardViewSelectItemOption<string>[] = [{label : 'Option 1', key: '1'}, {label : 'Option 2', key: '2'}];
component.properties = [new CardViewSelectItemModel({
label: 'My default label',
value: '1',
default: 'default value',
key: 'some-key',
editable: true,
options$: of(options)
})];
const options: CardViewSelectItemOption<string>[] = [
{ label: 'Option 1', key: '1' },
{ label: 'Option 2', key: '2' }
];
component.properties = [
new CardViewSelectItemModel({
label: 'My default label',
value: '1',
default: 'default value',
key: 'some-key',
editable: true,
options$: of(options)
})
];
component.editable = true;
component.displayEmpty = false;
fixture.detectChanges();
await fixture.whenStable();
const labelValue = fixture.debugElement.query(By.css('adf-card-view-selectitem .mat-select-trigger'));
labelValue.triggerEventHandler('click', null);
fixture.detectChanges();
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const currentOptions = document.querySelectorAll('mat-option');
const currentOptions = await select.getOptions();
expect(currentOptions.length).toBe(3);
expect(currentOptions[0].innerHTML).toContain('CORE.CARDVIEW.NONE');
expect(currentOptions[1].innerHTML).toContain(options[0].label);
expect(currentOptions[2].innerHTML).toContain(options[1].label);
expect(await currentOptions[0].getText()).toContain('CORE.CARDVIEW.NONE');
expect(await currentOptions[1].getText()).toContain(options[0].label);
expect(await currentOptions[2].getText()).toContain(options[1].label);
});
it('should render the select element with the None option when set true in the properties', async () => {
const options: CardViewSelectItemOption<string>[] = [{label : 'Option 1', key: '1'}, {label : 'Option 2', key: '2'}];
component.properties = [new CardViewSelectItemModel({
label: 'My default label',
value: '1',
default: 'default value',
key: 'some-key',
editable: true,
displayNoneOption: true,
options$: of(options)
})];
const options: CardViewSelectItemOption<string>[] = [
{ label: 'Option 1', key: '1' },
{ label: 'Option 2', key: '2' }
];
component.properties = [
new CardViewSelectItemModel({
label: 'My default label',
value: '1',
default: 'default value',
key: 'some-key',
editable: true,
displayNoneOption: true,
options$: of(options)
})
];
component.editable = true;
component.displayEmpty = false;
fixture.detectChanges();
await fixture.whenStable();
const labelValue = fixture.debugElement.query(By.css('adf-card-view-selectitem .mat-select-trigger'));
labelValue.triggerEventHandler('click', null);
fixture.detectChanges();
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const currentOptions = document.querySelectorAll('mat-option');
const currentOptions = await select.getOptions();
expect(currentOptions.length).toBe(3);
expect(currentOptions[0].innerHTML).toContain('CORE.CARDVIEW.NONE');
expect(currentOptions[1].innerHTML).toContain(options[0].label);
expect(currentOptions[2].innerHTML).toContain(options[1].label);
expect(await currentOptions[0].getText()).toContain('CORE.CARDVIEW.NONE');
expect(await currentOptions[1].getText()).toContain(options[0].label);
expect(await currentOptions[2].getText()).toContain(options[1].label);
});
it('should not render the select element with the None option when set false in the properties', async () => {
const options: CardViewSelectItemOption<string>[] = [{label : 'Option 1', key: '1'}, {label : 'Option 2', key: '2'}];
component.properties = [new CardViewSelectItemModel({
label: 'My default label',
value: '1',
default: 'default value',
key: 'some-key',
editable: true,
displayNoneOption: false,
options$: of(options)
})];
const options: CardViewSelectItemOption<string>[] = [
{ label: 'Option 1', key: '1' },
{ label: 'Option 2', key: '2' }
];
component.properties = [
new CardViewSelectItemModel({
label: 'My default label',
value: '1',
default: 'default value',
key: 'some-key',
editable: true,
displayNoneOption: false,
options$: of(options)
})
];
component.editable = true;
component.displayEmpty = false;
fixture.detectChanges();
await fixture.whenStable();
const labelValue = fixture.debugElement.query(By.css('adf-card-view-selectitem .mat-select-trigger'));
labelValue.triggerEventHandler('click', null);
fixture.detectChanges();
await fixture.whenStable();
const select = await loader.getHarness(MatSelectHarness);
await select.open();
const currentOptions = document.querySelectorAll('mat-option');
const currentOptions = await select.getOptions();
expect(currentOptions.length).toBe(2);
expect(currentOptions[0].innerHTML).toContain(options[0].label);
expect(currentOptions[1].innerHTML).toContain(options[1].label);
expect(await currentOptions[0].getText()).toContain(options[0].label);
expect(await currentOptions[1].getText()).toContain(options[1].label);
});
it('should show/hide the label for multivalued chip property based on displayLabelForChips input', () => {
const multiValueProperty: CardViewItem = new CardViewTextItemModel({
label: 'My Multivalue Label',
value: ['Value 1', 'Value 2', 'Value 3'],
key: 'multi-key'
label: 'My Multivalue Label',
value: ['Value 1', 'Value 2', 'Value 3'],
key: 'multi-key'
});
component.properties = [multiValueProperty];
@@ -256,5 +277,4 @@ describe('CardViewComponent', () => {
const cardViewItemDispatcherDebugElement = fixture.debugElement.query(By.directive(CardViewItemDispatcherComponent));
return cardViewItemDispatcherDebugElement.componentInstance as CardViewItemDispatcherComponent;
}
});
@@ -21,8 +21,12 @@ import { ObjectDataColumn } from '../../data/object-datacolumn.model';
import { CoreTestingModule } from '../../../testing/core.testing.module';
import { JsonCellComponent } from './json-cell.component';
import { TranslateModule } from '@ngx-translate/core';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { HarnessLoader } from '@angular/cdk/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
describe('JsonCellComponent', () => {
let loader: HarnessLoader;
let component: JsonCellComponent;
let fixture: ComponentFixture<JsonCellComponent>;
let dataTableAdapter: ObjectDataTableAdapter;
@@ -31,13 +35,11 @@ describe('JsonCellComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
fixture = TestBed.createComponent(JsonCellComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
beforeEach(() => {
@@ -50,12 +52,9 @@ describe('JsonCellComponent', () => {
}
};
columnData = { format: '/somewhere', type: 'json', key: 'entity'};
columnData = { format: '/somewhere', type: 'json', key: 'entity' };
dataTableAdapter = new ObjectDataTableAdapter(
[rowData],
[new ObjectDataColumn(columnData)]
);
dataTableAdapter = new ObjectDataTableAdapter([rowData], [new ObjectDataColumn(columnData)]);
component.column = dataTableAdapter.getColumns()[0];
component.data = dataTableAdapter;
@@ -68,21 +67,22 @@ describe('JsonCellComponent', () => {
it('should set value', () => {
fixture.detectChanges();
component.value$.subscribe( (result) => {
component.value$.subscribe((result) => {
expect(result).toBe(rowData.entity);
});
});
it('should render json button inside cell', () => {
it('should render json button inside cell', async () => {
fixture.detectChanges();
const button: HTMLElement = fixture.debugElement.nativeElement.querySelector('.mat-button');
expect(button).toBeDefined();
const buttonExists = await loader.hasHarness(MatButtonHarness);
expect(buttonExists).toBe(true);
});
it('should not setup cell when has no data', () => {
rowData.entity = {};
fixture.detectChanges();
component.value$.subscribe( (result) => {
component.value$.subscribe((result) => {
expect(result).toEqual({});
});
});
@@ -23,25 +23,26 @@ import { FormFieldTypes } from '../core/form-field-types';
import { CoreTestingModule } from '../../../../testing/core.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { FormModel } from '../core/form.model';
import { By } from '@angular/platform-browser';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
describe('AmountWidgetComponent', () => {
let loader: HarnessLoader;
let widget: AmountWidgetComponent;
let fixture: ComponentFixture<AmountWidgetComponent>;
let element: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
FormBaseModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, FormBaseModule]
});
fixture = TestBed.createComponent(AmountWidgetComponent);
widget = fixture.componentInstance;
element = fixture.nativeElement;
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should setup currency from field', () => {
@@ -81,7 +82,6 @@ describe('AmountWidgetComponent', () => {
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.AMOUNT,
@@ -91,57 +91,45 @@ describe('AmountWidgetComponent', () => {
});
it('should show tooltip', async () => {
const amountInput = fixture.nativeElement.querySelector('input');
amountInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement;
expect(tooltipElement).toBeTruthy();
expect(tooltipElement.textContent.trim()).toBe('my custom tooltip');
});
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.getTooltipText()).toBe('my custom tooltip');
});
it('should hide tooltip', async () => {
const amountInput = fixture.nativeElement.querySelector('input');
amountInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
await (await input.host()).mouseAway();
amountInput.dispatchEvent(new Event('mouseleave'));
await fixture.whenStable();
fixture.detectChanges();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip'));
expect(tooltipElement).toBeFalsy();
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.isOpen()).toBe(false);
});
});
describe('when is required', () => {
beforeEach(() => {
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.AMOUNT,
required: true
});
});
it('should be marked as invalid after interaction', async () => {
const amount = fixture.nativeElement.querySelector('input');
const input = await loader.getHarness(MatInputHarness);
const host = await input.host();
expect(element.querySelector('.adf-invalid')).toBeFalsy();
amount.dispatchEvent(new Event('blur'));
fixture.detectChanges();
await fixture.whenStable();
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeTruthy();
await host.blur();
expect(element.querySelector('.adf-invalid')).toBeTruthy();
});
it('should be able to display label with asterisk', async () => {
fixture.detectChanges();
await fixture.whenStable();
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
const asterisk = element.querySelector('.adf-asterisk');
expect(asterisk).toBeTruthy();
expect(asterisk.textContent).toEqual('*');
@@ -150,25 +138,22 @@ describe('AmountWidgetComponent', () => {
});
describe('AmountWidgetComponent - rendering', () => {
let loader: HarnessLoader;
let widget: AmountWidgetComponent;
let fixture: ComponentFixture<AmountWidgetComponent>;
let element: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
FormBaseModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, FormBaseModule]
});
fixture = TestBed.createComponent(AmountWidgetComponent);
widget = fixture.componentInstance;
element = fixture.nativeElement;
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('[C289915] - Should be able to display different currency icons', () => {
it('[C289915] - Should be able to display different currency icons', async () => {
widget.field = new FormFieldModel(new FormModel(), {
id: 'TestAmount1',
name: 'Test Amount',
@@ -177,22 +162,20 @@ describe('AmountWidgetComponent - rendering', () => {
});
fixture.detectChanges();
let widgetPrefix = fixture.nativeElement.querySelector('div.mat-form-field-prefix');
expect(widgetPrefix.textContent.trim()).toBe('$');
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getPrefixText()).toBe('$');
widget.field.currency = '£';
widget.ngOnInit();
fixture.detectChanges();
widgetPrefix = fixture.nativeElement.querySelector('div.mat-form-field-prefix');
expect(widgetPrefix.textContent.trim()).toBe('£');
expect(await field.getPrefixText()).toBe(');
widget.field.currency = '€';
widget.ngOnInit();
fixture.detectChanges();
widgetPrefix = fixture.nativeElement.querySelector('div.mat-form-field-prefix');
expect(widgetPrefix.textContent.trim()).toBe('€');
expect(await field.getPrefixText()).toBe('€');
});
it('[C309692] - Should be possible to set the General Properties for Amount Widget', async () => {
@@ -216,28 +199,21 @@ describe('AmountWidgetComponent - rendering', () => {
fixture.detectChanges();
await fixture.whenStable();
const widgetPlaceholder = fixture.nativeElement.querySelector('label.mat-form-field-label');
expect(widgetPlaceholder.textContent).toBe('Check Placeholder Text');
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getLabel()).toBe('Check Placeholder Text');
expect(await field.getPrefixText()).toBe('$');
const widgetLabel = fixture.nativeElement.querySelector('label.adf-label');
expect(widgetLabel.textContent).toBe('Test Amount*');
const widgetPrefix = fixture.nativeElement.querySelector('div.mat-form-field-prefix');
expect(widgetPrefix.textContent.trim()).toBe('$');
expect(widget.field.isValid).toBe(false);
const widgetById: HTMLInputElement = fixture.nativeElement.querySelector('#TestAmount1');
expect(widgetById).toBeDefined();
expect(widgetById).not.toBeNull();
widgetById.value = '90';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(true, 'amount widget with a valid field');
const input = await loader.getHarness(MatInputHarness);
await input.setValue('90');
expect(widget.field.isValid).toBe(true);
await input.setValue('gdfgdf');
expect(widget.field.isValid).toBe(false);
widgetById.value = 'gdfgdf';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(false, 'amount widget with an invalid field');
const errorWidget = fixture.nativeElement.querySelector('error-widget .adf-error-text');
expect(errorWidget.textContent).toBe('FORM.FIELD.VALIDATOR.INVALID_NUMBER');
});
@@ -265,52 +241,37 @@ describe('AmountWidgetComponent - rendering', () => {
const widgetLabel = fixture.nativeElement.querySelector('label.adf-label');
expect(widgetLabel.textContent).toBe('Test Amount*');
const widgetPrefix = fixture.nativeElement.querySelector('div.mat-form-field-prefix');
expect(widgetPrefix.textContent.trim()).toBe('£');
expect(widget.field.isValid).toBe(false);
const widgetById: HTMLInputElement = fixture.nativeElement.querySelector('#TestAmount1');
expect(widgetById).toBeDefined();
expect(widgetById).not.toBeNull();
widgetById.value = '8';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(false, 'amount widget field is valid');
let errorMessage: HTMLElement = fixture.nativeElement.querySelector('.adf-error-text');
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getPrefixText()).toBe('£');
expect(widget.field.isValid).toBe(false);
const input = await loader.getHarness(MatInputHarness);
await input.setValue('8');
expect(widget.field.isValid).toBe(false);
let errorMessage = fixture.nativeElement.querySelector('.adf-error-text');
expect(errorMessage.textContent.trim()).toContain('FORM.FIELD.VALIDATOR.NOT_LESS_THAN');
widgetById.value = '99';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(false, 'amount widget field is valid');
await input.setValue('99');
expect(widget.field.isValid).toBe(false);
errorMessage = fixture.nativeElement.querySelector('.adf-error-text');
expect(errorMessage.textContent.trim()).toContain('FORM.FIELD.VALIDATOR.NOT_GREATER_THAN');
widgetById.value = '80';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(true, 'amount widget field is invalid');
await input.setValue('80');
expect(widget.field.isValid).toBe(true);
widgetById.value = '80.67';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(true, 'amount widget field is invalid');
await input.setValue('80.67');
expect(widget.field.isValid).toBe(true);
widgetById.value = 'incorrect format';
widgetById.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable();
expect(widget.field.isValid).toBe(false, 'amount widget field is valid');
await input.setValue('incorrect format');
expect(widget.field.isValid).toBe(false);
errorMessage = fixture.nativeElement.querySelector('.adf-error-text');
expect(errorMessage.textContent.trim()).toContain('FORM.FIELD.VALIDATOR.INVALID_NUMBER');
});
describe('when form model has left labels', () => {
it('should have left labels classes on leftLabels true', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), {
id: 'amount-id',
@@ -379,11 +340,7 @@ describe('AmountWidgetComponent settings', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
FormBaseModule
],
imports: [TranslateModule.forRoot(), CoreTestingModule, FormBaseModule],
providers: [
{
provide: ADF_AMOUNT_SETTINGS,
@@ -26,37 +26,33 @@ import { TranslateLoaderService } from '../../../../translation/translate-loader
import { MatCheckboxModule } from '@angular/material/checkbox';
import { CoreTestingModule } from '../../../../testing';
import { MatTooltipModule } from '@angular/material/tooltip';
import { By } from '@angular/platform-browser';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
describe('CheckboxWidgetComponent', () => {
let loader: HarnessLoader;
let widget: CheckboxWidgetComponent;
let fixture: ComponentFixture<CheckboxWidgetComponent>;
let element: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
FormBaseModule,
MatCheckboxModule,
MatTooltipModule
],
providers: [
{ provide: TranslateLoader, useClass: TranslateLoaderService }
]
imports: [TranslateModule.forRoot(), CoreTestingModule, FormBaseModule, MatCheckboxModule, MatTooltipModule],
providers: [{ provide: TranslateLoader, useClass: TranslateLoaderService }]
});
fixture = TestBed.createComponent(CheckboxWidgetComponent);
widget = fixture.componentInstance;
element = fixture.nativeElement;
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => fixture.destroy());
describe('when template is ready', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
id: 'check-id',
@@ -69,14 +65,11 @@ describe('CheckboxWidgetComponent', () => {
});
it('should be marked as invalid when required after interaction', async () => {
const checkbox = element.querySelector('mat-checkbox');
const checkbox = await loader.getHarness(MatCheckboxHarness);
expect(element.querySelector('.adf-invalid')).toBeFalsy();
checkbox.dispatchEvent(new Event('click'));
checkbox.dispatchEvent(new Event('click'));
fixture.detectChanges();
await fixture.whenStable();
await checkbox.check();
await checkbox.uncheck();
expect(element.querySelector('.adf-invalid')).toBeTruthy();
});
@@ -85,7 +78,7 @@ describe('CheckboxWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
const asterisk = element.querySelector('.adf-asterisk');
expect(asterisk).toBeTruthy();
expect(asterisk.textContent).toEqual('*');
@@ -94,24 +87,20 @@ describe('CheckboxWidgetComponent', () => {
it('should be checked if boolean true is passed', async () => {
widget.field.value = true;
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();
const checkbox = fixture.debugElement.nativeElement.querySelector('mat-checkbox input');
expect(checkbox.getAttribute('aria-checked')).toBe('true');
const checkbox = await loader.getHarness(MatCheckboxHarness);
expect(await checkbox.isChecked()).toBe(true);
});
it('should not be checked if false is passed', async () => {
widget.field.value = false;
fixture.detectChanges();
await fixture.whenStable();
const checkbox = fixture.debugElement.nativeElement.querySelector('mat-checkbox input');
expect(checkbox.getAttribute('aria-checked')).toBe('false');
const checkbox = await loader.getHarness(MatCheckboxHarness);
expect(await checkbox.isChecked()).toBe(false);
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.BOOLEAN,
@@ -121,28 +110,20 @@ describe('CheckboxWidgetComponent', () => {
});
it('should show tooltip', async () => {
const checkboxInput = fixture.nativeElement.querySelector('mat-checkbox');
checkboxInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const checkbox = await loader.getHarness(MatCheckboxHarness);
await (await checkbox.host()).hover();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement;
expect(tooltipElement).toBeTruthy();
expect(tooltipElement.textContent.trim()).toBe('my custom tooltip');
});
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.getTooltipText()).toBe('my custom tooltip');
});
it('should hide tooltip', async () => {
const checkboxInput = fixture.nativeElement.querySelector('mat-checkbox');
checkboxInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const checkbox = await loader.getHarness(MatCheckboxHarness);
await (await checkbox.host()).hover();
await (await checkbox.host()).mouseAway();
checkboxInput.dispatchEvent(new Event('mouseleave'));
await fixture.whenStable();
fixture.detectChanges();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip'));
expect(tooltipElement).toBeFalsy();
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.isOpen()).toBe(false);
});
});
});
@@ -23,11 +23,14 @@ import { CoreTestingModule } from '../../../../testing/core.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { MatTooltipModule } from '@angular/material/tooltip';
import { FormFieldTypes } from '../core/form-field-types';
import { By } from '@angular/platform-browser';
import { DateFieldValidator, DateTimeFieldValidator } from '../core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
import { MatInputHarness } from '@angular/material/input/testing';
describe('DateTimeWidgetComponent', () => {
let loader: HarnessLoader;
let widget: DateTimeWidgetComponent;
let fixture: ComponentFixture<DateTimeWidgetComponent>;
let element: HTMLElement;
@@ -35,11 +38,7 @@ describe('DateTimeWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
MatTooltipModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, MatTooltipModule]
});
fixture = TestBed.createComponent(DateTimeWidgetComponent);
@@ -47,7 +46,8 @@ describe('DateTimeWidgetComponent', () => {
widget = fixture.componentInstance;
form = new FormModel();
form.fieldValidators = [new DateFieldValidator(), new DateTimeFieldValidator() ];
form.fieldValidators = [new DateFieldValidator(), new DateTimeFieldValidator()];
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -238,7 +238,6 @@ describe('DateTimeWidgetComponent', () => {
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.DATETIME,
@@ -248,35 +247,26 @@ describe('DateTimeWidgetComponent', () => {
});
it('should show tooltip', async () => {
const dateTimeInput = fixture.nativeElement.querySelector('input');
dateTimeInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement;
expect(tooltipElement).toBeTruthy();
expect(tooltipElement.textContent.trim()).toBe('my custom tooltip');
});
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.getTooltipText()).toBe('my custom tooltip');
});
it('should hide tooltip', async () => {
const dateTimeInput = fixture.nativeElement.querySelector('input');
dateTimeInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
await (await input.host()).mouseAway();
dateTimeInput.dispatchEvent(new Event('mouseleave'));
await fixture.whenStable();
fixture.detectChanges();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip'));
expect(tooltipElement).toBeFalsy();
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.isOpen()).toBe(false);
});
});
describe('when is required', () => {
beforeEach(() => {
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.DATETIME,
required: true
});
@@ -304,7 +294,6 @@ describe('DateTimeWidgetComponent', () => {
});
describe('template check', () => {
it('should show visible date widget', async () => {
widget.field = new FormFieldModel(form, {
id: 'date-field-id',
@@ -316,9 +305,8 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
expect(dateElement).not.toBeNull();
expect(dateElement?.value).toBe('30-11-9999 10:30 AM');
const input = await loader.getHarness(MatInputHarness);
expect(await input.getValue()).toBe('30-11-9999 10:30 AM');
});
it('should show the correct format type', async () => {
@@ -333,9 +321,8 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
expect(dateElement).not.toBeNull();
expect(dateElement?.value).toContain('12-30-9999 10:30 AM');
const input = await loader.getHarness(MatInputHarness);
expect(await input.getValue()).toBe('12-30-9999 10:30 AM');
});
it('should disable date button when is readonly', () => {
@@ -374,9 +361,8 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
expect(dateElement).not.toBeNull();
expect(dateElement?.value).toContain('12-30-9999 10:30 AM');
const input = await loader.getHarness(MatInputHarness);
expect(await input.getValue()).toBe('12-30-9999 10:30 AM');
widget.field.value = '2020-03-02T00:00:00.000Z';
@@ -384,11 +370,10 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
expect(dateElement?.value).toContain('03-02-2020 00:00 AM');
expect(await input.getValue()).toBe('03-02-2020 00:00 AM');
});
describe('when form model has left labels', () => {
it('should have left labels classes on leftLabels true', () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), {
id: 'datetime-id',
@@ -22,32 +22,28 @@ import { CoreTestingModule } from '../../../../testing/core.testing.module';
import { FormFieldModel } from '../core/form-field.model';
import { FormModel } from '../core/form.model';
import { FormFieldTypes } from '../core/form-field-types';
import { By } from '@angular/platform-browser';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
describe('MultilineTextWidgetComponentComponent', () => {
let loader: HarnessLoader;
let widget: MultilineTextWidgetComponentComponent;
let fixture: ComponentFixture<MultilineTextWidgetComponentComponent>;
let element: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
fixture = TestBed.createComponent(MultilineTextWidgetComponentComponent);
widget = fixture.componentInstance;
element = fixture.nativeElement;
});
it('should exist', () => {
expect(widget).toBeDefined();
loader = TestbedHarnessEnvironment.loader(fixture);
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.MULTILINE_TEXT,
@@ -57,57 +53,42 @@ describe('MultilineTextWidgetComponentComponent', () => {
});
it('should show tooltip', async () => {
const multilineTextarea = fixture.nativeElement.querySelector('textarea');
multilineTextarea.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement;
expect(tooltipElement).toBeTruthy();
expect(tooltipElement.textContent.trim()).toBe('my custom tooltip');
});
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.getTooltipText()).toBe('my custom tooltip');
});
it('should hide tooltip', async () => {
const multilineTextarea = fixture.nativeElement.querySelector('textarea');
multilineTextarea.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
await (await input.host()).mouseAway();
multilineTextarea.dispatchEvent(new Event('mouseleave'));
await fixture.whenStable();
fixture.detectChanges();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip'));
expect(tooltipElement).toBeFalsy();
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.isOpen()).toBe(false);
});
});
describe('when is required', () => {
beforeEach(() => {
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.MULTILINE_TEXT,
required: true
});
fixture.detectChanges();
});
it('should be marked as invalid after interaction', async () => {
const multilineTextarea = fixture.nativeElement.querySelector('textarea');
const input = await loader.getHarness(MatInputHarness);
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeFalsy();
multilineTextarea.dispatchEvent(new Event('blur'));
fixture.detectChanges();
await fixture.whenStable();
await (await input.host()).blur();
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeTruthy();
});
it('should be able to display label with asterisk', async () => {
fixture.detectChanges();
await fixture.whenStable();
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
const asterisk = element.querySelector('.adf-asterisk');
expect(asterisk).toBeTruthy();
expect(asterisk.textContent).toEqual('*');
@@ -19,39 +19,32 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { CoreTestingModule } from '../../../../testing';
import { FormFieldModel, FormFieldTypes, FormModel } from '../core';
import { NumberWidgetComponent } from './number.widget';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
describe('NumberWidgetComponent', () => {
let loader: HarnessLoader;
let widget: NumberWidgetComponent;
let fixture: ComponentFixture<NumberWidgetComponent>;
let element: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
MatInputModule,
FormsModule,
MatIconModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, MatInputModule, FormsModule, MatIconModule]
});
fixture = TestBed.createComponent(NumberWidgetComponent);
widget = fixture.componentInstance;
element = fixture.nativeElement;
});
it('should exist', () => {
expect(widget).toBeDefined();
loader = TestbedHarnessEnvironment.loader(fixture);
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.NUMBER,
@@ -61,57 +54,43 @@ describe('NumberWidgetComponent', () => {
});
it('should show tooltip', async () => {
const numberInput = fixture.nativeElement.querySelector('input');
numberInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement;
expect(tooltipElement).toBeTruthy();
expect(tooltipElement.textContent.trim()).toBe('my custom tooltip');
});
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.getTooltipText()).toBe('my custom tooltip');
});
it('should hide tooltip', async () => {
const numberInput = fixture.nativeElement.querySelector('input');
numberInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
await (await input.host()).mouseAway();
numberInput.dispatchEvent(new Event('mouseleave'));
await fixture.whenStable();
fixture.detectChanges();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip'));
expect(tooltipElement).toBeFalsy();
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.isOpen()).toBe(false);
});
});
describe('when is required', () => {
beforeEach(() => {
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.NUMBER,
required: true
});
fixture.detectChanges();
});
it('should be marked as invalid after interaction', async () => {
const numberInput = fixture.nativeElement.querySelector('input');
const input = await loader.getHarness(MatInputHarness);
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeFalsy();
numberInput.dispatchEvent(new Event('blur'));
fixture.detectChanges();
await fixture.whenStable();
await (await input.host()).blur();
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeTruthy();
});
it('should be able to display label with asterisk', async () => {
fixture.detectChanges();
await fixture.whenStable();
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
const asterisk = element.querySelector('.adf-asterisk');
expect(asterisk).toBeTruthy();
expect(asterisk.textContent).toEqual('*');
@@ -119,7 +98,6 @@ describe('NumberWidgetComponent', () => {
});
describe('when form model has left labels', () => {
it('should have left labels classes on leftLabels true', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), {
id: 'number-id',
@@ -25,15 +25,16 @@ import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { CoreTestingModule } from '../../../../testing';
import { TranslateModule } from '@ngx-translate/core';
import { By } from '@angular/platform-browser';
const enterValueInTextField = (element: HTMLInputElement, value: string) => {
element.value = value;
element.dispatchEvent(new Event('input'));
};
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
import { MatTooltipHarness } from '@angular/material/tooltip/testing';
describe('TextWidgetComponent', () => {
const form = new FormModel({ taskId: 'fake-task-id' });
let loader: HarnessLoader;
let widget: TextWidgetComponent;
let fixture: ComponentFixture<TextWidgetComponent>;
let element: HTMLElement;
@@ -41,25 +42,18 @@ describe('TextWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
MatInputModule,
FormsModule,
MatIconModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, MatInputModule, FormsModule, MatIconModule]
});
fixture = TestBed.createComponent(TextWidgetComponent);
widget = fixture.componentInstance;
element = fixture.nativeElement;
loader = TestbedHarnessEnvironment.loader(fixture);
});
describe('when template is ready', () => {
describe('and no mask is configured on text element', () => {
it('should raise ngModelChange event', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -70,16 +64,14 @@ describe('TextWidgetComponent', () => {
fixture.detectChanges();
expect(widget.field.value).toBe('');
enterValueInTextField(element.querySelector('#text-id'), 'TEXT');
await fixture.whenStable();
fixture.detectChanges();
expect(widget.field).not.toBeNull();
expect(widget.field.value).not.toBeNull();
const input = await loader.getHarness(MatInputHarness);
await input.setValue('TEXT');
expect(widget.field.value).toBe('TEXT');
});
it('should be able to set label property', () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -93,7 +85,7 @@ describe('TextWidgetComponent', () => {
});
it('should be able to set a placeholder for Text widget', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -104,12 +96,12 @@ describe('TextWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const label = element.querySelector<HTMLElement>('label.mat-form-field-label[for="text-id"]');
expect(label.innerText).toBe('Your name here');
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getLabel()).toBe('Your name here');
});
it('should be able to set min/max length properties for Text widget', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -119,30 +111,20 @@ describe('TextWidgetComponent', () => {
maxLength: 10
});
fixture.detectChanges();
enterValueInTextField(element.querySelector('#text-id'), 'TEXT');
fixture.detectChanges();
await fixture.whenStable();
const input = await loader.getHarness(MatInputHarness);
await input.setValue('TEXT');
errorWidget = element.querySelector('.adf-error-text');
expect(errorWidget).toBeDefined();
expect(errorWidget.innerHTML).toBe('FORM.FIELD.VALIDATOR.AT_LEAST_LONG');
expect(widget.field.isValid).toBe(false);
enterValueInTextField(element.querySelector('#text-id'), 'TEXT VALUE');
await fixture.whenStable();
fixture.detectChanges();
await input.setValue('TEXT VALUE');
errorWidget = element.querySelector('.adf-error-text');
expect(widget.field.isValid).toBe(true);
enterValueInTextField(element.querySelector('#text-id'), 'TEXT VALUE TOO LONG');
fixture.detectChanges();
await fixture.whenStable();
await input.setValue('TEXT VALUE TOO LONG');
expect(widget.field.isValid).toBe(false);
errorWidget = element.querySelector('.adf-error-text');
@@ -150,7 +132,7 @@ describe('TextWidgetComponent', () => {
});
it('should be able to set regex pattern property for Text widget', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -159,25 +141,20 @@ describe('TextWidgetComponent', () => {
regexPattern: '[0-9]'
});
fixture.detectChanges();
enterValueInTextField(element.querySelector('#text-id'), 'TEXT');
await fixture.whenStable();
const input = await loader.getHarness(MatInputHarness);
await input.setValue('TEXT');
expect(widget.field.isValid).toBe(false);
enterValueInTextField(element.querySelector('#text-id'), '8');
await fixture.whenStable();
await input.setValue('8');
expect(widget.field.isValid).toBe(true);
enterValueInTextField(element.querySelector('#text-id'), '8XYZ');
await fixture.whenStable();
await input.setValue('8XYZ');
expect(widget.field.isValid).toBe(false);
});
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
type: FormFieldTypes.TEXT,
@@ -187,35 +164,26 @@ describe('TextWidgetComponent', () => {
});
it('should show tooltip', async () => {
const textInput = fixture.nativeElement.querySelector('input');
textInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement;
expect(tooltipElement).toBeTruthy();
expect(tooltipElement.textContent.trim()).toBe('my custom tooltip');
});
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.getTooltipText()).toBe('my custom tooltip');
});
it('should hide tooltip', async () => {
const textInput = fixture.nativeElement.querySelector('input');
textInput.dispatchEvent(new Event('mouseenter'));
await fixture.whenStable();
fixture.detectChanges();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).hover();
await (await input.host()).mouseAway();
textInput.dispatchEvent(new Event('mouseleave'));
await fixture.whenStable();
fixture.detectChanges();
const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip'));
expect(tooltipElement).toBeFalsy();
const tooltip = await loader.getHarness(MatTooltipHarness);
expect(await tooltip.isOpen()).toBe(false);
});
});
describe('when is required', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -226,13 +194,10 @@ describe('TextWidgetComponent', () => {
});
it('should be marked as invalid after interaction', async () => {
const textInput = fixture.nativeElement.querySelector('input');
const input = await loader.getHarness(MatInputHarness);
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeFalsy();
textInput.dispatchEvent(new Event('blur'));
fixture.detectChanges();
await fixture.whenStable();
await (await input.host()).blur();
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeTruthy();
});
@@ -241,7 +206,7 @@ describe('TextWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
const asterisk = element.querySelector('.adf-asterisk');
expect(asterisk).toBeTruthy();
expect(asterisk.textContent).toEqual('*');
@@ -249,11 +214,8 @@ describe('TextWidgetComponent', () => {
});
describe('and no mask is configured on text element', () => {
let inputElement: HTMLInputElement;
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -262,26 +224,19 @@ describe('TextWidgetComponent', () => {
});
fixture.detectChanges();
inputElement = element.querySelector<HTMLInputElement>('#text-id');
});
it('should be disabled on readonly forms', async () => {
await fixture.whenStable();
fixture.detectChanges();
expect(inputElement).toBeDefined();
expect(inputElement).not.toBeNull();
expect(inputElement.disabled).toBeTruthy();
const input = await loader.getHarness(MatInputHarness);
expect(await input.isDisabled()).toBe(true);
});
});
describe('and mask is configured on text element', () => {
let inputElement: HTMLInputElement;
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -295,23 +250,21 @@ describe('TextWidgetComponent', () => {
inputElement = element.querySelector<HTMLInputElement>('#text-id');
});
it('should show text widget', () => {
expect(element.querySelector('#text-id')).toBeDefined();
expect(element.querySelector('#text-id')).not.toBeNull();
it('should show text widget', async () => {
expect(await loader.hasHarness(MatInputHarness)).toBe(true);
});
it('should show the field placeholder', () => {
const label = element.querySelector<HTMLElement>('label.mat-form-field-label[for="text-id"]');
expect(label.innerText).toBe('simple placeholder');
it('should show the field placeholder', async () => {
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getLabel()).toBe('simple placeholder');
});
it('should show the field placeholder when clicked', async () => {
inputElement.click();
fixture.detectChanges();
await fixture.whenStable();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).click();
const label = element.querySelector<HTMLElement>('label.mat-form-field-label[for="text-id"]');
expect(label.innerText).toBe('simple placeholder');
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getLabel()).toBe('simple placeholder');
});
it('should prevent text to be written if is not allowed by the mask on keyUp event', async () => {
@@ -384,11 +337,10 @@ describe('TextWidgetComponent', () => {
});
describe('when the mask is reversed ', () => {
let inputElement: HTMLInputElement;
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -427,11 +379,8 @@ describe('TextWidgetComponent', () => {
});
describe('and a mask placeholder is configured', () => {
let inputElement: HTMLInputElement;
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -442,26 +391,23 @@ describe('TextWidgetComponent', () => {
});
fixture.detectChanges();
inputElement = element.querySelector<HTMLInputElement>('#text-id');
});
it('should show the input mask placeholder', () => {
const label = element.querySelector<HTMLElement>('label.mat-form-field-label[for="text-id"]');
expect(label.innerText).toBe('Phone : (__) ___-___');
it('should show the input mask placeholder', async () => {
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getLabel()).toBe('Phone : (__) ___-___');
});
it('should show the input mask placeholder when clicked', async () => {
inputElement.click();
fixture.detectChanges();
await fixture.whenStable();
const input = await loader.getHarness(MatInputHarness);
await (await input.host()).click();
const label = element.querySelector<HTMLElement>('label.mat-form-field-label[for="text-id"]');
expect(label.innerText).toBe('Phone : (__) ___-___');
const field = await loader.getHarness(MatFormFieldHarness);
expect(await field.getLabel()).toBe('Phone : (__) ___-___');
});
});
describe('when form model has left labels', () => {
it('should have left labels classes on leftLabels true', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), {
id: 'text-id',
@@ -503,7 +449,7 @@ describe('TextWidgetComponent', () => {
});
it('should not have left labels classes on leftLabels not present', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(form, {
id: 'text-id',
name: 'text-name',
value: '',
@@ -23,21 +23,23 @@ import { SidenavLayoutModule } from '../../layout.module';
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
import { TranslateModule } from '@ngx-translate/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatToolbarHarness } from '@angular/material/toolbar/testing';
describe('HeaderLayoutComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<HeaderLayoutComponent>;
let component: HeaderLayoutComponent;
describe('Input parameters', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
fixture = TestBed.createComponent(HeaderLayoutComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -57,13 +59,14 @@ describe('HeaderLayoutComponent', () => {
expect(titleElement.innerText).toEqual('TEST TITLE');
});
it('color attribute should be present on mat-toolbar', () => {
it('color attribute should be present on toolbar', async () => {
component.color = 'primary';
fixture.detectChanges();
const toolbar = fixture.nativeElement.querySelector('mat-toolbar');
expect(toolbar.getAttribute('ng-reflect-color') === null).toBeFalsy();
expect(toolbar.getAttribute('ng-reflect-color')).toEqual('primary');
const toolbar = await loader.getHarness(MatToolbarHarness);
const host = await toolbar.host();
expect(await host.getAttribute('ng-reflect-color')).toBe('primary');
});
it('should display the img element with the expected src if a logo path is set', () => {
@@ -79,7 +82,7 @@ describe('HeaderLayoutComponent', () => {
component.redirectUrl = '/customHomePage';
fixture.detectChanges();
const logoAnchor = fixture.nativeElement.querySelector('mat-toolbar>a');
const logoAnchor = fixture.nativeElement.querySelector('a');
expect(/\/customHomePage$/.test(logoAnchor.href)).toEqual(true);
});
@@ -87,7 +90,7 @@ describe('HeaderLayoutComponent', () => {
component.tooltip = 'logo title';
fixture.detectChanges();
const logoAnchor = fixture.nativeElement.querySelector('mat-toolbar>a');
const logoAnchor = fixture.nativeElement.querySelector('a');
expect(logoAnchor.title).toEqual('logo title');
});
@@ -213,21 +216,18 @@ describe('HeaderLayoutComponent', () => {
});
describe('Template transclusion', () => {
@Component({
selector: 'adf-test-layout-header',
template: `<adf-layout-header title="test" color="primary"><p>Test text<p></adf-layout-header>`
template: `<adf-layout-header title="test" color="primary"
><p>Test text</p>
<p></p
></adf-layout-header>`
})
class HeaderLayoutTesterComponent {}
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
SidenavLayoutModule,
MaterialModule
],
imports: [TranslateModule.forRoot(), CoreTestingModule, SidenavLayoutModule, MaterialModule],
declarations: [HeaderLayoutTesterComponent]
});
});
@@ -235,7 +235,7 @@ describe('HeaderLayoutComponent', () => {
it('should project the provided nodes into the component', () => {
const hostFixture = TestBed.createComponent(HeaderLayoutTesterComponent);
hostFixture.detectChanges();
const innerText = hostFixture.nativeElement.querySelector('mat-toolbar>p').innerText;
const innerText = hostFixture.nativeElement.querySelector('p').innerText;
expect(innerText).toEqual('Test text');
});
});
@@ -47,12 +47,12 @@ describe('DataTableWidgetComponent', () => {
const errorIcon: string = 'error_outline';
const getDataVariable = (
variableConfig: VariableConfig,
schemaDefinition: DataColumn[],
processVariables?: TaskVariableCloud[],
variables?: TaskVariableCloud[]
) => new FormFieldModel(
new FormModel({ taskId: 'fake-task-id', processVariables, variables }), {
variableConfig: VariableConfig,
schemaDefinition: DataColumn[],
processVariables?: TaskVariableCloud[],
variables?: TaskVariableCloud[]
) =>
new FormFieldModel(new FormModel({ taskId: 'fake-task-id', processVariables, variables }), {
id: 'fake-datatable-id',
name: 'Data Table',
type: FormFieldTypes.DATA_TABLE,
@@ -71,11 +71,11 @@ describe('DataTableWidgetComponent', () => {
expect(failedErrorMsgElement.nativeElement.textContent.trim()).toBe(errorIcon.concat('FORM.FIELD.DATA_TABLE_LOAD_FAILED'));
};
const getPreview = () => fixture.nativeElement.querySelector('[data-automation-id="adf-data-table-widget-preview"]');
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
ProcessServiceCloudTestingModule
]
imports: [ProcessServiceCloudTestingModule]
});
fixture = TestBed.createComponent(DataTableWidgetComponent);
widget = fixture.componentInstance;
@@ -83,7 +83,7 @@ describe('DataTableWidgetComponent', () => {
formCloudService = TestBed.inject(FormCloudService);
logService = TestBed.inject(LogService);
widget.field = new FormFieldModel( new FormModel({ taskId: 'fake-task-id' }), {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
type: FormFieldTypes.DATA_TABLE,
name: 'Data Table'
});
@@ -104,7 +104,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const dataTable = fixture.nativeElement.querySelector('[data-automation-id="adf-data-table-widget"]');
const dataTablePreview = fixture.nativeElement.querySelector('[data-automation-id="adf-data-table-widget-preview"]');
const dataTablePreview = getPreview();
expect(dataTable).toBeTruthy();
expect(dataTablePreview).toBeNull();
@@ -114,9 +114,7 @@ describe('DataTableWidgetComponent', () => {
widget.field = getDataVariable(mockVariableConfig, mockSchemaDefinition, [], mockJsonFormVariable);
fixture.detectChanges();
widget.dataSource.getColumns().forEach((column, index) =>
expect(column.key).toEqual(mockSchemaDefinition[index].key
));
widget.dataSource.getColumns().forEach((column, index) => expect(column.key).toEqual(mockSchemaDefinition[index].key));
});
it('should properly initialize data source with priority on the field value if process and form variables are provided', () => {
@@ -125,7 +123,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockAmericaCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -136,7 +134,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockAmericaCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -147,7 +145,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockEuropeCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -157,7 +155,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockEuropeCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -168,17 +166,22 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockEuropeCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
it('should properly initialize json response data source based on variable if path is provided', () => {
widget.field = getDataVariable({ ...mockVariableConfig, optionsPath: 'response.my-data' }, mockSchemaDefinition, [], mockJsonNestedResponseFormVariable);
widget.field = getDataVariable(
{ ...mockVariableConfig, optionsPath: 'response.my-data' },
mockSchemaDefinition,
[],
mockJsonNestedResponseFormVariable
);
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockEuropeCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -188,7 +191,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockEuropeCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -198,7 +201,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const expectedData = new WidgetDataTableAdapter(mockEuropeCountriesData, mockSchemaDefinition);
expectedData.getRows().forEach(row => row.cssClass = '');
expectedData.getRows().forEach((row) => (row.cssClass = ''));
expect(widget.dataSource.getRows()).toEqual(expectedData.getRows());
});
@@ -209,7 +212,7 @@ describe('DataTableWidgetComponent', () => {
fixture.detectChanges();
const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-data-table-widget-failed-message'));
const previewDataTable = fixture.nativeElement.querySelector('[data-automation-id="adf-data-table-widget-preview"]');
const previewDataTable = getPreview();
expect(failedErrorMsgElement).toBeNull();
expect(previewDataTable).toBeTruthy();
@@ -220,7 +223,7 @@ describe('DataTableWidgetComponent', () => {
spyOn(formCloudService, 'getPreviewState').and.returnValue(true);
fixture.detectChanges();
const previewDataTable = fixture.nativeElement.querySelector('[data-automation-id="adf-data-table-widget-preview"]');
const previewDataTable = getPreview();
const dataTable = fixture.nativeElement.querySelector('[data-automation-id="adf-data-table-widget"]');
expect(previewDataTable).toBeTruthy();
@@ -255,7 +258,12 @@ describe('DataTableWidgetComponent', () => {
});
it('should display and log error if path is incorrect', () => {
widget.field = getDataVariable({ ...mockVariableConfig, optionsPath: 'wrong.path' }, mockSchemaDefinition, mockJsonNestedResponseFormVariable, []);
widget.field = getDataVariable(
{ ...mockVariableConfig, optionsPath: 'wrong.path' },
mockSchemaDefinition,
mockJsonNestedResponseFormVariable,
[]
);
fixture.detectChanges();
checkDataTableErrorMessage();
@@ -264,7 +272,12 @@ describe('DataTableWidgetComponent', () => {
});
it('should display and log error if provided data by path is not an array', () => {
widget.field = getDataVariable({ ...mockVariableConfig, optionsPath: 'response.no-array' }, mockSchemaDefinition, mockJsonNestedResponseFormVariable, []);
widget.field = getDataVariable(
{ ...mockVariableConfig, optionsPath: 'response.no-array' },
mockSchemaDefinition,
mockJsonNestedResponseFormVariable,
[]
);
fixture.detectChanges();
checkDataTableErrorMessage();
@@ -17,14 +17,16 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SimpleChange } from '@angular/core';
import { By } from '@angular/platform-browser';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
import { MatDialog } from '@angular/material/dialog';
import { of } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component';
import { EditProcessFilterCloudComponent, PROCESS_FILTER_ACTION_RESTORE, PROCESS_FILTER_ACTION_SAVE_DEFAULT } from './edit-process-filter-cloud.component';
import {
EditProcessFilterCloudComponent,
PROCESS_FILTER_ACTION_RESTORE,
PROCESS_FILTER_ACTION_SAVE_DEFAULT
} from './edit-process-filter-cloud.component';
import { ProcessFiltersCloudModule } from '../process-filters-cloud.module';
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
import { ProcessFilterCloudService } from '../services/process-filter-cloud.service';
@@ -40,8 +42,14 @@ import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud
import { mockAppVersions } from '../mock/process-filters-cloud.mock';
import { fakeEnvironmentList } from '../../../common/mock/environment.mock';
import { endOfDay, format, startOfDay, subYears, isValid } from 'date-fns';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
describe('EditProcessFilterCloudComponent', () => {
let loader: HarnessLoader;
let component: EditProcessFilterCloudComponent;
let service: ProcessFilterCloudService;
let fixture: ComponentFixture<EditProcessFilterCloudComponent>;
@@ -76,16 +84,8 @@ describe('EditProcessFilterCloudComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessFiltersCloudModule,
ProcessServiceCloudTestingModule,
MatIconTestingModule
],
providers: [
MatDialog,
{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }
]
imports: [TranslateModule.forRoot(), ProcessFiltersCloudModule, ProcessServiceCloudTestingModule, MatIconTestingModule],
providers: [MatDialog, { provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
});
fixture = TestBed.createComponent(EditProcessFilterCloudComponent);
component = fixture.componentInstance;
@@ -96,45 +96,42 @@ describe('EditProcessFilterCloudComponent', () => {
alfrescoApiService = TestBed.inject(AlfrescoApiService);
dialog = TestBed.inject(MatDialog);
spyOn(dialog, 'open').and.returnValue({
afterClosed: () => of({
action: ProcessFilterDialogCloudComponent.ACTION_SAVE,
icon: 'icon',
name: 'fake-name'
})
afterClosed: () =>
of({
action: ProcessFilterDialogCloudComponent.ACTION_SAVE,
icon: 'icon',
name: 'fake-name'
})
} as any);
getProcessFilterByIdSpy = spyOn(service, 'getFilterById').and.returnValue(of(fakeFilter));
getRunningApplicationsSpy = spyOn(appsService, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
fixture.destroy();
});
const clickExpansionPanel = async () => {
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
const getFilterActionButton = (action: string) =>
nativeElement.querySelector<HTMLButtonElement>(`[data-automation-id="adf-filter-action-${action}"]`);
fixture.detectChanges();
await fixture.whenStable();
const getSelect = (automationId: string) => loader.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="${automationId}"]` }));
const clickExpansionPanel = async () => {
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
};
const clickDeleteButton = async () => {
const deleteButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
deleteButton.click();
fixture.detectChanges();
await fixture.whenStable();
};
const clickPropertyStatus = () => {
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-status"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
};
it('should not raise filter change events if filter remains the same', () => {
let count = 0;
component.filterChange.subscribe(() => count++);
@@ -190,7 +187,7 @@ describe('EditProcessFilterCloudComponent', () => {
expect(title).toBeNull();
});
it('should not display mat-spinner if isloading set to false', async () => {
it('should not display spinner if isLoading set to false', async () => {
const processFilterIdChange = new SimpleChange(null, 'mock-process-filter-id', true);
component.ngOnChanges({ id: processFilterIdChange });
@@ -199,29 +196,30 @@ describe('EditProcessFilterCloudComponent', () => {
const title = nativeElement.querySelector<HTMLElement>('#adf-edit-process-filter-title-id');
const subTitle = nativeElement.querySelector<HTMLElement>('#adf-edit-process-filter-sub-title-id');
const matSpinnerElement = nativeElement.querySelector('.adf-cloud-edit-process-filter-loading-margin');
expect(matSpinnerElement).toBeNull();
const hasSpinner = await loader.hasHarness(MatProgressSpinnerHarness);
expect(hasSpinner).toBe(false);
expect(title).toBeDefined();
expect(subTitle).toBeDefined();
expect(title.innerText).toEqual('FakeRunningProcess');
expect(subTitle.innerText.trim()).toEqual('ADF_CLOUD_EDIT_PROCESS_FILTER.TITLE');
});
it('should display mat-spinner if isloading set to true', async () => {
it('should display spinner if isLoading set to true', async () => {
component.isLoading = true;
const processFilterIdChange = new SimpleChange(null, 'mock-process-filter-id', true);
component.ngOnChanges({ id: processFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
await clickExpansionPanel();
const matSpinnerElement = nativeElement.querySelector('.adf-cloud-edit-process-filter-loading-margin');
expect(matSpinnerElement).toBeDefined();
component.isLoading = true;
fixture.detectChanges();
const hasSpinner = await loader.hasHarness(MatProgressSpinnerHarness);
expect(hasSpinner).toBe(true);
});
describe('EditProcessFilter form', () => {
beforeEach(() => {
const processFilterIdChange = new SimpleChange(null, 'mock-process-filter-id', true);
component.ngOnChanges({ id: processFilterIdChange });
@@ -251,51 +249,45 @@ describe('EditProcessFilterCloudComponent', () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
expect(deleteButton.disabled).toEqual(false);
});
it('should enable save button if the filter is changed for custom process filters', (done) => {
it('should enable save button if the filter is changed for custom process filters', async () => {
component.toggleFilterActions = true;
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editProcessFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
done();
});
await clickExpansionPanel();
clickPropertyStatus();
const select = await getSelect('adf-cloud-edit-process-property-status');
await select.open();
const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
stateOptions[2].nativeElement.click();
fixture.detectChanges();
const options = await select.getOptions();
await options[2].click();
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toBe(false);
});
it('should disable save button if the filter is not changed for custom filter', async () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toBe(true);
});
});
describe('SaveAs Button', () => {
it('should disable saveAs button if the process filter is not changed for default filter', async () => {
getProcessFilterByIdSpy.and.returnValue(of({
id: 'filter-id',
name: 'ADF_CLOUD_PROCESS_FILTERS.RUNNING_PROCESSES',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
}));
getProcessFilterByIdSpy.and.returnValue(
of({
id: 'filter-id',
name: 'ADF_CLOUD_PROCESS_FILTERS.RUNNING_PROCESSES',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
})
);
const processFilterIdChange = new SimpleChange(null, 'filter-id', true);
component.ngOnChanges({ id: processFilterIdChange });
@@ -304,7 +296,7 @@ describe('EditProcessFilterCloudComponent', () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
const saveButton = getFilterActionButton('saveAs');
expect(saveButton.disabled).toEqual(true);
});
@@ -312,64 +304,54 @@ describe('EditProcessFilterCloudComponent', () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
const saveButton = getFilterActionButton('saveAs');
expect(saveButton.disabled).toEqual(true);
});
it('should enable saveAs button if the filter values are changed for default filter', (done) => {
getProcessFilterByIdSpy.and.returnValue(of({
id: 'filter-id',
name: 'ADF_CLOUD_PROCESS_FILTERS.RUNNING_PROCESSES',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
}));
it('should enable saveAs button if the filter values are changed for default filter', async () => {
getProcessFilterByIdSpy.and.returnValue(
of({
id: 'filter-id',
name: 'ADF_CLOUD_PROCESS_FILTERS.RUNNING_PROCESSES',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
})
);
const processFilterIdChange = new SimpleChange(null, 'filter-id', true);
component.ngOnChanges({ id: processFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editProcessFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
done();
});
await clickExpansionPanel();
clickPropertyStatus();
const select = await getSelect('adf-cloud-edit-process-property-status');
await select.open();
const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
stateOptions[2].nativeElement.click();
const options = await select.getOptions();
await options[2].click();
const saveButton = getFilterActionButton('saveAs');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
});
it('should enable saveAs button if the filter values are changed for custom filter', (done) => {
it('should enable saveAs button if the filter values are changed for custom filter', async () => {
component.toggleFilterActions = true;
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editProcessFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
done();
});
await clickExpansionPanel();
clickPropertyStatus();
const select = await getSelect('adf-cloud-edit-process-property-status');
await select.open();
const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
stateOptions[2].nativeElement.click();
const options = await select.getOptions();
await options[2].click();
const saveButton = getFilterActionButton('saveAs');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
});
});
@@ -394,43 +376,37 @@ describe('EditProcessFilterCloudComponent', () => {
await fixture.whenStable();
await clickExpansionPanel();
clickPropertyStatus();
const select = await getSelect('adf-cloud-edit-process-property-status');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const statusOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(statusOptions.length).toEqual(5);
const options = await select.getOptions();
expect(options.length).toEqual(5);
});
it('should display sort drop down', async () => {
fixture.detectChanges();
await fixture.whenStable();
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-sort"] .mat-select-trigger');
sortElement.click();
const select = await getSelect('adf-cloud-edit-process-property-sort');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortOptions.length).toEqual(4);
const options = await select.getOptions();
expect(options.length).toEqual(4);
});
it('should display order drop down', async () => {
fixture.detectChanges();
await fixture.whenStable();
await clickExpansionPanel();
const orderElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-order"] .mat-select-trigger');
orderElement.click();
const select = await getSelect('adf-cloud-edit-process-property-order');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const orderOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(orderOptions.length).toEqual(2);
const options = await select.getOptions();
expect(options.length).toEqual(2);
});
});
@@ -484,7 +460,7 @@ describe('EditProcessFilterCloudComponent', () => {
});
const oneYearAgoDate = format(subYears(new Date(), 1), 'yyyy-MM-dd');
const todayDate = format(new Date(),'yyyy-MM-dd');
const todayDate = format(new Date(), 'yyyy-MM-dd');
filter.suspendedFrom = oneYearAgoDate.toString();
filter.suspendedTo = todayDate.toString();
getProcessFilterByIdSpy.and.returnValue(of(filter));
@@ -584,7 +560,6 @@ describe('EditProcessFilterCloudComponent', () => {
});
it('should fetch appVersionMultiple options when appVersionMultiple filter property is set', async () => {
const applicationVersionsSpy = spyOn(processService, 'getApplicationVersions').and.returnValue(of(mockAppVersions));
fixture.detectChanges();
@@ -596,23 +571,23 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
const controller = component.editProcessFilterForm.get('appVersionMultiple');
const appVersionMultiple = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-appVersionMultiple"]');
appVersionMultiple.click();
fixture.detectChanges();
await fixture.whenStable();
const select = await getSelect('adf-cloud-edit-process-property-appVersionMultiple');
await select.open();
const appVersionOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
const options = await select.getOptions();
expect(applicationVersionsSpy).toHaveBeenCalled();
expect(controller).toBeDefined();
expect(appVersionOptions.length).toEqual(2);
expect(appVersionOptions[0].nativeElement.innerText).toEqual('1');
expect(appVersionOptions[1].nativeElement.innerText).toEqual('2');
expect(options.length).toEqual(2);
expect(await options[0].getText()).toEqual('1');
expect(await options[1].getText()).toEqual('2');
});
it('should fetch process definitions when processDefinitionName filter property is set', async () => {
const processSpy = spyOn(processService, 'getProcessDefinitions').and.returnValue(of([new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })]));
const processSpy = spyOn(processService, 'getProcessDefinitions').and.returnValue(
of([new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })])
);
component.filterProperties = ['processDefinitionName'];
fixture.detectChanges();
@@ -625,17 +600,15 @@ describe('EditProcessFilterCloudComponent', () => {
await fixture.whenStable();
const controller = component.editProcessFilterForm.get('processDefinitionName');
const processDefinitionNamesElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-processDefinitionName"]');
processDefinitionNamesElement.click();
fixture.detectChanges();
await fixture.whenStable();
const select = await getSelect('adf-cloud-edit-process-property-processDefinitionName');
await select.open();
const options = await select.getOptions();
expect(processSpy).toHaveBeenCalled();
expect(controller).toBeDefined();
const processDefinitionNamesOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(processDefinitionNamesOptions[0].nativeElement.value).toBeUndefined();
expect(processDefinitionNamesOptions[0].nativeElement.innerText).toEqual(component.allProcessDefinitionNamesOption.label);
expect(await options[0].getText()).toEqual(component.allProcessDefinitionNamesOption.label);
});
it('should display default sort properties', async () => {
@@ -647,27 +620,27 @@ describe('EditProcessFilterCloudComponent', () => {
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-sort"]');
sortElement.click();
const select = await getSelect('adf-cloud-edit-process-property-sort');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options = await select.getOptions();
const sortController = component.editProcessFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortController).toBeDefined();
expect(sortController.value).toEqual('id');
expect(sortOptions.length).toEqual(4);
expect(options.length).toEqual(4);
});
it('should display sort properties when sort properties are specified', async () => {
getProcessFilterByIdSpy.and.returnValue(of({
id: 'filter-id',
processName: 'process-name',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
}));
getProcessFilterByIdSpy.and.returnValue(
of({
id: 'filter-id',
processName: 'process-name',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
})
);
component.sortProperties = ['id', 'name', 'processDefinitionId'];
fixture.detectChanges();
@@ -681,29 +654,29 @@ describe('EditProcessFilterCloudComponent', () => {
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-sort"]');
sortElement.click();
const select = await getSelect('adf-cloud-edit-process-property-sort');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const options = await select.getOptions();
const sortController = component.editProcessFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortController).toBeDefined();
expect(component.sortProperties).toBeDefined();
expect(component.sortProperties.length).toBe(3);
expect(sortController.value).toBe('my-custom-sort');
expect(sortOptions.length).toEqual(3);
expect(options.length).toEqual(3);
});
it('should display the process name label for the name property', async () => {
getProcessFilterByIdSpy.and.returnValue(of({
id: 'filter-id',
processName: 'process-name',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
}));
getProcessFilterByIdSpy.and.returnValue(
of({
id: 'filter-id',
processName: 'process-name',
sort: 'my-custom-sort',
processDefinitionId: 'process-definition-id',
priority: '12'
})
);
component.sortProperties = ['name'];
const processFilterIdChange = new SimpleChange(null, 'mock-process-filter-id', true);
component.ngOnChanges({ id: processFilterIdChange });
@@ -713,18 +686,14 @@ describe('EditProcessFilterCloudComponent', () => {
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-sort"]');
sortElement.click();
const select = await getSelect('adf-cloud-edit-process-property-sort');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortOptions[0].nativeElement.textContent).toEqual('ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.PROCESS_NAME');
const options = await select.getOptions();
expect(await options[0].getText()).toEqual('ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.PROCESS_NAME');
});
describe('edit filter actions', () => {
beforeEach(() => {
const processFilterIdChange = new SimpleChange(null, 'mock-process-filter-id', true);
getProcessFilterByIdSpy.and.returnValue(of(fakeFilter));
@@ -737,31 +706,25 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.destroy();
});
it('should emit save event and save the filter on click save button', (done) => {
it('should emit save event and save the filter on click save button', async () => {
component.toggleFilterActions = true;
const saveFilterSpy = spyOn(service, 'updateFilter').and.returnValue(of([fakeFilter]));
const saveSpy: jasmine.Spy = spyOn(component.action, 'emit');
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editProcessFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
saveButton.click();
expect(saveFilterSpy).toHaveBeenCalled();
expect(saveSpy).toHaveBeenCalled();
done();
});
await clickExpansionPanel();
clickPropertyStatus();
const select = await getSelect('adf-cloud-edit-process-property-status');
await select.open();
const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
stateOptions[2].nativeElement.click();
const options = await select.getOptions();
await options[2].click();
const saveButton = getFilterActionButton('save');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
saveButton.click();
expect(saveFilterSpy).toHaveBeenCalled();
expect(saveSpy).toHaveBeenCalled();
});
it('should emit delete event and delete the filter on click of delete button', async () => {
@@ -773,52 +736,41 @@ describe('EditProcessFilterCloudComponent', () => {
await fixture.whenStable();
await clickExpansionPanel();
clickPropertyStatus();
fixture.detectChanges();
await fixture.whenStable();
await clickDeleteButton();
expect(deleteFilterSpy).toHaveBeenCalled();
expect(deleteSpy).toHaveBeenCalled();
});
it('should emit saveAs event and add filter on click saveAs button', (done) => {
it('should emit saveAs event and add filter on click saveAs button', async () => {
component.toggleFilterActions = true;
const saveAsFilterSpy = spyOn(service, 'addFilter').and.callThrough();
const saveAsSpy = spyOn(component.action, 'emit');
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editProcessFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
saveButton.click();
expect(saveAsFilterSpy).toHaveBeenCalled();
expect(saveAsSpy).toHaveBeenCalled();
expect(dialog.open).toHaveBeenCalled();
done();
});
await clickExpansionPanel();
clickPropertyStatus();
const select = await getSelect('adf-cloud-edit-process-property-status');
await select.open();
const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
stateOptions[2].nativeElement.click();
const options = await select.getOptions();
await options[2].click();
const saveButton = getFilterActionButton('saveAs');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
saveButton.click();
expect(saveAsFilterSpy).toHaveBeenCalled();
expect(saveAsSpy).toHaveBeenCalled();
expect(dialog.open).toHaveBeenCalled();
});
it('should display default filter actions', async () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveAsButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-saveAs"]');
const saveButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-save"]');
const deleteButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-delete"]');
const saveAsButton = getFilterActionButton('saveAs');
const saveButton = getFilterActionButton('save');
const deleteButton = getFilterActionButton('delete');
expect(component.processFilterActions).toBeDefined();
expect(component.processFilterActions.length).toEqual(3);
expect(saveButton).toBeDefined();
@@ -867,7 +819,9 @@ describe('EditProcessFilterCloudComponent', () => {
const saveDefaultFilterEmitSpy = spyOn(component.action, 'emit');
await clickExpansionPanel();
const saveDefaultFilterButton = nativeElement.querySelector<HTMLButtonElement>(`[data-automation-id="adf-filter-action-${PROCESS_FILTER_ACTION_SAVE_DEFAULT}"]`);
const saveDefaultFilterButton = nativeElement.querySelector<HTMLButtonElement>(
`[data-automation-id="adf-filter-action-${PROCESS_FILTER_ACTION_SAVE_DEFAULT}"]`
);
fixture.detectChanges();
expect(saveDefaultFilterButton.disabled).toBe(false);
saveDefaultFilterButton.click();
@@ -904,7 +858,9 @@ describe('EditProcessFilterCloudComponent', () => {
const resetDefaultsEmitSpy: jasmine.Spy = spyOn(component.action, 'emit');
await clickExpansionPanel();
const resetButton = nativeElement.querySelector<HTMLButtonElement>(`[data-automation-id="adf-filter-action-${PROCESS_FILTER_ACTION_RESTORE}"]`);
const resetButton = nativeElement.querySelector<HTMLButtonElement>(
`[data-automation-id="adf-filter-action-${PROCESS_FILTER_ACTION_RESTORE}"]`
);
fixture.detectChanges();
expect(resetButton.disabled).toBe(false);
resetButton.click();
@@ -926,9 +882,9 @@ describe('EditProcessFilterCloudComponent', () => {
await fixture.whenStable();
await clickExpansionPanel();
const saveAsButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-saveAs"]');
const saveButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-save"]');
const deleteButton = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-filter-action-delete"]');
const saveAsButton = getFilterActionButton('saveAs');
const saveButton = getFilterActionButton('save');
const deleteButton = getFilterActionButton('delete');
expect(component.processFilterActions).toBeDefined();
expect(component.processFilterActions.length).toEqual(3);
expect(saveButton).toBeDefined();
@@ -987,7 +943,7 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
component.onDateChanged('20/03/2023', { key: 'lastModifiedTo' } as any );
component.onDateChanged('20/03/2023', { key: 'lastModifiedTo' } as any);
expect(component.lastModifiedTo.value).toEqual(new Date('2023-03-20'));
expect(component.lastModifiedTo.valid).toBeTrue();
@@ -1005,7 +961,7 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
component.onDateChanged('20/03/2023', { key: 'lastModifiedFrom' } as any );
component.onDateChanged('20/03/2023', { key: 'lastModifiedFrom' } as any);
expect(component.lastModifiedFrom.value).toEqual(new Date('2023-03-20'));
expect(component.lastModifiedFrom.valid).toBeTrue();
@@ -1042,7 +998,9 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const dateInput = nativeElement.querySelector<HTMLInputElement>(`[data-automation-id="adf-cloud-edit-process-property-lastModifiedFrom"]`);
const dateInput = nativeElement.querySelector<HTMLInputElement>(
`[data-automation-id="adf-cloud-edit-process-property-lastModifiedFrom"]`
);
expect(dateInput).not.toBeNull();
dateInput.value = '20/03/2023';
@@ -1061,7 +1019,9 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const dateInput = nativeElement.querySelector<HTMLInputElement>(`[data-automation-id="adf-cloud-edit-process-property-lastModifiedFrom"]`);
const dateInput = nativeElement.querySelector<HTMLInputElement>(
`[data-automation-id="adf-cloud-edit-process-property-lastModifiedFrom"]`
);
expect(dateInput).not.toBeNull();
dateInput.value = 'invalid';
@@ -1165,7 +1125,7 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
await clickExpansionPanel();
clickPropertyStatus();
await clickDeleteButton();
expect(deleteFilterSpy).toHaveBeenCalled();
@@ -1185,9 +1145,6 @@ describe('EditProcessFilterCloudComponent', () => {
fixture.detectChanges();
await clickExpansionPanel();
clickPropertyStatus();
fixture.detectChanges();
await clickDeleteButton();
expect(deleteFilterSpy).toHaveBeenCalled();
@@ -22,7 +22,7 @@
</ng-container>
<ng-template #loadingTemplate>
<div class="adf-cloud-edit-task-filter-loading-margin">
<mat-spinner [diameter]="30"></mat-spinner>
<mat-progress-spinner mode="indeterminate" [diameter]="30"></mat-progress-spinner>
</div>
</ng-template>
</mat-expansion-panel-header>
@@ -17,10 +17,8 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SimpleChange } from '@angular/core';
import { By } from '@angular/platform-browser';
import { MatDialog } from '@angular/material/dialog';
import { of, Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../../services/local-preference-cloud.service';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
@@ -37,8 +35,14 @@ import { ProcessDefinitionCloud } from '../../../../models/process-definition-cl
import { TaskFilterDialogCloudComponent } from '../task-filter-dialog/task-filter-dialog-cloud.component';
import { fakeEnvironmentList } from '../../../../common/mock/environment.mock';
import { mockApplicationTaskFilterProperties } from '../../mock/edit-task-filter-cloud.mock';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
import { MatSelectHarness } from '@angular/material/select/testing';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
describe('EditServiceTaskFilterCloudComponent', () => {
let loader: HarnessLoader;
let component: EditServiceTaskFilterCloudComponent;
let service: ServiceTaskFilterCloudService;
let appsService: AppsProcessCloudService;
@@ -51,16 +55,8 @@ describe('EditServiceTaskFilterCloudComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessServiceCloudTestingModule,
TaskFiltersCloudModule,
MatIconTestingModule
],
providers: [
MatDialog,
{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }
]
imports: [TranslateModule.forRoot(), ProcessServiceCloudTestingModule, TaskFiltersCloudModule, MatIconTestingModule],
providers: [MatDialog, { provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
});
fixture = TestBed.createComponent(EditServiceTaskFilterCloudComponent);
component = fixture.componentInstance;
@@ -69,16 +65,19 @@ describe('EditServiceTaskFilterCloudComponent', () => {
taskService = TestBed.inject(TaskCloudService);
dialog = TestBed.inject(MatDialog);
const dialogRefMock: any = {
afterClosed: () => afterClosedSubject
afterClosed: () => afterClosedSubject
};
spyOn(dialog, 'open').and.returnValue(dialogRefMock);
getTaskFilterSpy = spyOn(service, 'getTaskFilterById').and.returnValue(of(fakeServiceFilter));
getRunningApplicationsSpy = spyOn(appsService, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => fixture.destroy());
const getSelect = (automationId: string) => loader.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="${automationId}"]` }));
it('should fetch task filter by taskId', async () => {
const taskFilterIdChange = new SimpleChange(undefined, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
@@ -93,9 +92,9 @@ describe('EditServiceTaskFilterCloudComponent', () => {
});
it('should fetch process definitions when processDefinitionName filter property is set', async () => {
const processSpy = spyOn(taskService, 'getProcessDefinitions').and.returnValue(of([
new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })
]));
const processSpy = spyOn(taskService, 'getProcessDefinitions').and.returnValue(
of([new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })])
);
fixture.detectChanges();
component.filterProperties = ['processDefinitionName'];
fixture.detectChanges();
@@ -136,7 +135,7 @@ describe('EditServiceTaskFilterCloudComponent', () => {
expect(title).toBeNull();
});
it('should not display mat-spinner if isloading set to false', async () => {
it('should not display spinner if isLoading set to false', async () => {
const taskFilterIdChange = new SimpleChange(null, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
@@ -145,27 +144,28 @@ describe('EditServiceTaskFilterCloudComponent', () => {
const title = fixture.debugElement.nativeElement.querySelector('#adf-edit-task-filter-title-id');
const subTitle = fixture.debugElement.nativeElement.querySelector('#adf-edit-task-filter-sub-title-id');
const matSpinnerElement = fixture.debugElement.nativeElement.querySelector('.adf-cloud-edit-task-filter-loading-margin');
expect(matSpinnerElement).toBeNull();
expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(false);
expect(title.innerText).toEqual('FakeInvolvedTasks');
expect(subTitle.innerText.trim()).toEqual('ADF_CLOUD_EDIT_TASK_FILTER.TITLE');
});
it('should display mat-spinner if isloading set to true', async () => {
it('should display spinner if isLoading set to true', async () => {
component.isLoading = true;
const taskFilterIdChange = new SimpleChange(null, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const matSpinnerElement = fixture.debugElement.nativeElement.querySelector('.adf-cloud-edit-task-filter-loading-margin');
expect(matSpinnerElement).toBeDefined();
component.isLoading = true;
fixture.detectChanges();
expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(true);
});
describe('EditServiceTaskFilter form', () => {
beforeEach(() => {
const taskFilterIdChange = new SimpleChange(undefined, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
@@ -191,26 +191,25 @@ describe('EditServiceTaskFilterCloudComponent', () => {
describe('Save & Delete buttons', () => {
it('should disable save and delete button for default task filters', async () => {
getTaskFilterSpy.and.returnValue(of({
name: 'ADF_CLOUD_SERVICE_TASK_FILTERS.ALL_SERVICE_TASKS',
id: 'filter-id',
key: 'all-fake-task',
icon: 'adjust',
sort: 'startDate',
status: 'ALL',
order: 'DESC'
}));
getTaskFilterSpy.and.returnValue(
of({
name: 'ADF_CLOUD_SERVICE_TASK_FILTERS.ALL_SERVICE_TASKS',
id: 'filter-id',
key: 'all-fake-task',
icon: 'adjust',
sort: 'startDate',
status: 'ALL',
order: 'DESC'
})
);
const taskFilterIdChange = new SimpleChange(null, 'filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
expect(saveButton.disabled).toBe(true);
@@ -224,11 +223,8 @@ describe('EditServiceTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
expect(saveButton.disabled).toBe(true);
@@ -236,40 +232,34 @@ describe('EditServiceTaskFilterCloudComponent', () => {
expect(deleteButton.disabled).toBe(false);
});
it('should enable save button if the filter is changed for custom task filters', (done) => {
it('should enable save button if the filter is changed for custom task filters', async () => {
const taskFilterIdChange = new SimpleChange(null, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editTaskFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
done();
});
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
const select = await loader.getHarness(
MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` })
);
await select.open();
const options = await select.getOptions();
await options[3].click();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
});
it('should disable save button if the filter is not changed for custom filter', async () => {
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
expect(saveButton.disabled).toBe(true);
@@ -278,26 +268,25 @@ describe('EditServiceTaskFilterCloudComponent', () => {
describe('SaveAs button', () => {
it('should disable saveAs button if the process filter is not changed for default filter', async () => {
getTaskFilterSpy.and.returnValue(of({
name: 'ADF_CLOUD_TASK_FILTERS.MY_TASKS',
id: 'filter-id',
key: 'all-fake-task',
icon: 'adjust',
sort: 'startDate',
status: 'ALL',
order: 'DESC'
}));
getTaskFilterSpy.and.returnValue(
of({
name: 'ADF_CLOUD_TASK_FILTERS.MY_TASKS',
id: 'filter-id',
key: 'all-fake-task',
icon: 'adjust',
sort: 'startDate',
status: 'ALL',
order: 'DESC'
})
);
const taskFilterIdChange = new SimpleChange(null, 'filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
expect(saveButton.disabled).toEqual(true);
@@ -305,88 +294,67 @@ describe('EditServiceTaskFilterCloudComponent', () => {
it('should disable saveAs button if the process filter is not changed for custom filter', async () => {
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
expect(saveButton.disabled).toEqual(true);
});
it('should enable saveAs button if the filter values are changed for default filter', (done) => {
getTaskFilterSpy.and.returnValue(of({
name: 'ADF_CLOUD_TASK_FILTERS.MY_TASKS',
id: 'filter-id',
key: 'all-fake-task',
icon: 'adjust',
sort: 'startDate',
status: 'ALL',
order: 'DESC'
}));
it('should enable saveAs button if the filter values are changed for default filter', async () => {
getTaskFilterSpy.and.returnValue(
of({
name: 'ADF_CLOUD_TASK_FILTERS.MY_TASKS',
id: 'filter-id',
key: 'all-fake-task',
icon: 'adjust',
sort: 'startDate',
status: 'ALL',
order: 'DESC'
})
);
const taskFilterIdChange = new SimpleChange(null, 'filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editTaskFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
done();
});
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
const options = await select.getOptions();
await options[3].click();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
});
it('should enable saveAs button if the filter values are changed for custom filter', (done) => {
it('should enable saveAs button if the filter values are changed for custom filter', async () => {
component.toggleFilterActions = true;
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editTaskFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
done();
});
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
const options = await select.getOptions();
await options[3].click();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
});
});
it('should display current task filter details', async () => {
fixture.detectChanges();
await fixture.whenStable();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-status"]');
const assigneeElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-assignee"]');
@@ -399,75 +367,41 @@ describe('EditServiceTaskFilterCloudComponent', () => {
});
it('should display all the statuses that are defined in the task filter', async () => {
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
fixture.detectChanges();
await fixture.whenStable();
const select = await getSelect('adf-cloud-edit-task-property-status');
await select.open();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-status"]');
stateElement.click();
const options = await select.getOptions();
fixture.detectChanges();
await fixture.whenStable();
const statusOptions = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-cloud-edit-task-property-options-status"]'));
expect(statusOptions[0].nativeElement.textContent.trim()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.ALL');
expect(statusOptions[1].nativeElement.textContent.trim()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.STARTED');
expect(statusOptions[2].nativeElement.textContent.trim()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.COMPLETED');
expect(statusOptions[3].nativeElement.textContent.trim()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.CANCELLED');
expect(statusOptions[4].nativeElement.textContent.trim()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.ERROR');
expect(await options[0].getText()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.ALL');
expect(await options[1].getText()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.STARTED');
expect(await options[2].getText()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.COMPLETED');
expect(await options[3].getText()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.CANCELLED');
expect(await options[4].getText()).toBe('ADF_CLOUD_SERVICE_TASK_FILTERS.STATUS.ERROR');
});
it('should display sort drop down', async () => {
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const sortElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
fixture.detectChanges();
await fixture.whenStable();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortOptions.length).toEqual(4);
const options = await select.getOptions();
expect(options.length).toEqual(4);
});
it('should display order drop down', async () => {
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-order"]` }));
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const orderElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-order"]');
orderElement.click();
fixture.detectChanges();
await fixture.whenStable();
const orderOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(orderOptions.length).toEqual(2);
});
it('should have floating labels when values are present', async () => {
fixture.detectChanges();
await fixture.whenStable();
const inputLabelsNodes = document.querySelectorAll('mat-form-field');
inputLabelsNodes.forEach(labelNode => {
expect(labelNode.getAttribute('ng-reflect-float-label')).toBe('auto');
});
const options = await select.getOptions();
expect(options.length).toBe(2);
});
it('should able to build a editTaskFilter form with default properties if input is empty', async () => {
@@ -508,51 +442,50 @@ describe('EditServiceTaskFilterCloudComponent', () => {
});
describe('sort properties', () => {
it('should display default sort properties', async () => {
const taskFilterIdChange = new SimpleChange(undefined, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const sortElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const options = await select.getOptions();
const sortController = component.editTaskFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortController.value).toBe('id');
expect(sortOptions.length).toEqual(4);
expect(options.length).toBe(4);
});
it('should display sort properties when sort properties are specified', async () => {
component.sortProperties = ['id', 'name', 'processInstanceId'];
getTaskFilterSpy.and.returnValue(of({
sort: 'my-custom-sort',
processInstanceId: 'process-instance-id',
priority: '12'
}));
getTaskFilterSpy.and.returnValue(
of({
sort: 'my-custom-sort',
processInstanceId: 'process-instance-id',
priority: '12'
})
);
fixture.detectChanges();
const taskFilterIdChange = new SimpleChange(undefined, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const sortElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const options = await select.getOptions();
const sortController = component.editTaskFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(component.sortProperties.length).toBe(3);
expect(sortController.value).toBe('my-custom-sort');
expect(sortOptions.length).toEqual(3);
expect(options.length).toBe(3);
});
it('should display default sort properties if input is empty', async () => {
@@ -561,39 +494,35 @@ describe('EditServiceTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.sortProperties = [];
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const sortElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const options = await select.getOptions();
const sortController = component.editTaskFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortController.value).toBe('id');
expect(sortOptions.length).toEqual(4);
expect(options.length).toBe(4);
});
});
describe('filter actions', () => {
it('should display default filter actions', async () => {
component.toggleFilterActions = true;
const taskFilterIdChange = new SimpleChange(undefined, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveAsButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]');
expect(component.taskFilterActions.map(action => action.actionType)).toEqual(['save', 'saveAs', 'delete']);
expect(component.taskFilterActions.map((action) => action.actionType)).toEqual(['save', 'saveAs', 'delete']);
expect(component.taskFilterActions.length).toBe(3);
expect(saveButton.disabled).toBe(true);
expect(saveAsButton.disabled).toBe(true);
@@ -608,14 +537,12 @@ describe('EditServiceTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.toggleFilterActions = true;
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
expect(component.taskFilterActions.map(action => action.actionType)).toEqual(['save']);
expect(component.taskFilterActions.map((action) => action.actionType)).toEqual(['save']);
expect(component.taskFilterActions.length).toBe(1);
expect(saveButton.disabled).toBeTruthy();
const saveAsButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
@@ -626,7 +553,6 @@ describe('EditServiceTaskFilterCloudComponent', () => {
});
describe('edit filter actions', () => {
beforeEach(() => {
const taskFilterIdChange = new SimpleChange(undefined, 'mock-task-filter-id', true);
component.ngOnChanges({ id: taskFilterIdChange });
@@ -638,15 +564,16 @@ describe('EditServiceTaskFilterCloudComponent', () => {
component.toggleFilterActions = true;
spyOn(service, 'updateFilter').and.returnValue(of(null));
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const options = await select.getOptions();
await options[3].click();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]');
await fixture.whenStable();
fixture.detectChanges();
@@ -660,12 +587,13 @@ describe('EditServiceTaskFilterCloudComponent', () => {
component.toggleFilterActions = true;
spyOn(service, 'deleteFilter').and.returnValue(of(null));
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]');
await fixture.whenStable();
fixture.detectChanges();
@@ -680,18 +608,14 @@ describe('EditServiceTaskFilterCloudComponent', () => {
spyOn(service, 'addFilter').and.returnValue(of(null));
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const sortOptions = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-cloud-edit-task-property-options-sort"] .mat-option-ripple'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
await fixture.whenStable();
const options = await select.getOptions();
await options[3].click();
const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]');
saveButton.dispatchEvent(new Event('click'));
@@ -713,12 +637,13 @@ describe('EditServiceTaskFilterCloudComponent', () => {
spyOn(service, 'deleteFilter').and.returnValue(of([]));
const restoreDefaultFiltersSpy = spyOn(component, 'restoreDefaultTaskFilters').and.returnValue(of([]));
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]');
await fixture.whenStable();
fixture.detectChanges();
@@ -734,12 +659,13 @@ describe('EditServiceTaskFilterCloudComponent', () => {
spyOn(service, 'deleteFilter').and.returnValue(of([{ name: 'mock-filter-name' }]));
const restoreDefaultFiltersSpy = spyOn(component, 'restoreDefaultTaskFilters').and.returnValue(of([]));
fixture.detectChanges();
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await panel.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` }));
await select.open();
const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]');
await fixture.whenStable();
fixture.detectChanges();
@@ -15,12 +15,11 @@
* limitations under the License.
*/
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { MatDialog } from '@angular/material/dialog';
import { of, Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { TASK_FILTERS_SERVICE_TOKEN } from '../../../../services/cloud-token.service';
import { LocalPreferenceCloudService } from '../../../../services/local-preference-cloud.service';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
@@ -31,7 +30,6 @@ import { EditTaskFilterCloudComponent } from './edit-task-filter-cloud.component
import { TaskFilterCloudService } from '../../services/task-filter-cloud.service';
import { TaskCloudService } from '../../../services/task-cloud.service';
import { fakeFilter } from '../../mock/task-filters-cloud.mock';
import { AbstractControl } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { DateCloudFilterType } from '../../../../models/date-cloud-filter.model';
import { AssignmentType, TaskFilterCloudModel, TaskStatusFilter } from '../../models/filter-cloud.model';
@@ -55,8 +53,14 @@ import { mockFoodGroups } from '../../../../group/mock/group-cloud.mock';
import { SimpleChanges } from '@angular/core';
import { TaskFilterDialogCloudComponent } from '../task-filter-dialog/task-filter-dialog-cloud.component';
import { set } from 'date-fns';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
describe('EditTaskFilterCloudComponent', () => {
let loader: HarnessLoader;
let component: EditTaskFilterCloudComponent;
let service: TaskFilterCloudService;
let appsService: AppsProcessCloudService;
@@ -71,17 +75,8 @@ describe('EditTaskFilterCloudComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessServiceCloudTestingModule,
TaskFiltersCloudModule,
PeopleCloudModule,
MatIconTestingModule
],
providers: [
MatDialog,
{ provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }
]
imports: [TranslateModule.forRoot(), ProcessServiceCloudTestingModule, TaskFiltersCloudModule, PeopleCloudModule, MatIconTestingModule],
providers: [MatDialog, { provide: TASK_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
});
fixture = TestBed.createComponent(EditTaskFilterCloudComponent);
component = fixture.componentInstance;
@@ -92,24 +87,22 @@ describe('EditTaskFilterCloudComponent', () => {
alfrescoApiService = TestBed.inject(AlfrescoApiService);
dialog = TestBed.inject(MatDialog);
const dialogRefMock: any = {
afterClosed: () => afterClosedSubject
afterClosed: () => afterClosedSubject
};
spyOn(dialog, 'open').and.returnValue(dialogRefMock);
spyOn(alfrescoApiService, 'getInstance').and.returnValue(mockAlfrescoApi);
getTaskFilterSpy = spyOn(service, 'getTaskFilterById').and.returnValue(of(fakeFilter));
getRunningApplicationsSpy = spyOn(appsService, 'getDeployedApplicationsByStatus').and.returnValue(of(fakeApplicationInstance));
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => fixture.destroy());
const clickExpansionPanel = async () => {
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
const getFilterActionButton = (action: string) =>
nativeElement.querySelector<HTMLButtonElement>(`[data-automation-id="adf-filter-action-${action}"]`);
fixture.detectChanges();
await fixture.whenStable();
};
const getSelect = (automationId: string) => loader.getHarness(MatSelectHarness.with({ selector: `[data-automation-id="${automationId}"]` }));
it('should fetch task filter by taskId', async () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
@@ -125,93 +118,99 @@ describe('EditTaskFilterCloudComponent', () => {
});
describe('processInstanceId filter', () => {
const cssSelector = {
processInstanceIdInput: '[data-automation-id="adf-cloud-edit-task-property-processInstanceId"]'
};
/**
* expand filter panel
*/
function expandFilterPanel(){
const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
}
/**
* resolve filter instance input element
*
* @returns native element
*/
function getProcessInstanceIdInputElement(){
function getProcessInstanceIdInputElement() {
return fixture.debugElement.query(By.css(cssSelector.processInstanceIdInput)).nativeElement;
}
it('should set processInstanceId filter when id changes', async () => {
getTaskFilterSpy.and.returnValue(of(mockTaskFilterResponse));
component.processInstanceId = 'fakeProcessInstanceId';
component.filterProperties = [ 'appName', 'processInstanceId', 'sort', 'order'];
component.filterProperties = ['appName', 'processInstanceId', 'sort', 'order'];
fixture.detectChanges();
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
expandFilterPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
expect(getProcessInstanceIdInputElement().value).toEqual('fakeProcessInstanceId');
});
it('should processInstanceId filter be empty string if processInstanceId is null', async () => {
getTaskFilterSpy.and.returnValue(of(mockTaskFilterResponseWithProcessInstanceIdNull));
component.processInstanceId = null;
component.filterProperties = [ 'appName', 'processInstanceId', 'sort', 'order'];
component.filterProperties = ['appName', 'processInstanceId', 'sort', 'order'];
fixture.detectChanges();
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
expandFilterPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
expect(getProcessInstanceIdInputElement().value).toEqual('');
});
it('should processInstanceId filter be empty string if processInstanceId is undefined', async () => {
getTaskFilterSpy.and.returnValue(of(mockTaskFilterResponseWithProcessInstanceIdNull));
component.processInstanceId = undefined;
component.filterProperties = [ 'appName', 'processInstanceId', 'sort', 'order'];
component.filterProperties = ['appName', 'processInstanceId', 'sort', 'order'];
fixture.detectChanges();
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
expandFilterPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
expect(getProcessInstanceIdInputElement().value).toEqual('');
});
it('should processInstanceId filter be set with the processInstanceId from response if processInstanceId input is null', async () => {
getTaskFilterSpy.and.returnValue(of(mockTaskFilterResponse));
component.processInstanceId = null;
component.filterProperties = [ 'appName', 'processInstanceId', 'sort', 'order'];
component.filterProperties = ['appName', 'processInstanceId', 'sort', 'order'];
fixture.detectChanges();
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
expandFilterPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
expect(getProcessInstanceIdInputElement().value).toEqual('fakeProcessInstanceIdFromResponse');
});
it('should processInstanceId filter be set with the processInstanceId from response if processInstanceId input is undefined', async () => {
getTaskFilterSpy.and.returnValue(of(mockTaskFilterResponse));
component.processInstanceId = undefined;
component.filterProperties = [ 'appName', 'processInstanceId', 'sort', 'order'];
component.filterProperties = ['appName', 'processInstanceId', 'sort', 'order'];
fixture.detectChanges();
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
expandFilterPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
expect(getProcessInstanceIdInputElement().value).toEqual('fakeProcessInstanceIdFromResponse');
});
});
it('should fetch process definitions when processDefinitionName filter property is set', async () => {
const processSpy = spyOn(taskService, 'getProcessDefinitions').and.returnValue(of([new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })]));
const processSpy = spyOn(taskService, 'getProcessDefinitions').and.returnValue(
of([new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })])
);
fixture.detectChanges();
component.filterProperties = ['processDefinitionName'];
fixture.detectChanges();
@@ -249,7 +248,7 @@ describe('EditTaskFilterCloudComponent', () => {
expect(title).toBeNull();
});
it('should not display mat-spinner if isloading set to false', async () => {
it('should not display spinner if isLoading set to false', async () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
@@ -257,26 +256,28 @@ describe('EditTaskFilterCloudComponent', () => {
const title = nativeElement.querySelector<HTMLElement>('#adf-edit-task-filter-title-id');
const subTitle = nativeElement.querySelector<HTMLElement>('#adf-edit-task-filter-sub-title-id');
const matSpinnerElement = nativeElement.querySelector<HTMLElement>('.adf-cloud-edit-task-filter-loading-margin');
expect(matSpinnerElement).toBeNull();
const hasSpinner = await loader.hasHarness(MatProgressSpinnerHarness);
expect(hasSpinner).toBe(false);
expect(title.innerText).toEqual('FakeInvolvedTasks');
expect(subTitle.innerText.trim()).toEqual('ADF_CLOUD_EDIT_TASK_FILTER.TITLE');
});
it('should display mat-spinner if isloading set to true', async () => {
it('should display spinner if isLoading set to true', async () => {
component.isLoading = true;
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const matSpinnerElement = nativeElement.querySelector('.adf-cloud-edit-task-filter-loading-margin');
expect(matSpinnerElement).toBeDefined();
component.isLoading = true;
fixture.detectChanges();
const hasSpinner = await loader.hasHarness(MatProgressSpinnerHarness);
expect(hasSpinner).toBe(true);
});
describe('EditTaskFilter form', () => {
beforeEach(() => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
@@ -306,11 +307,13 @@ describe('EditTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toBe(true);
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
expect(deleteButton.disabled).toBe(true);
});
@@ -319,45 +322,42 @@ describe('EditTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toBe(true);
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
expect(deleteButton.disabled).toBe(false);
});
it('should enable save button if the filter is changed for custom task filters', (done) => {
it('should enable save button if the filter is changed for custom task filters', async () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editTaskFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
fixture.detectChanges();
expect(saveButton.disabled).toBe(false);
done();
});
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const options = await select.getOptions();
await options[3].click();
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toBe(false);
});
it('should disable save button if the filter is not changed for custom filter', async () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toBe(true);
});
});
@@ -369,71 +369,63 @@ describe('EditTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = getFilterActionButton('save');
expect(saveButton.disabled).toEqual(true);
});
it('should disable saveAs button if the process filter is not changed for custom filter', async () => {
component.toggleFilterActions = true;
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = getFilterActionButton('saveAs');
expect(saveButton.disabled).toEqual(true);
});
it('should enable saveAs button if the filter values are changed for default filter', (done) => {
it('should enable saveAs button if the filter values are changed for default filter', async () => {
getTaskFilterSpy.and.returnValue(of(mockDefaultTaskFilter));
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
component.toggleFilterActions = true;
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editTaskFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
done();
});
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const select = await loader.getHarness(
MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` })
);
await select.open();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
const options = await select.getOptions();
await options[3].click();
const saveButton = getFilterActionButton('saveAs');
expect(saveButton.disabled).toEqual(false);
});
it('should enable saveAs button if the filter values are changed for custom filter', (done) => {
it('should enable saveAs button if the filter values are changed for custom filter', async () => {
component.toggleFilterActions = true;
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
component.editTaskFilterForm.valueChanges
.pipe(debounceTime(500))
.subscribe(() => {
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
fixture.detectChanges();
expect(saveButton.disabled).toEqual(false);
done();
});
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const select = await loader.getHarness(
MatSelectHarness.with({ selector: `[data-automation-id="adf-cloud-edit-task-property-sort"]` })
);
await select.open();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
const options = await select.getOptions();
await options[3].click();
const saveButton = getFilterActionButton('saveAs');
expect(saveButton.disabled).toEqual(false);
});
});
@@ -441,62 +433,61 @@ describe('EditTaskFilterCloudComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
await clickExpansionPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-status"]');
const assigneeElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-assignee"]');
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"]');
const orderElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-order"]');
expect(assigneeElement).toBeDefined();
expect(stateElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.CREATED');
expect(sortElement.textContent.trim()).toBe('id');
expect(orderElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.DIRECTION.ASCENDING');
const status = await getSelect('adf-cloud-edit-task-property-status');
expect(await status.getValueText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.CREATED');
const assignee = nativeElement.querySelector(`[data-automation-id="adf-cloud-edit-task-property-assignee"]`);
expect(assignee).toBeDefined();
const sort = await getSelect('adf-cloud-edit-task-property-sort');
expect(await sort.getValueText()).toBe('id');
const order = await getSelect('adf-cloud-edit-task-property-order');
expect(await order.getValueText()).toBe('ADF_CLOUD_TASK_FILTERS.DIRECTION.ASCENDING');
});
it('should display all the statuses that are defined in the task filter', async () => {
await clickExpansionPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-status"]');
stateElement.click();
fixture.detectChanges();
await fixture.whenStable();
const select = await getSelect('adf-cloud-edit-task-property-status');
await select.open();
const statusOptions = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-cloud-edit-task-property-options-status"]'));
const options = await select.getOptions();
expect(statusOptions[0].nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.ALL');
expect(statusOptions[1].nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.CREATED');
expect(statusOptions[2].nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.ASSIGNED');
expect(statusOptions[3].nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.SUSPENDED');
expect(statusOptions[4].nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.CANCELLED');
expect(statusOptions[5].nativeElement.textContent.trim()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.COMPLETED');
expect(await options[0].getText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.ALL');
expect(await options[1].getText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.CREATED');
expect(await options[2].getText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.ASSIGNED');
expect(await options[3].getText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.SUSPENDED');
expect(await options[4].getText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.CANCELLED');
expect(await options[5].getText()).toBe('ADF_CLOUD_TASK_FILTERS.STATUS.COMPLETED');
});
it('should display sort drop down', async () => {
fixture.detectChanges();
await clickExpansionPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortOptions.length).toEqual(4);
const options = await select.getOptions();
expect(options.length).toBe(4);
});
it('should display order drop down', async () => {
fixture.detectChanges();
await clickExpansionPanel();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const orderElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-order"]');
orderElement.click();
const select = await getSelect('adf-cloud-edit-task-property-order');
await select.open();
fixture.detectChanges();
await fixture.whenStable();
const orderOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(orderOptions.length).toEqual(2);
const options = await select.getOptions();
expect(options.length).toBe(2);
});
it('should able to build a editTaskFilter form with default properties if input is empty', async () => {
@@ -540,10 +531,12 @@ describe('EditTaskFilterCloudComponent', () => {
await fixture.whenStable();
expect(appController).toBeDefined();
expect(JSON.stringify(appController.value)).toBe(JSON.stringify({
id: 'mock-id',
username: 'testCompletedByUser'
}));
expect(JSON.stringify(appController.value)).toBe(
JSON.stringify({
id: 'mock-id',
username: 'testCompletedByUser'
})
);
});
it('should show completedBy filter', async () => {
@@ -564,7 +557,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('completedBy');
const startedDateTypeControl = component.editTaskFilterForm.get('completedBy');
startedDateTypeControl.setValue('hruser');
component.onChangedUser(mockFoodUsers, {
@@ -589,7 +582,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('dueDateType');
const startedDateTypeControl = component.editTaskFilterForm.get('dueDateType');
startedDateTypeControl.setValue(DateCloudFilterType.TODAY);
component.filterChange.subscribe(() => {
@@ -600,22 +593,17 @@ describe('EditTaskFilterCloudComponent', () => {
component.onFilterChange();
});
it('should have correct options on dueDate filters', () => {
it('should have correct options on dueDate filters', async () => {
component.appName = 'fake';
component.filterProperties = ['appName', 'processInstanceId', 'priority', 'dueDateRange'];
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-process-property-dueDateRange"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const select = await getSelect('adf-cloud-edit-process-property-dueDateRange');
await select.open();
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortOptions.length).toEqual(5);
sortOptions[1].nativeElement.click('TODAY');
sortOptions[2].nativeElement.click('TOMOROW');
sortOptions[3].nativeElement.click('NEXT_7_DAYS');
sortOptions[4].nativeElement.click('RANGE');
const options = await select.getOptions();
expect(options.length).toEqual(5);
});
it('should update form on date range value is updated', (done) => {
@@ -624,7 +612,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('dueDateType');
const startedDateTypeControl = component.editTaskFilterForm.get('dueDateType');
startedDateTypeControl.setValue(DateCloudFilterType.RANGE);
component.onDateRangeFilterChanged(mockDateFilterStartEnd, mockDueDateFilter);
@@ -645,7 +633,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('completedDateType');
const startedDateTypeControl = component.editTaskFilterForm.get('completedDateType');
startedDateTypeControl.setValue(DateCloudFilterType.TODAY);
component.filterChange.subscribe(() => {
@@ -662,7 +650,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('completedDateType');
const startedDateTypeControl = component.editTaskFilterForm.get('completedDateType');
startedDateTypeControl.setValue(DateCloudFilterType.RANGE);
component.onDateRangeFilterChanged(mockDateFilterStartEnd, mockCompletedDateFilter);
@@ -682,7 +670,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('createdDateType');
const startedDateTypeControl = component.editTaskFilterForm.get('createdDateType');
startedDateTypeControl.setValue(DateCloudFilterType.TODAY);
component.filterChange.subscribe(() => {
@@ -699,7 +687,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.filterProperties = ['assignment'];
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const assignmentComponent = nativeElement.querySelector<HTMLElement>('adf-cloud-task-assignment-filter');
const assignmentComponent = nativeElement.querySelector('adf-cloud-task-assignment-filter');
expect(assignmentComponent).toBeTruthy();
});
@@ -723,7 +711,7 @@ describe('EditTaskFilterCloudComponent', () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
const startedDateTypeControl: AbstractControl = component.editTaskFilterForm.get('createdDateType');
const startedDateTypeControl = component.editTaskFilterForm.get('createdDateType');
startedDateTypeControl.setValue(DateCloudFilterType.RANGE);
component.onDateRangeFilterChanged(mockDateFilterStartEnd, mockCreatedDateFilter);
@@ -755,7 +743,6 @@ describe('EditTaskFilterCloudComponent', () => {
});
describe('assignment type change', () => {
beforeEach(() => {
component.appName = 'fake';
component.filterProperties = ['assignment', 'status'];
@@ -800,47 +787,49 @@ describe('EditTaskFilterCloudComponent', () => {
});
describe('sort properties', () => {
it('should display default sort properties', async () => {
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const options = await select.getOptions();
expect(options.length).toBe(4);
const sortController = component.editTaskFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortController.value).toBe('id');
expect(sortOptions.length).toEqual(4);
});
it('should display sort properties when sort properties are specified', async () => {
component.sortProperties = ['id', 'name', 'processInstanceId'];
getTaskFilterSpy.and.returnValue(of({
sort: 'my-custom-sort',
processInstanceId: 'process-instance-id',
priority: '12'
}));
getTaskFilterSpy.and.returnValue(
of({
sort: 'my-custom-sort',
processInstanceId: 'process-instance-id',
priority: '12'
})
);
fixture.detectChanges();
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
fixture.detectChanges();
await fixture.whenStable();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const options = await select.getOptions();
expect(options.length).toBe(3);
const sortController = component.editTaskFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(component.sortProperties.length).toBe(3);
expect(sortController.value).toBe('my-custom-sort');
expect(sortOptions.length).toEqual(3);
});
it('should display default sort properties if input is empty', async () => {
@@ -848,32 +837,34 @@ describe('EditTaskFilterCloudComponent', () => {
fixture.detectChanges();
component.sortProperties = [];
fixture.detectChanges();
await clickExpansionPanel();
const sortElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"]');
sortElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const options = await select.getOptions();
expect(options.length).toBe(4);
const sortController = component.editTaskFilterForm.get('sort');
const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text'));
expect(sortController.value).toBe('id');
expect(sortOptions.length).toEqual(4);
});
});
describe('filter actions', () => {
it('should display default filter actions', async () => {
component.toggleFilterActions = true;
component.ngOnChanges({ id: mockTaskFilterIdChange });
fixture.detectChanges();
await clickExpansionPanel();
const saveAsButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
expect(component.taskFilterActions.map(action => action.actionType)).toEqual(['save', 'saveAs', 'delete']);
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveAsButton = getFilterActionButton('saveAs');
const saveButton = getFilterActionButton('save');
const deleteButton = getFilterActionButton('delete');
expect(component.taskFilterActions.map((action) => action.actionType)).toEqual(['save', 'saveAs', 'delete']);
expect(component.taskFilterActions.length).toBe(3);
expect(saveButton.disabled).toBe(true);
expect(saveAsButton.disabled).toBe(true);
@@ -889,14 +880,16 @@ describe('EditTaskFilterCloudComponent', () => {
component.toggleFilterActions = true;
fixture.detectChanges();
await clickExpansionPanel();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
expect(component.taskFilterActions.map(action => action.actionType)).toEqual(['save']);
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = getFilterActionButton('save');
expect(component.taskFilterActions.map((action) => action.actionType)).toEqual(['save']);
expect(component.taskFilterActions.length).toBe(1);
expect(saveButton.disabled).toBeTruthy();
const saveAsButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const saveAsButton = getFilterActionButton('saveAs');
const deleteButton = getFilterActionButton('delete');
expect(saveAsButton).toBeFalsy();
expect(deleteButton).toBeFalsy();
});
@@ -928,7 +921,6 @@ describe('EditTaskFilterCloudComponent', () => {
});
describe('edit filter actions', () => {
beforeEach(() => {
component.changedTaskFilter = { name: 'mock-filter-name' } as TaskFilterCloudModel;
component.ngOnChanges({ id: mockTaskFilterIdChange } as SimpleChanges);
@@ -936,43 +928,35 @@ describe('EditTaskFilterCloudComponent', () => {
component.toggleFilterActions = true;
});
it('should emit save event and save the filter on click save button', fakeAsync(() => {
it('should emit save event and save the filter on click save button', async () => {
spyOn(service, 'updateFilter').and.returnValue(of([new TaskFilterCloudModel({ name: 'mock-filter-name' })]));
fixture.detectChanges();
const expansionPanel = nativeElement.querySelector<HTMLElement>('mat-expansion-panel-header');
expansionPanel.click();
fixture.detectChanges();
tick();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
tick();
const sortOptions = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-cloud-edit-task-property-options-sort"] .mat-option-ripple'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
tick(550);
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-save"]');
saveButton.dispatchEvent(new Event('click'));
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const options = await select.getOptions();
await options[3].click();
const saveButton = getFilterActionButton('save');
saveButton.click();
fixture.detectChanges();
tick();
expect(service.updateFilter).toHaveBeenCalled();
expect(component.action.emit).toHaveBeenCalled();
}));
});
it('should emit delete event and delete the filter on click of delete button', async () => {
spyOn(service, 'deleteFilter').and.returnValue(of(null));
fixture.detectChanges();
await clickExpansionPanel();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
expect(deleteButton.getAttribute('disabled')).toBeNull();
deleteButton.click();
expect(service.deleteFilter).toHaveBeenCalled();
@@ -982,19 +966,18 @@ describe('EditTaskFilterCloudComponent', () => {
it('should emit saveAs event and add filter on click saveAs button', async () => {
spyOn(service, 'addFilter').and.returnValue(of(null));
fixture.detectChanges();
await clickExpansionPanel();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const sortOptions = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-cloud-edit-task-property-options-sort"] .mat-option-ripple'));
sortOptions[3].nativeElement.click();
fixture.detectChanges();
await fixture.whenStable();
const select = await getSelect('adf-cloud-edit-task-property-sort');
await select.open();
const saveButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-saveAs"]');
saveButton.dispatchEvent(new Event('click'));
const options = await select.getOptions();
await options[3].click();
const saveButton = getFilterActionButton('saveAs');
saveButton.click();
fixture.detectChanges();
afterClosedSubject.next({
action: TaskFilterDialogCloudComponent.ACTION_SAVE,
@@ -1012,14 +995,11 @@ describe('EditTaskFilterCloudComponent', () => {
spyOn(service, 'deleteFilter').and.returnValue(of([]));
const restoreDefaultFiltersSpy = spyOn(component, 'restoreDefaultTaskFilters').and.returnValue(of([]));
fixture.detectChanges();
await clickExpansionPanel();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
expect(deleteButton.disabled).toBe(false);
deleteButton.click();
expect(service.deleteFilter).toHaveBeenCalled();
@@ -1031,14 +1011,11 @@ describe('EditTaskFilterCloudComponent', () => {
spyOn(service, 'deleteFilter').and.returnValue(of([new TaskFilterCloudModel({ name: 'mock-filter-name' })]));
const restoreDefaultFiltersSpy = spyOn(component, 'restoreDefaultTaskFilters').and.returnValue(of([]));
fixture.detectChanges();
await clickExpansionPanel();
const stateElement = nativeElement.querySelector<HTMLElement>('[data-automation-id="adf-cloud-edit-task-property-sort"] .mat-select-trigger');
stateElement.click();
fixture.detectChanges();
await fixture.whenStable();
const panel = await loader.getHarness(MatExpansionPanelHarness);
await panel.expand();
const deleteButton = nativeElement.querySelector<HTMLButtonElement>('[data-automation-id="adf-filter-action-delete"]');
const deleteButton = getFilterActionButton('delete');
expect(deleteButton.disabled).toBe(false);
deleteButton.click();
expect(service.deleteFilter).toHaveBeenCalled();
@@ -31,6 +31,7 @@ import { TaskFilterDialogCloudComponent } from './components/task-filter-dialog/
import { ServiceTaskFiltersCloudComponent } from './components/service-task-filters-cloud.component';
import { TaskAssignmentFilterCloudComponent } from './components/task-assignment-filter/task-assignment-filter.component';
import { GroupCloudModule } from '../../group/group-cloud.module';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
@NgModule({
imports: [
@@ -43,7 +44,8 @@ import { GroupCloudModule } from '../../group/group-cloud.module';
CoreModule,
GroupCloudModule,
ProcessCommonModule,
PeopleCloudModule
PeopleCloudModule,
MatProgressSpinnerModule
],
declarations: [
TaskFiltersCloudComponent,
@@ -53,11 +55,6 @@ import { GroupCloudModule } from '../../group/group-cloud.module';
TaskFilterDialogCloudComponent,
TaskAssignmentFilterCloudComponent
],
exports: [
TaskFiltersCloudComponent,
ServiceTaskFiltersCloudComponent,
EditTaskFilterCloudComponent,
EditServiceTaskFilterCloudComponent
]
exports: [TaskFiltersCloudComponent, ServiceTaskFiltersCloudComponent, EditTaskFilterCloudComponent, EditServiceTaskFilterCloudComponent]
})
export class TaskFiltersCloudModule { }
export class TaskFiltersCloudModule {}
@@ -63,10 +63,7 @@ describe('TaskFormComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
],
imports: [TranslateModule.forRoot(), ProcessTestingModule],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(TaskFormComponent);
@@ -92,8 +89,13 @@ describe('TaskFormComponent', () => {
fixture.destroy();
});
describe('Task with form', () => {
const getClaimButton = () =>
fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'))?.nativeElement as HTMLButtonElement;
const getUnclaimButton = () =>
fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'))?.nativeElement as HTMLButtonElement;
describe('Task with form', () => {
beforeEach(async () => {
await fixture.whenStable();
getTaskDetailsSpy.calls.reset();
@@ -117,12 +119,14 @@ describe('TaskFormComponent', () => {
});
it('Should be able to complete assigned task', async () => {
getBpmLoggedUserSpy.and.returnValue(of({
id: 1001,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
}));
getBpmLoggedUserSpy.and.returnValue(
of({
id: 1001,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
})
);
getTaskDetailsSpy.and.returnValue(of(taskDetailsMock));
const formCompletedSpy: jasmine.Spy = spyOn(component.formCompleted, 'emit');
const completeTaskFormSpy = spyOn(taskFormService, 'completeTaskForm').and.returnValue(of({}));
@@ -139,7 +143,7 @@ describe('TaskFormComponent', () => {
it('Should emit error event in case form complete service fails', async () => {
const errorSpy: jasmine.Spy = spyOn(component.error, 'emit');
const completeTaskFormSpy = spyOn(taskFormService, 'completeTaskForm').and.returnValue(throwError({message: 'servce failed'}));
const completeTaskFormSpy = spyOn(taskFormService, 'completeTaskForm').and.returnValue(throwError({ message: 'servce failed' }));
getTaskDetailsSpy.and.returnValue(of(initiatorCanCompleteTaskDetailsMock));
component.taskId = '123';
fixture.detectChanges();
@@ -155,7 +159,6 @@ describe('TaskFormComponent', () => {
});
describe('change detection', () => {
beforeEach(async () => {
component.taskId = '123';
fixture.detectChanges();
@@ -165,14 +168,14 @@ describe('TaskFormComponent', () => {
it('should fetch new task details when taskId changed', () => {
const change = new SimpleChange('123', '456', true);
component.ngOnChanges({taskId: change});
component.ngOnChanges({ taskId: change });
fixture.detectChanges();
expect(getTaskDetailsSpy).toHaveBeenCalledWith('123');
});
it('should NOT fetch new task details when taskId changed to null', async () => {
const nullChange = new SimpleChange('123', null, true);
component.ngOnChanges({taskId: nullChange});
component.ngOnChanges({ taskId: nullChange });
fixture.detectChanges();
await fixture.whenStable();
expect(getTaskDetailsSpy).not.toHaveBeenCalled();
@@ -180,7 +183,6 @@ describe('TaskFormComponent', () => {
});
describe('Task assigned to candidates', () => {
beforeEach(async () => {
component.taskId = '123';
fixture.detectChanges();
@@ -204,7 +206,6 @@ describe('TaskFormComponent', () => {
});
describe('Form events', () => {
beforeEach(() => {
component.taskId = '123';
fixture.detectChanges();
@@ -259,7 +260,6 @@ describe('TaskFormComponent', () => {
});
describe('Completed Process Task', () => {
beforeEach(async () => {
component.taskId = '123';
fixture.detectChanges();
@@ -307,7 +307,6 @@ describe('TaskFormComponent', () => {
});
describe('Process Task with no form', () => {
beforeEach(() => {
component.taskId = '123';
fixture.detectChanges();
@@ -348,7 +347,7 @@ describe('TaskFormComponent', () => {
it('Should emit error event in case complete task service fails', async () => {
const errorSpy: jasmine.Spy = spyOn(component.error, 'emit');
completeTaskSpy.and.returnValue(throwError({message: 'servce failed'}));
completeTaskSpy.and.returnValue(throwError({ message: 'servce failed' }));
component.taskDetails = new TaskDetailsModel(taskDetailsWithOutFormMock);
fixture.detectChanges();
await fixture.whenStable();
@@ -403,7 +402,6 @@ describe('TaskFormComponent', () => {
});
describe('Standalone Task with no form', () => {
beforeEach(() => {
component.taskId = '123';
fixture.detectChanges();
@@ -470,7 +468,6 @@ describe('TaskFormComponent', () => {
});
describe('Form with visibility', () => {
beforeEach(async () => {
component.taskId = '123';
spyOn(taskFormService, 'completeTaskForm').and.returnValue(of({}));
@@ -548,14 +545,15 @@ describe('TaskFormComponent', () => {
});
describe('Complete task', () => {
it('Should be able to complete the assigned task in case process initiator not allowed to complete the task', async () => {
getBpmLoggedUserSpy.and.returnValue(of({
id: 1002,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
}));
getBpmLoggedUserSpy.and.returnValue(
of({
id: 1002,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
})
);
getTaskDetailsSpy.and.returnValue(of(taskDetailsMock));
const formCompletedSpy: jasmine.Spy = spyOn(component.formCompleted, 'emit');
@@ -578,12 +576,14 @@ describe('TaskFormComponent', () => {
});
it('Should be able to complete the task if process initiator allowed to complete the task', async () => {
getBpmLoggedUserSpy.and.returnValue(of({
id: 1001,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
}));
getBpmLoggedUserSpy.and.returnValue(
of({
id: 1001,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
})
);
const formCompletedSpy: jasmine.Spy = spyOn(component.formCompleted, 'emit');
const completeTaskFormSpy = spyOn(taskFormService, 'completeTaskForm').and.returnValue(of({}));
getTaskDetailsSpy.and.returnValue(of(initiatorCanCompleteTaskDetailsMock));
@@ -625,12 +625,14 @@ describe('TaskFormComponent', () => {
it('Should be able to complete a task with candidates users if process initiator not allowed to complete the task', async () => {
const formCompletedSpy: jasmine.Spy = spyOn(component.formCompleted, 'emit');
getBpmLoggedUserSpy.and.returnValue(of({
id: 1001,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
}));
getBpmLoggedUserSpy.and.returnValue(
of({
id: 1001,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.activiti.com'
})
);
const completeTaskFormSpy = spyOn(taskFormService, 'completeTaskForm').and.returnValue(of({}));
getTaskDetailsSpy.and.returnValue(of(claimedTaskDetailsMock));
@@ -654,7 +656,6 @@ describe('TaskFormComponent', () => {
});
describe('Claim/Unclaim buttons', () => {
it('should display the claim button if no assignee', async () => {
getTaskDetailsSpy.and.returnValue(of(claimableTaskDetailsMock));
@@ -662,8 +663,8 @@ describe('TaskFormComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_FORM.EMPTY_FORM.BUTTONS.CLAIM');
const claimButton = getClaimButton();
expect(claimButton.innerText).toBe('ADF_TASK_FORM.EMPTY_FORM.BUTTONS.CLAIM');
});
it('should not display the claim/requeue button if the task is not claimable ', async () => {
@@ -673,13 +674,13 @@ describe('TaskFormComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const unclaimButton = getUnclaimButton();
expect(component.isTaskClaimable()).toBe(false);
expect(component.isTaskClaimedByCandidateMember()).toBe(false);
expect(unclaimButton).toBeNull();
expect(claimButton).toBeNull();
expect(unclaimButton).toBeUndefined();
expect(claimButton).toBeUndefined();
});
it('should display the claim button if the task is claimable', async () => {
@@ -689,10 +690,10 @@ describe('TaskFormComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const claimButton = getClaimButton();
expect(component.isTaskClaimable()).toBe(true);
expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_FORM.EMPTY_FORM.BUTTONS.CLAIM');
expect(claimButton.innerText).toBe('ADF_TASK_FORM.EMPTY_FORM.BUTTONS.CLAIM');
});
it('should display the release button if task is claimed by the current logged-in user', async () => {
@@ -703,10 +704,10 @@ describe('TaskFormComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const unclaimButton = getUnclaimButton();
expect(component.isTaskClaimedByCandidateMember()).toBe(true);
expect(unclaimButton.nativeElement.innerText).toBe('ADF_TASK_FORM.EMPTY_FORM.BUTTONS.UNCLAIM');
expect(unclaimButton.innerText).toBe('ADF_TASK_FORM.EMPTY_FORM.BUTTONS.UNCLAIM');
});
it('should not display the release button to logged in user if task is claimed by other candidate member', async () => {
@@ -716,10 +717,10 @@ describe('TaskFormComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const unclaimButton = getUnclaimButton();
expect(component.isTaskClaimedByCandidateMember()).toBe(false);
expect(unclaimButton).toBeNull();
expect(unclaimButton).toBeUndefined();
});
it('should not display the release button if the task is completed', async () => {
@@ -729,11 +730,11 @@ describe('TaskFormComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const unclaimButton = getUnclaimButton();
expect(claimButton).toBeNull();
expect(unclaimButton).toBeNull();
expect(claimButton).toBeUndefined();
expect(unclaimButton).toBeUndefined();
});
it('should emit taskClaimed when task is claimed', (done) => {
@@ -755,7 +756,7 @@ describe('TaskFormComponent', () => {
});
it('should emit error event in case claim task api fails', (done) => {
const mockError = {message: 'Api Failed'};
const mockError = { message: 'Api Failed' };
spyOn(taskListService, 'claimTask').and.returnValue(throwError(mockError));
getTaskDetailsSpy.and.returnValue(of(claimableTaskDetailsMock));
@@ -793,7 +794,7 @@ describe('TaskFormComponent', () => {
});
it('should emit error event in case unclaim task api fails', (done) => {
const mockError = {message: 'Api Failed'};
const mockError = { message: 'Api Failed' };
spyOn(taskListService, 'unclaimTask').and.returnValue(throwError(mockError));
getBpmLoggedUserSpy.and.returnValue(of(claimedTaskDetailsMock.assignee));
getTaskDetailsSpy.and.returnValue(of(claimedTaskDetailsMock));
@@ -814,7 +815,6 @@ describe('TaskFormComponent', () => {
});
describe('Involved user task', () => {
beforeEach(() => {
component.taskId = '20259';
spyOn(taskFormService, 'saveTaskForm').and.returnValue(of({}));
@@ -857,7 +857,6 @@ describe('TaskFormComponent', () => {
});
describe('Task Form Fields Visibility', () => {
it('Should task form fields be disabled when the form is readonly', async () => {
fixture.detectChanges();
getTaskDetailsSpy.and.returnValue(of(taskDetailsMock));
@@ -874,9 +873,9 @@ describe('TaskFormComponent', () => {
const inputFieldTwo = fixture.debugElement.nativeElement.querySelector('#text2');
const inputFieldThree = fixture.debugElement.nativeElement.querySelector('#text3');
expect(formSelector).toBeDefined();
expect(inputFieldOne['disabled']).toEqual(true, 'Task Form field is enabled');
expect(inputFieldTwo['disabled']).toEqual(true, 'Task Form field is enabled');
expect(inputFieldThree['disabled']).toEqual(true, 'Task Form field is enabled');
expect(inputFieldOne['disabled']).toEqual(true);
expect(inputFieldTwo['disabled']).toEqual(true);
expect(inputFieldThree['disabled']).toEqual(true);
});
it('Should task form fields be disabled when the task has not been claimed', async () => {
@@ -894,9 +893,9 @@ describe('TaskFormComponent', () => {
const inputFieldTwo = fixture.debugElement.nativeElement.querySelector('#text2');
const inputFieldThree = fixture.debugElement.nativeElement.querySelector('#text3');
expect(formSelector).toBeDefined();
expect(inputFieldOne['disabled']).toEqual(true, 'Task Form field is enabled');
expect(inputFieldTwo['disabled']).toEqual(true, 'Task Form field is enabled');
expect(inputFieldThree['disabled']).toEqual(true, 'Task Form field is enabled');
expect(inputFieldOne['disabled']).toEqual(true);
expect(inputFieldTwo['disabled']).toEqual(true);
expect(inputFieldThree['disabled']).toEqual(true);
});
it('Should task form fields be disabled when the task is completed', async () => {
@@ -935,14 +934,13 @@ describe('TaskFormComponent', () => {
const inputFieldThree = fixture.debugElement.nativeElement.querySelector('#text3');
expect(formSelector).toBeDefined();
expect(inputFieldOne['disabled']).toEqual(false, 'Task Form field is disabled');
expect(inputFieldTwo['disabled']).toEqual(false, 'Task Form field is disabled');
expect(inputFieldThree['disabled']).toEqual(false, 'Task Form field is disabled');
expect(inputFieldOne['disabled']).toEqual(false);
expect(inputFieldTwo['disabled']).toEqual(false);
expect(inputFieldThree['disabled']).toEqual(false);
});
});
describe('Task form action buttons', () => {
it('Should disable Complete button when candidate user is not have a access to the task claimed by another candidate user', async () => {
getTaskDetailsSpy.and.returnValue(of(involvedUserTaskForm));
component.taskId = 'mock-task-id';
@@ -951,15 +949,15 @@ describe('TaskFormComponent', () => {
const saveButton = fixture.debugElement.nativeElement.querySelector('[id="adf-form-save"]');
const completeButton = fixture.debugElement.nativeElement.querySelector('#adf-form-complete');
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const releaseButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const releaseButton = getUnclaimButton();
expect(saveButton).not.toBeNull();
expect(saveButton['disabled']).toBe(false, 'Save button is disabled');
expect(saveButton['disabled']).toBe(false);
expect(completeButton).not.toBeNull();
expect(completeButton['disabled']).toBe(true, 'Complete button is disabled');
expect(claimButton).toBeNull();
expect(releaseButton).toBeNull();
expect(completeButton['disabled']).toBe(true);
expect(claimButton).toBeUndefined();
expect(releaseButton).toBeUndefined();
});
it('Should show only the Claim button as enabled before claiming a task with form', async () => {
@@ -970,16 +968,16 @@ describe('TaskFormComponent', () => {
const saveButton = fixture.debugElement.nativeElement.querySelector('[id="adf-form-save"]');
const completeButton = fixture.debugElement.nativeElement.querySelector('#adf-form-complete');
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const releaseButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const releaseButton = getUnclaimButton();
expect(saveButton).not.toBeNull();
expect(saveButton['disabled']).toBe(true, 'Save button is enabled');
expect(saveButton['disabled']).toBe(true);
expect(completeButton).not.toBeNull();
expect(completeButton['disabled']).toBe(true, 'Complete button is enabled');
expect(completeButton['disabled']).toBe(true);
expect(claimButton).not.toBeNull();
expect(claimButton.nativeElement.disabled).toBe(false, 'Claim button is disabled');
expect(releaseButton).toBeNull();
expect(claimButton.disabled).toBe(false);
expect(releaseButton).toBeUndefined();
});
it('Should show only Save/Complete/Release buttons as enabled after claiming a task with form', async () => {
@@ -991,20 +989,20 @@ describe('TaskFormComponent', () => {
const saveButton = fixture.debugElement.nativeElement.querySelector('[id="adf-form-save"]');
const completeButton = fixture.debugElement.nativeElement.querySelector('#adf-form-complete');
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const releaseButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const releaseButton = getUnclaimButton();
expect(saveButton).not.toBeNull();
expect(saveButton['disabled']).toBe(false, 'Save button is disabled');
expect(saveButton['disabled']).toBe(false);
expect(completeButton).not.toBeNull();
expect(completeButton['disabled']).toBe(false, 'Complete button is disabled');
expect(completeButton['disabled']).toBe(false);
expect(releaseButton).not.toBeNull();
expect(releaseButton.nativeElement.disabled).toBe(false, 'Release button is disabled');
expect(claimButton).toBeNull();
expect(releaseButton.disabled).toBe(false);
expect(claimButton).toBeUndefined();
});
it('Should show only the Claim button as enabled before claiming a task without form', async () => {
const claimableTaskDetailsWithoutFormMock = {...claimableTaskDetailsMock, formKey: null};
const claimableTaskDetailsWithoutFormMock = { ...claimableTaskDetailsMock, formKey: null };
getTaskDetailsSpy.and.returnValue(of(claimableTaskDetailsWithoutFormMock));
component.taskId = 'mock-task-id';
fixture.detectChanges();
@@ -1012,19 +1010,19 @@ describe('TaskFormComponent', () => {
const cancelButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-cancel-button');
const completeButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-complete-button');
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const releaseButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const releaseButton = getUnclaimButton();
expect(cancelButton).not.toBeNull();
expect(completeButton).not.toBeNull();
expect(completeButton['disabled']).toEqual(true, 'Complete button is enabled');
expect(completeButton['disabled']).toEqual(true);
expect(claimButton).not.toBeNull();
expect(claimButton.nativeElement.disabled).toBe(false, 'Claim button is disabled');
expect(releaseButton).toBeNull();
expect(claimButton.disabled).toBe(false);
expect(releaseButton).toBeUndefined();
});
it('Should show only Complete/Release buttons as enabled after claiming a task without form', async () => {
const claimedTaskDetailsWithoutFormMock = {...claimedTaskDetailsMock, formKey: null};
const claimedTaskDetailsWithoutFormMock = { ...claimedTaskDetailsMock, formKey: null };
getBpmLoggedUserSpy.and.returnValue(of(claimedTaskDetailsWithoutFormMock.assignee));
getTaskDetailsSpy.and.returnValue(of(claimedTaskDetailsWithoutFormMock));
component.taskId = 'mock-task-id';
@@ -1033,15 +1031,15 @@ describe('TaskFormComponent', () => {
const cancelButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-cancel-button');
const completeButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-complete-button');
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]'));
const releaseButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]'));
const claimButton = getClaimButton();
const releaseButton = getUnclaimButton();
expect(cancelButton).not.toBeNull();
expect(completeButton).not.toBeNull();
expect(completeButton['disabled']).toEqual(false, 'Complete button is disabled');
expect(completeButton['disabled']).toEqual(false);
expect(releaseButton).not.toBeNull();
expect(releaseButton.nativeElement.disabled).toBe(false, 'Release button is disabled');
expect(claimButton).toBeNull();
expect(releaseButton.disabled).toBe(false);
expect(claimButton).toBeUndefined();
});
});
});
@@ -37,7 +37,6 @@ import { PeopleProcessService } from '../../common/services/people-process.servi
import { BpmUserModel } from '../../common/models/bpm-user.model';
describe('TaskHeaderComponent', () => {
let service: TaskListService;
let component: TaskHeaderComponent;
let fixture: ComponentFixture<TaskHeaderComponent>;
@@ -60,10 +59,7 @@ describe('TaskHeaderComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ProcessTestingModule
]
imports: [TranslateModule.forRoot(), ProcessTestingModule]
});
fixture = TestBed.createComponent(TaskHeaderComponent);
component = fixture.componentInstance;
@@ -74,6 +70,11 @@ describe('TaskHeaderComponent', () => {
appConfigService = TestBed.inject(AppConfigService);
});
const getClaimButton = () => fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'))?.nativeElement as HTMLButtonElement;
const getUnclaimButton = () =>
fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'))?.nativeElement as HTMLButtonElement;
it('should render empty component if no task details provided', async () => {
component.taskDetails = undefined;
@@ -138,7 +139,6 @@ describe('TaskHeaderComponent', () => {
});
describe('Claiming', () => {
it('should be able display the claim/release button if showClaimRelease set to true', async () => {
component.taskDetails = new TaskDetailsModel(claimableTaskDetailsMock);
component.showClaimRelease = true;
@@ -147,8 +147,8 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
const claimButton = getClaimButton();
expect(claimButton.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
});
it('should not be able display the claim/release button if showClaimRelease set to false', async () => {
@@ -159,8 +159,8 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
expect(claimButton).toBeNull();
const claimButton = getClaimButton();
expect(claimButton).toBeUndefined();
});
it('should display the claim button if no assignee', async () => {
@@ -171,8 +171,8 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
const claimButton = getClaimButton();
expect(claimButton.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
});
it('should display the claim button if the task is claimable', async () => {
@@ -182,9 +182,9 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
const claimButton = getClaimButton();
expect(component.isTaskClaimable()).toBeTruthy();
expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
expect(claimButton.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
});
it('should not display the claim/requeue button if the task is not claimable ', async () => {
@@ -194,12 +194,12 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'));
const claimButton = getClaimButton();
const unclaimButton = getUnclaimButton();
expect(component.isTaskClaimable()).toBeFalsy();
expect(component.isTaskClaimedByCandidateMember()).toBeFalsy();
expect(unclaimButton).toBeNull();
expect(claimButton).toBeNull();
expect(unclaimButton).toBeUndefined();
expect(claimButton).toBeUndefined();
});
});
@@ -210,9 +210,9 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'));
const unclaimButton = getUnclaimButton();
expect(component.isTaskClaimedByCandidateMember()).toBeTruthy();
expect(unclaimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.UNCLAIM');
expect(unclaimButton.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.UNCLAIM');
});
it('should not display the requeue button to logged in user if task is claimed by other candidate member', async () => {
@@ -222,9 +222,9 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'));
const unclaimButton = getUnclaimButton();
expect(component.isTaskClaimedByCandidateMember()).toBeFalsy();
expect(unclaimButton).toBeNull();
expect(unclaimButton).toBeUndefined();
});
it('should display the claim button if the task is claimable by candidates members', async () => {
@@ -234,10 +234,10 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
const claimButton = getClaimButton();
expect(component.isTaskClaimable()).toBeTruthy();
expect(component.isTaskClaimedByCandidateMember()).toBeFalsy();
expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
expect(claimButton.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM');
});
it('should not display the requeue button if the task is completed', async () => {
@@ -247,10 +247,10 @@ describe('TaskHeaderComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'));
expect(claimButton).toBeNull();
expect(unclaimButton).toBeNull();
const claimButton = getClaimButton();
const unclaimButton = getUnclaimButton();
expect(claimButton).toBeUndefined();
expect(unclaimButton).toBeUndefined();
});
it('should emit claim event when task is claimed', (done) => {
@@ -367,7 +367,6 @@ describe('TaskHeaderComponent', () => {
});
describe('Config Filtering', () => {
it('should show only the properties from the configuration file', async () => {
spyOn(appConfigService, 'get').and.returnValue(['assignee', 'status']);
component.taskDetails.processInstanceId = '1';
@@ -21,15 +21,14 @@ import { BrowserVisibility } from '../../../core/utils/browser-visibility';
import { BrowserActions } from '../../../core/utils/browser-actions';
export class DateRangeFilterPage {
fromField = 'input[data-automation-id="date-range-from-input"]';
fromDateToggle = 'mat-datepicker-toggle[data-automation-id="date-range-from-date-toggle"]';
toField = 'input[data-automation-id="date-range-to-input"]';
toDateToggle = 'mat-datepicker-toggle[data-automation-id="date-range-to-date-toggle"]';
applyButton = 'button[data-automation-id="date-range-apply-btn"]';
clearButton = 'button[data-automation-id="date-range-clear-btn"]';
fromErrorMessage = 'mat-error[data-automation-id="date-range-from-error"]';
toErrorMessage = 'mat-error[data-automation-id="date-range-to-error"]';
fromField = '[data-automation-id="date-range-from-input"]';
fromDateToggle = '[data-automation-id="date-range-from-date-toggle"]';
toField = '[data-automation-id="date-range-to-input"]';
toDateToggle = '[data-automation-id="date-range-to-date-toggle"]';
applyButton = '[data-automation-id="date-range-apply-btn"]';
clearButton = '[data-automation-id="date-range-clear-btn"]';
fromErrorMessage = '[data-automation-id="date-range-from-error"]';
toErrorMessage = '[data-automation-id="date-range-to-error"]';
filter: ElementFinder;
constructor(filter: ElementFinder) {
@@ -139,5 +138,4 @@ export class DateRangeFilterPage {
async checkClearButtonIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.filter.$(this.clearButton));
}
}
@@ -20,15 +20,14 @@ import { BrowserActions } from '../../../core/utils/browser-actions';
import { BrowserVisibility } from '../../../core/utils/browser-visibility';
export class NumberRangeFilterPage {
fromInput = 'input[data-automation-id="number-range-from-input"]';
toInput = 'input[data-automation-id="number-range-to-input"]';
applyButton = 'button[data-automation-id="number-range-btn-apply"]';
clearButton = 'button[data-automation-id="number-range-btn-clear"]';
fromErrorInvalid = 'mat-error[data-automation-id="number-range-from-error-invalid"]';
fromErrorRequired = 'mat-error[data-automation-id="number-range-from-error-required"]';
toErrorInvalid = 'mat-error[data-automation-id="number-range-to-error-invalid"]';
toErrorRequired = 'mat-error[data-automation-id="number-range-to-error-required"]';
fromInput = '[data-automation-id="number-range-from-input"]';
toInput = '[data-automation-id="number-range-to-input"]';
applyButton = '[data-automation-id="number-range-btn-apply"]';
clearButton = '[data-automation-id="number-range-btn-clear"]';
fromErrorInvalid = '[data-automation-id="number-range-from-error-invalid"]';
fromErrorRequired = '[data-automation-id="number-range-from-error-required"]';
toErrorInvalid = '[data-automation-id="number-range-to-error-invalid"]';
toErrorRequired = '[data-automation-id="number-range-to-error-required"]';
filter: ElementFinder;
constructor(filter: ElementFinder) {