mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-27 15:30:37 +05:30
Add tests for auth middlewares
This commit is contained in:
parent
5d054c3baa
commit
54664044eb
@ -4,6 +4,8 @@ import request from 'services/request';
|
||||
import bearerHeaderMiddleware from './middlewares/bearerHeaderMiddleware';
|
||||
import refreshTokenMiddleware from './middlewares/refreshTokenMiddleware';
|
||||
|
||||
let promise;
|
||||
|
||||
/**
|
||||
* Initializes User state with the fresh data
|
||||
*
|
||||
@ -12,10 +14,14 @@ import refreshTokenMiddleware from './middlewares/refreshTokenMiddleware';
|
||||
* @return {Promise} - a promise, that resolves in User state
|
||||
*/
|
||||
export function factory(store) {
|
||||
if (promise) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
request.addMiddleware(refreshTokenMiddleware(store));
|
||||
request.addMiddleware(bearerHeaderMiddleware(store));
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
promise = new Promise((resolve, reject) => {
|
||||
const {user} = store.getState();
|
||||
|
||||
if (user.token) {
|
||||
@ -26,4 +32,6 @@ export function factory(store) {
|
||||
// auto-detect guests language
|
||||
store.dispatch(changeLang(user.lang)).then(resolve, reject);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ export default function refreshTokenMiddleware({dispatch, getState}) {
|
||||
const {isGuest, refreshToken, token} = getState().user;
|
||||
const isRefreshTokenRequest = data.url.includes('refresh-token');
|
||||
|
||||
if (isGuest || isRefreshTokenRequest || !token) {
|
||||
if (isGuest || isRefreshTokenRequest) {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -65,14 +65,14 @@ export default function refreshTokenMiddleware({dispatch, getState}) {
|
||||
function requestAccessToken(refreshToken, dispatch) {
|
||||
let promise;
|
||||
if (refreshToken) {
|
||||
promise = authentication.refreshToken(refreshToken);
|
||||
promise = authentication.requestToken(refreshToken);
|
||||
} else {
|
||||
promise = Promise.reject();
|
||||
}
|
||||
|
||||
return promise
|
||||
.then((resp) => dispatch(updateUser({
|
||||
token: resp.access_token
|
||||
.then(({token}) => dispatch(updateUser({
|
||||
token
|
||||
})))
|
||||
.catch(() => dispatch(logout()));
|
||||
}
|
||||
|
@ -36,10 +36,19 @@ export default {
|
||||
);
|
||||
},
|
||||
|
||||
refreshToken(refresh_token) {
|
||||
/**
|
||||
* Request new access token using a refreshToken
|
||||
*
|
||||
* @param {string} refreshToken
|
||||
*
|
||||
* @return {Promise} - resolves to {token}
|
||||
*/
|
||||
requestToken(refreshToken) {
|
||||
return request.post(
|
||||
'/api/authentication/refresh-token',
|
||||
{refresh_token}
|
||||
);
|
||||
{refresh_token: refreshToken}
|
||||
).then((resp) => ({
|
||||
token: resp.access_token
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
@ -0,0 +1,44 @@
|
||||
import expect from 'unexpected';
|
||||
|
||||
import bearerHeaderMiddleware from 'components/user/middlewares/bearerHeaderMiddleware';
|
||||
|
||||
describe('bearerHeaderMiddleware', () => {
|
||||
it('should set Authorization header', () => {
|
||||
const token = 'foo';
|
||||
const middleware = bearerHeaderMiddleware({
|
||||
getState: () => ({
|
||||
user: {token}
|
||||
})
|
||||
});
|
||||
|
||||
const data = {
|
||||
options: {
|
||||
headers: {}
|
||||
}
|
||||
};
|
||||
|
||||
middleware.before(data);
|
||||
|
||||
expect(data.options.headers, 'to satisfy', {
|
||||
Authorization: `Bearer ${token}`
|
||||
});
|
||||
});
|
||||
|
||||
it('should not set Authorization header if no token', () => {
|
||||
const middleware = bearerHeaderMiddleware({
|
||||
getState: () => ({
|
||||
user: {}
|
||||
})
|
||||
});
|
||||
|
||||
const data = {
|
||||
options: {
|
||||
headers: {}
|
||||
}
|
||||
};
|
||||
|
||||
middleware.before(data);
|
||||
|
||||
expect(data.options.headers.Authorization, 'to be undefined');
|
||||
});
|
||||
});
|
154
tests/components/user/middlewares/refreshTokenMiddleware.test.js
Normal file
154
tests/components/user/middlewares/refreshTokenMiddleware.test.js
Normal file
@ -0,0 +1,154 @@
|
||||
import expect from 'unexpected';
|
||||
|
||||
import refreshTokenMiddleware from 'components/user/middlewares/refreshTokenMiddleware';
|
||||
|
||||
import authentication from 'services/api/authentication';
|
||||
|
||||
const refreshToken = 'foo';
|
||||
const expiredToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzA3NjE0NDMsImV4cCI6MTQ3MDc2MTQ0MywiaWF0IjoxNDcwNzYxNDQzLCJqdGkiOiJpZDEyMzQ1NiJ9.gWdnzfQQvarGpkbldUvB8qdJZSVkvdNtCbhbbl2yJW8';
|
||||
// valid till 2100 year
|
||||
const validToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzA3NjE5NzcsImV4cCI6NDEwMjQ0NDgwMCwiaWF0IjoxNDcwNzYxOTc3LCJqdGkiOiJpZDEyMzQ1NiJ9.M4KY4QgHOUzhpAZjWoHJbGsEJPR-RBsJ1c1BKyxvAoU';
|
||||
|
||||
describe('refreshTokenMiddleware', () => {
|
||||
let middleware;
|
||||
let getState;
|
||||
let dispatch;
|
||||
|
||||
beforeEach(() => {
|
||||
sinon.stub(authentication, 'requestToken').named('authentication.requestToken');
|
||||
|
||||
getState = sinon.stub().named('store.getState');
|
||||
dispatch = sinon.stub().named('store.dispatch');
|
||||
|
||||
middleware = refreshTokenMiddleware({getState, dispatch});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
authentication.requestToken.restore();
|
||||
});
|
||||
|
||||
describe('#before', () => {
|
||||
it('should request new token', () => {
|
||||
getState.returns({
|
||||
user: {
|
||||
token: expiredToken,
|
||||
refreshToken,
|
||||
isGuest: false
|
||||
}
|
||||
});
|
||||
|
||||
const data = {
|
||||
url: 'foo',
|
||||
options: {
|
||||
headers: {}
|
||||
}
|
||||
};
|
||||
|
||||
authentication.requestToken.returns(Promise.resolve({token: validToken}));
|
||||
|
||||
return middleware.before(data).then((resp) => {
|
||||
expect(resp, 'to satisfy', data);
|
||||
|
||||
expect(authentication.requestToken, 'to have a call satisfying', [
|
||||
refreshToken
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not be applied for guests', () => {
|
||||
getState.returns({
|
||||
user: {
|
||||
isGuest: true
|
||||
}
|
||||
});
|
||||
|
||||
authentication.requestToken.returns(Promise.resolve({token: validToken}));
|
||||
|
||||
const data = {url: 'foo'};
|
||||
const resp = middleware.before(data);
|
||||
|
||||
expect(resp, 'to satisfy', data);
|
||||
|
||||
expect(authentication.requestToken, 'was not called');
|
||||
});
|
||||
|
||||
it('should not apply to refresh-token request', () => {
|
||||
getState.returns({
|
||||
user: {}
|
||||
});
|
||||
|
||||
authentication.requestToken.returns(Promise.resolve({token: validToken}));
|
||||
|
||||
const data = {url: '/refresh-token'};
|
||||
const resp = middleware.before(data);
|
||||
|
||||
expect(resp, 'to satisfy', data);
|
||||
|
||||
expect(authentication.requestToken, 'was not called');
|
||||
});
|
||||
|
||||
xit('should update user with new token'); // TODO: need a way to test, that action was called
|
||||
|
||||
xit('should logout if token request failed', () => {
|
||||
getState.returns({
|
||||
user: {
|
||||
token: expiredToken,
|
||||
refreshToken,
|
||||
isGuest: false
|
||||
}
|
||||
});
|
||||
|
||||
authentication.requestToken.returns(Promise.reject());
|
||||
|
||||
return middleware.before({url: 'foo'}).then((resp) => {
|
||||
// TODO: need a way to test, that action was called
|
||||
expect(dispatch, 'to have a call satisfying', logout);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#catch', () => {
|
||||
it('should request new token', () => {
|
||||
getState.returns({
|
||||
user: {
|
||||
refreshToken
|
||||
}
|
||||
});
|
||||
|
||||
const restart = sinon.stub().named('restart');
|
||||
|
||||
const data = {
|
||||
url: 'foo',
|
||||
options: {
|
||||
headers: {}
|
||||
}
|
||||
};
|
||||
|
||||
authentication.requestToken.returns(Promise.resolve({token: validToken}));
|
||||
|
||||
return middleware.catch({
|
||||
status: 401,
|
||||
message: 'Token expired'
|
||||
}, restart).then(() => {
|
||||
expect(authentication.requestToken, 'to have a call satisfying', [
|
||||
refreshToken
|
||||
]);
|
||||
expect(restart, 'was called');
|
||||
});
|
||||
});
|
||||
|
||||
xit('should logout user if token cannot be refreshed'); // TODO: need a way to test, that action was called
|
||||
|
||||
it('should pass the rest of failed requests through', () => {
|
||||
const resp = {};
|
||||
|
||||
const promise = middleware.catch(resp);
|
||||
|
||||
expect(promise, 'to be rejected');
|
||||
|
||||
return promise.catch((actual) => {
|
||||
expect(actual, 'to be', resp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user