Skip to content

Commit

Permalink
feat: respect returnUrl query parameter when logout guard is triggered
Browse files Browse the repository at this point in the history
  • Loading branch information
dhhyi committed May 18, 2020
1 parent e2372a9 commit c7d49c2
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 30 deletions.
72 changes: 44 additions & 28 deletions src/app/core/guards/logout.guard.spec.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,58 @@
import { TestBed, async } from '@angular/core/testing';
import { Location } from '@angular/common';
import { Component } from '@angular/core';
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Action, Store } from '@ngrx/store';
import { anything, capture, spy, verify } from 'ts-mockito';

import { UserActionTypes } from 'ish-core/store/user';
import { ngrxTesting } from 'ish-core/utils/dev/ngrx-testing';
import { TestStore, containsActionWithType, ngrxTesting } from 'ish-core/utils/dev/ngrx-testing';

import { LogoutGuard } from './logout.guard';

describe('Logout Guard', () => {
describe('canActivate()', () => {
let logoutGuard: LogoutGuard;
let store$: Store;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, ngrxTesting()],
}).compileComponents();
let store$: TestStore;
let router: Router;
let location: Location;

beforeEach(() => {
@Component({ template: 'dummy' })
class DummyComponent {}

TestBed.configureTestingModule({
declarations: [DummyComponent],
imports: [
RouterTestingModule.withRoutes([
{ path: 'home', component: DummyComponent },
{ path: 'foo', component: DummyComponent },
{ path: '**', component: DummyComponent, canActivate: [LogoutGuard] },
]),
ngrxTesting({ routerStore: true }),
],
}).compileComponents();

store$ = TestBed.inject(TestStore);
router = TestBed.inject(Router);
location = TestBed.inject(Location);
});

store$ = spy(TestBed.inject(Store));
}));
it('should log out when called', fakeAsync(() => {
router.navigateByUrl('/any');
tick(500);

beforeEach(() => {
logoutGuard = TestBed.inject(LogoutGuard);
});
expect(store$.actionsArray()).toSatisfy(containsActionWithType(UserActionTypes.LogoutUser));
}));

it('should log out when called', () => {
logoutGuard.canActivate();
verify(store$.dispatch(anything())).called();
it('should redirect to /home when called', fakeAsync(() => {
router.navigateByUrl('/any');
tick(500);

const [arg] = capture(store$.dispatch).last();
expect((arg as Action).type).toBe(UserActionTypes.LogoutUser);
});
expect(location.path()).toMatchInlineSnapshot(`"/home"`);
}));

it('should redirect to /home when called', () => {
const tree = logoutGuard.canActivate();
it('should redirect to returnUrl when supplied', fakeAsync(() => {
router.navigateByUrl('/any?returnUrl=/foo');
tick(500);

expect(tree.toString()).toMatchInlineSnapshot(`"/home"`);
});
});
expect(location.path()).toMatchInlineSnapshot(`"/foo"`);
}));
});
12 changes: 10 additions & 2 deletions src/app/core/guards/logout.guard.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { Store, select } from '@ngrx/store';
import { map } from 'rxjs/operators';

import { selectQueryParam } from 'ish-core/store/router';
import { LogoutUser } from 'ish-core/store/user';

/**
* triggers logging out the user if the guarded route is visited
*
* if returnUrl is supplied as a queryParam, it redirects there (default is /home)
*/
@Injectable({ providedIn: 'root' })
export class LogoutGuard implements CanActivate {
constructor(private store: Store, private router: Router) {}

canActivate() {
this.store.dispatch(new LogoutUser());
return this.router.createUrlTree(['/home']);
return this.store.pipe(
select(selectQueryParam('returnUrl')),
map(returnUrl => returnUrl || '/home'),
map(returnUrl => this.router.parseUrl(returnUrl))
);
}
}

0 comments on commit c7d49c2

Please sign in to comment.