include posts into store (#125)
* include posts into store * addressing feedback
This commit is contained in:
parent
61c4d8b585
commit
aa01be831f
13 changed files with 966 additions and 188 deletions
|
|
@ -1,17 +1,182 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {bindClientFunc} from './helpers.js';
|
||||
import Client from 'service/client';
|
||||
import {PostsTypes} from 'service/constants';
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
import {Constants, PostsTypes} from 'service/constants';
|
||||
|
||||
export function fetchPosts(teamId, channelId) {
|
||||
export function createPost(teamId, post) {
|
||||
return bindClientFunc(
|
||||
Client.fetchPosts,
|
||||
PostsTypes.FETCH_POSTS_REQUEST,
|
||||
PostsTypes.FETCH_POSTS_SUCCESS,
|
||||
PostsTypes.FETCH_POSTS_FAILURE,
|
||||
Client.createPost,
|
||||
PostsTypes.CREATE_POST_REQUEST,
|
||||
[PostsTypes.RECEIVED_POST, PostsTypes.CREATE_POST_SUCCESS],
|
||||
PostsTypes.CREATE_POST_FAILURE,
|
||||
teamId,
|
||||
channelId
|
||||
post
|
||||
);
|
||||
}
|
||||
|
||||
export function editPost(teamId, post) {
|
||||
return bindClientFunc(
|
||||
Client.editPost,
|
||||
PostsTypes.EDIT_POST_REQUEST,
|
||||
[PostsTypes.RECEIVED_POST, PostsTypes.EDIT_POST_SUCCESS],
|
||||
PostsTypes.EDIT_POST_FAILURE,
|
||||
teamId,
|
||||
post
|
||||
);
|
||||
}
|
||||
|
||||
export function deletePost(teamId, post) {
|
||||
return async (dispatch, getState) => {
|
||||
try {
|
||||
dispatch({type: PostsTypes.DELETE_POST_REQUEST}, getState);
|
||||
|
||||
await Client.deletePost(teamId, post.channel_id, post.id);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: PostsTypes.POST_DELETED,
|
||||
data: post
|
||||
},
|
||||
{
|
||||
type: PostsTypes.DELETE_POST_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PostsTypes.DELETE_POST_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function removePost(post) {
|
||||
return async (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: PostsTypes.REMOVE_POST,
|
||||
data: post
|
||||
}, getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function getPost(teamId, channelId, postId) {
|
||||
return async (dispatch, getState) => {
|
||||
try {
|
||||
dispatch({type: PostsTypes.GET_POST_REQUEST}, getState);
|
||||
const post = await Client.getPost(teamId, channelId, postId);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: PostsTypes.RECEIVED_POSTS,
|
||||
data: post,
|
||||
channelId
|
||||
},
|
||||
{
|
||||
type: PostsTypes.GET_POST_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PostsTypes.GET_POST_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getPosts(teamId, channelId, offset = 0, limit = Constants.POST_CHUNK_SIZE) {
|
||||
return async (dispatch, getState) => {
|
||||
try {
|
||||
dispatch({type: PostsTypes.GET_POSTS_REQUEST}, getState);
|
||||
const posts = await Client.getPosts(teamId, channelId, offset, limit);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: PostsTypes.RECEIVED_POSTS,
|
||||
data: posts,
|
||||
channelId
|
||||
},
|
||||
{
|
||||
type: PostsTypes.GET_POSTS_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PostsTypes.GET_POSTS_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getPostsSince(teamId, channelId, since) {
|
||||
return async (dispatch, getState) => {
|
||||
try {
|
||||
dispatch({type: PostsTypes.GET_POSTS_SINCE_REQUEST}, getState);
|
||||
const posts = await Client.getPostsSince(teamId, channelId, since);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: PostsTypes.RECEIVED_POSTS,
|
||||
data: posts,
|
||||
channelId
|
||||
},
|
||||
{
|
||||
type: PostsTypes.GET_POSTS_SINCE_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PostsTypes.GET_POSTS_SINCE_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getPostsBefore(teamId, channelId, postId, offset = 0, limit = Constants.POST_CHUNK_SIZE) {
|
||||
return async (dispatch, getState) => {
|
||||
try {
|
||||
dispatch({type: PostsTypes.GET_POSTS_BEFORE_REQUEST}, getState);
|
||||
const posts = await Client.getPostsBefore(teamId, channelId, postId, offset, limit);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: PostsTypes.RECEIVED_POSTS,
|
||||
data: posts,
|
||||
channelId
|
||||
},
|
||||
{
|
||||
type: PostsTypes.GET_POSTS_BEFORE_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PostsTypes.GET_POSTS_BEFORE_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getPostsAfter(teamId, channelId, postId, offset = 0, limit = Constants.POST_CHUNK_SIZE) {
|
||||
return async (dispatch, getState) => {
|
||||
try {
|
||||
dispatch({type: PostsTypes.GET_POSTS_AFTER_REQUEST}, getState);
|
||||
const posts = await Client.getPostsAfter(teamId, channelId, postId, offset, limit);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
type: PostsTypes.RECEIVED_POSTS,
|
||||
data: posts,
|
||||
channelId
|
||||
},
|
||||
{
|
||||
type: PostsTypes.GET_POSTS_AFTER_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PostsTypes.GET_POSTS_AFTER_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
createPost,
|
||||
editPost,
|
||||
deletePost,
|
||||
removePost,
|
||||
getPost,
|
||||
getPosts,
|
||||
getPostsSince,
|
||||
getPostsBefore,
|
||||
getPostsAfter
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import Client from 'service/client';
|
||||
|
||||
import {PreferencesTypes} from 'service/constants';
|
||||
import {bindClientFunc, forceLogoutIfNecessary, requestData, requestFailure} from './helpers';
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ export function getMyPreferences() {
|
|||
|
||||
export function savePreferences(preferences) {
|
||||
return async (dispatch, getState) => {
|
||||
dispatch(requestData(PreferencesTypes.SAVE_PREFERENCES_REQUEST), getState);
|
||||
dispatch({type: PreferencesTypes.SAVE_PREFERENCES_REQUEST}, getState);
|
||||
|
||||
try {
|
||||
await Client.savePreferences(preferences);
|
||||
|
|
@ -33,16 +33,16 @@ export function savePreferences(preferences) {
|
|||
type: PreferencesTypes.SAVE_PREFERENCES_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (err) {
|
||||
forceLogoutIfNecessary(err, dispatch);
|
||||
dispatch(requestFailure(PreferencesTypes.SAVE_PREFERENCES_FAILURE, err), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PreferencesTypes.SAVE_PREFERENCES_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function deletePreferences(preferences) {
|
||||
return async (dispatch, getState) => {
|
||||
dispatch(requestData(PreferencesTypes.DELETE_PREFERENCES_REQUEST), getState);
|
||||
dispatch({type: PreferencesTypes.DELETE_PREFERENCES_REQUEST}, getState);
|
||||
|
||||
try {
|
||||
await Client.deletePreferences(preferences);
|
||||
|
|
@ -56,9 +56,9 @@ export function deletePreferences(preferences) {
|
|||
type: PreferencesTypes.DELETE_PREFERENCES_SUCCESS
|
||||
}
|
||||
]), getState);
|
||||
} catch (err) {
|
||||
forceLogoutIfNecessary(err, dispatch);
|
||||
dispatch(requestFailure(PreferencesTypes.DELETE_PREFERENCES_FAILURE, err), getState);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch);
|
||||
dispatch({type: PreferencesTypes.DELETE_PREFERENCES_FAILURE, error}, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -499,17 +499,6 @@ export default class Client {
|
|||
};
|
||||
|
||||
// Post routes
|
||||
|
||||
fetchPosts = (teamId, channelId, onRequest, onSuccess, onFailure) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/page/0/60`,
|
||||
{method: 'get'},
|
||||
onRequest,
|
||||
onSuccess,
|
||||
onFailure
|
||||
);
|
||||
};
|
||||
|
||||
createPost = async (teamId, post) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, post.channel_id)}/create`,
|
||||
|
|
@ -517,6 +506,56 @@ export default class Client {
|
|||
);
|
||||
};
|
||||
|
||||
editPost = async (teamId, post) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, post.channel_id)}/update`,
|
||||
{method: 'post', body: JSON.stringify(post)}
|
||||
);
|
||||
};
|
||||
|
||||
deletePost = async (teamId, channelId, postId) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/${postId}/delete`,
|
||||
{method: 'post'}
|
||||
);
|
||||
};
|
||||
|
||||
getPost = async (teamId, channelId, postId) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/${postId}/get`,
|
||||
{method: 'get'}
|
||||
);
|
||||
};
|
||||
|
||||
getPosts = async (teamId, channelId, offset, limit) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/page/${offset}/${limit}`,
|
||||
{method: 'get'}
|
||||
);
|
||||
};
|
||||
|
||||
getPostsSince = async (teamId, channelId, since) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/since/${since}`,
|
||||
{method: 'get'}
|
||||
);
|
||||
};
|
||||
|
||||
getPostsBefore = async (teamId, channelId, postId, offset, limit) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/${postId}/before/${offset}/${limit}`,
|
||||
{method: 'get'}
|
||||
);
|
||||
};
|
||||
|
||||
getPostsAfter = async (teamId, channelId, postId, offset, limit) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(teamId, channelId)}/${postId}/after/${offset}/${limit}`,
|
||||
{method: 'get'}
|
||||
);
|
||||
};
|
||||
|
||||
// Client helpers
|
||||
// Preferences routes
|
||||
|
||||
getMyPreferences = async () => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ const Constants = {
|
|||
TEAM_ADMIN_ROLE: 'team_admin',
|
||||
|
||||
CHANNEL_USER_ROLE: 'channel_user',
|
||||
CHANNEL_ADMIN_ROLE: 'channel_admin'
|
||||
CHANNEL_ADMIN_ROLE: 'channel_admin',
|
||||
|
||||
POST_DELETED: 'DELETED'
|
||||
};
|
||||
|
||||
export default Constants;
|
||||
|
|
|
|||
|
|
@ -4,17 +4,43 @@
|
|||
import keymirror from 'keymirror';
|
||||
|
||||
const PostsTypes = keymirror({
|
||||
FETCH_POSTS_REQUEST: null,
|
||||
FETCH_POSTS_SUCCESS: null,
|
||||
FETCH_POSTS_FAILURE: null,
|
||||
CREATE_POST_REQUEST: null,
|
||||
CREATE_POST_SUCCESS: null,
|
||||
CREATE_POST_FAILURE: null,
|
||||
|
||||
EDIT_POST_REQUEST: null,
|
||||
EDIT_POST_SUCCESS: null,
|
||||
EDIT_POST_FAILURE: null,
|
||||
|
||||
DELETE_POST_REQUEST: null,
|
||||
DELETE_POST_SUCCESS: null,
|
||||
DELETE_POST_FAILURE: null,
|
||||
|
||||
GET_POST_REQUEST: null,
|
||||
GET_POST_SUCCESS: null,
|
||||
GET_POST_FAILURE: null,
|
||||
|
||||
GET_POSTS_REQUEST: null,
|
||||
GET_POSTS_SUCCESS: null,
|
||||
GET_POSTS_FAILURE: null,
|
||||
|
||||
GET_POSTS_SINCE_REQUEST: null,
|
||||
GET_POSTS_SINCE_SUCCESS: null,
|
||||
GET_POSTS_SINCE_FAILURE: null,
|
||||
|
||||
GET_POSTS_BEFORE_REQUEST: null,
|
||||
GET_POSTS_BEFORE_SUCCESS: null,
|
||||
GET_POSTS_BEFORE_FAILURE: null,
|
||||
|
||||
GET_POSTS_AFTER_REQUEST: null,
|
||||
GET_POSTS_AFTER_SUCCESS: null,
|
||||
GET_POSTS_AFTER_FAILURE: null,
|
||||
|
||||
RECEIVED_POST: null,
|
||||
RECEIVED_POSTS: null,
|
||||
RECEIVED_FOCUSED_POST: null,
|
||||
RECEIVED_POST_SELECTED: null,
|
||||
RECEIVED_EDIT_POST: null,
|
||||
CREATE_POST: null,
|
||||
CREATE_COMMENT: null,
|
||||
POST_DELETED: null,
|
||||
REMOVE_POST: null
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ export default keymirror({
|
|||
DELETE_PREFERENCES_SUCCESS: null,
|
||||
DELETE_PREFERENCES_FAILURE: null,
|
||||
|
||||
RECEIVED_PREFERENCE: null,
|
||||
RECEIVED_PREFERENCES: null,
|
||||
DELETED_PREFERENCES: null
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,130 +0,0 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
function isPostListNull(pl) {
|
||||
if (!pl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pl.posts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !pl.order;
|
||||
}
|
||||
|
||||
function makePostListNonNull(pl) {
|
||||
let postList = {...pl};
|
||||
if (!postList) {
|
||||
postList = {order: [], posts: {}};
|
||||
}
|
||||
|
||||
if (!postList.order) {
|
||||
postList.order = [];
|
||||
}
|
||||
|
||||
if (!postList.posts) {
|
||||
postList.posts = {};
|
||||
}
|
||||
|
||||
return postList;
|
||||
}
|
||||
|
||||
export function addPosts(state, action) {
|
||||
const newState = {...state};
|
||||
const newPosts = action.data;
|
||||
const id = action.channel_id;
|
||||
|
||||
if (isPostListNull(newPosts)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (action.checkLatest) {
|
||||
const currentLatest = newState.latestPageTime[id] || 0;
|
||||
if (newPosts.order.length >= 1) {
|
||||
const newLatest = newPosts.posts[newPosts.order[0]].create_at || 0;
|
||||
if (newLatest > currentLatest) {
|
||||
newState.latestPageTime = {
|
||||
...newState.latestPageTime,
|
||||
[id]: newLatest
|
||||
};
|
||||
}
|
||||
} else if (currentLatest === 0) {
|
||||
// Mark that an empty page was received
|
||||
newState.latestPageTime = {
|
||||
...newState.latestPageTime,
|
||||
[id]: 1
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const combinedPosts = {...makePostListNonNull(newState.postsInfo[id].postList)};
|
||||
|
||||
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: 'DELETED', fileIds: []};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
combinedPosts.order.sort((a, b) => {
|
||||
if (combinedPosts.posts[a].create_at > combinedPosts.posts[b].create_at) {
|
||||
return -1;
|
||||
}
|
||||
if (combinedPosts.posts[a].create_at < combinedPosts.posts[b].create_at) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
newState.postsInfo = {
|
||||
...newState.postsInfo,
|
||||
[id]: {
|
||||
...newState.postsInfo[id],
|
||||
postList: combinedPosts
|
||||
}
|
||||
};
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
export function profilesToSet(state, action) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
Object.keys(action.data).forEach((key) => {
|
||||
nextSet.add(key);
|
||||
});
|
||||
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet
|
||||
};
|
||||
}
|
||||
|
||||
export function addProfileToSet(state, action) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.add(action.data.user_id);
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet
|
||||
};
|
||||
}
|
||||
|
||||
export function removeProfileFromSet(state, action) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.delete(action.data.user_id);
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet
|
||||
};
|
||||
}
|
||||
|
|
@ -1,9 +1,177 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {PostsTypes, UsersTypes} from 'service/constants';
|
||||
import {Constants, PostsTypes, UsersTypes} from 'service/constants';
|
||||
import {combineReducers} from 'redux';
|
||||
import {addPosts} from './helpers';
|
||||
|
||||
function isPostListNull(pl) {
|
||||
if (!pl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pl.posts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !pl.order;
|
||||
}
|
||||
|
||||
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;
|
||||
const channelId = action.channelId;
|
||||
|
||||
if (isPostListNull(newPosts)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const postList = state[channelId] || {};
|
||||
const combinedPosts = makePostListNonNull(postList);
|
||||
|
||||
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: []};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
combinedPosts.order.sort((a, b) => {
|
||||
if (combinedPosts.posts[a].create_at > combinedPosts.posts[b].create_at) {
|
||||
return -1;
|
||||
}
|
||||
if (combinedPosts.posts[a].create_at < combinedPosts.posts[b].create_at) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
}
|
||||
|
||||
function storePost(state, action) {
|
||||
const post = action.data;
|
||||
const channelId = post.channel_id;
|
||||
|
||||
const postList = state[channelId] || {};
|
||||
const combinedPosts = makePostListNonNull(postList);
|
||||
|
||||
combinedPosts.posts[post.id] = post;
|
||||
|
||||
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[post.id] = {
|
||||
...post,
|
||||
state: Constants.POST_DELETED,
|
||||
file_ids: [],
|
||||
has_reactions: false
|
||||
};
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function removePost(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);
|
||||
Reflect.deleteProperty(combinedPosts.posts, post.id);
|
||||
|
||||
const index = combinedPosts.order.indexOf(post.id);
|
||||
if (index !== -1) {
|
||||
combinedPosts.order.splice(index, 1);
|
||||
}
|
||||
|
||||
for (const pid in combinedPosts.posts) {
|
||||
if (!combinedPosts.posts.hasOwnProperty(pid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (combinedPosts.posts[pid].root_id === post.id) {
|
||||
Reflect.deleteProperty(combinedPosts.posts, pid);
|
||||
const commentIndex = combinedPosts.order.indexOf(pid);
|
||||
if (commentIndex !== -1) {
|
||||
combinedPosts.order.splice(commentIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
[channelId]: combinedPosts
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function selectedPostId(state = '', action) {
|
||||
switch (action.type) {
|
||||
|
|
@ -25,17 +193,14 @@ function currentFocusedPostId(state = '', action) {
|
|||
|
||||
function postsInfo(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case PostsTypes.FETCH_POSTS_SUCCESS:
|
||||
return addPosts(state, action);
|
||||
case UsersTypes.LOGOUT_SUCCESS:
|
||||
return {};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function latestPageTime(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:
|
||||
|
|
@ -52,8 +217,5 @@ export default combineReducers({
|
|||
currentFocusedPostId,
|
||||
|
||||
// object where every key is the channel id and has and object with the postList
|
||||
postsInfo,
|
||||
|
||||
// object where the every key is the channel id and has the timestamp of the latest post created in that channel
|
||||
latestPageTime
|
||||
postsInfo
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,39 @@
|
|||
|
||||
import {combineReducers} from 'redux';
|
||||
import {UsersTypes} from 'service/constants';
|
||||
import {profilesToSet, addProfileToSet, removeProfileFromSet} from './helpers';
|
||||
|
||||
function profilesToSet(state, action) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
Object.keys(action.data).forEach((key) => {
|
||||
nextSet.add(key);
|
||||
});
|
||||
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet
|
||||
};
|
||||
}
|
||||
|
||||
function addProfileToSet(state, action) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.add(action.data.user_id);
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet
|
||||
};
|
||||
}
|
||||
|
||||
function removeProfileFromSet(state, action) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.delete(action.data.user_id);
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet
|
||||
};
|
||||
}
|
||||
|
||||
function currentId(state = '', action) {
|
||||
switch (action.type) {
|
||||
|
|
|
|||
|
|
@ -3,16 +3,18 @@
|
|||
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
import general from './general';
|
||||
import channels from './channels';
|
||||
import users from './users';
|
||||
import general from './general';
|
||||
import posts from './posts';
|
||||
import teams from './teams';
|
||||
import users from './users';
|
||||
import preferences from './preferences';
|
||||
|
||||
export default combineReducers({
|
||||
general,
|
||||
channels,
|
||||
users,
|
||||
general,
|
||||
posts,
|
||||
teams,
|
||||
users,
|
||||
preferences
|
||||
});
|
||||
|
|
|
|||
98
service/reducers/requests/posts.js
Normal file
98
service/reducers/requests/posts.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {handleRequest, initialRequestState} from './helpers';
|
||||
import {PostsTypes} from 'service/constants';
|
||||
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
function createPost(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.CREATE_POST_REQUEST,
|
||||
PostsTypes.CREATE_POST_SUCCESS,
|
||||
PostsTypes.CREATE_POST_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function editPost(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.EDIT_POST_REQUEST,
|
||||
PostsTypes.EDIT_POST_SUCCESS,
|
||||
PostsTypes.EDIT_POST_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function deletePost(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.DELETE_POST_REQUEST,
|
||||
PostsTypes.DELETE_POST_SUCCESS,
|
||||
PostsTypes.DELETE_POST_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function getPost(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.GET_POST_REQUEST,
|
||||
PostsTypes.GET_POST_SUCCESS,
|
||||
PostsTypes.GET_POST_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function getPosts(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.GET_POSTS_REQUEST,
|
||||
PostsTypes.GET_POSTS_SUCCESS,
|
||||
PostsTypes.GET_POSTS_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function getPostsSince(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.GET_POSTS_SINCE_REQUEST,
|
||||
PostsTypes.GET_POSTS_SINCE_SUCCESS,
|
||||
PostsTypes.GET_POSTS_SINCE_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function getPostsBefore(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.GET_POSTS_BEFORE_REQUEST,
|
||||
PostsTypes.GET_POSTS_BEFORE_SUCCESS,
|
||||
PostsTypes.GET_POSTS_BEFORE_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
function getPostsAfter(state = initialRequestState(), action) {
|
||||
return handleRequest(
|
||||
PostsTypes.GET_POSTS_AFTER_REQUEST,
|
||||
PostsTypes.GET_POSTS_AFTER_SUCCESS,
|
||||
PostsTypes.GET_POSTS_AFTER_FAILURE,
|
||||
state,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
createPost,
|
||||
editPost,
|
||||
deletePost,
|
||||
getPost,
|
||||
getPosts,
|
||||
getPostsSince,
|
||||
getPostsBefore,
|
||||
getPostsAfter
|
||||
});
|
||||
384
test/service/actions/posts.test.js
Normal file
384
test/service/actions/posts.test.js
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import assert from 'assert';
|
||||
|
||||
import * as Actions from 'service/actions/posts';
|
||||
import Client from 'service/client';
|
||||
import configureStore from 'app/store';
|
||||
import {Constants, RequestStatus} from 'service/constants';
|
||||
import TestHelper from 'test/test_helper';
|
||||
|
||||
describe('Actions.Posts', () => {
|
||||
it('createPost', (done) => {
|
||||
TestHelper.initBasic(Client).then(() => {
|
||||
const store = configureStore();
|
||||
|
||||
store.subscribe(() => {
|
||||
const createRequest = store.getState().requests.posts.createPost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const post = TestHelper.fakePost(TestHelper.basicChannel.id);
|
||||
Actions.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
post
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('editPost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const message = post.message;
|
||||
|
||||
store.subscribe(() => {
|
||||
const editRequest = store.getState().requests.posts.editPost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
post.message = `${message} (edited)`;
|
||||
Actions.editPost(
|
||||
TestHelper.basicTeam.id,
|
||||
post
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('deletePost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
let created;
|
||||
|
||||
store.subscribe(() => {
|
||||
const createRequest = store.getState().requests.posts.createPost;
|
||||
const deleteRequest = store.getState().requests.posts.deletePost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
if (deleteRequest.status === RequestStatus.SUCCESS || deleteRequest.status === RequestStatus.FAILURE) {
|
||||
if (deleteRequest.error) {
|
||||
done(new Error(JSON.stringify(deleteRequest.error)));
|
||||
} else {
|
||||
assert.ok(postsInfo[TestHelper.basicChannel.id]);
|
||||
assert.strictEqual(
|
||||
postsInfo[TestHelper.basicChannel.id].posts[created.id].state,
|
||||
Constants.POST_DELETED
|
||||
);
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
if (deleteRequest.status === RequestStatus.NOT_STARTED &&
|
||||
(createRequest.status === RequestStatus.SUCCESS || createRequest.status === RequestStatus.FAILURE)) {
|
||||
if (createRequest.error) {
|
||||
done(new Error(JSON.stringify(createRequest.error)));
|
||||
} else {
|
||||
const posts = postsInfo[TestHelper.basicChannel.id].posts;
|
||||
created = posts[Object.keys(posts)[0]];
|
||||
Actions.deletePost(TestHelper.basicTeam.id, created)(store.dispatch, store.getState);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const post = TestHelper.fakePost(TestHelper.basicChannel.id);
|
||||
Actions.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
post
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('removePost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post1a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: TestHelper.basicPost.id}
|
||||
);
|
||||
|
||||
await Actions.getPosts(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id
|
||||
)(store.dispatch, store.getState);
|
||||
|
||||
store.subscribe(() => {
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
const postList = postsInfo[TestHelper.basicChannel.id];
|
||||
assert.strictEqual(postList.order.length, 0);
|
||||
assert.ifError(postList.posts[post1a.id]);
|
||||
assert.ifError(postList.posts[TestHelper.basicPost.id]);
|
||||
done();
|
||||
});
|
||||
|
||||
Actions.removePost(
|
||||
TestHelper.basicPost
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('getPost', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPost;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
post.id
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
});
|
||||
|
||||
it('getPosts', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post1a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPosts;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPosts(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
}).timeout(3000);
|
||||
|
||||
it('getPostsSince', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPostsSince;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPostsSince(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
post2.create_at
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
}).timeout(3000);
|
||||
|
||||
it('getPostsBefore', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post1a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPostsBefore;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPostsBefore(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
post2.id,
|
||||
0,
|
||||
10
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
}).timeout(3000);
|
||||
|
||||
it('getPostsAfter', (done) => {
|
||||
TestHelper.initBasic(Client).then(async () => {
|
||||
const store = configureStore();
|
||||
const post1 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post1.id}
|
||||
);
|
||||
const post2 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3 = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.fakePost(TestHelper.basicChannel.id)
|
||||
);
|
||||
const post3a = await Client.createPost(
|
||||
TestHelper.basicTeam.id,
|
||||
{...TestHelper.fakePost(TestHelper.basicChannel.id), root_id: post3.id}
|
||||
);
|
||||
|
||||
store.subscribe(() => {
|
||||
const getRequest = store.getState().requests.posts.getPostsAfter;
|
||||
const postsInfo = store.getState().entities.posts.postsInfo;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Actions.getPostsAfter(
|
||||
TestHelper.basicTeam.id,
|
||||
TestHelper.basicChannel.id,
|
||||
post2.id,
|
||||
0,
|
||||
10
|
||||
)(store.dispatch, store.getState);
|
||||
});
|
||||
}).timeout(3000);
|
||||
});
|
||||
|
|
@ -96,7 +96,6 @@ describe('Actions.Users', () => {
|
|||
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.latestPageTime, {}, 'posts latest page time 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