mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-05-31 14:11:58 +05:30
#48: initial logic for multy-accounts actions
This commit is contained in:
134
tests/components/accounts/actions.test.js
Normal file
134
tests/components/accounts/actions.test.js
Normal file
@@ -0,0 +1,134 @@
|
||||
import expect from 'unexpected';
|
||||
|
||||
import accounts from 'services/api/accounts';
|
||||
import { authenticate, revoke, add, activate, remove, ADD, REMOVE, ACTIVATE } from 'components/accounts/actions';
|
||||
|
||||
import { updateUser, logout } from 'components/user/actions';
|
||||
|
||||
const account = {
|
||||
id: 1,
|
||||
username: 'username',
|
||||
email: 'email@test.com',
|
||||
token: 'foo',
|
||||
refreshToken: 'foo'
|
||||
};
|
||||
|
||||
const user = {
|
||||
id: 1,
|
||||
username: 'username',
|
||||
email: 'email@test.com',
|
||||
};
|
||||
|
||||
describe('Accounts actions', () => {
|
||||
let dispatch;
|
||||
let getState;
|
||||
|
||||
beforeEach(() => {
|
||||
dispatch = sinon.spy(function dispatch(arg) {
|
||||
return typeof arg === 'function' ? arg(dispatch, getState) : arg;
|
||||
}).named('dispatch');
|
||||
getState = sinon.stub().named('getState');
|
||||
|
||||
getState.returns({
|
||||
accounts: [],
|
||||
user: {}
|
||||
});
|
||||
|
||||
sinon.stub(accounts, 'current').named('accounts.current');
|
||||
accounts.current.returns(Promise.resolve(user));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
accounts.current.restore();
|
||||
});
|
||||
|
||||
describe('#authenticate()', () => {
|
||||
it('should request user state using token', () => {
|
||||
authenticate(account)(dispatch);
|
||||
|
||||
expect(accounts.current, 'to have a call satisfying', [
|
||||
{token: account.token}
|
||||
]);
|
||||
});
|
||||
|
||||
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)
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
it('should update user state', () =>
|
||||
authenticate(account)(dispatch).then(() =>
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
updateUser(user)
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
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({}));
|
||||
|
||||
const promise = authenticate(account)(dispatch);
|
||||
|
||||
expect(promise, 'to be rejected');
|
||||
|
||||
return promise.catch(() => {
|
||||
expect(dispatch, 'was not called');
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#revoke()', () => {
|
||||
it(`should dispatch ${REMOVE} action`, () => {
|
||||
revoke(account)(dispatch, getState);
|
||||
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
remove(account)
|
||||
]);
|
||||
});
|
||||
|
||||
it('should switch next account if available', () => {
|
||||
const account2 = {...account, id: 2};
|
||||
|
||||
getState.returns({
|
||||
accounts: [account2]
|
||||
});
|
||||
|
||||
return revoke(account)(dispatch, getState).then(() =>
|
||||
expect(dispatch, 'to have calls satisfying', [
|
||||
[remove(account)],
|
||||
[expect.it('to be a function')]
|
||||
// [authenticate(account2)] // TODO: this is not a plain action. How should we simplify its testing?
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('should logout if no other accounts available', () => {
|
||||
revoke(account)(dispatch, getState)
|
||||
.then(() =>
|
||||
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?
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
87
tests/components/accounts/reducer.test.js
Normal file
87
tests/components/accounts/reducer.test.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import expect from 'unexpected';
|
||||
|
||||
import accounts from 'components/accounts/reducer';
|
||||
import { ADD, REMOVE, ACTIVATE } from 'components/accounts/actions';
|
||||
|
||||
const account = {
|
||||
id: 1,
|
||||
username: 'username',
|
||||
email: 'email@test.com',
|
||||
token: 'foo',
|
||||
refreshToken: 'foo'
|
||||
};
|
||||
|
||||
describe('Accounts reducer', () => {
|
||||
let initial;
|
||||
|
||||
beforeEach(() => {
|
||||
initial = accounts(null, {});
|
||||
});
|
||||
|
||||
it('should be empty', () => expect(accounts(null, {}), 'to equal', {
|
||||
active: null,
|
||||
available: []
|
||||
}));
|
||||
|
||||
describe(ACTIVATE, () => {
|
||||
it('sets active account', () => {
|
||||
expect(accounts(initial, {
|
||||
type: ACTIVATE,
|
||||
payload: account
|
||||
}), 'to satisfy', {
|
||||
active: account
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(ADD, () => {
|
||||
it('adds an account', () =>
|
||||
expect(accounts(initial, {
|
||||
type: ADD,
|
||||
payload: account
|
||||
}), 'to satisfy', {
|
||||
available: [account]
|
||||
})
|
||||
);
|
||||
|
||||
it('should not add the same account twice', () =>
|
||||
expect(accounts({...initial, available: [account]}, {
|
||||
type: ADD,
|
||||
payload: account
|
||||
}), 'to satisfy', {
|
||||
available: [account]
|
||||
})
|
||||
);
|
||||
|
||||
it('throws, when account is invalid', () => {
|
||||
expect(() => accounts(initial, {
|
||||
type: ADD
|
||||
}), 'to throw', 'Invalid or empty payload passed for accounts.add');
|
||||
|
||||
expect(() => accounts(initial, {
|
||||
type: ADD,
|
||||
payload: {}
|
||||
}), 'to throw', 'Invalid or empty payload passed for accounts.add');
|
||||
});
|
||||
});
|
||||
|
||||
describe(REMOVE, () => {
|
||||
it('should remove an account', () =>
|
||||
expect(accounts({...initial, available: [account]}, {
|
||||
type: REMOVE,
|
||||
payload: account
|
||||
}), 'to equal', initial)
|
||||
);
|
||||
|
||||
it('throws, when account is invalid', () => {
|
||||
expect(() => accounts(initial, {
|
||||
type: REMOVE
|
||||
}), 'to throw', 'Invalid or empty payload passed for accounts.remove');
|
||||
|
||||
expect(() => accounts(initial, {
|
||||
type: REMOVE,
|
||||
payload: {}
|
||||
}), 'to throw', 'Invalid or empty payload passed for accounts.remove');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user