Skip to content
65 changes: 65 additions & 0 deletions app/sagas/__tests__/login.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { runSaga } from 'redux-saga';

import { SERVER } from '../../actions/actionsTypes';
import database from '../../lib/database';
import UserPreferences from '../../lib/methods/userPreferences';
import { TOKEN_KEY } from '../../lib/constants/keys';
import { handleLogout } from '../login';

jest.mock('../../lib/methods/logout', () => ({
logout: jest.fn(() => Promise.resolve()),
removeServerData: jest.fn(),
removeServerDatabase: jest.fn()
}));
jest.mock('../../lib/services/connect', () => ({
connect: jest.fn(),
disconnect: jest.fn(),
login: jest.fn(),
loginWithPassword: jest.fn()
}));
jest.mock('../../lib/services/voip/MediaSessionInstance', () => ({ mediaSessionInstance: {} }));
jest.mock('../../lib/services/voip/MediaSessionStore', () => ({ mediaSessionStore: { getState: () => ({}) } }));
jest.mock('../../lib/methods/helpers/info', () => ({ showErrorAlert: jest.fn() }));
jest.mock('../../lib/database', () => ({ servers: { get: jest.fn() } }));
jest.mock('../../lib/methods/userPreferences', () => ({ getString: jest.fn() }));

const loggedOutServer = 'https://open.rocket.chat';

const setServers = servers => {
database.servers.get.mockReturnValue({ query: () => ({ fetch: () => Promise.resolve(servers) }) });
};

const runForcedLogout = async () => {
const dispatched = [];
await runSaga(
{
dispatch: action => dispatched.push(action),
getState: () => ({ server: { server: loggedOutServer } })
},
handleLogout,
{ forcedByServer: true }
).toPromise();
return dispatched;
};

describe('handleLogout forced by the server', () => {
beforeEach(() => jest.clearAllMocks());

it('should set the previous server to another logged in server, so the user can leave NewServerView', async () => {
setServers([{ id: 'https://other.rocket.chat' }]);
UserPreferences.getString.mockImplementation(key => (key === `${TOKEN_KEY}-https://other.rocket.chat` ? 'token' : null));

const dispatched = await runForcedLogout();

expect(dispatched).toEqual(expect.arrayContaining([{ type: SERVER.INIT_ADD, previousServer: 'https://other.rocket.chat' }]));
});

it('should not set a previous server when no other server is logged in', async () => {
setServers([{ id: 'https://logged-out.rocket.chat' }]);
UserPreferences.getString.mockReturnValue(null);

const dispatched = await runForcedLogout();

expect(dispatched.some(({ type }) => type === SERVER.INIT_ADD)).toBe(false);
});
});
14 changes: 12 additions & 2 deletions app/sagas/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Q } from '@nozbe/watermelondb';
import dayjs from '../lib/dayjs';
import * as types from '../actions/actionsTypes';
import { appStart } from '../actions/app';
import { selectServerRequest, serverFinishAdd } from '../actions/server';
import { selectServerRequest, serverFinishAdd, serverInitAdd } from '../actions/server';
import { loginFailure, loginSuccess, logout as logoutAction, setUser } from '../actions/login';
import { roomsRequest } from '../actions/rooms';
import log, { events, logEvent } from '../lib/methods/helpers/log';
Expand Down Expand Up @@ -369,7 +369,13 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
}
};

const handleLogout = function* handleLogout({ forcedByServer, message }) {
const findLoggedInServer = function* findLoggedInServer() {
const serversCollection = database.servers.get('servers');
const servers = yield serversCollection.query().fetch();
return servers.find(({ id }) => UserPreferences.getString(`${TOKEN_KEY}-${id}`));
};

export const handleLogout = function* handleLogout({ forcedByServer, message }) {
yield put(encryptionStop());
yield put(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Logging_out') }));
const server = yield select(getServer);
Expand All @@ -379,6 +385,10 @@ const handleLogout = function* handleLogout({ forcedByServer, message }) {

// if the user was logged out by the server
if (forcedByServer) {
const loggedInServer = yield call(findLoggedInServer);
if (loggedInServer) {
yield put(serverInitAdd(loggedInServer.id));
}
yield put(appStart({ root: RootEnum.ROOT_OUTSIDE }));
if (message) {
showErrorAlert(I18n.t(message), I18n.t('Oops'));
Expand Down
Loading