[Enhancement] Fetch previous messages in the conversation (#355)
* Fetch previous messages in the conversation * Add specs for conversation store * Fix codeclimate issues * Exclude specs folder * Exclude globally * Fix path in exclude patterns * Add endPoints spec * Add snapshots for Spinner * Add specs for actions
This commit is contained in:
@@ -21,42 +21,54 @@ export const findUndeliveredMessage = (messageInbox, { content }) =>
|
||||
);
|
||||
|
||||
export const DEFAULT_CONVERSATION = 'default';
|
||||
|
||||
const state = {
|
||||
conversations: {},
|
||||
uiFlags: {
|
||||
allMessagesLoaded: false,
|
||||
isFetchingList: false,
|
||||
},
|
||||
};
|
||||
|
||||
const getters = {
|
||||
export const getters = {
|
||||
getConversation: _state => _state.conversations,
|
||||
getConversationSize: _state => Object.keys(_state.conversations).length,
|
||||
getAllMessagesLoaded: _state => _state.uiFlags.allMessagesLoaded,
|
||||
getIsFetchingList: _state => _state.uiFlags.isFetchingList,
|
||||
getEarliestMessage: _state => {
|
||||
const conversation = Object.values(_state.conversations);
|
||||
if (conversation.length) {
|
||||
return conversation[0];
|
||||
}
|
||||
return {};
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
export const actions = {
|
||||
sendMessage: async ({ commit }, params) => {
|
||||
const { content } = params;
|
||||
commit('pushMessageToConversations', createTemporaryMessage(content));
|
||||
commit('pushMessageToConversation', createTemporaryMessage(content));
|
||||
await sendMessageAPI(content);
|
||||
},
|
||||
|
||||
fetchOldConversations: async ({ commit }) => {
|
||||
fetchOldConversations: async ({ commit }, { before } = {}) => {
|
||||
try {
|
||||
const { data } = await getConversationAPI();
|
||||
commit('initMessagesInConversation', data);
|
||||
commit('setConversationListLoading', true);
|
||||
const { data } = await getConversationAPI({ before });
|
||||
commit('setMessagesInConversation', data);
|
||||
commit('setConversationListLoading', false);
|
||||
} catch (error) {
|
||||
// Handle error
|
||||
commit('setConversationListLoading', false);
|
||||
}
|
||||
},
|
||||
|
||||
addMessage({ commit }, data) {
|
||||
commit('pushMessageToConversations', data);
|
||||
commit('pushMessageToConversation', data);
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
initInboxInConversations($state, lastConversation) {
|
||||
Vue.set($state.conversations, lastConversation, {});
|
||||
},
|
||||
|
||||
pushMessageToConversations($state, message) {
|
||||
export const mutations = {
|
||||
pushMessageToConversation($state, message) {
|
||||
const { id, status, message_type: type } = message;
|
||||
const messagesInbox = $state.conversations;
|
||||
const isMessageIncoming = type === MESSAGE_TYPE.INCOMING;
|
||||
@@ -71,7 +83,6 @@ const mutations = {
|
||||
messagesInbox,
|
||||
message
|
||||
);
|
||||
|
||||
if (!messageInConversation) {
|
||||
Vue.set(messagesInbox, id, message);
|
||||
} else {
|
||||
@@ -80,12 +91,17 @@ const mutations = {
|
||||
}
|
||||
},
|
||||
|
||||
initMessagesInConversation(_state, payload) {
|
||||
setConversationListLoading($state, status) {
|
||||
$state.uiFlags.isFetchingList = status;
|
||||
},
|
||||
|
||||
setMessagesInConversation($state, payload) {
|
||||
if (!payload.length) {
|
||||
$state.uiFlags.allMessagesLoaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
payload.map(message => Vue.set(_state.conversations, message.id, message));
|
||||
payload.map(message => Vue.set($state.conversations, message.id, message));
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { actions } from '../../conversation';
|
||||
import getUuid from '../../../../helpers/uuid';
|
||||
|
||||
jest.mock('../../../../helpers/uuid');
|
||||
|
||||
const commit = jest.fn();
|
||||
|
||||
describe('#actions', () => {
|
||||
describe('#addMessage', () => {
|
||||
it('sends correct mutations', () => {
|
||||
actions.addMessage({ commit }, { id: 1 });
|
||||
expect(commit).toBeCalledWith('pushMessageToConversation', { id: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('#sendMessage', () => {
|
||||
it('sends correct mutations', () => {
|
||||
const mockDate = new Date(1466424490000);
|
||||
getUuid.mockImplementationOnce(() => '1111');
|
||||
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
|
||||
actions.sendMessage({ commit }, { content: 'hello' });
|
||||
spy.mockRestore();
|
||||
expect(commit).toBeCalledWith('pushMessageToConversation', {
|
||||
id: '1111',
|
||||
content: 'hello',
|
||||
status: 'in_progress',
|
||||
created_at: 1466424490000,
|
||||
message_type: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { getters } from '../../conversation';
|
||||
|
||||
describe('#getters', () => {
|
||||
it('getConversation', () => {
|
||||
const state = {
|
||||
conversations: {
|
||||
1: {
|
||||
content: 'hello',
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(getters.getConversation(state)).toEqual({
|
||||
1: {
|
||||
content: 'hello',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('getConversationSize', () => {
|
||||
const state = {
|
||||
conversations: {
|
||||
1: {
|
||||
content: 'hello',
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(getters.getConversationSize(state)).toEqual(1);
|
||||
});
|
||||
|
||||
it('getEarliestMessage', () => {
|
||||
const state = {
|
||||
conversations: {
|
||||
1: {
|
||||
content: 'hello',
|
||||
},
|
||||
2: {
|
||||
content: 'hello1',
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(getters.getEarliestMessage(state)).toEqual({
|
||||
content: 'hello',
|
||||
});
|
||||
});
|
||||
|
||||
it('uiFlags', () => {
|
||||
const state = {
|
||||
uiFlags: {
|
||||
allMessagesLoaded: false,
|
||||
isFetchingList: false,
|
||||
},
|
||||
};
|
||||
expect(getters.getAllMessagesLoaded(state)).toEqual(false);
|
||||
expect(getters.getIsFetchingList(state)).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
import { mutations } from '../../conversation';
|
||||
|
||||
const temporaryMessagePayload = {
|
||||
content: 'hello',
|
||||
id: 1,
|
||||
message_type: 0,
|
||||
status: 'in_progress',
|
||||
};
|
||||
|
||||
const incomingMessagePayload = {
|
||||
content: 'hello',
|
||||
id: 1,
|
||||
message_type: 0,
|
||||
status: 'sent',
|
||||
};
|
||||
|
||||
const outgoingMessagePayload = {
|
||||
content: 'hello',
|
||||
id: 1,
|
||||
message_type: 1,
|
||||
status: 'sent',
|
||||
};
|
||||
|
||||
describe('#mutations', () => {
|
||||
describe('#pushMessageToConversation', () => {
|
||||
it('add message to conversation if outgoing', () => {
|
||||
const state = { conversations: {} };
|
||||
mutations.pushMessageToConversation(state, outgoingMessagePayload);
|
||||
expect(state.conversations).toEqual({
|
||||
1: outgoingMessagePayload,
|
||||
});
|
||||
});
|
||||
|
||||
it('add message to conversation if message in undelivered', () => {
|
||||
const state = { conversations: {} };
|
||||
mutations.pushMessageToConversation(state, temporaryMessagePayload);
|
||||
expect(state.conversations).toEqual({
|
||||
1: temporaryMessagePayload,
|
||||
});
|
||||
});
|
||||
|
||||
it('replaces temporary message in conversation with actual message', () => {
|
||||
const state = {
|
||||
conversations: {
|
||||
rand_id_123: {
|
||||
content: 'hello',
|
||||
id: 'rand_id_123',
|
||||
message_type: 0,
|
||||
status: 'in_progress',
|
||||
},
|
||||
},
|
||||
};
|
||||
mutations.pushMessageToConversation(state, incomingMessagePayload);
|
||||
expect(state.conversations).toEqual({
|
||||
1: incomingMessagePayload,
|
||||
});
|
||||
});
|
||||
|
||||
it('adds message in conversation if it is a new message', () => {
|
||||
const state = { conversations: {} };
|
||||
mutations.pushMessageToConversation(state, incomingMessagePayload);
|
||||
expect(state.conversations).toEqual({
|
||||
1: incomingMessagePayload,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setConversationListLoading', () => {
|
||||
it('set status correctly', () => {
|
||||
const state = { uiFlags: { isFetchingList: false } };
|
||||
mutations.setConversationListLoading(state, true);
|
||||
expect(state.uiFlags.isFetchingList).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setMessagesInConversation', () => {
|
||||
it('sets allMessagesLoaded flag if payload is empty', () => {
|
||||
const state = { uiFlags: { allMessagesLoaded: false } };
|
||||
mutations.setMessagesInConversation(state, []);
|
||||
expect(state.uiFlags.allMessagesLoaded).toEqual(true);
|
||||
});
|
||||
|
||||
it('sets messages if payload is not empty', () => {
|
||||
const state = {
|
||||
uiFlags: { allMessagesLoaded: false },
|
||||
conversations: {},
|
||||
};
|
||||
mutations.setMessagesInConversation(state, [{ id: 1, content: 'hello' }]);
|
||||
expect(state.conversations).toEqual({
|
||||
1: { id: 1, content: 'hello' },
|
||||
});
|
||||
expect(state.uiFlags.allMessagesLoaded).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
findUndeliveredMessage,
|
||||
createTemporaryMessage,
|
||||
} from '../conversation';
|
||||
} from '../../conversation';
|
||||
|
||||
describe('#findUndeliveredMessage', () => {
|
||||
it('returns message objects if exist', () => {
|
||||
Reference in New Issue
Block a user