Skip to content

Commit

Permalink
feat(router-store): add routerState config option (#1847)
Browse files Browse the repository at this point in the history
Closes #1834
  • Loading branch information
timdeschryver authored and brandonroberts committed May 20, 2019
1 parent 29c426b commit d874cfc
Show file tree
Hide file tree
Showing 13 changed files with 423 additions and 126 deletions.
85 changes: 82 additions & 3 deletions modules/router-store/spec/router_store_module.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';
import { Router, RouterEvent } from '@angular/router';
import {
routerReducer,
RouterReducerState,
StoreRouterConnectingModule,
RouterAction,
RouterState,
RouterStateSerializer,
MinimalRouterStateSerializer,
DefaultRouterStateSerializer,
} from '@ngrx/router-store';
import { select, Store } from '@ngrx/store';
import { withLatestFrom } from 'rxjs/operators';
import { select, Store, ActionsSubject } from '@ngrx/store';
import { withLatestFrom, filter } from 'rxjs/operators';

import { createTestModule } from './utils';

Expand Down Expand Up @@ -134,4 +139,78 @@ describe('Router Store Module', () => {
});
});
});

describe('routerState', () => {
function setup(routerState: RouterState, serializer?: any) {
createTestModule({
reducers: {},
config: {
routerState,
serializer,
},
});

return {
actions: TestBed.get(ActionsSubject) as ActionsSubject,
router: TestBed.get(Router) as Router,
serializer: TestBed.get(RouterStateSerializer) as RouterStateSerializer,
};
}

const onlyRouterActions = (a: any): a is RouterAction<any, any> =>
a.payload && a.payload.event;

describe('Full', () => {
it('should dispatch the full event', async () => {
const { actions, router } = setup(RouterState.Full);
actions
.pipe(filter(onlyRouterActions))
.subscribe(({ payload }) =>
expect(payload.event instanceof RouterEvent).toBe(true)
);

await router.navigateByUrl('/');
});

it('should use the default router serializer', () => {
const { serializer } = setup(RouterState.Full);
expect(serializer).toEqual(new DefaultRouterStateSerializer());
});

it('should use the provided serializer if one is provided', () => {
const { serializer } = setup(
RouterState.Full,
MinimalRouterStateSerializer
);
expect(serializer).toEqual(new MinimalRouterStateSerializer());
});
});

describe('Minimal', () => {
it('should dispatch the navigation id with url', async () => {
const { actions, router } = setup(RouterState.Minimal);
actions
.pipe(filter(onlyRouterActions))
.subscribe(({ payload }: any) => {
expect(payload.event instanceof RouterEvent).toBe(false);
expect(payload.event).toEqual({ id: 1, url: '/' });
});

await router.navigateByUrl('/');
});

it('should use the minimal router serializer', () => {
const { serializer } = setup(RouterState.Minimal);
expect(serializer).toEqual(new MinimalRouterStateSerializer());
});

it('should use the provided serializer if one is provided', () => {
const { serializer } = setup(
RouterState.Minimal,
DefaultRouterStateSerializer
);
expect(serializer).toEqual(new DefaultRouterStateSerializer());
});
});
});
});
101 changes: 0 additions & 101 deletions modules/router-store/spec/serializer.spec.ts

This file was deleted.

192 changes: 192 additions & 0 deletions modules/router-store/spec/serializers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { RouterStateSnapshot } from '@angular/router';
import {
DefaultRouterStateSerializer,
MinimalRouterStateSerializer,
} from '../src';

