forked from Ivasoft/mattermost-mobile
MM-16752 Fix unhandled promise rejection TypeError state.websocket.lastConnectAt (#3039)
This commit is contained in:
committed by
Miguel Alatzar
parent
8167c2ddea
commit
76df42bbd1
@@ -199,7 +199,7 @@ export function loadPostsIfNecessaryWithRetry(channelId) {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const {lastConnectAt} = state.websocket;
|
||||
const lastConnectAt = state.websocket?.lastConnectAt || 0;
|
||||
const lastGetPosts = state.views.channel.lastGetPosts[channelId];
|
||||
|
||||
let since;
|
||||
|
||||
@@ -4,7 +4,15 @@
|
||||
import configureStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import {handleSelectChannelByName} from 'app/actions/views/channel';
|
||||
import initialState from 'app/initial_state';
|
||||
import testHelper from 'test/test_helper';
|
||||
|
||||
import {
|
||||
handleSelectChannelByName,
|
||||
loadPostsIfNecessaryWithRetry,
|
||||
} from 'app/actions/views/channel';
|
||||
|
||||
import postReducer from 'mattermost-redux/reducers/entities/posts';
|
||||
|
||||
jest.mock('mattermost-redux/selectors/entities/channels', () => ({
|
||||
getChannel: () => ({data: 'received-channel-id'}),
|
||||
@@ -19,6 +27,9 @@ describe('Actions.Views.Channel', () => {
|
||||
|
||||
const MOCK_SELECT_CHANNEL_TYPE = 'MOCK_SELECT_CHANNEL_TYPE';
|
||||
const MOCK_RECEIVE_CHANNEL_TYPE = 'MOCK_RECEIVE_CHANNEL_TYPE';
|
||||
const MOCK_RECEIVED_POSTS = 'RECEIVED_POSTS';
|
||||
const MOCK_RECEIVED_POSTS_IN_CHANNEL = 'RECEIVED_POSTS_IN_CHANNEL';
|
||||
const MOCK_RECEIVED_POSTS_SINCE = 'MOCK_RECEIVED_POSTS_SINCE';
|
||||
|
||||
const actions = require('mattermost-redux/actions/channels');
|
||||
actions.getChannelByNameAndTeamName = jest.fn((teamName) => {
|
||||
@@ -38,14 +49,51 @@ describe('Actions.Views.Channel', () => {
|
||||
type: MOCK_SELECT_CHANNEL_TYPE,
|
||||
data: 'selected-channel-id',
|
||||
});
|
||||
const postActions = require('mattermost-redux/actions/posts');
|
||||
postActions.getPostsSince = jest.fn(() => {
|
||||
return {
|
||||
type: MOCK_RECEIVED_POSTS_SINCE,
|
||||
data: {
|
||||
order: [],
|
||||
posts: {},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
postActions.getPosts = jest.fn((channelId) => {
|
||||
const order = [];
|
||||
const posts = {};
|
||||
|
||||
for (let i = 0; i < 60; i++) {
|
||||
const p = testHelper.fakePost(channelId);
|
||||
order.push(p.id);
|
||||
posts[p.id] = p;
|
||||
}
|
||||
|
||||
return {
|
||||
type: MOCK_RECEIVED_POSTS,
|
||||
data: {
|
||||
order,
|
||||
posts,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const postUtils = require('mattermost-redux/utils/post_utils');
|
||||
postUtils.getLastCreateAt = jest.fn((array) => {
|
||||
return array[0].create_at;
|
||||
});
|
||||
|
||||
let nextPostState = {};
|
||||
const currentUserId = 'current-user-id';
|
||||
const currentChannelId = 'channel-id';
|
||||
const currentChannelName = 'channel-name';
|
||||
const currentTeamId = 'current-team-id';
|
||||
const currentTeamName = 'current-team-name';
|
||||
const storeObj = {
|
||||
...initialState,
|
||||
entities: {
|
||||
...initialState.entities,
|
||||
users: {
|
||||
currentUserId,
|
||||
},
|
||||
@@ -93,4 +141,84 @@ describe('Actions.Views.Channel', () => {
|
||||
const storeBatchActions = storeActions.some(({type}) => type === 'BATCHING_REDUCER.BATCH');
|
||||
expect(storeBatchActions).toBe(false);
|
||||
});
|
||||
|
||||
test('loadPostsIfNecessaryWithRetry for the first time', async () => {
|
||||
store = mockStore(storeObj);
|
||||
|
||||
await store.dispatch(loadPostsIfNecessaryWithRetry(currentChannelId));
|
||||
expect(postActions.getPosts).toBeCalled();
|
||||
|
||||
const storeActions = store.getActions();
|
||||
const storeBatchActions = storeActions.filter(({type}) => type === 'BATCHING_REDUCER.BATCH');
|
||||
const receivedPosts = storeActions.find(({type}) => type === MOCK_RECEIVED_POSTS);
|
||||
const receivedPostsAtAction = storeBatchActions[0].payload.some((action) => action.type === 'RECEIVED_POSTS_FOR_CHANNEL_AT_TIME');
|
||||
|
||||
nextPostState = postReducer(store.getState().entities.posts, receivedPosts);
|
||||
nextPostState = postReducer(nextPostState, {
|
||||
type: MOCK_RECEIVED_POSTS_IN_CHANNEL,
|
||||
channelId: currentChannelId,
|
||||
data: receivedPosts.data,
|
||||
recent: true,
|
||||
});
|
||||
|
||||
expect(receivedPostsAtAction).toBe(true);
|
||||
});
|
||||
|
||||
test('loadPostsIfNecessaryWithRetry get posts since', async () => {
|
||||
store = mockStore({
|
||||
...storeObj,
|
||||
entities: {
|
||||
...storeObj.entities,
|
||||
posts: nextPostState,
|
||||
},
|
||||
views: {
|
||||
...storeObj.views,
|
||||
channel: {
|
||||
...storeObj.views.channel,
|
||||
lastGetPosts: {
|
||||
[currentChannelId]: Date.now(),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await store.dispatch(loadPostsIfNecessaryWithRetry(currentChannelId));
|
||||
const storeActions = store.getActions();
|
||||
const receivedPostsSince = storeActions.find(({type}) => type === MOCK_RECEIVED_POSTS_SINCE);
|
||||
|
||||
expect(postUtils.getLastCreateAt).toBeCalled();
|
||||
expect(postActions.getPostsSince).toHaveBeenCalledWith(currentChannelId, Object.values(store.getState().entities.posts.posts)[0].create_at);
|
||||
expect(receivedPostsSince).not.toBe(null);
|
||||
});
|
||||
|
||||
test('loadPostsIfNecessaryWithRetry get posts since the websocket reconnected', async () => {
|
||||
const time = Date.now();
|
||||
store = mockStore({
|
||||
...storeObj,
|
||||
entities: {
|
||||
...storeObj.entities,
|
||||
posts: nextPostState,
|
||||
},
|
||||
views: {
|
||||
...storeObj.views,
|
||||
channel: {
|
||||
...storeObj.views.channel,
|
||||
lastGetPosts: {
|
||||
[currentChannelId]: time,
|
||||
},
|
||||
},
|
||||
},
|
||||
websocket: {
|
||||
lastConnectAt: time + (1 * 60 * 1000),
|
||||
},
|
||||
});
|
||||
|
||||
await store.dispatch(loadPostsIfNecessaryWithRetry(currentChannelId));
|
||||
const storeActions = store.getActions();
|
||||
const receivedPostsSince = storeActions.find(({type}) => type === MOCK_RECEIVED_POSTS_SINCE);
|
||||
|
||||
expect(postUtils.getLastCreateAt).not.toBeCalled();
|
||||
expect(postActions.getPostsSince).toHaveBeenCalledWith(currentChannelId, store.getState().views.channel.lastGetPosts[currentChannelId]);
|
||||
expect(receivedPostsSince).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import assert from 'assert';
|
||||
|
||||
import Config from 'assets/config.json';
|
||||
|
||||
import Client from 'mattermost-redux/client/client';
|
||||
import Client from 'mattermost-redux/client/client4';
|
||||
|
||||
const PASSWORD = 'password1';
|
||||
|
||||
@@ -103,8 +103,13 @@ class TestHelper {
|
||||
};
|
||||
|
||||
fakePost = (channelId) => {
|
||||
const time = Date.now();
|
||||
|
||||
return {
|
||||
id: this.generateId(),
|
||||
channel_id: channelId,
|
||||
create_at: time,
|
||||
update_at: time,
|
||||
message: `Unit Test ${this.generateId()}`,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user