Decouple auth states from routing redux state

This commit is contained in:
SleepWalker 2016-06-15 09:02:12 +03:00
parent 0b1a50f788
commit baacadad31
9 changed files with 30 additions and 34 deletions

View File

@ -4,13 +4,13 @@ import ResendActivationState from './ResendActivationState';
export default class ActivationState extends AbstractState { export default class ActivationState extends AbstractState {
enter(context) { enter(context) {
const {user, routing} = context.getState(); const {user} = context.getState();
if (user.isActive) { if (user.isActive) {
context.setState(new CompleteState()); context.setState(new CompleteState());
} else { } else {
const url = routing.location.pathname.includes('/activation') const url = context.getCurrentPath().includes('/activation')
? routing.location.pathname ? context.getCurrentPath()
: '/activation'; : '/activation';
context.navigate(url); context.navigate(url);
} }

View File

@ -25,9 +25,7 @@ export default class AuthFlow {
setStore(store) { setStore(store) {
this.navigate = (route) => { this.navigate = (route) => {
const {routing} = this.getState(); if (this.currentPath !== route) {
if (routing.location.pathname !== route) {
this.currentPath = route; this.currentPath = route;
if (this.replace) { 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 * This should be called from onEnter prop of react-router Route component
* *

View File

@ -3,7 +3,7 @@ import CompleteState from './CompleteState';
export default class OAuthState extends AbstractState { export default class OAuthState extends AbstractState {
enter(context) { enter(context) {
const query = context.getState().routing.location.query; const query = context.getQuery();
return context.run('oAuthValidate', { return context.run('oAuthValidate', {
clientId: query.client_id, clientId: query.client_id,

View File

@ -4,11 +4,11 @@ import CompleteState from './CompleteState';
export default class RecoverPasswordState extends AbstractState { export default class RecoverPasswordState extends AbstractState {
enter(context) { enter(context) {
const {user, routing} = context.getState(); const {user} = context.getState();
if (user.isGuest) { if (user.isGuest) {
const url = routing.location.pathname.includes('/recover-password') const url = context.getCurrentPath().includes('/recover-password')
? routing.location.pathname ? context.getCurrentPath()
: '/recover-password'; : '/recover-password';
context.navigate(url); context.navigate(url);
} else { } else {

View File

@ -27,12 +27,11 @@ describe('ActivationState', () => {
context.getState.returns({ context.getState.returns({
user: { user: {
isActive: false isActive: false
},
routing: {
location: {pathname: expectedPath}
} }
}); });
context.getCurrentPath.returns(expectedPath);
expectNavigate(mock, '/activation'); expectNavigate(mock, '/activation');
state.enter(context); state.enter(context);
@ -43,12 +42,11 @@ describe('ActivationState', () => {
context.getState.returns({ context.getState.returns({
user: { user: {
isActive: false isActive: false
},
routing: {
location: {pathname: expectedPath}
} }
}); });
context.getCurrentPath.returns(expectedPath);
expectNavigate(mock, expectedPath); expectNavigate(mock, expectedPath);
state.enter(context); state.enter(context);

View File

@ -30,10 +30,6 @@ describe('AuthFlow.functional', () => {
flow.setStore(store); flow.setStore(store);
navigate = function navigate(url) { // emulates router behaviour 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) { if (navigate.lastUrl !== url) {
navigate.lastUrl = url; navigate.lastUrl = url;
flow.handleRequest(url, navigate); flow.handleRequest(url, navigate);

View File

@ -30,9 +30,7 @@ describe('OAuthState', () => {
state: 'state' state: 'state'
}; };
context.getState.returns({ context.getQuery.returns(query);
routing: {location: {query}}
});
expectRun( expectRun(
mock, mock,
@ -52,9 +50,7 @@ describe('OAuthState', () => {
it('should transition to complete state on success', () => { it('should transition to complete state on success', () => {
const promise = Promise.resolve(); const promise = Promise.resolve();
context.getState.returns({ context.getQuery.returns({});
routing: {location: {query: {}}}
});
mock.expects('run').returns(promise); mock.expects('run').returns(promise);
expectState(mock, CompleteState); expectState(mock, CompleteState);

View File

@ -25,12 +25,11 @@ describe('RecoverPasswordState', () => {
it('should navigate to /recover-password', () => { it('should navigate to /recover-password', () => {
const expectedPath = '/recover-password'; const expectedPath = '/recover-password';
context.getState.returns({ context.getState.returns({
user: {isGuest: true}, user: {isGuest: true}
routing: {
location: {pathname: expectedPath}
}
}); });
context.getCurrentPath.returns(expectedPath);
expectNavigate(mock, expectedPath); expectNavigate(mock, expectedPath);
state.enter(context); state.enter(context);
@ -39,12 +38,11 @@ describe('RecoverPasswordState', () => {
it('should navigate to /recover-password/key', () => { it('should navigate to /recover-password/key', () => {
const expectedPath = '/recover-password/sasx5AS4d61'; const expectedPath = '/recover-password/sasx5AS4d61';
context.getState.returns({ context.getState.returns({
user: {isGuest: true}, user: {isGuest: true}
routing: {
location: {pathname: expectedPath}
}
}); });
context.getCurrentPath.returns(expectedPath);
expectNavigate(mock, expectedPath); expectNavigate(mock, expectedPath);
state.enter(context); state.enter(context);

View File

@ -7,6 +7,8 @@ export function bootstrap() {
getState: sinon.stub(), getState: sinon.stub(),
run() {}, run() {},
setState() {}, setState() {},
getCurrentPath: sinon.stub(),
getQuery: sinon.stub(),
navigate() {} navigate() {}
}; };