Skip to content

Commit

Permalink
fix(VotingEventComponent): token expired managed
Browse files Browse the repository at this point in the history
Requests which result unauthorized because the token is expired are managed - in these cases the
user is sent to the login page with a message explaining the problem
  • Loading branch information
EnricoPicci committed Jul 7, 2019
1 parent 64a70d7 commit 4626823
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fileignoreconfig:
checksum: 96f4f7aa4bd17b66037dcd3c066dfa5d1e11fa2d44ea6ba3f9d7ad02ec41bff8
ignore_detectors: []
- filename: src/app/modules/login/login.component.ts
checksum: 510ff54745a0315fdaa5de0cf6923cc4e30081789e358120baf277f8cd1b5379
checksum: 315ca49589fbaf0d8b61cf25e0463236dcd9e5fe2f5ba3ee406f854dd36397ca
ignore_detectors: []
- filename: src/app/services/backend.service.spec.ts
checksum: ff6dcfb54a6626c09e49b637631dc543cfcf504b03adb56e97d15321211afc94
Expand Down
54 changes: 42 additions & 12 deletions src/app/modules/admin/voting-event/voting-event.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export class VotingEventComponent implements OnInit {
}
},
(err) => {
if (err.errorCode === ERRORS.unauthorized) {
this.unauthorized();
return;
}
this.messageCreate = `Event <strong> ${inputValue} </strong> could not be created - look at the browser console
- maybe there is something there`;
},
Expand Down Expand Up @@ -137,9 +141,14 @@ export class VotingEventComponent implements OnInit {
const selectedEventId = this.getSelectedEvent()._id;
this.backend.openVotingEvent(selectedEventId).subscribe(
() => (this.messageAction = `Event <strong> ${this.selectedName} </strong> opened`),
(err) =>
(this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be opened -
look at the browser console to see if there is any detail`),
(err) => {
if (err.errorCode === ERRORS.unauthorized) {
this.unauthorized();
return;
}
this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be opened -
look at the browser console to see if there is any detail`;
},
() => this.refreshVotingEvents()
);
}
Expand All @@ -148,9 +157,14 @@ export class VotingEventComponent implements OnInit {
const selectedEventId = this.getSelectedEvent()._id;
this.backend.closeVotingEvent(selectedEventId).subscribe(
() => (this.messageAction = `Event <strong> ${this.selectedName} </strong> closed`),
(err) =>
(this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be closed -
look at the browser console to see if there is any detail`),
(err) => {
if (err.errorCode === ERRORS.unauthorized) {
this.unauthorized();
return;
}
this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be closed -
look at the browser console to see if there is any detail`;
},
() => this.refreshVotingEvents()
);
}
Expand All @@ -177,9 +191,14 @@ export class VotingEventComponent implements OnInit {
const selectedEvent = this.getSelectedEvent();
this.backend.openForRevote(selectedEvent).subscribe(
() => (this.messageAction = `Event <strong> ${this.selectedName} </strong> open for revote`),
(err) =>
(this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be opened for revote -
look at the browser console to see if there is any detail`),
(err) => {
if (err.errorCode === ERRORS.unauthorized) {
this.unauthorized();
return;
}
this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be opened for revote -
look at the browser console to see if there is any detail`;
},
() => this.refreshVotingEvents()
);
}
Expand All @@ -188,9 +207,14 @@ export class VotingEventComponent implements OnInit {
const selectedEvent = this.getSelectedEvent();
this.backend.closeForRevote(selectedEvent).subscribe(
() => (this.messageAction = `Event <strong> ${this.selectedName} </strong> closed for revote`),
(err) =>
(this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be closed for revote -
look at the browser console to see if there is any detail`),
(err) => {
if (err.errorCode === ERRORS.unauthorized) {
this.unauthorized();
return;
}
this.messageAction = `Event <strong> ${this.selectedName} </strong> could not be closed for revote -
look at the browser console to see if there is any detail`;
},
() => this.refreshVotingEvents()
);
}
Expand All @@ -214,4 +238,10 @@ export class VotingEventComponent implements OnInit {
this.backend.getBlipsForAllEvent(config);
});
}

unauthorized() {
this.authenticationService.logout();
this.authenticationService.setMessage('Request not authorized - pls login and try again');
this.router.navigate(['login']);
}
}
7 changes: 6 additions & 1 deletion src/app/modules/login/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Observable, of, Subject, ReplaySubject } from 'rxjs';
import { tap, delay } from 'rxjs/operators';
import { BackendService } from 'src/app/services/backend.service';

Expand All @@ -9,6 +9,7 @@ import { BackendService } from 'src/app/services/backend.service';
export class AuthService {
user: string;
isLoggedIn = false;
message$ = new ReplaySubject<string>(1);

constructor(private backend: BackendService) {}

Expand Down Expand Up @@ -41,4 +42,8 @@ export class AuthService {
})
);
}

setMessage(msg: string) {
this.message$.next(msg);
}
}
218 changes: 108 additions & 110 deletions src/app/modules/login/login.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import {RouterTestingModule} from '@angular/router/testing';
import { of, throwError } from 'rxjs';
import { RouterTestingModule } from '@angular/router/testing';
import { of, throwError, Subject } from 'rxjs';

import { marbles } from 'rxjs-marbles/jasmine';

import {AppMaterialModule} from '../../app-material.module';
import { AppMaterialModule } from '../../app-material.module';

import { LoginComponent } from './login.component';
import { AuthService } from './auth.service';
Expand All @@ -17,14 +17,14 @@ describe('LoginComponent', () => {
const userNotValidMsg = 'user not right';
const pwdNotValidMsg = 'pwd not right';
class MockAuthService {
message$ = new Subject<string>();
login(user: string, pwd: string) {
if (user === validUserId && pwd === validPwd) {
return of(true);
} else
if (user !== validUserId) {
return throwError({message: userNotValidMsg});
} else if (user !== validUserId) {
return throwError({ message: userNotValidMsg });
} else {
return throwError({message: pwdNotValidMsg});
return throwError({ message: pwdNotValidMsg });
}
}
}
Expand All @@ -34,11 +34,10 @@ describe('LoginComponent', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
declarations: [LoginComponent],
imports: [HttpClientModule, AppMaterialModule, RouterTestingModule],
providers: [{provide: AuthService, useClass: MockAuthService}]
})
.compileComponents();
providers: [{ provide: AuthService, useClass: MockAuthService }]
}).compileComponents();
}));

beforeEach(() => {
Expand All @@ -51,105 +50,104 @@ describe('LoginComponent', () => {
expect(component).toBeTruthy();
});

it('1.1 - test the login Obaservable pipe when the user and password are right - uses marble test', marbles(m => {
const userId = {
a: 'u',
b: 'us',
c: 'use',
d: 'user'
};
const pwd = {
x: 'p',
y: 'pw',
z: 'pwd',
};
const loginClick = {
c: {},
};
const output = {
o: true,
};
const userId$ = m.hot( '^--a-b-c-d------------', userId);
const pwd$ = m.hot( '^----------x-y-z------', pwd);
const loginButtonClick$ = m.hot( '^------------------c--', pwd);
const expected = m.cold( '-------------------o--', output);

const destination = component.logIn$(userId$, pwd$, loginButtonClick$);

m.expect(destination).toBeObservable(expected);

}));

it('1.2 - test the login Obaservable pipe when the user NOT right - uses marble test', marbles(m => {
const userId = {
a: 'u',
b: 'us',
c: 'uss',
d: 'usss'
};
const pwd = {
x: 'p',
y: 'pw',
z: 'pwd',
};
const loginClick = {
c: {},
};
const output = {
o: false,
};
const userId$ = m.hot( '^--a-b-c-d------------', userId);
const pwd$ = m.hot( '^----------x-y-z------', pwd);
const loginButtonClick$ = m.hot( '^------------------c--', pwd);
const expected = m.cold( '----------------------', output);

const destination = component.logIn$(userId$, pwd$, loginButtonClick$);

m.expect(destination).toBeObservable(expected);

component.message$
.subscribe(
message => {
it(
'1.1 - test the login Obaservable pipe when the user and password are right - uses marble test',
marbles((m) => {
const userId = {
a: 'u',
b: 'us',
c: 'use',
d: 'user'
};
const pwd = {
x: 'p',
y: 'pw',
z: 'pwd'
};
const loginClick = {
c: {}
};
const output = {
o: true
};
const userId$ = m.hot('^--a-b-c-d------------', userId);
const pwd$ = m.hot('^----------x-y-z------', pwd);
const loginButtonClick$ = m.hot('^------------------c--', pwd);
const expected = m.cold('-------------------o--', output);

const destination = component.logIn$(userId$, pwd$, loginButtonClick$);

m.expect(destination).toBeObservable(expected);
})
);

it(
'1.2 - test the login Obaservable pipe when the user NOT right - uses marble test',
marbles((m) => {
const userId = {
a: 'u',
b: 'us',
c: 'uss',
d: 'usss'
};
const pwd = {
x: 'p',
y: 'pw',
z: 'pwd'
};
const loginClick = {
c: {}
};
const output = {
o: false
};
const userId$ = m.hot('^--a-b-c-d------------', userId);
const pwd$ = m.hot('^----------x-y-z------', pwd);
const loginButtonClick$ = m.hot('^------------------c--', pwd);
const expected = m.cold('----------------------', output);

const destination = component.logIn$(userId$, pwd$, loginButtonClick$);

m.expect(destination).toBeObservable(expected);

component.message$.subscribe((message) => {
expect(message).toBe(userNotValidMsg);
}
);

}));

it('1.3 - test the login Obaservable pipe when the password is NOT right - uses marble test', marbles(m => {
const userId = {
a: 'u',
b: 'us',
c: 'use',
d: 'user'
};
const pwd = {
x: 'p',
y: 'pp',
z: 'ppp',
};
const loginClick = {
c: {},
};
const output = {
o: false,
};
const userId$ = m.hot( '^--a-b-c-d------------', userId);
const pwd$ = m.hot( '^----------x-y-z------', pwd);
const loginButtonClick$ = m.hot( '^------------------c--', pwd);
const expected = m.cold( '----------------------', output);

const destination = component.logIn$(userId$, pwd$, loginButtonClick$);

m.expect(destination).toBeObservable(expected);

component.message$
.subscribe(
message => {
});
})
);

it(
'1.3 - test the login Obaservable pipe when the password is NOT right - uses marble test',
marbles((m) => {
const userId = {
a: 'u',
b: 'us',
c: 'use',
d: 'user'
};
const pwd = {
x: 'p',
y: 'pp',
z: 'ppp'
};
const loginClick = {
c: {}
};
const output = {
o: false
};
const userId$ = m.hot('^--a-b-c-d------------', userId);
const pwd$ = m.hot('^----------x-y-z------', pwd);
const loginButtonClick$ = m.hot('^------------------c--', pwd);
const expected = m.cold('----------------------', output);

const destination = component.logIn$(userId$, pwd$, loginButtonClick$);

m.expect(destination).toBeObservable(expected);

component.message$.subscribe((message) => {
expect(message).toBe(pwdNotValidMsg);
}
);

}));

});
})
);
});
Loading

0 comments on commit 4626823

Please sign in to comment.