Skip to content

Commit

Permalink
test(menu): add unit tests for rendering logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Malkevich committed Feb 27, 2019
1 parent 15fc5b2 commit eccbb66
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 14 deletions.
6 changes: 3 additions & 3 deletions projects/dynamic-menu/src/lib/dynamic-menu.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('Service: DynamicMenu', () => {
expect(menu[1].data.menu.label).toBe('Route 2');
}));

it('should resolve `subMenuComponent` from map', fakeAsync(() => {
it('should resolve `data.menu.subMenuComponent` from map', fakeAsync(() => {
class Comp1 {}
class Comp2 {}

Expand Down Expand Up @@ -141,13 +141,13 @@ describe('Service: DynamicMenu', () => {

expect(menu[0].path).toBe('route1');
expect(menu[0].data.menu.label).toBe('Route 1');
expect(menu[0].subMenuComponent).toBe(Comp1);
expect(menu[0].data.menu.subMenuComponent).toBe(Comp1);

const subMenu = menu[0].data.menu.children;
expect(subMenu.length).toBe(1);
expect(subMenu[0].path).toBe('route2');
expect(subMenu[0].data.menu.label).toBe('Route 2');
expect(subMenu[0].subMenuComponent).toBe(Comp2);
expect(subMenu[0].data.menu.subMenuComponent).toBe(Comp2);
}));

it('should update menu when `listenForConfigChanges` is `true` and lazy module resolved', fakeAsync(() => {
Expand Down
10 changes: 6 additions & 4 deletions projects/dynamic-menu/src/lib/dynamic-menu.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ export class DynamicMenuService {
? parentConfig.fullUrl || [parentConfig.path]
: [];

config.data.menu.subMenuComponent = this.resolveSubMenuComponent(
config,
subMenuMap,
);
if (config.data && config.data.menu) {
config.data.menu.subMenuComponent = this.resolveSubMenuComponent(
config,
subMenuMap,
);
}

return {
...config,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Component } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { DynamicMenuService } from '../../dynamic-menu.service';
import { DynamicMenuTemplateContext } from '../context-template';
import { DynamicMenuItemsComponent } from './dynamic-menu-items.component';

class DynamicMenuServiceMock {
isActive = jasmine.createSpy('isActive spy');
}

@Component({
selector: 'ndm-host',
template: `
Expand All @@ -20,7 +26,11 @@ describe('DynamicMenuItemsComponent', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [DynamicMenuItemsComponent, HostComponent],
providers: [
{ provide: DynamicMenuService, useClass: DynamicMenuServiceMock },
],
});
});

Expand Down Expand Up @@ -68,9 +78,194 @@ describe('DynamicMenuItemsComponent', () => {

expect(fixture.nativeElement.textContent).toBe('Tpl: var');
});

describe('`config.showChildrenIfActivated`', () => {
describe('set to `true`', () => {
beforeEach(() => {
hostComp.getCtx.and.callFake(
(tpl: any) =>
new DynamicMenuTemplateContext(
tpl,
{},
{
fullUrl: 'full-url' as any,
data: {
menu: {
showChildrenIfActivated: true,
label: '',
children: [],
},
},
},
),
);
});

it('should call `dynamicMenuService.isActive()` with `config.fullUrl`', () => {
fixture.detectChanges();

expect(getDynamicMenuService().isActive).toHaveBeenCalledWith(
'full-url',
);
});

it('should render tpl if `dynamicMenuService.isActive` returns `true`', () => {
getDynamicMenuService().isActive.and.returnValue(true);

fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('Tpl: ');
});

it('should NOT render tpl if `dynamicMenuService.isActive` returns `false`', () => {
getDynamicMenuService().isActive.and.returnValue(false);

fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('');
});
});

describe('set to `false`', () => {
beforeEach(() => {
hostComp.getCtx.and.callFake(
(tpl: any) =>
new DynamicMenuTemplateContext(
tpl,
{},
{
fullUrl: 'full-url' as any,
data: {
menu: {
showChildrenIfActivated: false,
label: '',
children: [],
},
},
},
),
);
});

it('should NOT call `dynamicMenuService.isActive()`', () => {
fixture.detectChanges();

expect(getDynamicMenuService().isActive).not.toHaveBeenCalled();
});

it('should always render tpl', () => {
fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('Tpl: ');
});
});
});

describe('`config.showChildrenIfChildActivated`', () => {
describe('set to `true`', () => {
beforeEach(() => {
hostComp.getCtx.and.callFake(
(tpl: any) =>
new DynamicMenuTemplateContext(
tpl,
{},
{
fullUrl: 'full-url' as any,
data: {
menu: {
showChildrenIfChildActivated: true,
label: '',
children: [],
},
},
},
),
);
});

it('should call `dynamicMenuService.isActive()` with `config.fullUrl, true`', () => {
fixture.detectChanges();

expect(getDynamicMenuService().isActive).toHaveBeenCalledWith(
'full-url',
true,
);
});

it('should call `dynamicMenuService.isActive()` with `config.fullUrl`', () => {
fixture.detectChanges();

expect(getDynamicMenuService().isActive).toHaveBeenCalledWith(
'full-url',
);
});

it('should render tpl if `dynamicMenuService.isActive` first returns `false` and second `true`', () => {
getDynamicMenuService().isActive.and.returnValues(false, true);

fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('Tpl: ');
});

it('should NOT render tpl if `dynamicMenuService.isActive` first returns `true`', () => {
getDynamicMenuService().isActive.and.returnValue(false);

fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('');
});

it('should NOT render tpl if `dynamicMenuService.isActive` second returns `false`', () => {
getDynamicMenuService().isActive.and.returnValues(false, false);

fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('');
});
});

describe('set to `false`', () => {
beforeEach(() => {
hostComp.getCtx.and.callFake(
(tpl: any) =>
new DynamicMenuTemplateContext(
tpl,
{},
{
fullUrl: 'full-url' as any,
data: {
menu: {
showChildrenIfChildActivated: false,
label: '',
children: [],
},
},
},
),
);
});

it('should NOT call `dynamicMenuService.isActive()`', () => {
fixture.detectChanges();

expect(getDynamicMenuService().isActive).not.toHaveBeenCalled();
});

it('should always render tpl', () => {
fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('Tpl: ');
});
});
});
});
});

function overrideHostTpl(tpl: string) {
TestBed.overrideTemplate(HostComponent, tpl);
}

function getDynamicMenuService(): DynamicMenuServiceMock {
return TestBed.get(DynamicMenuService);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface NgView<T, C = T> {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DynamicMenuItemsComponent implements OnInit {
ctx: DynamicMenuTemplateContext | undefined;
ctx!: DynamicMenuTemplateContext;

navigationEnd$ = this.router.events.pipe(
filter(e => e instanceof NavigationEnd),
Expand All @@ -41,11 +41,13 @@ export class DynamicMenuItemsComponent implements OnInit {
) {}

ngOnInit(): void {
this.ctx = this.getTplContext((this.vcr as any)._view);
const ctx = this.getTplContext((this.vcr as any)._view);

if (!this.ctx) {
if (!ctx) {
throw Error(`DynamicMenuItemsComponent: Used outside of context!`);
}

this.ctx = ctx;
}

private getTplContext(view: NgView<any> | undefined) {
Expand All @@ -59,10 +61,6 @@ export class DynamicMenuItemsComponent implements OnInit {
}

private shouldRender() {
if (!this.ctx) {
return false;
}

const { parentConfig } = this.ctx;

if (parentConfig) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { DynamicMenuComponent } from './dynamic-menu.component';

class DynamicMenuServiceMock {
getMenu = jasmine.createSpy('getMenu spy');
isActive = jasmine.createSpy('isActive spy');
}

@Component({
Expand Down

0 comments on commit eccbb66

Please sign in to comment.