diff --git a/lib/content-services/src/lib/aspect-list/aspect-list.component.html b/lib/content-services/src/lib/aspect-list/aspect-list.component.html
index e97c642cb29..abb8cb0c511 100644
--- a/lib/content-services/src/lib/aspect-list/aspect-list.component.html
+++ b/lib/content-services/src/lib/aspect-list/aspect-list.component.html
@@ -8,7 +8,7 @@
(click)="onCheckBoxClick($event)"
(change)="onChange($event, aspect?.entry?.id)">
{{getTitle(aspect)}}
-
+
@@ -39,6 +39,6 @@
-
+
diff --git a/lib/content-services/src/lib/aspect-list/aspect-list.component.spec.ts b/lib/content-services/src/lib/aspect-list/aspect-list.component.spec.ts
index 289aa37ea74..87b77c5a1db 100644
--- a/lib/content-services/src/lib/aspect-list/aspect-list.component.spec.ts
+++ b/lib/content-services/src/lib/aspect-list/aspect-list.component.spec.ts
@@ -24,86 +24,96 @@ import { AspectListService } from './services/aspect-list.service';
import { of } from 'rxjs';
import { AspectEntry } from '@alfresco/js-api';
import { delay } from 'rxjs/operators';
+import { HarnessLoader } from '@angular/cdk/testing';
+import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
+import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
+import { MatTableHarness } from '@angular/material/table/testing';
+import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
+import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
-const aspectListMock: AspectEntry[] = [{
- entry: {
- parentId: 'frs:aspectZero',
- id: 'frs:AspectOne',
- description: 'First Aspect with random description',
- title: 'FirstAspect',
- properties: [
- {
- id: 'channelPassword',
- title: 'The authenticated channel password',
- dataType: 'd:propA'
- },
- {
- id: 'channelUsername',
- title: 'The authenticated channel username',
- dataType: 'd:propB'
- }
- ]
+const aspectListMock: AspectEntry[] = [
+ {
+ entry: {
+ parentId: 'frs:aspectZero',
+ id: 'frs:AspectOne',
+ description: 'First Aspect with random description',
+ title: 'FirstAspect',
+ properties: [
+ {
+ id: 'channelPassword',
+ title: 'The authenticated channel password',
+ dataType: 'd:propA'
+ },
+ {
+ id: 'channelUsername',
+ title: 'The authenticated channel username',
+ dataType: 'd:propB'
+ }
+ ]
+ }
+ },
+ {
+ entry: {
+ parentId: 'frs:AspectZer',
+ id: 'frs:SecondAspect',
+ description: 'Second Aspect description',
+ title: 'SecondAspect',
+ properties: [
+ {
+ id: 'assetId',
+ title: 'Published Asset Id',
+ dataType: 'd:text'
+ },
+ {
+ id: 'assetUrl',
+ title: 'Published Asset URL',
+ dataType: 'd:text'
+ }
+ ]
+ }
}
-},
-{
- entry: {
- parentId: 'frs:AspectZer',
- id: 'frs:SecondAspect',
- description: 'Second Aspect description',
- title: 'SecondAspect',
- properties: [
- {
- id: 'assetId',
- title: 'Published Asset Id',
- dataType: 'd:text'
- },
- {
- id: 'assetUrl',
- title: 'Published Asset URL',
- dataType: 'd:text'
- }
- ]
- }
-}];
-
-const customAspectListMock: AspectEntry[] = [{
- entry: {
- parentId: 'cst:parentAspect',
- id: 'cst:customAspect',
- description: 'Custom Aspect with random description',
- title: 'CustomAspect',
- properties: [
- {
- id: 'channelPassword',
- title: 'The authenticated channel password',
- dataType: 'd:propA'
- },
- {
- id: 'channelUsername',
- title: 'The authenticated channel username',
- dataType: 'd:propB'
- }
- ]
- }
-},
-{
- entry: {
- parentId: 'cst:commonaspect',
- id: 'cst:nonamedAspect',
- description: '',
- title: '',
- properties: [
- {
- id: 'channelPassword',
- title: 'The authenticated channel password',
- dataType: 'd:propA'
- }
- ]
+];
+
+const customAspectListMock: AspectEntry[] = [
+ {
+ entry: {
+ parentId: 'cst:parentAspect',
+ id: 'cst:customAspect',
+ description: 'Custom Aspect with random description',
+ title: 'CustomAspect',
+ properties: [
+ {
+ id: 'channelPassword',
+ title: 'The authenticated channel password',
+ dataType: 'd:propA'
+ },
+ {
+ id: 'channelUsername',
+ title: 'The authenticated channel username',
+ dataType: 'd:propB'
+ }
+ ]
+ }
+ },
+ {
+ entry: {
+ parentId: 'cst:commonaspect',
+ id: 'cst:nonamedAspect',
+ description: '',
+ title: '',
+ properties: [
+ {
+ id: 'channelPassword',
+ title: 'The authenticated channel password',
+ dataType: 'd:propA'
+ }
+ ]
+ }
}
-}];
+];
describe('AspectListComponent', () => {
-
+ let loader: HarnessLoader;
let component: AspectListComponent;
let fixture: ComponentFixture;
let aspectListService: AspectListService;
@@ -111,36 +121,31 @@ describe('AspectListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- imports: [
- TranslateModule.forRoot(),
- ContentTestingModule
- ],
+ imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [AspectListService]
});
});
describe('Loading', () => {
-
beforeEach(() => {
fixture = TestBed.createComponent(AspectListComponent);
component = fixture.componentInstance;
nodeService = TestBed.inject(NodesApiService);
aspectListService = TestBed.inject(AspectListService);
+ loader = TestbedHarnessEnvironment.loader(fixture);
});
- it('should show the loading spinner when result is loading', () => {
+ it('should show the loading spinner when result is loading', async () => {
const delayResult = of(null).pipe(delay(0));
spyOn(nodeService, 'getNode').and.returnValue(delayResult);
spyOn(aspectListService, 'getAspects').and.returnValue(delayResult);
fixture.detectChanges();
- const spinner = fixture.nativeElement.querySelector('#adf-aspect-spinner');
- expect(spinner).toBeDefined();
- expect(spinner).not.toBeNull();
+
+ expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(true);
});
});
describe('When passing a node id', () => {
-
beforeEach(() => {
fixture = TestBed.createComponent(AspectListComponent);
component = fixture.componentInstance;
@@ -152,6 +157,7 @@ describe('AspectListComponent', () => {
spyOn(nodeService, 'getNode').and.returnValue(of({ id: 'fake-node-id', aspectNames: ['frs:AspectOne'] } as any));
component.nodeId = 'fake-node-id';
fixture.detectChanges();
+ loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -167,106 +173,80 @@ describe('AspectListComponent', () => {
expect(component.hasEqualAspect).toBe(false);
});
- it('should show all the aspects', () => {
- const firstElement = fixture.nativeElement.querySelector('#aspect-list-FirstAspect');
- const secondElement = fixture.nativeElement.querySelector('#aspect-list-SecondAspect');
-
- expect(firstElement).not.toBeNull();
- expect(firstElement).toBeDefined();
- expect(secondElement).not.toBeNull();
- expect(secondElement).toBeDefined();
+ it('should show all the aspects', async () => {
+ expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-FirstAspect' }))).toBe(true);
+ expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-SecondAspect' }))).toBe(true);
});
it('should show aspect id when name or title is not set', () => {
- const noNameAspect: HTMLElement = fixture.nativeElement.querySelector('#aspect-list-cst-nonamedAspect .adf-aspect-list-element-title');
+ const noNameAspect = fixture.nativeElement.querySelector('#aspect-list-cst-nonamedAspect .adf-aspect-list-element-title');
expect(noNameAspect).toBeDefined();
expect(noNameAspect).not.toBeNull();
expect(noNameAspect.innerText).toBe('cst:nonamedAspect');
});
- it('should show the details when a row is clicked', () => {
- const firstElement = fixture.nativeElement.querySelector('#aspect-list-FirstAspect');
- firstElement.click();
- fixture.detectChanges();
- const firstElementDesc = fixture.nativeElement.querySelector('#aspect-list-0-description');
- expect(firstElementDesc).not.toBeNull();
- expect(firstElementDesc).toBeDefined();
-
- const firstElementPropertyTable = fixture.nativeElement.querySelector('#aspect-list-0-properties-table');
- expect(firstElementPropertyTable).not.toBeNull();
- expect(firstElementPropertyTable).toBeDefined();
- const nameProperties = fixture.nativeElement.querySelectorAll('#aspect-list-0-properties-table tbody .mat-column-name');
- expect(nameProperties[0]).not.toBeNull();
- expect(nameProperties[0]).toBeDefined();
- expect(nameProperties[0].innerText).toBe('channelPassword');
- expect(nameProperties[1]).not.toBeNull();
- expect(nameProperties[1]).toBeDefined();
- expect(nameProperties[1].innerText).toBe('channelUsername');
-
- const titleProperties = fixture.nativeElement.querySelectorAll('#aspect-list-0-properties-table tbody .mat-column-title');
- expect(titleProperties[0]).not.toBeNull();
- expect(titleProperties[0]).toBeDefined();
- expect(titleProperties[0].innerText).toBe('The authenticated channel password');
- expect(titleProperties[1]).not.toBeNull();
- expect(titleProperties[1]).toBeDefined();
- expect(titleProperties[1].innerText).toBe('The authenticated channel username');
-
- const dataTypeProperties = fixture.nativeElement.querySelectorAll('#aspect-list-0-properties-table tbody .mat-column-dataType');
- expect(dataTypeProperties[0]).not.toBeNull();
- expect(dataTypeProperties[0]).toBeDefined();
- expect(dataTypeProperties[0].innerText).toBe('d:propA');
- expect(dataTypeProperties[1]).not.toBeNull();
- expect(dataTypeProperties[1]).toBeDefined();
- expect(dataTypeProperties[1].innerText).toBe('d:propB');
+ it('should show the details when a row is clicked', async () => {
+ const panel = await loader.getHarness(MatExpansionPanelHarness);
+ await panel.expand();
+ expect(await panel.getDescription()).not.toBeNull();
+
+ const table = await panel.getHarness(MatTableHarness);
+ const [row1, row2] = await table.getRows();
+ const [r1c1, r1c2, r1c3] = await row1.getCells();
+ expect(await r1c1.getText()).toBe('channelPassword');
+ expect(await r1c2.getText()).toBe('The authenticated channel password');
+ expect(await r1c3.getText()).toBe('d:propA');
+
+ const [r2c1, r2c2, r2c3] = await row2.getCells();
+ expect(await r2c1.getText()).toBe('channelUsername');
+ expect(await r2c2.getText()).toBe('The authenticated channel username');
+ expect(await r2c3.getText()).toBe('d:propB');
});
- it('should show as checked the node properties', () => {
- const firstAspectCheckbox: HTMLInputElement = fixture.nativeElement.querySelector('#aspect-list-0-check-input');
- expect(firstAspectCheckbox).toBeDefined();
- expect(firstAspectCheckbox).not.toBeNull();
- expect(firstAspectCheckbox.checked).toBeTruthy();
+ it('should show as checked the node properties', async () => {
+ const panel = await loader.getHarness(MatExpansionPanelHarness);
+ await panel.expand();
+
+ const checkbox = await panel.getHarness(MatCheckboxHarness);
+ expect(await checkbox.isChecked()).toBe(true);
});
- it('should remove aspects unchecked', (done) => {
- const secondElement = fixture.nativeElement.querySelector('#aspect-list-1-check-input');
- expect(secondElement).toBeDefined();
- expect(secondElement).not.toBeNull();
- expect(secondElement.checked).toBeFalsy();
- secondElement.click();
- fixture.detectChanges();
+ it('should remove aspects unchecked', async () => {
+ const panel = await loader.getAllHarnesses(MatExpansionPanelHarness);
+ await panel[1].expand();
+
+ const checkbox = await panel[1].getHarness(MatCheckboxHarness);
+ expect(await checkbox.isChecked()).toBe(false);
+
+ await checkbox.toggle();
+
expect(component.nodeAspects.length).toBe(2);
expect(component.nodeAspects[1]).toBe('frs:SecondAspect');
- component.valueChanged.subscribe((aspects) => {
- expect(aspects.length).toBe(1);
- expect(aspects[0]).toBe('frs:AspectOne');
- done();
- });
- secondElement.click();
- fixture.detectChanges();
+
+ await checkbox.toggle();
+
+ expect(component.nodeAspects.length).toBe(1);
+ expect(component.nodeAspects[0]).toBe('frs:AspectOne');
});
- it('should reset the properties on reset', (done) => {
- const secondElement = fixture.nativeElement.querySelector('#aspect-list-1-check-input');
- expect(secondElement).toBeDefined();
- expect(secondElement).not.toBeNull();
- expect(secondElement.checked).toBeFalsy();
- secondElement.click();
- fixture.detectChanges();
+ it('should reset the properties on reset', async () => {
+ const panel = await loader.getAllHarnesses(MatExpansionPanelHarness);
+ await panel[1].expand();
+
+ const checkbox = await panel[1].getHarness(MatCheckboxHarness);
+ expect(await checkbox.isChecked()).toBe(false);
+
+ await checkbox.toggle();
+
expect(component.nodeAspects.length).toBe(2);
- component.valueChanged.subscribe((aspects) => {
- expect(aspects.length).toBe(1);
- done();
- });
component.reset();
+ expect(component.nodeAspects.length).toBe(1);
});
- it('should clear all the properties on clear', (done) => {
+ it('should clear all the properties on clear', async () => {
expect(component.nodeAspects.length).toBe(1);
- component.valueChanged.subscribe((aspects) => {
- expect(aspects.length).toBe(0);
- done();
- });
component.clear();
+ expect(component.nodeAspects.length).toBe(0);
});
});
@@ -277,21 +257,16 @@ describe('AspectListComponent', () => {
aspectListService = TestBed.inject(AspectListService);
spyOn(aspectListService, 'getAspects').and.returnValue(of(aspectListMock));
fixture.detectChanges();
+ loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
fixture.destroy();
});
- it('should show all the aspects', () => {
- const firstElement = fixture.nativeElement.querySelector('#aspect-list-FirstAspect');
- const secondElement = fixture.nativeElement.querySelector('#aspect-list-SecondAspect');
-
- expect(firstElement).not.toBeNull();
- expect(firstElement).toBeDefined();
- expect(secondElement).not.toBeNull();
- expect(secondElement).toBeDefined();
+ it('should show all the aspects', async () => {
+ expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-FirstAspect' }))).toBe(true);
+ expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-SecondAspect' }))).toBe(true);
});
});
-
});
diff --git a/lib/content-services/src/lib/category/categories-management/categories-management.component.html b/lib/content-services/src/lib/category/categories-management/categories-management.component.html
index 516f0acca93..f0ca8efe99f 100644
--- a/lib/content-services/src/lib/category/categories-management/categories-management.component.html
+++ b/lib/content-services/src/lib/category/categories-management/categories-management.component.html
@@ -71,7 +71,8 @@
[value]="category">
{{ category.name }}
-
+
{{ 'CATEGORIES_MANAGEMENT.NO_EXISTING_CATEGORIES' | translate }}
diff --git a/lib/content-services/src/lib/category/categories-management/categories-management.component.spec.ts b/lib/content-services/src/lib/category/categories-management/categories-management.component.spec.ts
index d7e3801e14f..e7e88da813a 100644
--- a/lib/content-services/src/lib/category/categories-management/categories-management.component.spec.ts
+++ b/lib/content-services/src/lib/category/categories-management/categories-management.component.spec.ts
@@ -16,7 +16,6 @@
*/
import { Category, CategoryPaging, ResultNode, ResultSetPaging } from '@alfresco/js-api';
-import { DebugElement } from '@angular/core';
import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { Validators } from '@angular/forms';
import { MatError } from '@angular/material/form-field';
@@ -28,8 +27,12 @@ import { ContentTestingModule } from '../../testing/content.testing.module';
import { CategoriesManagementMode } from './categories-management-mode';
import { CategoryService } from '../services/category.service';
import { CategoriesManagementComponent } from './categories-management.component';
+import { HarnessLoader } from '@angular/cdk/testing';
+import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
+import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
describe('CategoriesManagementComponent', () => {
+ let loader: HarnessLoader;
let component: CategoriesManagementComponent;
let fixture: ComponentFixture;
let categoryService: CategoryService;
@@ -38,18 +41,15 @@ describe('CategoriesManagementComponent', () => {
const category2 = new Category({ id: 'test2', name: 'testCat2' });
const category3 = new Category({ id: 'test3', name: 'testCat3' });
const category4 = new Category({ id: 'test4', name: 'testCat4' });
- const resultCat1 = new ResultNode({ id: 'test', name: 'testCat', path: { name: 'general/categories' }});
- const resultCat2 = new ResultNode({ id: 'test2', name: 'testCat2', path: { name: 'general/categories' }});
- const categoryPagingResponse: CategoryPaging = { list: { pagination: {}, entries: [ { entry: category1 }, { entry: category2 }]}};
- const categorySearchResponse: ResultSetPaging = { list: { pagination: {}, entries: [ { entry: resultCat1 }, { entry: resultCat2 }]}};
+ const resultCat1 = new ResultNode({ id: 'test', name: 'testCat', path: { name: 'general/categories' } });
+ const resultCat2 = new ResultNode({ id: 'test2', name: 'testCat2', path: { name: 'general/categories' } });
+ const categoryPagingResponse: CategoryPaging = { list: { pagination: {}, entries: [{ entry: category1 }, { entry: category2 }] } };
+ const categorySearchResponse: ResultSetPaging = { list: { pagination: {}, entries: [{ entry: resultCat1 }, { entry: resultCat2 }] } };
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CategoriesManagementComponent],
- imports: [
- TranslateModule.forRoot(),
- ContentTestingModule
- ],
+ imports: [TranslateModule.forRoot(), ContentTestingModule],
providers: [
{
provide: CategoryService,
@@ -65,6 +65,7 @@ describe('CategoriesManagementComponent', () => {
fixture = TestBed.createComponent(CategoriesManagementComponent);
component = fixture.componentInstance;
categoryService = TestBed.inject(CategoryService);
+ loader = TestbedHarnessEnvironment.loader(fixture);
});
/**
@@ -138,7 +139,9 @@ describe('CategoriesManagementComponent', () => {
* @returns list of native elements
*/
function getRemoveCategoryButtons(): HTMLButtonElement[] {
- return fixture.debugElement.queryAll(By.css(`[data-automation-id="categories-remove-category-button"]`)).map((debugElem) => debugElem.nativeElement);
+ return fixture.debugElement
+ .queryAll(By.css(`[data-automation-id="categories-remove-category-button"]`))
+ .map((debugElem) => debugElem.nativeElement);
}
/**
@@ -261,39 +264,28 @@ describe('CategoriesManagementComponent', () => {
});
describe('Spinner', () => {
- /**
- * Get the spinner element
- *
- * @returns debug element
- */
- function getSpinner(): DebugElement {
- return fixture.debugElement.query(By.css(`.mat-progress-spinner`));
- }
-
- it('should be displayed with correct diameter when existing categories are loading', fakeAsync(() => {
- typeCategory('Category 1', 0);
-
- const spinner = getSpinner();
- expect(spinner).toBeTruthy();
- expect(spinner.componentInstance.diameter).toBe(50);
-
- discardPeriodicTasks();
- flush();
- }));
+ it('should not be displayed when existing categories stopped loading', async () => {
+ component.categoryNameControlVisible = true;
+ fixture.detectChanges();
- it('should not be displayed when existing categories stopped loading', fakeAsync(() => {
- typeCategory('Category 1');
+ const categoryControlInput = getCategoryControlInput();
+ categoryControlInput.value = 'Category 1';
+ categoryControlInput.dispatchEvent(new InputEvent('input'));
- const spinner = getSpinner();
- expect(spinner).toBeFalsy();
- }));
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(false);
+ });
});
it('should display correct message when there are no existing categories', fakeAsync(() => {
- spyOn(categoryService, 'getSubcategories').and.returnValue(of({list: { pagination: {}, entries: []}}));
+ spyOn(categoryService, 'getSubcategories').and.returnValue(of({ list: { pagination: {}, entries: [] } }));
typeCategory('test');
- const noExistingCategoriesMsg = fixture.debugElement.query(By.css('mat-selection-list p'))?.nativeElement.textContent.trim();
+ const noExistingCategoriesMsg = fixture.debugElement
+ .query(By.css(`[data-automation-id="no-categories-message"]`))
+ ?.nativeElement.textContent.trim();
expect(noExistingCategoriesMsg).toBe('CATEGORIES_MANAGEMENT.NO_EXISTING_CATEGORIES');
}));
});
@@ -328,7 +320,9 @@ describe('CategoriesManagementComponent', () => {
it('should have correct remove category title', () => {
const removeButtons = getRemoveCategoryButtons();
- const isTitleCorrect = removeButtons.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.UNASSIGN_CATEGORY');
+ const isTitleCorrect = removeButtons.every(
+ (removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.UNASSIGN_CATEGORY'
+ );
expect(isTitleCorrect).toBeTrue();
});
@@ -434,7 +428,9 @@ describe('CategoriesManagementComponent', () => {
it('should have correct remove category title', () => {
const removeButtons = getRemoveCategoryButtons();
- const isTitleCorrect = removeButtons.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.DELETE_CATEGORY');
+ const isTitleCorrect = removeButtons.every(
+ (removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.DELETE_CATEGORY'
+ );
expect(isTitleCorrect).toBeTrue();
});
diff --git a/lib/content-services/src/lib/content-node-selector/content-node-selector.component.ts b/lib/content-services/src/lib/content-node-selector/content-node-selector.component.ts
index e13aec2fab7..fe939ff96d6 100644
--- a/lib/content-services/src/lib/content-node-selector/content-node-selector.component.ts
+++ b/lib/content-services/src/lib/content-node-selector/content-node-selector.component.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
+import { Component, Inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
-import { TranslationService, NotificationService} from '@alfresco/adf-core';
+import { TranslationService, NotificationService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { AllowableOperationsEnum } from '../common/models/allowable-operations.enum';
import { ContentService } from '../common/services/content.service';
@@ -26,6 +26,8 @@ import { ContentNodeSelectorComponentData } from './content-node-selector.compon
import { NodeEntryEvent } from '../document-list/components/node.event';
import { NodeAction } from '../document-list/models/node-action.enum';
import { OverlayContainer } from '@angular/cdk/overlay';
+import { Subject } from 'rxjs';
+import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'adf-content-node-selector',
@@ -33,7 +35,9 @@ import { OverlayContainer } from '@angular/cdk/overlay';
styleUrls: ['./content-node-selector.component.scss'],
encapsulation: ViewEncapsulation.None
})
-export class ContentNodeSelectorComponent implements OnInit {
+export class ContentNodeSelectorComponent implements OnInit, OnDestroy {
+ private onDestroy$ = new Subject();
+
title: string;
action: NodeAction;
buttonActionName: string;
@@ -48,13 +52,15 @@ export class ContentNodeSelectorComponent implements OnInit {
emptyFolderImageUrl: string = './assets/images/empty_doc_lib.svg';
breadcrumbFolderNode: Node;
- constructor(private translation: TranslationService,
- private contentService: ContentService,
- private notificationService: NotificationService,
- private uploadService: UploadService,
- private dialog: MatDialogRef,
- private overlayContainer: OverlayContainer,
- @Inject(MAT_DIALOG_DATA) public data: ContentNodeSelectorComponentData) {
+ constructor(
+ private translation: TranslationService,
+ private contentService: ContentService,
+ private notificationService: NotificationService,
+ private uploadService: UploadService,
+ private dialog: MatDialogRef,
+ private overlayContainer: OverlayContainer,
+ @Inject(MAT_DIALOG_DATA) public data: ContentNodeSelectorComponentData
+ ) {
this.action = data.actionName ?? NodeAction.CHOOSE;
this.buttonActionName = `NODE_SELECTOR.${this.action}`;
this.title = data.title;
@@ -62,28 +68,41 @@ export class ContentNodeSelectorComponent implements OnInit {
}
ngOnInit() {
- this.dialog.keydownEvents().subscribe(event => {
- // Esc
- if (event.keyCode === 27) {
- event.preventDefault();
- event.stopImmediatePropagation();
+ this.dialog
+ .keydownEvents()
+ .pipe(takeUntil(this.onDestroy$))
+ .subscribe((event) => {
+ if (event?.key === 'Escape') {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ this.close();
+ }
+ });
+
+ this.dialog
+ .backdropClick()
+ .pipe(takeUntil(this.onDestroy$))
+ .subscribe(() => {
this.close();
- }
- });
+ });
- this.dialog.backdropClick().subscribe(() => {
- this.close();
- });
-
- this.dialog.afterOpened().subscribe(() => {
- this.overlayContainer.getContainerElement().setAttribute('role', 'main');
- });
+ this.dialog
+ .afterOpened()
+ .pipe(takeUntil(this.onDestroy$))
+ .subscribe(() => {
+ this.overlayContainer.getContainerElement().setAttribute('role', 'main');
+ });
- this.uploadService.fileUploadStarting.subscribe(() => {
+ this.uploadService.fileUploadStarting.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.uploadStarted = true;
});
}
+ ngOnDestroy() {
+ this.onDestroy$.next();
+ this.onDestroy$.complete();
+ }
+
close() {
this.dialog.close();
this.overlayContainer.getContainerElement().setAttribute('role', 'region');
@@ -179,16 +198,17 @@ export class ContentNodeSelectorComponent implements OnInit {
}
getWarningMessage(): string {
- return this.showingSearch ? 'NODE_SELECTOR.UPLOAD_BUTTON_SEARCH_WARNING_MESSAGE' :
- (this.hasNoPermissionToUpload() ? 'NODE_SELECTOR.UPLOAD_BUTTON_PERMISSION_WARNING_MESSAGE' : '');
+ if (this.showingSearch) {
+ return 'NODE_SELECTOR.UPLOAD_BUTTON_SEARCH_WARNING_MESSAGE';
+ }
+ return this.hasNoPermissionToUpload() ? 'NODE_SELECTOR.UPLOAD_BUTTON_PERMISSION_WARNING_MESSAGE' : '';
}
hasNoPermissionToUpload(): boolean {
- return (!this.hasAllowableOperations && !this.showingSearch) && !this.isLoading;
+ return !this.hasAllowableOperations && !this.showingSearch && !this.isLoading;
}
hasUploadError(): boolean {
return this.showingSearch || this.hasNoPermissionToUpload();
}
-
}
diff --git a/lib/content-services/src/lib/dialogs/folder.dialog.spec.ts b/lib/content-services/src/lib/dialogs/folder.dialog.spec.ts
index 63418db8f39..7cd36094da6 100644
--- a/lib/content-services/src/lib/dialogs/folder.dialog.spec.ts
+++ b/lib/content-services/src/lib/dialogs/folder.dialog.spec.ts
@@ -48,6 +48,8 @@ describe('FolderDialogComponent', () => {
fixture.destroy();
});
+ const getTitle = () => fixture.debugElement.query(By.css('[data-automation-id="adf-folder-dialog-title"]'));
+
describe('Edit', () => {
beforeEach(() => {
component.data = {
@@ -70,8 +72,8 @@ describe('FolderDialogComponent', () => {
});
it('should have the proper title', () => {
- const title = fixture.debugElement.query(By.css('[mat-dialog-title]'));
- expect(title === null).toBe(false);
+ const title = getTitle();
+ expect(title).not.toBeNull();
expect(title.nativeElement.innerText.trim()).toBe('CORE.FOLDER_DIALOG.EDIT_FOLDER_TITLE');
});
@@ -165,8 +167,8 @@ describe('FolderDialogComponent', () => {
});
it('should have the proper title', () => {
- const title = fixture.debugElement.query(By.css(`[data-automation-id="adf-folder-dialog-title"]`));
- expect(title === null).toBe(false);
+ const title = getTitle();
+ expect(title).not.toBeNull();
expect(title.nativeElement.innerText.trim()).toBe('CORE.FOLDER_DIALOG.CREATE_FOLDER_TITLE');
});
diff --git a/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts b/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts
index 00adf1b0942..cdcf8701f4a 100644
--- a/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts
+++ b/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts
@@ -62,12 +62,16 @@ import { domSanitizerMock } from '../../testing/dom-sanitizer-mock';
import { MatDialog } from '@angular/material/dialog';
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
import { ShareDataTableAdapter } from '../data/share-datatable-adapter';
+import { HarnessLoader } from '@angular/cdk/testing';
+import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
+import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
const mockDialog = {
open: jasmine.createSpy('open')
};
describe('DocumentList', () => {
+ let loader: HarnessLoader;
let documentList: DocumentListComponent;
let documentListService: DocumentListService;
let customResourcesService: CustomResourcesService;
@@ -116,6 +120,8 @@ describe('DocumentList', () => {
spyFavorite = spyOn(customResourcesService.favoritesApi, 'listFavorites').and.returnValue(
Promise.resolve(new FavoritePaging({ list: new FavoritePagingList({ entries: [] }) }))
);
+
+ loader = TestbedHarnessEnvironment.loader(fixture);
});
afterEach(() => {
@@ -219,7 +225,7 @@ describe('DocumentList', () => {
it('should show the header when there are no records in the table but filter is active', () => {
documentList.data = new ShareDataTableAdapter(thumbnailService, contentService, []);
- documentList.filterValue = { $thumbnail: 'TYPE:"cm:folder"' };
+ documentList.filterValue = { $thumbnail: 'TYPE:"cm:folder"' };
fixture.detectChanges();
@@ -1075,10 +1081,11 @@ describe('DocumentList', () => {
expect(fixture.debugElement.query(By.css('.adf-no-permission__template'))).not.toBeNull();
});
- it('should display loading template when data is loading', () => {
+ it('should display loading template when data is loading', async () => {
documentList.loading = true;
fixture.detectChanges();
- expect(fixture.debugElement.query(By.css('mat-progress-spinner'))).not.toBeNull();
+
+ expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(true);
});
it('should empty folder NOT show the pagination', () => {
@@ -1406,14 +1413,16 @@ describe('DocumentList', () => {
expect(documentList.reload).toHaveBeenCalled();
});
- it('should not show loading state if pagination is updated with merge setting as true', fakeAsync (() => {
+ it('should not show loading state if pagination is updated with merge setting as true', fakeAsync(() => {
spyFolderNode = spyOn(documentListService, 'loadFolderByNodeId').and.callFake(() =>
- of(new DocumentLoaderNode(null, {
- list: {
- pagination: {},
- entries: mockPreselectedNodes
- }
- }))
+ of(
+ new DocumentLoaderNode(null, {
+ list: {
+ pagination: {},
+ entries: mockPreselectedNodes
+ }
+ })
+ )
);
fixture.detectChanges();
const fakeDatatableRows = [
diff --git a/lib/content-services/src/lib/new-version-uploader/new-version-uploader.dialog.html b/lib/content-services/src/lib/new-version-uploader/new-version-uploader.dialog.html
index 871bc59ace4..a47f6d297c1 100644
--- a/lib/content-services/src/lib/new-version-uploader/new-version-uploader.dialog.html
+++ b/lib/content-services/src/lib/new-version-uploader/new-version-uploader.dialog.html
@@ -1,4 +1,4 @@
-{{ title | translate }}
+{{ title | translate }}
{
let component: NewVersionUploaderDialogComponent;
let fixture: ComponentFixture;
- let nativeElement;
+ let nativeElement: HTMLElement;
const cssSelectors = {
adfVersionUploadButton: '#adf-version-upload-button',
adfVersionComparison: '#adf-version-comparison',
adfVersionList: '.adf-version-list',
- matDialogTitle: '.mat-dialog-title'
+ title: '[data-automation-id="new-version-uploader-dialog-title"]'
};
const mockDialogRef = {
@@ -45,10 +45,7 @@ describe('NewVersionUploaderDialog', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- imports: [
- TranslateModule.forRoot(),
- ContentTestingModule
- ],
+ imports: [TranslateModule.forRoot(), ContentTestingModule],
declarations: [
NewVersionUploaderDialogComponent,
VersionListComponent,
@@ -59,7 +56,8 @@ describe('NewVersionUploaderDialog', () => {
providers: [
{ provide: MAT_DIALOG_DATA, useValue: { node: mockNode, showVersionsOnly, file: mockFile } },
{
- provide: MatDialogRef, useValue: mockDialogRef
+ provide: MatDialogRef,
+ useValue: mockDialogRef
}
]
});
@@ -72,12 +70,7 @@ describe('NewVersionUploaderDialog', () => {
fixture.destroy();
});
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-
describe('Upload New Version', () => {
-
const expectedUploadNewVersionTitle = 'ADF-NEW-VERSION-UPLOADER.DIALOG_UPLOAD.TITLE';
it('should display adf version upload button if showVersionsOnly is passed as false from parent component', () => {
@@ -104,7 +97,7 @@ describe('NewVersionUploaderDialog', () => {
it('should show default title if title is not provided from parent component', () => {
component.data.showVersionsOnly = false;
fixture.detectChanges();
- const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
+ const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
expect(matDialogTitle.innerHTML).toEqual(expectedUploadNewVersionTitle);
});
@@ -112,7 +105,7 @@ describe('NewVersionUploaderDialog', () => {
component.data.showVersionsOnly = false;
component.data.title = '';
fixture.detectChanges();
- const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
+ const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
expect(matDialogTitle.innerHTML).toEqual(expectedUploadNewVersionTitle);
});
@@ -120,7 +113,7 @@ describe('NewVersionUploaderDialog', () => {
component.data.showVersionsOnly = false;
component.data.title = 'TEST_TITLE';
fixture.detectChanges();
- const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
+ const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
expect(matDialogTitle.innerHTML).toEqual('TEST_TITLE');
});
@@ -150,11 +143,9 @@ describe('NewVersionUploaderDialog', () => {
component.handleCancel();
expect(mockDialogRef.close).toHaveBeenCalled();
});
-
});
describe('Manage Versions', () => {
-
const expectedManageVersionsTitle = 'ADF-NEW-VERSION-UPLOADER.DIALOG_LIST.TITLE';
it('should display adf version list if showVersionsOnly is passed as true from parent component', () => {
@@ -182,7 +173,7 @@ describe('NewVersionUploaderDialog', () => {
component.data.showVersionsOnly = true;
component.data.title = undefined;
fixture.detectChanges();
- const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
+ const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
expect(matDialogTitle.innerHTML).toEqual(expectedManageVersionsTitle);
});
@@ -190,7 +181,7 @@ describe('NewVersionUploaderDialog', () => {
component.data.showVersionsOnly = true;
component.data.title = '';
fixture.detectChanges();
- const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
+ const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
expect(matDialogTitle.innerHTML).toEqual(expectedManageVersionsTitle);
});
@@ -198,10 +189,8 @@ describe('NewVersionUploaderDialog', () => {
component.data.showVersionsOnly = true;
component.data.title = 'TEST_TITLE';
fixture.detectChanges();
- const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
+ const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
expect(matDialogTitle.innerHTML).toEqual('TEST_TITLE');
});
-
});
-
});
diff --git a/lib/core/src/lib/card-view/components/card-view-selectitem/select-filter-input/select-filter-input.component.html b/lib/core/src/lib/card-view/components/card-view-selectitem/select-filter-input/select-filter-input.component.html
index be1de8e54a7..a5afdbdc4a9 100644
--- a/lib/core/src/lib/card-view/components/card-view-selectitem/select-filter-input/select-filter-input.component.html
+++ b/lib/core/src/lib/card-view/components/card-view-selectitem/select-filter-input/select-filter-input.component.html
@@ -12,7 +12,7 @@
(change)="$event.stopPropagation()"
/>
-