Skip to content

Commit

Permalink
Merge pull request #5 from orchestratora/feat-custom-menu
Browse files Browse the repository at this point in the history
[Feat] Custom menu
  • Loading branch information
gund authored Mar 12, 2019
2 parents ddc4a91 + 7307bf9 commit 1eeb4b5
Show file tree
Hide file tree
Showing 6 changed files with 644 additions and 94 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"build": "ng build dynamic-menu",
"test": "ng test --watch=false",
"test:w": "ng test --watch=true",
"test:ci": "npm run test -- --code-coverage --browsers ChromeHeadless",
"test:ci": "npm-run-all -p test:ci:*",
"test:ci:lib": "npm run test -- dynamic-menu --code-coverage --browsers ChromeHeadless",
"test:ci:demo": "npm run test -- demo --browsers ChromeHeadless",
"test:report": "cd coverage/dynamic-menu && codecov",
"lint": "ng lint dynamic-menu",
"e2e": "ng e2e",
Expand Down
6 changes: 5 additions & 1 deletion projects/demo/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';

import { AppComponent } from './app.component';
import { By } from '@angular/platform-browser';
import { DynamicMenuService } from 'projects/dynamic-menu/src/public_api';

describe('Component: App', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
providers: [{ provide: DynamicMenuService, useValue: {} }],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
});
});
Expand Down
30 changes: 28 additions & 2 deletions projects/demo/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { DynamicMenuService } from 'projects/dynamic-menu/src/public_api';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {}
export class AppComponent implements OnInit {
constructor(private dynamicMenuService: DynamicMenuService) {}

ngOnInit(): void {
this.dynamicMenuService.addMenuAfter(['path3', ':id', 'path6'], {
path: 'custom-path',
data: { menu: { label: 'Custom Section' } },
});
this.dynamicMenuService.addMenuToStart(['path3', ':id', 'path6'], {
path: 'custom-path2',
data: { menu: { label: 'Custom Section - Start' } },
});
this.dynamicMenuService.addMenuToEnd(['path3', ':id', 'path6'], {
path: 'custom-path3',
data: { menu: { label: 'Custom Section - End' } },
});
this.dynamicMenuService.addMenuToStart([''], {
path: 'custom-path-start',
data: { menu: { label: 'Custom Section - Start' } },
});
this.dynamicMenuService.addMenuToEnd([''], {
path: 'custom-path-end',
data: { menu: { label: 'Custom Section - End' } },
});
}
}
305 changes: 304 additions & 1 deletion projects/dynamic-menu/src/lib/dynamic-menu.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ describe('Service: DynamicMenu', () => {

expect(menu[1].path).toBe('child');
expect(menu[1].data.menu.label).toBe('Child');
expect(menu[1].data.menu.children.length).toBe(0); // Not yet loaded
expect(menu[1].data.menu.children).toBeUndefined(); // Not yet loaded

callback.calls.reset();

Expand Down Expand Up @@ -245,6 +245,309 @@ describe('Service: DynamicMenu', () => {
expect(child1[0].data.menu.label).toBe('Sub menu');
}));
});

describe('addMenuAfter() method', () => {
beforeEach(() => {
const routes: RoutesWithMenu = [
{
path: '',
component: TestComponent,
data: { menu: { label: 'Main' } },
},
{
path: 'child',
data: { menu: { label: 'Child' } },
children: [
{
path: 'child1',
component: TestComponent,
data: { menu: { label: 'Child1' } },
},
{
path: 'child2',
component: TestComponent,
data: { menu: { label: 'Child2' } },
},
],
},
];

@NgModule({
imports: [TestModule, RouterTestingModule.withRoutes(routes)],
})
class TestRootModule {}

TestBed.configureTestingModule({
imports: [TestRootModule],
});
});

it('should insert custom menu after specified link', fakeAsync(() => {
const callback = jasmine.createSpy('callback');

getService().addMenuAfter(['child', 'child1'], {
path: 'custom',
data: { menu: { label: 'Custom' } },
});

getService()
.getMenu()
.pipe(untilDestroyed)
.subscribe(callback);

tick();

expect(callback).toHaveBeenCalled();

const menu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(menu.length).toBe(2);

const child = menu[1].data.menu.children;

expect(child.length).toBe(3);
expect(child[0].path).toBe('child1');
expect(child[1].path).toBe('custom');
expect(child[2].path).toBe('child2');
}));

it('should update menu dynamically', fakeAsync(() => {
const callback = jasmine.createSpy('callback');

getService()
.getMenu()
.pipe(untilDestroyed)
.subscribe(callback);

tick();

expect(callback).toHaveBeenCalled();

const menu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(menu.length).toBe(2);

callback.calls.reset();

getService().addMenuAfter([''], {
path: 'custom',
data: { menu: { label: 'Custom' } },
});

tick();

expect(callback).toHaveBeenCalled();

const newMenu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(newMenu.length).toBe(3);
}));
});

