Tests for ContextHelpDirective

This commit is contained in:
Koen Pauwels
2023-01-09 11:37:29 +01:00
parent 8850f005b4
commit 365b0208d9
4 changed files with 165 additions and 44 deletions

View File

@@ -1,21 +1,60 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { of as observableOf, Observable, BehaviorSubject } from 'rxjs';
import { ContextHelpWrapperComponent } from './context-help-wrapper.component';
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { ContextHelpService } from '../context-help.service';
import { ContextHelp } from '../context-help.model';
describe('ContextHelpWrapperComponent', () => {
let component: ContextHelpWrapperComponent;
let fixture: ComponentFixture<ContextHelpWrapperComponent>;
let translateService: any;
let contextHelpService: any;
let getContextHelp$: BehaviorSubject<ContextHelp>;
let shouldShowIcons$: BehaviorSubject<boolean>;
beforeEach(async () => {
await TestBed.configureTestingModule({
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 {
let el: HTMLElement = document.createElement('div')
el.innerHTML = 'example element';
return el;
}
beforeEach(waitForAsync( () => {
translateService = jasmine.createSpyObj('translateService', ['get']);
translateService.get.and.callFake((content) => messages[content]);
contextHelpService = jasmine.createSpyObj('contextHelpService', [
'shouldShowIcons$',
'getContextHelp$',
'add'
])
TestBed.configureTestingModule({
imports: [ NgbTooltipModule ],
providers: [
{ provide: TranslateService, useValue: translateService },
{ provide: ContextHelpService, useValue: contextHelpService },
],
declarations: [ ContextHelpWrapperComponent ]
})
.compileComponents();
});
}).compileComponents();
}));
beforeEach(() => {
contextHelpService.getContextHelp$.and.returnValue(getContextHelp$);
contextHelpService.shouldShowIcons$.and.returnValue(shouldShowIcons$);
getContextHelp$.next({
id: 'example-id',
isTooltipVisible: false
});
shouldShowIcons$.next(false);
fixture = TestBed.createComponent(ContextHelpWrapperComponent);
component = fixture.componentInstance;
component.templateRef
fixture.detectChanges();
});

View File

@@ -33,13 +33,13 @@ export class ContextHelpWrapperComponent implements OnInit, OnDestroy {
/**
* Indicate where the tooltip should show up, relative to the info icon.
*/
@Input() tooltipPlacement?: PlacementArray;
@Input() tooltipPlacement?: PlacementArray = [];
/**
* Indicate whether the info icon should appear to the left or to
* the right of the wrapped element.
*/
@Input() iconPlacement?: PlacementDir;
@Input() iconPlacement?: PlacementDir = 'left';
/**
* If true, don't process text to render links.

View File

@@ -1,65 +1,145 @@
import { Component, DebugElement, Input } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { of as observableOf, Observable } from 'rxjs';
import { ComponentFixture, TestBed, getTestBed, waitForAsync } from '@angular/core/testing';
import { of as observableOf, Observable, BehaviorSubject } from 'rxjs';
import { ContextHelpDirective, ContextHelpDirectiveInput } from './context-help.directive';
import { TranslateService } from '@ngx-translate/core';
import { ContextHelpWrapperComponent } from './context-help-wrapper/context-help-wrapper.component';
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { ContextHelpService } from './context-help.service';
import { ContextHelp } from './context-help.model';
import { before } from 'lodash';
@Component({
template: `<div *dsContextHelp="contextHelpParams()">some text</div>`
})
class TestComponent {
@Input() content = '';
@Input() id = '';
contextHelpParams(): ContextHelpDirectiveInput {
return {
content: this.content
content: this.content,
id: this.id,
iconPlacement: 'left',
tooltipPlacement: ['bottom']
};
}
}
// tslint:disable-next-line:max-classes-per-file
class MockTranslateService {
messages: {[index: string]: string} = {
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)'
};
get(key: string): Observable<string> {
return observableOf(this.messages[key]);
}
}
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('ContextHelpDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
// let el: DebugElement;
// let translateService: TranslateService;
let translateService: any;
let contextHelpService: any;
let getContextHelp$: BehaviorSubject<ContextHelp>;
let shouldShowIcons$: BehaviorSubject<boolean>;
beforeEach(() => {
console.log('Anyone hear that?');
fixture = TestBed.configureTestingModule({
beforeEach(waitForAsync(() => {
translateService = jasmine.createSpyObj('translateService', ['get']);
contextHelpService = jasmine.createSpyObj('contextHelpService', [
'shouldShowIcons$',
'getContextHelp$',
'add',
'remove',
'toggleIcons',
'toggleTooltip',
'showTooltip',
'hideTooltip'
]);
TestBed.configureTestingModule({
imports: [NgbTooltipModule],
providers: [
{ provide: TranslateService, useClass: MockTranslateService }
{ provide: TranslateService, useValue: translateService },
{ provide: ContextHelpService, useValue: contextHelpService }
],
declarations: [TestComponent, ContextHelpWrapperComponent, ContextHelpDirective]
}).createComponent(TestComponent);
}).compileComponents()
}));
beforeEach(() => {
// Set up service behavior.
getContextHelp$ = new BehaviorSubject<ContextHelp>(exampleContextHelp);
shouldShowIcons$ = new BehaviorSubject<boolean>(false);
contextHelpService.getContextHelp$.and.returnValue(getContextHelp$);
contextHelpService.shouldShowIcons$.and.returnValue(shouldShowIcons$);
translateService.get.and.callFake((content) => observableOf(messages[content]));
// Set up fixture and component.
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
component.id = 'test-tooltip';
component.content = 'lorem';
});
it('should add the tooltip icon', () => {
component.content = 'lorem';
it('should generate the context help wrapper component', (done) => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.nativeElement.children.length).toBe(1);
let [wrapper] = fixture.nativeElement.children;
expect(component).toBeDefined();
expect(wrapper.tagName).toBe('DS-CONTEXT-HELP-WRAPPER');
expect(contextHelpService.add).toHaveBeenCalledWith(exampleContextHelp)
done();
});
});
expect(component).toBeDefined();
const [wrapper] = fixture.nativeElement.children;
const [i, div] = wrapper.children;
expect(wrapper.tagName).toBe('DS-CONTEXT-HELP-WRAPPER');
expect(i.tagName).toBe('I');
expect(div.tagName).toBe('DIV');
expect(div.innerHTML).toBe('some text');
i.click(); // TODO: triggers a type error
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

@@ -54,9 +54,11 @@ export class ContextHelpDirective implements OnChanges, OnDestroy {
this.mostRecentId = this.dsContextHelp.id;
this.contextHelpService.add({id: this.dsContextHelp.id, isTooltipVisible: false});
const factory
= this.componentFactoryResolver.resolveComponentFactory(ContextHelpWrapperComponent);
this.wrapper = this.viewContainerRef.createComponent(factory);
if (this.wrapper === undefined) {
const factory
= this.componentFactoryResolver.resolveComponentFactory(ContextHelpWrapperComponent);
this.wrapper = this.viewContainerRef.createComponent(factory);
}
this.wrapper.instance.templateRef = this.templateRef;
this.wrapper.instance.content = this.dsContextHelp.content;
this.wrapper.instance.id = this.dsContextHelp.id;