2016-10-30 17:42:49 +05:30
|
|
|
import expect from 'unexpected';
|
|
|
|
|
|
|
|
import accounts from 'services/api/accounts';
|
2016-11-08 12:00:53 +05:30
|
|
|
import authentication from 'services/api/authentication';
|
2016-11-14 10:58:25 +05:30
|
|
|
import {
|
|
|
|
authenticate,
|
|
|
|
revoke,
|
|
|
|
add, ADD,
|
|
|
|
activate, ACTIVATE,
|
|
|
|
remove,
|
2016-11-15 11:25:15 +05:30
|
|
|
reset,
|
|
|
|
logoutAll
|
2016-11-14 10:58:25 +05:30
|
|
|
} from 'components/accounts/actions';
|
2016-11-05 15:41:41 +05:30
|
|
|
import { SET_LOCALE } from 'components/i18n/actions';
|
2016-10-30 17:42:49 +05:30
|
|
|
|
2016-11-05 15:41:41 +05:30
|
|
|
import { updateUser } from 'components/user/actions';
|
2016-10-30 17:42:49 +05:30
|
|
|
|
|
|
|
const account = {
|
|
|
|
id: 1,
|
|
|
|
username: 'username',
|
|
|
|
email: 'email@test.com',
|
|
|
|
token: 'foo',
|
2016-11-05 15:41:41 +05:30
|
|
|
refreshToken: 'bar'
|
2016-10-30 17:42:49 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
const user = {
|
|
|
|
id: 1,
|
|
|
|
username: 'username',
|
|
|
|
email: 'email@test.com',
|
2016-11-05 15:41:41 +05:30
|
|
|
lang: 'be'
|
2016-10-30 17:42:49 +05:30
|
|
|
};
|
|
|
|
|
2016-11-13 02:01:44 +05:30
|
|
|
describe('components/accounts/actions', () => {
|
2016-10-30 17:42:49 +05:30
|
|
|
let dispatch;
|
|
|
|
let getState;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2016-11-05 15:41:41 +05:30
|
|
|
dispatch = sinon.spy((arg) =>
|
|
|
|
typeof arg === 'function' ? arg(dispatch, getState) : arg
|
|
|
|
).named('store.dispatch');
|
|
|
|
getState = sinon.stub().named('store.getState');
|
2016-10-30 17:42:49 +05:30
|
|
|
|
|
|
|
getState.returns({
|
|
|
|
accounts: [],
|
|
|
|
user: {}
|
|
|
|
});
|
|
|
|
|
2016-11-08 12:00:53 +05:30
|
|
|
sinon.stub(authentication, 'validateToken').named('authentication.validateToken');
|
|
|
|
authentication.validateToken.returns(Promise.resolve({
|
|
|
|
token: account.token,
|
|
|
|
refreshToken: account.refreshToken
|
|
|
|
}));
|
|
|
|
|
2016-10-30 17:42:49 +05:30
|
|
|
sinon.stub(accounts, 'current').named('accounts.current');
|
|
|
|
accounts.current.returns(Promise.resolve(user));
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
2016-11-08 12:00:53 +05:30
|
|
|
authentication.validateToken.restore();
|
2016-10-30 17:42:49 +05:30
|
|
|
accounts.current.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#authenticate()', () => {
|
2016-11-05 15:41:41 +05:30
|
|
|
it('should request user state using token', () =>
|
|
|
|
authenticate(account)(dispatch).then(() =>
|
|
|
|
expect(accounts.current, 'to have a call satisfying', [
|
|
|
|
{token: account.token}
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
2016-10-30 17:42:49 +05:30
|
|
|
|
|
|
|
it(`dispatches ${ADD} action`, () =>
|
|
|
|
authenticate(account)(dispatch).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
add(account)
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it(`dispatches ${ACTIVATE} action`, () =>
|
|
|
|
authenticate(account)(dispatch).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
activate(account)
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2016-11-05 15:41:41 +05:30
|
|
|
it(`dispatches ${SET_LOCALE} action`, () =>
|
|
|
|
authenticate(account)(dispatch).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
{type: SET_LOCALE, payload: {locale: 'be'}}
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2016-10-30 17:42:49 +05:30
|
|
|
it('should update user state', () =>
|
|
|
|
authenticate(account)(dispatch).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
2016-11-05 15:41:41 +05:30
|
|
|
updateUser({...user, isGuest: false})
|
2016-10-30 17:42:49 +05:30
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it('resolves with account', () =>
|
|
|
|
authenticate(account)(dispatch).then((resp) =>
|
|
|
|
expect(resp, 'to equal', account)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it('rejects when bad auth data', () => {
|
|
|
|
accounts.current.returns(Promise.reject({}));
|
|
|
|
|
2016-11-05 15:41:41 +05:30
|
|
|
return expect(authenticate(account)(dispatch), 'to be rejected').then(() =>
|
|
|
|
expect(dispatch, 'was not called')
|
|
|
|
);
|
2016-10-30 17:42:49 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#revoke()', () => {
|
2016-11-15 11:25:15 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
sinon.stub(authentication, 'logout').named('authentication.logout');
|
|
|
|
});
|
2016-10-30 17:42:49 +05:30
|
|
|
|
2016-11-15 11:25:15 +05:30
|
|
|
afterEach(() => {
|
|
|
|
authentication.logout.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when one account available', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
getState.returns({
|
|
|
|
accounts: {
|
|
|
|
active: account,
|
|
|
|
available: [account]
|
|
|
|
},
|
|
|
|
user
|
|
|
|
});
|
2016-10-30 17:42:49 +05:30
|
|
|
});
|
|
|
|
|
2016-11-15 11:25:15 +05:30
|
|
|
it('should dispatch reset action', () =>
|
|
|
|
revoke(account)(dispatch, getState).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
reset()
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it('should call logout api method in background', () =>
|
|
|
|
revoke(account)(dispatch, getState).then(() =>
|
|
|
|
expect(authentication.logout, 'to have a call satisfying', [
|
|
|
|
account
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it('should update user state', () =>
|
|
|
|
revoke(account)(dispatch, getState).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
{payload: {isGuest: true}}
|
|
|
|
// updateUser({isGuest: true})
|
|
|
|
])
|
|
|
|
// expect(dispatch, 'to have calls satisfying', [
|
|
|
|
// [remove(account)],
|
|
|
|
// [expect.it('to be a function')]
|
|
|
|
// // [logout()] // TODO: this is not a plain action. How should we simplify its testing?
|
|
|
|
// ])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when multiple accounts available', () => {
|
|
|
|
const account2 = {...account, id: 2};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
getState.returns({
|
|
|
|
accounts: {
|
|
|
|
active: account2,
|
|
|
|
available: [account, account2]
|
|
|
|
},
|
|
|
|
user
|
|
|
|
});
|
2016-11-05 15:41:41 +05:30
|
|
|
});
|
2016-11-15 11:25:15 +05:30
|
|
|
|
|
|
|
it('should switch to the next account', () =>
|
|
|
|
revoke(account2)(dispatch, getState).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
activate(account)
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it('should remove current account', () =>
|
|
|
|
revoke(account2)(dispatch, getState).then(() =>
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
remove(account2)
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
it('should call logout api method in background', () =>
|
|
|
|
revoke(account2)(dispatch, getState).then(() =>
|
|
|
|
expect(authentication.logout, 'to have a call satisfying', [
|
|
|
|
account2
|
|
|
|
])
|
|
|
|
)
|
|
|
|
);
|
2016-10-30 17:42:49 +05:30
|
|
|
});
|
2016-11-15 11:25:15 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('#logoutAll()', () => {
|
|
|
|
const account2 = {...account, id: 2};
|
2016-10-30 17:42:49 +05:30
|
|
|
|
2016-11-15 11:25:15 +05:30
|
|
|
beforeEach(() => {
|
2016-11-13 02:01:44 +05:30
|
|
|
getState.returns({
|
|
|
|
accounts: {
|
2016-11-15 11:25:15 +05:30
|
|
|
active: account2,
|
|
|
|
available: [account, account2]
|
2016-11-13 02:01:44 +05:30
|
|
|
},
|
|
|
|
user
|
|
|
|
});
|
|
|
|
|
2016-11-15 11:25:15 +05:30
|
|
|
sinon.stub(authentication, 'logout').named('authentication.logout');
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
authentication.logout.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should call logout api method for each account', () => {
|
|
|
|
logoutAll()(dispatch, getState);
|
|
|
|
|
|
|
|
expect(authentication.logout, 'to have calls satisfying', [
|
|
|
|
[account],
|
|
|
|
[account2]
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should dispatch reset', () => {
|
|
|
|
logoutAll()(dispatch, getState);
|
|
|
|
|
|
|
|
expect(dispatch, 'to have a call satisfying', [
|
|
|
|
reset()
|
|
|
|
]);
|
2016-10-30 17:42:49 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|