describe('addMenuToStart() method', () => {
beforeEach(() => {
const routes: RoutesWithMenu = [
{
path: '',
component: TestComponent,
data: { menu: { label: 'Main' } },
},
{
path: 'child',
data: { menu: { label: 'Child' } },
children: [
{
path: 'child1',
component: TestComponent,
data: { menu: { label: 'Child1' } },
},
{
path: 'child2',
component: TestComponent,
data: { menu: { label: 'Child2' } },
},
],
},
];

@NgModule({
imports: [TestModule, RouterTestingModule.withRoutes(routes)],
})
class TestRootModule {}

TestBed.configureTestingModule({
imports: [TestRootModule],
});
});

it('should insert custom menu to start of link list', fakeAsync(() => {
const callback = jasmine.createSpy('callback');

getService().addMenuToStart(['child', 'child2'], {
path: 'custom',
data: { menu: { label: 'Custom' } },
});

getService()
.getMenu()
.pipe(untilDestroyed)
.subscribe(callback);

tick();

expect(callback).toHaveBeenCalled();

const menu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(menu.length).toBe(2);

const child = menu[1].data.menu.children;

expect(child.length).toBe(3);
expect(child[0].path).toBe('custom');
expect(child[1].path).toBe('child1');
expect(child[2].path).toBe('child2');
}));

it('should update menu dynamically', fakeAsync(() => {
const callback = jasmine.createSpy('callback');

getService()
.getMenu()
.pipe(untilDestroyed)
.subscribe(callback);

tick();

expect(callback).toHaveBeenCalled();

const menu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(menu.length).toBe(2);

callback.calls.reset();

getService().addMenuToStart([''], {
path: 'custom',
data: { menu: { label: 'Custom' } },
});

tick();

expect(callback).toHaveBeenCalled();

const newMenu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(newMenu.length).toBe(3);
}));
});

describe('addMenuToEnd() method', () => {
beforeEach(() => {
const routes: RoutesWithMenu = [
{
path: '',
component: TestComponent,
data: { menu: { label: 'Main' } },
},
{
path: 'child',
data: { menu: { label: 'Child' } },
children: [
{
path: 'child1',
component: TestComponent,
data: { menu: { label: 'Child1' } },
},
{
path: 'child2',
component: TestComponent,
data: { menu: { label: 'Child2' } },
},
],
},
];

@NgModule({
imports: [TestModule, RouterTestingModule.withRoutes(routes)],
})
class TestRootModule {}

TestBed.configureTestingModule({
imports: [TestRootModule],
});
});

it('should insert custom menu to start of link list', fakeAsync(() => {
const callback = jasmine.createSpy('callback');

getService().addMenuToEnd(['child', 'child1'], {
path: 'custom',
data: { menu: { label: 'Custom' } },
});

getService()
.getMenu()
.pipe(untilDestroyed)
.subscribe(callback);

tick();

expect(callback).toHaveBeenCalled();

const menu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(menu.length).toBe(2);

const child = menu[1].data.menu.children;

expect(child.length).toBe(3);
expect(child[0].path).toBe('child1');
expect(child[1].path).toBe('child2');
expect(child[2].path).toBe('custom');
}));

it('should update menu dynamically', fakeAsync(() => {
const callback = jasmine.createSpy('callback');

getService()
.getMenu()
.pipe(untilDestroyed)
.subscribe(callback);

tick();

expect(callback).toHaveBeenCalled();

const menu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(menu.length).toBe(2);

callback.calls.reset();

getService().addMenuToEnd([''], {
path: 'custom',
data: { menu: { label: 'Custom' } },
});

tick();

expect(callback).toHaveBeenCalled();

const newMenu = callback.calls.mostRecent()
.args[0] as DynamicMenuRouteConfig[];

expect(newMenu.length).toBe(3);
}));
});
});

function getService(): DynamicMenuService {
Expand Down
Loading

0 comments on commit 1eeb4b5

Please sign in to comment.