Improve AuthFlow request handling logic

This commit is contained in:
SleepWalker 2016-06-15 09:01:41 +03:00
parent 868d4877bc
commit 0b1a50f788
3 changed files with 24 additions and 35 deletions

View File

@ -28,6 +28,8 @@ export default class AuthFlow {
const {routing} = this.getState();
if (routing.location.pathname !== route) {
this.currentPath = route;
if (this.replace) {
this.replace(route);
}
@ -71,16 +73,6 @@ export default class AuthFlow {
throw new Error('State is required');
}
// if (this.state instanceof state.constructor) {
// // already in this state
// return;
// }
if (this.state instanceof ResendActivationState && state instanceof ResendActivationState) {
// NOTE: a temporary workaround for resend-activation goBack to return to correct prevState
return;
}
this.state && this.state.leave(this);
this.prevState = this.state;
this.state = state;
@ -111,6 +103,14 @@ export default class AuthFlow {
this.replace = replace;
this.onReady = callback;
if (this.currentPath === path) {
// we are already handling this path
this.onReady();
return;
}
this.currentPath = path;
if (path === '/') {
// reset oauth data if user tried to navigate to index route
this.run('setOAuthRequest', {});

View File

@ -1,13 +1,8 @@
import AuthFlow from 'services/authFlow/AuthFlow';
import AbstractState from 'services/authFlow/AbstractState';
import OAuthState from 'services/authFlow/OAuthState';
import RegisterState from 'services/authFlow/RegisterState';
import RecoverPasswordState from 'services/authFlow/RecoverPasswordState';
import ForgotPasswordState from 'services/authFlow/ForgotPasswordState';
import ActivationState from 'services/authFlow/ActivationState';
import ResendActivationState from 'services/authFlow/ResendActivationState';
import LoginState from 'services/authFlow/LoginState';
describe('AuthFlow.functional', () => {
let flow;
@ -60,9 +55,7 @@ describe('AuthFlow.functional', () => {
it('should redirect guest / -> /login', () => {
navigate('/');
// TODO: fix me. The commented line should be the correct assertion
// sinon.assert.calledOnce(flow.navigate);
sinon.assert.calledTwice(flow.navigate);
sinon.assert.calledOnce(flow.navigate);
sinon.assert.calledWithExactly(flow.navigate, '/login');
});
@ -74,9 +67,7 @@ describe('AuthFlow.functional', () => {
navigate('/login');
navigate('/');
// TODO: fix me. The commented line should be the correct assertion
// sinon.assert.calledTwice(flow.navigate);
sinon.assert.calledThrice(flow.navigate);
sinon.assert.calledTwice(flow.navigate);
sinon.assert.alwaysCalledWithExactly(flow.navigate, '/login');
});
});

View File

@ -66,20 +66,6 @@ describe('AuthFlow', () => {
sinon.assert.notCalled(spy2);
});
xit('should not change state, if current state is of the same type', () => {
const state1 = new AbstractState();
const state2 = new AbstractState();
const spy1 = sinon.spy(state1, 'enter');
const spy2 = sinon.spy(state2, 'enter');
flow.setState(state1);
flow.setState(state2);
sinon.assert.calledWith(spy1, flow);
sinon.assert.calledOnce(spy1);
sinon.assert.notCalled(spy2);
});
it('should return promise, if #enter returns it', () => {
const state = new AbstractState();
const expected = Promise.resolve();
@ -239,6 +225,18 @@ describe('AuthFlow', () => {
sinon.assert.calledOnce(callback);
});
it('should not handle the same request twice', () => {
const path = '/oauth';
const callback = sinon.stub();
flow.handleRequest(path, () => {}, callback);
flow.handleRequest(path, () => {}, callback);
sinon.assert.calledOnce(flow.setState);
sinon.assert.calledTwice(callback);
sinon.assert.calledWithExactly(flow.setState, sinon.match.instanceOf(OAuthState));
});
it('throws if unsupported request', () => {
expect(() => flow.handleRequest('/foo/bar')).to.throw('Unsupported request: /foo/bar');
});