describe('default serializer', () => {
it('should serialize all properties', () => {
const serializer = new DefaultRouterStateSerializer();
const snapshot = createRouteSnapshot();
const routerState = {
url: 'url',
root: snapshot,
} as RouterStateSnapshot;

const actual = serializer.serialize(routerState);
const expected = {
url: 'url',
root: createExpectedSnapshot(),
};
expect(actual).toEqual(expected);
});

it('should serialize with an empty routeConfig', () => {
const serializer = new DefaultRouterStateSerializer();
const snapshot = { ...createRouteSnapshot(), routeConfig: null };
const routerState = {
url: 'url',
root: snapshot,
} as RouterStateSnapshot;

const actual = serializer.serialize(routerState);
const expected = {
url: 'url',
root: {
...createExpectedSnapshot(),
routeConfig: null,
component: undefined,
},
};
expect(actual).toEqual(expected);
});

it('should serialize children', () => {
const serializer = new DefaultRouterStateSerializer();
const snapshot = {
...createRouteSnapshot(),
children: [createRouteSnapshot('child')],
};
const routerState = {
url: 'url',
root: snapshot,
} as RouterStateSnapshot;

const actual = serializer.serialize(routerState);

const expected = {
url: 'url',
root: {
...createExpectedSnapshot(),
firstChild: createExpectedSnapshot('child'),
children: [createExpectedSnapshot('child')],
},
};

expect(actual).toEqual(expected);
});

function createExpectedSnapshot(prefix = 'root') {
return {
...createRouteSnapshot(prefix),
component: `${prefix}-route.routeConfig.component`,
root: undefined,
parent: undefined,
firstChild: undefined,
pathFromRoot: undefined,
};
}
});

describe('minimal serializer', () => {
it('should serialize only the minimal properties', () => {
const serializer = new MinimalRouterStateSerializer();
const snapshot = createRouteSnapshot();
const routerState = {
url: 'url',
root: snapshot,
} as RouterStateSnapshot;

const actual = serializer.serialize(routerState);
const expected = {
url: 'url',
root: createExpectedSnapshot(),
};
expect(actual).toEqual(expected);
});

it('should serialize with an empty routeConfig', () => {
const serializer = new MinimalRouterStateSerializer();
const snapshot = { ...createRouteSnapshot(), routeConfig: null };
const routerState = {
url: 'url',
root: snapshot,
} as RouterStateSnapshot;

const actual = serializer.serialize(routerState);
const expected = {
url: 'url',
root: {
...createExpectedSnapshot(),
routeConfig: null,
},
};
expect(actual).toEqual(expected);
});

it('should serialize children', () => {
const serializer = new MinimalRouterStateSerializer();
const snapshot = {
...createRouteSnapshot(),
children: [createRouteSnapshot('child')],
};
const routerState = {
url: 'url',
root: snapshot,
} as RouterStateSnapshot;

const actual = serializer.serialize(routerState);

const expected = {
url: 'url',
root: {
...createExpectedSnapshot(),
firstChild: createExpectedSnapshot('child'),
children: [createExpectedSnapshot('child')],
},
};

expect(actual).toEqual(expected);
});

function createExpectedSnapshot(prefix = 'root') {
let snapshot = {
...createRouteSnapshot(prefix),
routeConfig: {
// config doesn't have a component because it isn't serializable
path: `${prefix}-route.routeConfig.path`,
pathMatch: `${prefix}-route.routeConfig.pathMatch`,
redirectTo: `${prefix}-route.routeConfig.redirectTo`,
outlet: `${prefix}-route.routeConfig.outlet`,
},
firstChild: undefined,
};

// properties that aren't serializable
delete snapshot.paramMap;
delete snapshot.queryParamMap;
delete snapshot.component;

// properties that do not exist on the minimal serializer
delete snapshot.root;
delete snapshot.parent;
delete snapshot.pathFromRoot;

return snapshot;
}
});

function createRouteSnapshot(prefix = 'root'): any {
return {
params: `${prefix}-route.params`,
paramMap: `${prefix}-route.paramMap`,
data: `${prefix}-route.data`,
url: `${prefix}-route.url`,
outlet: `${prefix}-route.outlet`,
routeConfig: {
component: `${prefix}-route.routeConfig.component`,
path: `${prefix}-route.routeConfig.path`,
pathMatch: `${prefix}-route.routeConfig.pathMatch`,
redirectTo: `${prefix}-route.routeConfig.redirectTo`,
outlet: `${prefix}-route.routeConfig.outlet`,
},
queryParams: `${prefix}-route.queryParams`,
queryParamMap: `${prefix}-route.queryParamMap`,
fragment: `${prefix}-route.fragment`,
root: `${prefix}-route.root`,
parent: `${prefix}-route.parent`,
pathFromRoot: `${prefix}-route.params`,
firstChild: null,
children: [],
};
}
Loading

0 comments on commit d874cfc

Please sign in to comment.