412 lines
13 KiB
JavaScript
412 lines
13 KiB
JavaScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
/* eslint-disable max-nested-callbacks */
|
|
|
|
import assert from 'assert';
|
|
|
|
import {ViewTypes} from 'app/constants';
|
|
import {
|
|
cleanUpPostsInChannel,
|
|
cleanUpState,
|
|
getAllFromPostsInChannel,
|
|
messageRetention,
|
|
} from 'app/store/middleware';
|
|
|
|
describe('messageRetention', () => {
|
|
describe('should chain the same incoming action type', () => {
|
|
const actions = [
|
|
{
|
|
type: 'persist/REHYDRATE',
|
|
payload: {
|
|
views: {
|
|
team: {
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: ViewTypes.DATA_CLEANUP,
|
|
payload: {
|
|
entities: {
|
|
channels: {
|
|
},
|
|
posts: {
|
|
},
|
|
},
|
|
views: {
|
|
team: {
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'other',
|
|
},
|
|
];
|
|
|
|
actions.forEach((action) => {
|
|
it(`for action type ${action.type}`, () => {
|
|
const store = {};
|
|
const next = (a) => a;
|
|
|
|
const nextAction = messageRetention(store)(next)(action);
|
|
assert.equal(action.type, nextAction.type);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('cleanUpState', () => {
|
|
test('should remove post because of data retention', () => {
|
|
const state = {
|
|
entities: {
|
|
channels: {
|
|
currentChannelId: 'channel1',
|
|
},
|
|
files: {
|
|
fileIdsByPostId: {},
|
|
},
|
|
general: {
|
|
dataRetentionPolicy: {
|
|
message_deletion_enabled: true,
|
|
message_retention_cutoff: 1000,
|
|
},
|
|
},
|
|
posts: {
|
|
posts: {
|
|
post1: {id: 'post1', channel_id: 'channel1', create_at: 1000},
|
|
post2: {id: 'post2', channel_id: 'channel1', create_at: 999},
|
|
},
|
|
postsInChannel: {
|
|
channel1: [
|
|
{order: ['post1', 'post2'], recent: true},
|
|
],
|
|
},
|
|
postsInThread: {},
|
|
reactions: {},
|
|
},
|
|
search: {
|
|
results: ['post1', 'post2'],
|
|
flagged: ['post1', 'post2', 'post3'],
|
|
},
|
|
},
|
|
views: {
|
|
team: {
|
|
lastChannelForTeam: {
|
|
team1: ['channel1'],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = cleanUpState({payload: state});
|
|
|
|
expect(result.payload.entities.posts.posts.post1).toBeDefined();
|
|
expect(result.payload.entities.posts.posts.post2).toBeUndefined();
|
|
expect(result.payload.entities.posts.postsInChannel.channel1).toEqual([{order: ['post1'], recent: true}]);
|
|
expect(result.payload.entities.search.results).toEqual(['post1', 'post2']);
|
|
expect(result.payload.entities.search.flagged).toEqual(['post1', 'post2', 'post3']);
|
|
});
|
|
|
|
test('should keep failed pending post', () => {
|
|
const state = {
|
|
entities: {
|
|
channels: {
|
|
currentChannelId: 'channel1',
|
|
},
|
|
files: {
|
|
fileIdsByPostId: {},
|
|
},
|
|
posts: {
|
|
pendingPostIds: ['pending'],
|
|
posts: {
|
|
pending: {id: 'pending', pending_post_id: 'pending', channel_id: 'channel1', failed: true},
|
|
post1: {id: 'post1', channel_id: 'channel1'},
|
|
post2: {id: 'post2', channel_id: 'channel1'},
|
|
},
|
|
postsInChannel: {
|
|
channel1: [
|
|
{order: ['pending', 'post1', 'post2'], recent: true},
|
|
],
|
|
},
|
|
postsInThread: {},
|
|
reactions: {},
|
|
},
|
|
},
|
|
views: {
|
|
team: {
|
|
lastChannelForTeam: {
|
|
team1: ['channel1'],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = cleanUpState({payload: state});
|
|
|
|
expect(result.payload.entities.posts.pendingPostIds).toEqual(['pending']);
|
|
expect(result.payload.entities.posts.posts.pending).toBeDefined();
|
|
expect(result.payload.entities.posts.postsInChannel.channel1).toEqual([{order: ['pending', 'post1', 'post2'], recent: true}]);
|
|
});
|
|
|
|
test('should remove non-failed pending post', () => {
|
|
const state = {
|
|
entities: {
|
|
channels: {
|
|
currentChannelId: 'channel1',
|
|
},
|
|
files: {
|
|
fileIdsByPostId: {},
|
|
},
|
|
posts: {
|
|
pendingPostIds: ['pending'],
|
|
posts: {
|
|
pending: {id: 'pending', pending_post_id: 'pending', channel_id: 'channel1'},
|
|
post1: {id: 'post1', channel_id: 'channel1'},
|
|
post2: {id: 'post2', channel_id: 'channel1'},
|
|
},
|
|
postsInChannel: {
|
|
channel1: [
|
|
{order: ['pending', 'post1', 'post2'], recent: true},
|
|
],
|
|
},
|
|
postsInThread: {},
|
|
reactions: {},
|
|
},
|
|
},
|
|
views: {
|
|
team: {
|
|
lastChannelForTeam: {
|
|
team1: ['channel1'],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = cleanUpState({payload: state});
|
|
|
|
expect(result.payload.entities.posts.pendingPostIds).toEqual([]);
|
|
expect(result.payload.entities.posts.posts.pending).toBeUndefined();
|
|
expect(result.payload.entities.posts.postsInChannel.channel1).toEqual([{order: ['post1', 'post2'], recent: true}]);
|
|
});
|
|
|
|
test('should remove non-existent pending post', () => {
|
|
const state = {
|
|
entities: {
|
|
channels: {
|
|
currentChannelId: 'channel1',
|
|
},
|
|
files: {
|
|
fileIdsByPostId: {},
|
|
},
|
|
posts: {
|
|
pendingPostIds: ['pending'],
|
|
posts: {
|
|
post1: {id: 'post1', channel_id: 'channel1'},
|
|
post2: {id: 'post2', channel_id: 'channel1'},
|
|
},
|
|
postsInChannel: {
|
|
channel1: [
|
|
{order: ['post1', 'post2'], recent: true},
|
|
],
|
|
},
|
|
postsInThread: {},
|
|
reactions: {},
|
|
},
|
|
},
|
|
views: {
|
|
team: {
|
|
lastChannelForTeam: {
|
|
team1: ['channel1'],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = cleanUpState({payload: state});
|
|
|
|
expect(result.payload.entities.posts.pendingPostIds).toEqual([]);
|
|
expect(result.payload.entities.posts.postsInChannel.channel1).toEqual([{order: ['post1', 'post2'], recent: true}]);
|
|
});
|
|
});
|
|
|
|
describe('cleanUpPostsInChannel', () => {
|
|
test('should only keep posts for recently viewed channels', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['c', 'd'], recent: true},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['channel1'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam);
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
channel1: [
|
|
{order: ['a', 'b'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
|
|
test('should keep posts for recently viewed channels across multiple teams', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['c', 'd'], recent: true},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['channel1'],
|
|
team2: ['channel2'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam);
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
channel1: [
|
|
{order: ['a', 'b'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['c', 'd'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
|
|
test('should only keep the last X posts in each channel', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['e', 'f', 'g', 'h'], recent: true},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['channel1', 'channel2'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam, '', 2);
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
channel1: [
|
|
{order: ['a', 'b'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['e', 'f'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
|
|
test('should only keep the most recent posts in a channel', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
{order: ['e', 'f', 'g', 'h']},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['channel1'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam, '');
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
channel1: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
|
|
test('should keep all posts in the current channel, if specified', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['e', 'f', 'g', 'h'], recent: true},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['channel1', 'channel2'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam, 'channel2', 2);
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
channel1: [
|
|
{order: ['a', 'b'], recent: true},
|
|
],
|
|
channel2: [
|
|
{order: ['e', 'f', 'g', 'h'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
|
|
test('should not error when a DM/GM channel appears on multiple teams', () => {
|
|
const postsInChannel = {
|
|
dmChannel: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['dmChannel'],
|
|
team2: ['dmChannel'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam);
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
dmChannel: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
|
|
test('should not error when a recent channel is missing', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
};
|
|
const lastChannelForTeam = {
|
|
team1: ['channel1', 'channel2'],
|
|
};
|
|
|
|
const nextPostsInChannel = cleanUpPostsInChannel(postsInChannel, lastChannelForTeam);
|
|
|
|
expect(nextPostsInChannel).toEqual({
|
|
channel1: [
|
|
{order: ['a', 'b', 'c', 'd'], recent: true},
|
|
],
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getAllFromPostsInChannel', () => {
|
|
test('should return every post ID', () => {
|
|
const postsInChannel = {
|
|
channel1: [
|
|
{order: ['a', 'b']},
|
|
{order: ['c', 'd']},
|
|
],
|
|
channel2: [
|
|
{order: ['e', 'f']},
|
|
],
|
|
channel3: [
|
|
{order: ['g', 'h']},
|
|
],
|
|
};
|
|
|
|
const postIds = getAllFromPostsInChannel(postsInChannel);
|
|
|
|
expect(postIds).toMatchObject(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
|
|
});
|
|
});
|