From baacadad31cbe1ab6e453ab08d3642149631a9cc Mon Sep 17 00:00:00 2001 From: SleepWalker Date: Wed, 15 Jun 2016 09:02:12 +0300 Subject: [PATCH] Decouple auth states from routing redux state --- src/services/authFlow/ActivationState.js | 6 +++--- src/services/authFlow/AuthFlow.js | 12 +++++++++--- src/services/authFlow/OAuthState.js | 2 +- src/services/authFlow/RecoverPasswordState.js | 6 +++--- tests/services/authFlow/ActivationState.test.js | 10 ++++------ .../services/authFlow/AuthFlow.functional.test.js | 4 ---- tests/services/authFlow/OAuthState.test.js | 8 ++------ .../services/authFlow/RecoverPasswordState.test.js | 14 ++++++-------- tests/services/authFlow/helpers.js | 2 ++ 9 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/services/authFlow/ActivationState.js b/src/services/authFlow/ActivationState.js index 37b8265..4718544 100644 --- a/src/services/authFlow/ActivationState.js +++ b/src/services/authFlow/ActivationState.js @@ -4,13 +4,13 @@ import ResendActivationState from './ResendActivationState'; export default class ActivationState extends AbstractState { enter(context) { - const {user, routing} = context.getState(); + const {user} = context.getState(); if (user.isActive) { context.setState(new CompleteState()); } else { - const url = routing.location.pathname.includes('/activation') - ? routing.location.pathname + const url = context.getCurrentPath().includes('/activation') + ? context.getCurrentPath() : '/activation'; context.navigate(url); } diff --git a/src/services/authFlow/AuthFlow.js b/src/services/authFlow/AuthFlow.js index 1fcbe39..31d4811 100644 --- a/src/services/authFlow/AuthFlow.js +++ b/src/services/authFlow/AuthFlow.js @@ -25,9 +25,7 @@ export default class AuthFlow { setStore(store) { this.navigate = (route) => { - const {routing} = this.getState(); - - if (routing.location.pathname !== route) { + if (this.currentPath !== route) { this.currentPath = route; if (this.replace) { @@ -91,6 +89,14 @@ export default class AuthFlow { } } + getCurrentPath() { + return this.currentPath; + } + + getQuery() { + return this.getState().routing.location.query; + } + /** * This should be called from onEnter prop of react-router Route component * diff --git a/src/services/authFlow/OAuthState.js b/src/services/authFlow/OAuthState.js index e33a35e..cec47c6 100644 --- a/src/services/authFlow/OAuthState.js +++ b/src/services/authFlow/OAuthState.js @@ -3,7 +3,7 @@ import CompleteState from './CompleteState'; export default class OAuthState extends AbstractState { enter(context) { - const query = context.getState().routing.location.query; + const query = context.getQuery(); return context.run('oAuthValidate', { clientId: query.client_id, diff --git a/src/services/authFlow/RecoverPasswordState.js b/src/services/authFlow/RecoverPasswordState.js index 0f9eef8..c274d4e 100644 --- a/src/services/authFlow/RecoverPasswordState.js +++ b/src/services/authFlow/RecoverPasswordState.js @@ -4,11 +4,11 @@ import CompleteState from './CompleteState'; export default class RecoverPasswordState extends AbstractState { enter(context) { - const {user, routing} = context.getState(); + const {user} = context.getState(); if (user.isGuest) { - const url = routing.location.pathname.includes('/recover-password') - ? routing.location.pathname + const url = context.getCurrentPath().includes('/recover-password') + ? context.getCurrentPath() : '/recover-password'; context.navigate(url); } else { diff --git a/tests/services/authFlow/ActivationState.test.js b/tests/services/authFlow/ActivationState.test.js index a0ff21b..c56e149 100644 --- a/tests/services/authFlow/ActivationState.test.js +++ b/tests/services/authFlow/ActivationState.test.js @@ -27,12 +27,11 @@ describe('ActivationState', () => { context.getState.returns({ user: { isActive: false - }, - routing: { - location: {pathname: expectedPath} } }); + context.getCurrentPath.returns(expectedPath); + expectNavigate(mock, '/activation'); state.enter(context); @@ -43,12 +42,11 @@ describe('ActivationState', () => { context.getState.returns({ user: { isActive: false - }, - routing: { - location: {pathname: expectedPath} } }); + context.getCurrentPath.returns(expectedPath); + expectNavigate(mock, expectedPath); state.enter(context); diff --git a/tests/services/authFlow/AuthFlow.functional.test.js b/tests/services/authFlow/AuthFlow.functional.test.js index 07ca308..4f38f17 100644 --- a/tests/services/authFlow/AuthFlow.functional.test.js +++ b/tests/services/authFlow/AuthFlow.functional.test.js @@ -30,10 +30,6 @@ describe('AuthFlow.functional', () => { flow.setStore(store); navigate = function navigate(url) { // emulates router behaviour - state.routing = state.routing || {}; - state.routing.location = state.routing.location || {}; - state.routing.location.pathname = url; - if (navigate.lastUrl !== url) { navigate.lastUrl = url; flow.handleRequest(url, navigate); diff --git a/tests/services/authFlow/OAuthState.test.js b/tests/services/authFlow/OAuthState.test.js index 97254d4..561440f 100644 --- a/tests/services/authFlow/OAuthState.test.js +++ b/tests/services/authFlow/OAuthState.test.js @@ -30,9 +30,7 @@ describe('OAuthState', () => { state: 'state' }; - context.getState.returns({ - routing: {location: {query}} - }); + context.getQuery.returns(query); expectRun( mock, @@ -52,9 +50,7 @@ describe('OAuthState', () => { it('should transition to complete state on success', () => { const promise = Promise.resolve(); - context.getState.returns({ - routing: {location: {query: {}}} - }); + context.getQuery.returns({}); mock.expects('run').returns(promise); expectState(mock, CompleteState); diff --git a/tests/services/authFlow/RecoverPasswordState.test.js b/tests/services/authFlow/RecoverPasswordState.test.js index 5e42b0c..da042cb 100644 --- a/tests/services/authFlow/RecoverPasswordState.test.js +++ b/tests/services/authFlow/RecoverPasswordState.test.js @@ -25,12 +25,11 @@ describe('RecoverPasswordState', () => { it('should navigate to /recover-password', () => { const expectedPath = '/recover-password'; context.getState.returns({ - user: {isGuest: true}, - routing: { - location: {pathname: expectedPath} - } + user: {isGuest: true} }); + context.getCurrentPath.returns(expectedPath); + expectNavigate(mock, expectedPath); state.enter(context); @@ -39,12 +38,11 @@ describe('RecoverPasswordState', () => { it('should navigate to /recover-password/key', () => { const expectedPath = '/recover-password/sasx5AS4d61'; context.getState.returns({ - user: {isGuest: true}, - routing: { - location: {pathname: expectedPath} - } + user: {isGuest: true} }); + context.getCurrentPath.returns(expectedPath); + expectNavigate(mock, expectedPath); state.enter(context); diff --git a/tests/services/authFlow/helpers.js b/tests/services/authFlow/helpers.js index 6d68de1..6ee896b 100644 --- a/tests/services/authFlow/helpers.js +++ b/tests/services/authFlow/helpers.js @@ -7,6 +7,8 @@ export function bootstrap() { getState: sinon.stub(), run() {}, setState() {}, + getCurrentPath: sinon.stub(), + getQuery: sinon.stub(), navigate() {} };