Refactored post store to store posts by their IDs (#142)
* Added hook to tests to catch uncaught promise rejections * Refactored post store to store posts by their IDs * Fixed post store when logging out
This commit is contained in:
parent
189668105b
commit
8e59ea606e
5 changed files with 377 additions and 317 deletions
|
|
@ -2,180 +2,146 @@
|
|||
// See License.txt for license information.
|
||||
|
||||
import {Constants, PostsTypes, UsersTypes} from 'service/constants';
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
function isPostListNull(pl) {
|
||||
if (!pl) {
|
||||
return true;
|
||||
function handleReceivedPost(posts = {}, postsByChannel = {}, action) {
|
||||
const post = action.data;
|
||||
const channelId = post.channel_id;
|
||||
|
||||
const nextPosts = {
|
||||
...posts,
|
||||
[post.id]: post
|
||||
};
|
||||
|
||||
let nextPostsByChannel = postsByChannel;
|
||||
|
||||
// Only change postsByChannel if the order of the posts needs to change
|
||||
if (!postsByChannel[channelId] || postsByChannel[channelId].indexOf(post.id) === -1) {
|
||||
// If we don't already have the post, assume it's the most recent one
|
||||
const postsInChannel = postsByChannel[channelId] || [];
|
||||
|
||||
nextPostsByChannel = {...postsByChannel};
|
||||
nextPostsByChannel[channelId] = [
|
||||
post.id,
|
||||
...postsInChannel
|
||||
];
|
||||
}
|
||||
|
||||
if (!pl.posts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !pl.order;
|
||||
return {posts: nextPosts, postsByChannel: nextPostsByChannel};
|
||||
}
|
||||
|
||||
function makePostListNonNull(pl) {
|
||||
let postList = {...pl};
|
||||
if (!postList) {
|
||||
postList = {order: [], posts: {}};
|
||||
}
|
||||
|
||||
if (!postList.order) {
|
||||
postList.order = [];
|
||||
}
|
||||
|
||||
if (!postList.posts) {
|
||||
postList.posts = {};
|
||||
}
|
||||
|
||||
return postList;
|
||||
}
|
||||
|
||||
function storePosts(state, action) {
|
||||
const newPosts = action.data;
|
||||
function handleReceivedPosts(posts = {}, postsByChannel = {}, action) {
|
||||
const newPosts = action.data.posts;
|
||||
const channelId = action.channelId;
|
||||
|
||||
if (isPostListNull(newPosts)) {
|
||||
return state;
|
||||
}
|
||||
const nextPosts = {...posts};
|
||||
const nextPostsByChannel = {...postsByChannel};
|
||||
const postsInChannel = postsByChannel[channelId] ? [...postsByChannel[channelId]] : [];
|
||||
|
||||
const postList = state[channelId] || {};
|
||||
const combinedPosts = makePostListNonNull(postList);
|
||||
for (const newPost of Object.values(newPosts)) {
|
||||
nextPosts[newPost.id] = newPost;
|
||||
|
||||
for (const pid in newPosts.posts) {
|
||||
if (newPosts.posts.hasOwnProperty(pid)) {
|
||||
const np = newPosts.posts[pid];
|
||||
if (np.delete_at === 0) {
|
||||
combinedPosts.posts[pid] = np;
|
||||
if (combinedPosts.order.indexOf(pid) === -1 && newPosts.order.indexOf(pid) !== -1) {
|
||||
combinedPosts.order.push(pid);
|
||||
}
|
||||
} else if (combinedPosts.posts.hasOwnProperty(pid)) {
|
||||
combinedPosts.posts[pid] = {...np, state: Constants.POST_DELETED, fileIds: []};
|
||||
}
|
||||
if (postsInChannel.indexOf(newPost.id) === -1) {
|
||||
// Just add the post id to the end of the order and we'll sort it out later
|
||||
postsInChannel.push(newPost.id);
|
||||
}
|
||||
}
|
||||
|
||||
combinedPosts.order.sort((a, b) => {
|
||||
if (combinedPosts.posts[a].create_at > combinedPosts.posts[b].create_at) {
|
||||
// Sort to ensure that the most recent posts are first
|
||||
postsInChannel.sort((a, b) => {
|
||||
if (nextPosts[a].create_at > nextPosts[b].create_at) {
|
||||
return -1;
|
||||
}
|
||||
if (combinedPosts.posts[a].create_at < combinedPosts.posts[b].create_at) {
|
||||
} else if (nextPosts[a].create_at < nextPosts[b].create_at) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
nextPostsByChannel[channelId] = postsInChannel;
|
||||
|
||||
return {posts: nextPosts, postsByChannel: nextPostsByChannel};
|
||||
}
|
||||
|
||||
function storePost(state, action) {
|
||||
function handlePostDeleted(posts = {}, postsByChannel = {}, action) {
|
||||
const post = action.data;
|
||||
const channelId = post.channel_id;
|
||||
|
||||
const postList = state[channelId] || {};
|
||||
const combinedPosts = makePostListNonNull(postList);
|
||||
let nextPosts = posts;
|
||||
|
||||
combinedPosts.posts[post.id] = post;
|
||||
// We only need to do something if already have the post
|
||||
if (posts[post.id]) {
|
||||
nextPosts = {...posts};
|
||||
|
||||
if (combinedPosts.order.indexOf(post.id) === -1) {
|
||||
combinedPosts.order.unshift(post.id);
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
}
|
||||
|
||||
function deletePost(state, action) {
|
||||
const post = action.data;
|
||||
const channelId = post.channel_id;
|
||||
const postInfo = state[channelId];
|
||||
|
||||
if (!postInfo) {
|
||||
// the post that has been deleted is in a channel that we haven't seen so just ignore it
|
||||
return state;
|
||||
}
|
||||
|
||||
if (isPostListNull(postInfo)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (postInfo.posts[post.id]) {
|
||||
const combinedPosts = makePostListNonNull(postInfo);
|
||||
|
||||
combinedPosts.posts = {
|
||||
...combinedPosts.posts,
|
||||
[post.id]: {
|
||||
...post,
|
||||
state: Constants.POST_DELETED,
|
||||
file_ids: [],
|
||||
has_reactions: false
|
||||
}
|
||||
nextPosts[post.id] = {
|
||||
...posts[post.id],
|
||||
state: Constants.POST_DELETED,
|
||||
file_ids: [],
|
||||
has_reactions: false
|
||||
};
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
// No changes to the order until the user actually removes the post
|
||||
}
|
||||
|
||||
return state;
|
||||
return {posts: nextPosts, postsByChannel};
|
||||
}
|
||||
|
||||
function removePost(state, action) {
|
||||
function handleRemovePost(posts = {}, postsByChannel = {}, action) {
|
||||
const post = action.data;
|
||||
const channelId = post.channel_id;
|
||||
const postInfo = state[channelId];
|
||||
|
||||
if (!postInfo) {
|
||||
// the post that has been deleted is in a channel that we haven't seen so just ignore it
|
||||
return state;
|
||||
}
|
||||
let nextPosts = posts;
|
||||
let nextPostsByChannel = postsByChannel;
|
||||
|
||||
if (isPostListNull(postInfo)) {
|
||||
return state;
|
||||
}
|
||||
// We only need to do something if already have the post
|
||||
if (nextPosts[post.id]) {
|
||||
nextPosts = {...posts};
|
||||
nextPostsByChannel = {...postsByChannel};
|
||||
const postsInChannel = postsByChannel[channelId] ? [...postsByChannel[channelId]] : [];
|
||||
|
||||
if (postInfo.posts[post.id]) {
|
||||
const combinedPosts = makePostListNonNull(postInfo);
|
||||
// Remove the post itself
|
||||
Reflect.deleteProperty(nextPosts, post.id);
|
||||
|
||||
combinedPosts.order = combinedPosts.order.slice(0);
|
||||
combinedPosts.posts = {...combinedPosts.posts};
|
||||
|
||||
// Remove the post
|
||||
Reflect.deleteProperty(combinedPosts.posts, post.id);
|
||||
|
||||
const index = combinedPosts.order.indexOf(post.id);
|
||||
const index = postsInChannel.indexOf(post.id);
|
||||
if (index !== -1) {
|
||||
combinedPosts.order.splice(index, 1);
|
||||
postsInChannel.splice(index, 1);
|
||||
}
|
||||
|
||||
// Remove any children of the post
|
||||
for (const pid of Object.keys(combinedPosts.posts)) {
|
||||
if (combinedPosts.posts[pid].root_id === post.id) {
|
||||
Reflect.deleteProperty(combinedPosts.posts, pid);
|
||||
const commentIndex = combinedPosts.order.indexOf(pid);
|
||||
// Remove any of its comments
|
||||
for (const id of postsInChannel) {
|
||||
if (nextPosts[id].root_id === post.id) {
|
||||
Reflect.deleteProperty(nextPosts, id);
|
||||
|
||||
const commentIndex = postsInChannel.indexOf(id);
|
||||
if (commentIndex !== -1) {
|
||||
combinedPosts.order.splice(commentIndex, 1);
|
||||
postsInChannel.splice(commentIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
nextPostsByChannel[channelId] = postsInChannel;
|
||||
}
|
||||
|
||||
return state;
|
||||
return {posts: nextPosts, postsByChannel: nextPostsByChannel};
|
||||
}
|
||||
|
||||
function handlePosts(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case PostsTypes.RECEIVED_POST:
|
||||
return handleReceivedPost(state.posts, state.postsByChannel, action);
|
||||
case PostsTypes.RECEIVED_POSTS:
|
||||
return handleReceivedPosts(state.posts, state.postsByChannel, action);
|
||||
case PostsTypes.POST_DELETED:
|
||||
return handlePostDeleted(state.posts, state.postsByChannel, action);
|
||||
case PostsTypes.REMOVE_POST:
|
||||
return handleRemovePost(state.posts, state.postsByChannel, action);
|
||||
|
||||
case UsersTypes.LOGOUT_SUCCESS:
|
||||
return {
|
||||
posts: {},
|
||||
postsByChannel: {}
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function selectedPostId(state = '', action) {
|
||||
|
|
@ -196,31 +162,30 @@ function currentFocusedPostId(state = '', action) {
|
|||
}
|
||||
}
|
||||
|
||||
function postsInfo(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case PostsTypes.RECEIVED_POST:
|
||||
return storePost(state, action);
|
||||
case PostsTypes.RECEIVED_POSTS:
|
||||
return storePosts(state, action);
|
||||
case PostsTypes.POST_DELETED:
|
||||
return deletePost(state, action);
|
||||
case PostsTypes.REMOVE_POST:
|
||||
return removePost(state, action);
|
||||
case UsersTypes.LOGOUT_SUCCESS:
|
||||
return {};
|
||||
default:
|
||||
export default function(state = {}, action) {
|
||||
const {posts, postsByChannel} = handlePosts(state, action);
|
||||
|
||||
const nextState = {
|
||||
|
||||
// Object mapping post ids to post objects
|
||||
posts,
|
||||
|
||||
// Object mapping channel ids to an list of posts ids in that channel with the most recent post first
|
||||
postsByChannel,
|
||||
|
||||
// The current selected post
|
||||
selectedPostId: selectedPostId(state.selectedPostId, action),
|
||||
|
||||
// The current selected focused post (permalink view)
|
||||
currentFocusedPostId: currentFocusedPostId(state.currentFocusedPostId, action)
|
||||
};
|
||||
|
||||
if (state.posts === nextState.posts && state.postsByChannel === nextState.postsByChannel &&
|
||||
state.selectedPostId === nextState.selectedPostId &&
|
||||
state.currentFocusedPostId === nextState.currentFocusedPostId) {
|
||||
// None of the children have changed so don't even let the parent object change
|
||||
return state;
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
|
||||
// the current selected post
|
||||
selectedPostId,
|
||||
|
||||
// the current selected focused post (permalink view)
|
||||
currentFocusedPostId,
|
||||
|
||||
// object where every key is the channel id and has and object with the postList
|
||||
postsInfo
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
--require react-native-mock/mock.js
|
||||
--require isomorphic-fetch
|
||||
--recursive
|
||||
--recursive
|
||||
|
|
|
|||
|
|
@ -3,6 +3,14 @@
|
|||
|
||||
import 'react-native';
|
||||
|
||||
// Set up a global hooks to make debugging tests less of a pain
|
||||
before(() => {
|
||||
process.on('unhandledRejection', (reason) => {
|
||||
// Rethrow so that tests will actually fail and not just timeout
|
||||
throw reason;
|
||||
});
|
||||
});
|
||||
|
||||
// Ensure that everything is imported correctly for testing
|
||||
describe('Sanity test', () => {
|
||||
it('Promise', (done) => {
|
||||
|
|
|
|||
|
|
@ -14,23 +14,43 @@ describe('Actions.Posts', () => {
|
|||
TestHelper.initBasic(Client).then(() => {
|
||||
const store = configureStore();
|
||||
|
||||
store.subscribe(() => {
|
||||
const createRequest = store.getState().requests.posts.createPost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
const post = TestHelper.fakePost(channelId);
|
||||
|
||||
if (createRequest.status === RequestStatus.SUCCESS || createRequest.status === RequestStatus.FAILURE) {
|
||||
if (createRequest.error) {
|
||||
done(new Error(JSON.stringify(createRequest.error)));
|
||||
} else {
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id]);
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id].order.length);
|
||||
assert.ok(Object.keys(postsInfo[TestHelper.basicChannel.id].posts).length);
|
||||
done();
|
||||
store.subscribe(() => {
|
||||
const state = store.getState();
|
||||
const createRequest = state.requests.posts.createPost;
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
if (createRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
assert.ok(postsByChannel[channelId]);
|
||||
|
||||
let found = false;
|
||||
for (const storedPost of Object.values(posts)) {
|
||||
if (storedPost.message === post.message) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert.ok(found, 'failed to find new post in posts');
|
||||
|
||||
found = false;
|
||||
for (const postIdInChannel of postsByChannel[channelId]) {
|
||||
if (posts[postIdInChannel].message === post.message) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert.ok(found, 'failed to find new post in postsByChannel');
|
||||
|
||||
done();
|
||||
} else if (createRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(createRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
const post = TestHelper.fakePost(TestHelper.basicChannel.id);
|
||||
Actions.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
post
|
||||
|
|
@ -41,60 +61,70 @@ describe('Actions.Posts', () => {
|
|||
it('editPost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
const post = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const message = post.message;
|
||||
|
||||
store.subscribe(() => {
|
||||
const editRequest = store.getState().requests.posts.editPost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const state = store.getState();
|
||||
const editRequest = state.requests.posts.editPost;
|
||||
const posts = state.entities.posts.posts;
|
||||
|
||||
if (editRequest.status === RequestStatus.SUCCESS || editRequest.status === RequestStatus.FAILURE) {
|
||||
if (editRequest.error) {
|
||||
done(new Error(JSON.stringify(editRequest.error)));
|
||||
} else {
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id]);
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id].order.length);
|
||||
assert.strictEqual(
|
||||
postsInfo[TestHelper.basicChannel.id].posts[post.id].message,
|
||||
`${message} (edited)`
|
||||
);
|
||||
done();
|
||||
}
|
||||
if (editRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(posts[post.id]);
|
||||
|
||||
assert.strictEqual(
|
||||
posts[post.id].message,
|
||||
`${message} (edited)`
|
||||
);
|
||||
|
||||
done();
|
||||
} else if (editRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(editRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
post.message = `${message} (edited)`;
|
||||
Actions.editPost(
|
||||
TestHelper.basicTeam.id,
|
||||
teamId,
|
||||
post
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('deletePost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async ({channel}) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
await Actions.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
const initialPostsInfo = store.getState().entities.posts.postsInfo[channel.id];
|
||||
const created = initialPostsInfo.posts[initialPostsInfo.order[0]];
|
||||
const initialPosts = store.getState().entities.posts;
|
||||
const created = initialPosts.posts[initialPosts.postsByChannel[channelId][0]];
|
||||
|
||||
store.subscribe(() => {
|
||||
const state = store.getState();
|
||||
const deleteRequest = state.requests.posts.deletePost;
|
||||
const postsInfo = state.entities.posts.postsInfo[channel.id];
|
||||
const posts = state.entities.posts.posts;
|
||||
|
||||
if (deleteRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(postsInfo);
|
||||
assert.ok(posts);
|
||||
assert.ok(posts[created.id]);
|
||||
|
||||
assert.strictEqual(
|
||||
postsInfo.posts[created.id].state,
|
||||
posts[created.id].state,
|
||||
Constants.POST_DELETED
|
||||
);
|
||||
|
||||
|
|
@ -104,30 +134,39 @@ describe('Actions.Posts', () => {
|
|||
}
|
||||
});
|
||||
|
||||
Actions.deletePost(TestHelper.basicTeam.id, created)(store.dispatch, store.getState);
|
||||
Actions.deletePost(teamId, created)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('removePost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
const postId = TestHelper.basicPost.id;
|
||||
|
||||
const post1a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: TestHelper.basicPost.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: postId}
|
||||
);
|
||||
|
||||
await Actions.getPosts(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id
|
||||
teamId,
|
||||
channelId
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
store.subscribe(() => {
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const postList = postsInfo[TestHelper.basicChannel.id];
|
||||
const state = store.getState();
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
assert.strictEqual(postList.order.length, 0);
|
||||
assert.ok(!postList.posts[post1a.id]);
|
||||
assert.ok(!postList.posts[TestHelper.basicPost.id]);
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
assert.ok(postsByChannel[channelId]);
|
||||
|
||||
assert.equal(postsByChannel[channelId].length, 0);
|
||||
assert.ok(!posts[postId]);
|
||||
assert.ok(!posts[post1a.id]);
|
||||
|
||||
done();
|
||||
});
|
||||
|
|
@ -141,30 +180,45 @@ describe('Actions.Posts', () => {
|
|||
it('getPost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
const post = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const state = store.getState();
|
||||
const getRequest = state.requests.posts.getPost;
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
if (getRequest.status === RequestStatus.SUCCESS || getRequest.status === RequestStatus.FAILURE) {
|
||||
if (getRequest.error) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
} else {
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id]);
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id].order.length);
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id].posts[post.id]);
|
||||
done();
|
||||
if (getRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
assert.ok(postsByChannel[channelId]);
|
||||
|
||||
assert.ok(posts[post.id]);
|
||||
|
||||
let found = false;
|
||||
for (const postIdInChannel of postsByChannel[channelId]) {
|
||||
if (postIdInChannel === post.id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert.ok(found, 'failed to find post in postsByChannel');
|
||||
|
||||
done();
|
||||
} else if (getRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
teamId,
|
||||
channelId,
|
||||
post.id
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
|
|
@ -173,50 +227,61 @@ describe('Actions.Posts', () => {
|
|||
it('getPosts', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post1a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPosts;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const state = store.getState();
|
||||
const getRequest = state.requests.posts.getPosts;
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
if (getRequest.status === RequestStatus.SUCCESS || getRequest.status === RequestStatus.FAILURE) {
|
||||
if (getRequest.error) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
} else {
|
||||
const postsList = postsInfo[TestHelper.basicChannel.id];
|
||||
assert.ok(postsList);
|
||||
assert.equal(postsList.order[0], post3a.id, 'wrong order');
|
||||
assert.equal(postsList.order[1], post3.id, 'wrong order');
|
||||
assert.equal(postsList.order[3], post1a.id, 'wrong order');
|
||||
assert.ok(postsList.posts[post1.id], 'should exists');
|
||||
assert.ok(postsList.posts[post2.id], 'should exists');
|
||||
done();
|
||||
}
|
||||
if (getRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
|
||||
const postsInChannel = postsByChannel[channelId];
|
||||
assert.ok(postsInChannel);
|
||||
assert.equal(postsInChannel[0], post3a.id, 'wrong order for post3a');
|
||||
assert.equal(postsInChannel[1], post3.id, 'wrong order for post3');
|
||||
assert.equal(postsInChannel[3], post1a.id, 'wrong order for post1a');
|
||||
|
||||
assert.ok(posts[post1.id]);
|
||||
assert.ok(posts[post1a.id]);
|
||||
assert.ok(posts[post2.id]);
|
||||
assert.ok(posts[post3.id]);
|
||||
assert.ok(posts[post3a.id]);
|
||||
|
||||
done();
|
||||
} else if (getRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPosts(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id
|
||||
teamId,
|
||||
channelId
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
}).timeout(3000);
|
||||
|
|
@ -224,48 +289,55 @@ describe('Actions.Posts', () => {
|
|||
it('getPostsSince', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPostsSince;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const state = store.getState();
|
||||
const getRequest = state.requests.posts.getPostsSince;
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
if (getRequest.status === RequestStatus.SUCCESS || getRequest.status === RequestStatus.FAILURE) {
|
||||
if (getRequest.error) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
} else {
|
||||
const postsList = postsInfo[TestHelper.basicChannel.id];
|
||||
assert.ok(postsList);
|
||||
assert.equal(postsList.order[0], post3a.id, 'wrong order');
|
||||
assert.equal(postsList.order[1], post3.id, 'wrong order');
|
||||
assert.equal(Object.keys(postsList.posts).length, 2, 'wrong size');
|
||||
done();
|
||||
}
|
||||
if (getRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
|
||||
const postsInChannel = postsByChannel[channelId];
|
||||
assert.ok(postsInChannel);
|
||||
assert.equal(postsInChannel[0], post3a.id, 'wrong order for post3a');
|
||||
assert.equal(postsInChannel[1], post3.id, 'wrong order for post3');
|
||||
assert.equal(postsInChannel.length, 2, 'wrong size');
|
||||
|
||||
done();
|
||||
} else if (getRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPostsSince(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
teamId,
|
||||
channelId,
|
||||
post2.create_at
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
|
|
@ -274,48 +346,55 @@ describe('Actions.Posts', () => {
|
|||
it('getPostsBefore', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post1a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPostsBefore;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const state = store.getState();
|
||||
const getRequest = state.requests.posts.getPostsBefore;
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
if (getRequest.status === RequestStatus.SUCCESS || getRequest.status === RequestStatus.FAILURE) {
|
||||
if (getRequest.error) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
} else {
|
||||
const postsList = postsInfo[TestHelper.basicChannel.id];
|
||||
assert.ok(postsList);
|
||||
assert.equal(postsList.order[0], post1a.id, 'wrong order');
|
||||
assert.equal(postsList.order[1], post1.id, 'wrong order');
|
||||
assert.equal(Object.keys(postsList.posts).length, 3, 'wrong size');
|
||||
done();
|
||||
}
|
||||
if (getRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
|
||||
const postsInChannel = postsByChannel[channelId];
|
||||
assert.ok(postsInChannel);
|
||||
assert.equal(postsInChannel[0], post1a.id, 'wrong order for post1a');
|
||||
assert.equal(postsInChannel[1], post1.id, 'wrong order for post1');
|
||||
assert.equal(postsInChannel.length, 3, 'wrong size');
|
||||
|
||||
done();
|
||||
} else if (getRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPostsBefore(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
teamId,
|
||||
channelId,
|
||||
post2.id,
|
||||
0,
|
||||
10
|
||||
|
|
@ -326,48 +405,55 @@ describe('Actions.Posts', () => {
|
|||
it('getPostsAfter', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const teamId = TestHelper.basicTeam.id;
|
||||
const channelId = TestHelper.basicChannel.id;
|
||||
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
teamId,
|
||||
TestHelper.fakePost(channelId)
|
||||
);
|
||||
const post3a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
teamId,
|
||||
{...TestHelper.fakePost(channelId), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPostsAfter;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const state = store.getState();
|
||||
const getRequest = state.requests.posts.getPostsAfter;
|
||||
const {posts, postsByChannel} = state.entities.posts;
|
||||
|
||||
if (getRequest.status === RequestStatus.SUCCESS || getRequest.status === RequestStatus.FAILURE) {
|
||||
if (getRequest.error) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
} else {
|
||||
const postsList = postsInfo[TestHelper.basicChannel.id];
|
||||
assert.ok(postsList);
|
||||
assert.equal(postsList.order[0], post3a.id, 'wrong order');
|
||||
assert.equal(postsList.order[1], post3.id, 'wrong order');
|
||||
assert.equal(Object.keys(postsList.posts).length, 2, 'wrong size');
|
||||
done();
|
||||
}
|
||||
if (getRequest.status === RequestStatus.SUCCESS) {
|
||||
assert.ok(posts);
|
||||
assert.ok(postsByChannel);
|
||||
|
||||
const postsInChannel = postsByChannel[channelId];
|
||||
assert.ok(postsInChannel);
|
||||
assert.equal(postsInChannel[0], post3a.id, 'wrong order for post3a');
|
||||
assert.equal(postsInChannel[1], post3.id, 'wrong order for post3');
|
||||
assert.equal(postsInChannel.length, 2, 'wrong size');
|
||||
|
||||
done();
|
||||
} else if (getRequest.status === RequestStatus.FAILURE) {
|
||||
done(new Error(JSON.stringify(getRequest.error)));
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPostsAfter(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
teamId,
|
||||
channelId,
|
||||
post2.id,
|
||||
0,
|
||||
10
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ describe('Actions.Users', () => {
|
|||
assert.deepStrictEqual(channels.stats, {}, 'channel stats is not empty');
|
||||
assert.strictEqual(posts.selectedPostId, '', 'selected post id is not empty');
|
||||
assert.strictEqual(posts.currentFocusedPostId, '', 'current focused post id is not empty');
|
||||
assert.deepStrictEqual(posts.postsInfo, {}, 'posts info is not empty');
|
||||
assert.deepStrictEqual(posts.posts, {}, 'posts is not empty');
|
||||
assert.deepStrictEqual(posts.postsByChannel, {}, 'posts by channel is not empty');
|
||||
assert.deepStrictEqual(preferences.myPreferences, {}, 'user preferences not empty');
|
||||
assert.strictEqual(navigation.index, 0, 'navigation not reset to first element of stack');
|
||||
assert.deepStrictEqual(navigation.routes, [Routes.Root], 'navigation not reset to root route');
|
||||
|
|
|
|||
Loading…
Reference in a new issue