Moved tests from ContextHelpDirective to ContextHelpWrapperComponent and added more tests

This commit is contained in:
Koen Pauwels
2023-01-09 17:15:07 +01:00
parent 365b0208d9
commit cad4f74173
4 changed files with 129 additions and 71 deletions

View File

@@ -5,19 +5,51 @@ import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ContextHelpService } from '../context-help.service'; import { ContextHelpService } from '../context-help.service';
import { ContextHelp } from '../context-help.model'; import { ContextHelp } from '../context-help.model';
import { Component, Input, ViewChild, DebugElement } from '@angular/core';
import { PlacementArray } from '@ng-bootstrap/ng-bootstrap/util/positioning';
import { PlacementDir } from './placement-dir.model';
import { By } from '@angular/platform-browser';
@Component({
template: `
<ng-template #div>template</ng-template>
<ds-context-help-wrapper
#chwrapper
[templateRef]="div"
[content]="content"
[id]="id"
[tooltipPlacement]="tooltipPlacement"
[iconPlacement]="iconPlacement"
>
</ds-context-help-wrapper>
`
})
class TemplateComponent {
@Input() content: string;
@Input() id: string;
@Input() tooltipPlacement?: PlacementArray;
@Input() iconPlacement?: PlacementDir;
}
const messages = {
lorem: 'lorem ipsum dolor sit amet',
linkTest: 'This is text, [this](https://dspace.lyrasis.org) is a link, and [so is this](https://google.com)'
};
const exampleContextHelp: ContextHelp = {
id: 'test-tooltip',
isTooltipVisible: false
};
describe('ContextHelpWrapperComponent', () => { describe('ContextHelpWrapperComponent', () => {
let component: ContextHelpWrapperComponent; let templateComponent: TemplateComponent;
let fixture: ComponentFixture<ContextHelpWrapperComponent>; let wrapperComponent: ContextHelpWrapperComponent;
let fixture: ComponentFixture<TemplateComponent>;
let el: DebugElement;
let translateService: any; let translateService: any;
let contextHelpService: any; let contextHelpService: any;
let getContextHelp$: BehaviorSubject<ContextHelp>; let getContextHelp$: BehaviorSubject<ContextHelp>;
let shouldShowIcons$: BehaviorSubject<boolean>; let shouldShowIcons$: BehaviorSubject<boolean>;
const messages = {
lorem: 'lorem ipsum dolor sit amet',
linkTest: 'This is text, [this](https://dspace.lyrasis.org) is a link, and [so is this](https://google.com)'
};
function makeWrappedElement(): HTMLElement { function makeWrappedElement(): HTMLElement {
let el: HTMLElement = document.createElement('div') let el: HTMLElement = document.createElement('div')
el.innerHTML = 'example element'; el.innerHTML = 'example element';
@@ -26,39 +58,113 @@ describe('ContextHelpWrapperComponent', () => {
beforeEach(waitForAsync( () => { beforeEach(waitForAsync( () => {
translateService = jasmine.createSpyObj('translateService', ['get']); translateService = jasmine.createSpyObj('translateService', ['get']);
translateService.get.and.callFake((content) => messages[content]);
contextHelpService = jasmine.createSpyObj('contextHelpService', [ contextHelpService = jasmine.createSpyObj('contextHelpService', [
'shouldShowIcons$', 'shouldShowIcons$',
'getContextHelp$', 'getContextHelp$',
'add' 'add',
]) 'remove',
'toggleIcons',
'toggleTooltip',
'showTooltip',
'hideTooltip'
]);
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ NgbTooltipModule ], imports: [ NgbTooltipModule ],
providers: [ providers: [
{ provide: TranslateService, useValue: translateService }, { provide: TranslateService, useValue: translateService },
{ provide: ContextHelpService, useValue: contextHelpService }, { provide: ContextHelpService, useValue: contextHelpService },
], ],
declarations: [ ContextHelpWrapperComponent ] declarations: [ TemplateComponent, ContextHelpWrapperComponent ]
}).compileComponents(); }).compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
// Initializing services.
getContextHelp$ = new BehaviorSubject<ContextHelp>(exampleContextHelp);
shouldShowIcons$ = new BehaviorSubject<boolean>(false);
contextHelpService.getContextHelp$.and.returnValue(getContextHelp$); contextHelpService.getContextHelp$.and.returnValue(getContextHelp$);
contextHelpService.shouldShowIcons$.and.returnValue(shouldShowIcons$); contextHelpService.shouldShowIcons$.and.returnValue(shouldShowIcons$);
getContextHelp$.next({ translateService.get.and.callFake((content) => observableOf(messages[content]));
id: 'example-id',
isTooltipVisible: false getContextHelp$.next(exampleContextHelp);
});
shouldShowIcons$.next(false); shouldShowIcons$.next(false);
fixture = TestBed.createComponent(ContextHelpWrapperComponent); // Initializing components.
component = fixture.componentInstance; fixture = TestBed.createComponent(TemplateComponent);
component.templateRef el = fixture.debugElement;
templateComponent = fixture.componentInstance;
templateComponent.content = 'lorem'
templateComponent.id = 'test-tooltip'
templateComponent.tooltipPlacement = ['bottom'];
templateComponent.iconPlacement = 'left';
wrapperComponent = el.query(By.css('ds-context-help-wrapper')).componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(templateComponent).toBeDefined();
expect(wrapperComponent).toBeDefined();
}); });
it('should not show the context help icon while icon visibility is not turned on', (done) => {
fixture.whenStable().then(() => {
let wrapper = el.query(By.css('ds-context-help-wrapper')).nativeElement;
expect(wrapper.children.length).toBe(0);
done();
});
});
describe('when icon visibility is turned on', () => {
beforeEach(() => {
shouldShowIcons$.next(true);
fixture.detectChanges();
spyOn(wrapperComponent.tooltip, 'open').and.callThrough();
spyOn(wrapperComponent.tooltip, 'close').and.callThrough();
});
it('should show the context help button', (done) => {
fixture.whenStable().then(() => {
let wrapper = el.query(By.css('ds-context-help-wrapper')).nativeElement;
expect(wrapper.children.length).toBe(1);
let [i] = wrapper.children;
expect(i.tagName).toBe('I');
done();
});
});
describe('after the icon is clicked', () => {
let i;
beforeEach(() => {
i = el.query(By.css('.ds-context-help-icon')).nativeElement;
i.click();
fixture.detectChanges();
});
it('should display the tooltip', () => {
expect(contextHelpService.toggleTooltip).toHaveBeenCalledWith('test-tooltip');
getContextHelp$.next({...exampleContextHelp, isTooltipVisible: true});
fixture.detectChanges();
expect(wrapperComponent.tooltip.open).toHaveBeenCalled();
expect(wrapperComponent.tooltip.close).toHaveBeenCalledTimes(0);
});
describe('after the icon is clicked again', () => {
beforeEach(() => {
i.click();
fixture.detectChanges();
spyOn(wrapperComponent.tooltip, 'isOpen').and.returnValue(true);
});
it('should close the tooltip', () => {
expect(contextHelpService.toggleTooltip).toHaveBeenCalledWith('test-tooltip');
getContextHelp$.next({...exampleContextHelp, isTooltipVisible: false});
fixture.detectChanges();
expect(wrapperComponent.tooltip.close).toHaveBeenCalled();
});
});
});
});
// TODO: link parsing tests
}); });

View File

@@ -81,6 +81,7 @@ export class ContextHelpWrapperComponent implements OnInit, OnDestroy {
this.contextHelpService.getContextHelp$(this.id) this.contextHelpService.getContextHelp$(this.id)
.pipe(hasValueOperator()) .pipe(hasValueOperator())
.subscribe((ch: ContextHelp) => { .subscribe((ch: ContextHelp) => {
if (ch.isTooltipVisible && !this.tooltip.isOpen()) { if (ch.isTooltipVisible && !this.tooltip.isOpen()) {
this.tooltip.open(); this.tooltip.open();
} else if (!ch.isTooltipVisible && this.tooltip.isOpen()) { } else if (!ch.isTooltipVisible && this.tooltip.isOpen()) {

View File

@@ -8,6 +8,7 @@ import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { ContextHelpService } from './context-help.service'; import { ContextHelpService } from './context-help.service';
import { ContextHelp } from './context-help.model'; import { ContextHelp } from './context-help.model';
import { before } from 'lodash'; import { before } from 'lodash';
import { By } from '@angular/platform-browser';
@Component({ @Component({
template: `<div *dsContextHelp="contextHelpParams()">some text</div>` template: `<div *dsContextHelp="contextHelpParams()">some text</div>`
@@ -36,7 +37,6 @@ const exampleContextHelp: ContextHelp = {
describe('ContextHelpDirective', () => { describe('ContextHelpDirective', () => {
let component: TestComponent; let component: TestComponent;
let fixture: ComponentFixture<TestComponent>; let fixture: ComponentFixture<TestComponent>;
// let el: DebugElement;
let translateService: any; let translateService: any;
let contextHelpService: any; let contextHelpService: any;
let getContextHelp$: BehaviorSubject<ContextHelp>; let getContextHelp$: BehaviorSubject<ContextHelp>;
@@ -79,10 +79,10 @@ describe('ContextHelpDirective', () => {
component.id = 'test-tooltip'; component.id = 'test-tooltip';
component.content = 'lorem'; component.content = 'lorem';
fixture.detectChanges();
}); });
it('should generate the context help wrapper component', (done) => { it('should generate the context help wrapper component', (done) => {
fixture.detectChanges();
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
expect(fixture.nativeElement.children.length).toBe(1); expect(fixture.nativeElement.children.length).toBe(1);
let [wrapper] = fixture.nativeElement.children; let [wrapper] = fixture.nativeElement.children;
@@ -92,54 +92,4 @@ describe('ContextHelpDirective', () => {
done(); done();
}); });
}); });
it('should not show the context help button while icon visibility is not turned on', (done) => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let wrapper = matchWrapper(fixture.nativeElement);
verifyNoButton(wrapper);
done();
});
});
describe('when icon visibility is toggled on', () => {
beforeEach(() => {
shouldShowIcons$.next(true);
});
it('should show the context help button', (done) => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let wrapper = matchWrapper(fixture.nativeElement);
let i = verifyButton(wrapper);
i.click();
expect(contextHelpService.toggleTooltip).toHaveBeenCalledWith('test-tooltip');
getContextHelp$.next({id: 'test-tooltip', isTooltipVisible: true});
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(wrapper.parentElement.parentElement.querySelector('ngb-tooltip-window')).toBeTruthy();
done();
});
});
});
});
}); });
function matchWrapper(el: HTMLElement): HTMLElement {
expect(el.children.length).toBe(1);
return el.children[0] as HTMLElement;
}
function verifyNoButton(wrapper: HTMLElement) {
expect(wrapper.children.length).toBe(1);
let [div] = wrapper.children;
expect(div.tagName).toBe('DIV');
}
function verifyButton(wrapper: Element): HTMLElement {
expect(wrapper.children.length).toBe(2);
let [i, div] = wrapper.children;
expect(i.tagName).toBe('I');
expect(div.tagName).toBe('DIV');
return i as HTMLElement;
}

View File

@@ -59,6 +59,7 @@ export class ContextHelpDirective implements OnChanges, OnDestroy {
= this.componentFactoryResolver.resolveComponentFactory(ContextHelpWrapperComponent); = this.componentFactoryResolver.resolveComponentFactory(ContextHelpWrapperComponent);
this.wrapper = this.viewContainerRef.createComponent(factory); this.wrapper = this.viewContainerRef.createComponent(factory);
} }
console.log(this.templateRef);
this.wrapper.instance.templateRef = this.templateRef; this.wrapper.instance.templateRef = this.templateRef;
this.wrapper.instance.content = this.dsContextHelp.content; this.wrapper.instance.content = this.dsContextHelp.content;
this.wrapper.instance.id = this.dsContextHelp.id; this.wrapper.instance.id = this.dsContextHelp.id;