2019-12-08 00:32:00 +05:30
|
|
|
import expect from 'app/test/unexpected';
|
2017-05-26 00:41:57 +05:30
|
|
|
import sinon from 'sinon';
|
2024-12-23 19:23:49 +05:30
|
|
|
import { SynchronousPromise } from 'synchronous-promise';
|
2016-07-30 16:14:43 +05:30
|
|
|
|
2020-01-18 02:07:52 +05:30
|
|
|
import { Store } from 'redux';
|
|
|
|
|
2019-12-08 00:32:00 +05:30
|
|
|
import AuthFlow from 'app/services/authFlow/AuthFlow';
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2019-12-08 00:32:00 +05:30
|
|
|
import RegisterState from 'app/services/authFlow/RegisterState';
|
|
|
|
import ActivationState from 'app/services/authFlow/ActivationState';
|
|
|
|
import ResendActivationState from 'app/services/authFlow/ResendActivationState';
|
2016-06-10 10:36:21 +05:30
|
|
|
|
|
|
|
describe('AuthFlow.functional', () => {
|
2020-05-24 04:38:24 +05:30
|
|
|
let flow: AuthFlow;
|
|
|
|
let actions: {};
|
|
|
|
let store: Store;
|
|
|
|
let state: { user?: { isGuest: boolean; isActive: boolean } };
|
|
|
|
let navigate: (path: string, extra?: {}) => void;
|
|
|
|
|
2016-06-10 10:36:21 +05:30
|
|
|
beforeEach(() => {
|
2020-05-24 04:38:24 +05:30
|
|
|
actions = {};
|
|
|
|
store = {
|
|
|
|
getState: sinon.stub().named('store.getState'),
|
|
|
|
// @ts-ignore
|
|
|
|
dispatch: sinon
|
|
|
|
.spy(({ type, payload = {} }) => {
|
|
|
|
if (type === '@@router/TRANSITION' && payload.method === 'push') {
|
|
|
|
// emulate redux-router
|
|
|
|
// @ts-ignore
|
|
|
|
navigate(...payload.args);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.named('store.dispatch'),
|
|
|
|
};
|
|
|
|
|
|
|
|
state = {};
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
flow = new AuthFlow(actions);
|
|
|
|
flow.setStore(store);
|
|
|
|
|
|
|
|
let lastUrl: string;
|
|
|
|
|
|
|
|
navigate = function navigate(path, extra = {}) {
|
|
|
|
// emulates router behaviour
|
|
|
|
if (lastUrl !== path) {
|
|
|
|
lastUrl = path;
|
|
|
|
flow.handleRequest({ path, query: new URLSearchParams(), params: {}, ...extra }, navigate);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
sinon.stub(flow, 'run').named('flow.run');
|
|
|
|
sinon.spy(flow, 'navigate').named('flow.navigate');
|
|
|
|
// @ts-ignore
|
|
|
|
store.getState.returns(state);
|
2016-06-10 10:36:21 +05:30
|
|
|
});
|
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
describe('guest', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
Object.assign(state, {
|
|
|
|
user: {
|
|
|
|
isGuest: true,
|
|
|
|
},
|
|
|
|
auth: {
|
|
|
|
credentials: {
|
|
|
|
login: null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should redirect guest / -> /login', () => {
|
|
|
|
navigate('/');
|
|
|
|
|
|
|
|
expect(flow.navigate, 'was called twice');
|
|
|
|
expect(flow.navigate, 'to have a call satisfying', ['/login']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should redirect guest to /login after /login -> /', () => {
|
|
|
|
// this is to ensure, that when AuthFlow is already on LoginState (on /login)
|
|
|
|
// it will not allow user to go to / (which is forbidden for users) and will
|
|
|
|
// always redirect to /login, so that enter condition of state is always satisfied
|
|
|
|
|
|
|
|
navigate('/login');
|
|
|
|
navigate('/');
|
|
|
|
|
|
|
|
expect(flow.navigate, 'was called thrice');
|
|
|
|
expect(flow.navigate, 'to have calls satisfying', [['/login'], ['/login'], ['/login']]);
|
|
|
|
});
|
2016-06-10 10:36:21 +05:30
|
|
|
});
|
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
describe('oauth', () => {
|
|
|
|
it('should oauth without any rendering if no acceptance required', () => {
|
|
|
|
const expectedRedirect = 'foo';
|
2019-11-27 14:33:32 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
Object.assign(state, {
|
|
|
|
user: {
|
|
|
|
isGuest: false,
|
|
|
|
},
|
2019-11-27 14:33:32 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
auth: {
|
2021-03-28 20:37:46 +05:30
|
|
|
credentials: {},
|
2020-05-24 04:38:24 +05:30
|
|
|
oauth: {
|
2024-12-23 19:23:49 +05:30
|
|
|
params: {
|
|
|
|
clientId: 123,
|
|
|
|
},
|
2020-05-24 04:38:24 +05:30
|
|
|
prompt: [],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
// @ts-ignore
|
2024-12-23 19:23:49 +05:30
|
|
|
flow.run.onCall(0).returns(SynchronousPromise.resolve());
|
2020-05-24 04:38:24 +05:30
|
|
|
// @ts-ignore
|
2024-12-23 19:23:49 +05:30
|
|
|
flow.run.onCall(1).returns(
|
|
|
|
SynchronousPromise.resolve({
|
|
|
|
redirectUri: expectedRedirect,
|
|
|
|
}),
|
|
|
|
);
|
2020-05-24 04:38:24 +05:30
|
|
|
|
|
|
|
navigate('/oauth2');
|
|
|
|
|
|
|
|
expect(flow.run, 'to have calls satisfying', [
|
|
|
|
['oAuthValidate', {}],
|
|
|
|
['oAuthComplete', {}],
|
|
|
|
['redirect', expectedRedirect],
|
|
|
|
]);
|
|
|
|
});
|
2019-11-27 14:33:32 +05:30
|
|
|
});
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
describe('/resend-activation #goBack()', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
state.user = {
|
|
|
|
isGuest: true,
|
|
|
|
isActive: false,
|
|
|
|
};
|
|
|
|
});
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
it('should goBack to /activation', () => {
|
|
|
|
navigate('/activation');
|
|
|
|
expect(flow.state, 'to be a', ActivationState);
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
flow.state.reject(flow);
|
|
|
|
expect(flow.state, 'to be a', ResendActivationState);
|
|
|
|
|
|
|
|
flow.state.goBack(flow);
|
|
|
|
expect(flow.state, 'to be a', ActivationState);
|
|
|
|
});
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
it('should goBack to /register', () => {
|
|
|
|
navigate('/register');
|
|
|
|
expect(flow.state, 'to be a', RegisterState);
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
flow.state.reject(flow, { requestEmail: true });
|
|
|
|
expect(flow.state, 'to be a', ResendActivationState);
|
2016-06-10 10:36:21 +05:30
|
|
|
|
2020-05-24 04:38:24 +05:30
|
|
|
flow.state.goBack(flow);
|
|
|
|
expect(flow.state, 'to be a', RegisterState);
|
|
|
|
});
|
2016-06-10 10:36:21 +05:30
|
|
|
});
|
|
|
|
});
|