fix: Update the logic to handle attachments in a conversation (#9784)
When the chat is viewed, a function `fetchAllAttachments` is run to get all attachments for a particular conversation. This function, before updating the record creates the `attachments` property on the `chat` object in the store. If in any case this function fails, the `attachments` property is not created, and when the code reaches the `dashboard/store/modules/conversations/index.js` the error occurs This PR fixes it by ensuring that `SET_ALL_ATTACHMENTS` is always run. And it handles the default case as well --- Sentry Issue: [CHATWOOT-FRONTEND-APP-5Y](https://chatwoot-p3.sentry.io/issues/5459056982/) ``` TypeError: Cannot read properties of undefined (reading 'some') at forEach(./app/javascript/dashboard/store/modules/conversations/index.js:160:31) at Array.forEach(<anonymous>) at mutations(./app/javascript/dashboard/store/modules/conversations/index.js:159:27) at handler(./node_modules/vuex/dist/vuex.js:771:7) at forEach(./node_modules/vuex/dist/vuex.js:470:9) at Array.forEach(<anonymous>) at fn(./node_modules/vuex/dist/vuex.js:469:13) at Store.prototype._withCommit(./node_modules/vuex/dist/vuex.js:574:5) at Store.prototype.commit(./node_modules/vuex/dist/vuex.js:468:10) at this.commit(./node_modules/vuex/dist/vuex.js:420:21) at call(./app/javascript/dashboard/store/modules/conversations/actions.js:273:7) at tryCatch(./node_modules/videojs-record/dist/videojs.record.js:2868:27) at _invoke(./node_modules/videojs-record/dist/videojs.record.js:3088:32) at prototype[method](./node_modules/videojs-record/dist/videojs.record.js:2921:31) at as(/packs/js/application-cf716bca3c984faeb095.js:4:76) at as(/packs/js/application-cf716bca3c984faeb095.js:4:76) at nrWrapper(/app/accounts/81898/conversations/95:6:17817) ``` --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
@@ -245,30 +245,18 @@ describe('#getters', () => {
|
||||
|
||||
describe('#getSelectedChatAttachments', () => {
|
||||
it('Returns attachments in selected chat', () => {
|
||||
const state = {};
|
||||
const getSelectedChat = {
|
||||
attachments: [
|
||||
{
|
||||
id: 1,
|
||||
file_name: 'test1',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
file_name: 'test2',
|
||||
},
|
||||
const attachments = {
|
||||
1: [
|
||||
{ id: 1, file_name: 'test1' },
|
||||
{ id: 2, file_name: 'test2' },
|
||||
],
|
||||
};
|
||||
const selectedChatId = 1;
|
||||
expect(
|
||||
getters.getSelectedChatAttachments(state, { getSelectedChat })
|
||||
getters.getSelectedChatAttachments({ selectedChatId, attachments })
|
||||
).toEqual([
|
||||
{
|
||||
id: 1,
|
||||
file_name: 'test1',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
file_name: 'test2',
|
||||
},
|
||||
{ id: 1, file_name: 'test1' },
|
||||
{ id: 2, file_name: 'test2' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -313,7 +313,6 @@ describe('#mutations', () => {
|
||||
{
|
||||
id: 1,
|
||||
messages: [{ id: 1, content: 'test' }],
|
||||
attachments: [{ id: 1, name: 'test1.png' }],
|
||||
dataFetched: true,
|
||||
allMessagesLoaded: true,
|
||||
},
|
||||
@@ -325,7 +324,6 @@ describe('#mutations', () => {
|
||||
id: 1,
|
||||
name: 'test',
|
||||
messages: [{ id: 1, content: 'updated message' }],
|
||||
attachments: [{ id: 1, name: 'test.png' }],
|
||||
dataFetched: true,
|
||||
allMessagesLoaded: true,
|
||||
},
|
||||
@@ -335,7 +333,6 @@ describe('#mutations', () => {
|
||||
id: 1,
|
||||
name: 'test',
|
||||
messages: [{ id: 1, content: 'test' }],
|
||||
attachments: [{ id: 1, name: 'test1.png' }],
|
||||
dataFetched: true,
|
||||
allMessagesLoaded: true,
|
||||
},
|
||||
@@ -371,25 +368,28 @@ describe('#mutations', () => {
|
||||
it('set all attachments', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: {},
|
||||
};
|
||||
const data = [{ id: 1, name: 'test' }];
|
||||
mutations[types.SET_ALL_ATTACHMENTS](state, { id: 1, data });
|
||||
expect(state.allConversations[0].attachments).toEqual(data);
|
||||
expect(state.attachments[1]).toEqual(data);
|
||||
});
|
||||
it('set attachments key even if the attachments are empty', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: {},
|
||||
};
|
||||
const data = [];
|
||||
mutations[types.SET_ALL_ATTACHMENTS](state, { id: 1, data });
|
||||
expect(state.allConversations[0].attachments).toEqual([]);
|
||||
expect(state.attachments[1]).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#ADD_CONVERSATION_ATTACHMENTS', () => {
|
||||
it('add conversation attachments', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1, attachments: [] }],
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: {},
|
||||
};
|
||||
const message = {
|
||||
conversation_id: 1,
|
||||
@@ -398,19 +398,13 @@ describe('#mutations', () => {
|
||||
};
|
||||
|
||||
mutations[types.ADD_CONVERSATION_ATTACHMENTS](state, message);
|
||||
expect(state.allConversations[0].attachments).toEqual(
|
||||
message.attachments
|
||||
);
|
||||
expect(state.attachments[1]).toEqual(message.attachments);
|
||||
});
|
||||
|
||||
it('should not add duplicate attachments', () => {
|
||||
const state = {
|
||||
allConversations: [
|
||||
{
|
||||
id: 1,
|
||||
attachments: [{ id: 1, name: 'existing' }],
|
||||
},
|
||||
],
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: { 1: [{ id: 1, name: 'existing' }] },
|
||||
};
|
||||
const message = {
|
||||
conversation_id: 1,
|
||||
@@ -422,12 +416,12 @@ describe('#mutations', () => {
|
||||
};
|
||||
|
||||
mutations[types.ADD_CONVERSATION_ATTACHMENTS](state, message);
|
||||
expect(state.allConversations[0].attachments).toHaveLength(2);
|
||||
expect(state.allConversations[0].attachments).toContainEqual({
|
||||
expect(state.attachments[1]).toHaveLength(2);
|
||||
expect(state.attachments[1]).toContainEqual({
|
||||
id: 1,
|
||||
name: 'existing',
|
||||
});
|
||||
expect(state.allConversations[0].attachments).toContainEqual({
|
||||
expect(state.attachments[1]).toContainEqual({
|
||||
id: 2,
|
||||
name: 'new',
|
||||
});
|
||||
@@ -436,6 +430,9 @@ describe('#mutations', () => {
|
||||
it('should not add attachments if chat not found', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1, attachments: [] }],
|
||||
attachments: {
|
||||
1: [],
|
||||
},
|
||||
};
|
||||
const message = {
|
||||
conversation_id: 2,
|
||||
@@ -444,14 +441,17 @@ describe('#mutations', () => {
|
||||
};
|
||||
|
||||
mutations[types.ADD_CONVERSATION_ATTACHMENTS](state, message);
|
||||
expect(state.allConversations[0].attachments).toHaveLength(0);
|
||||
expect(state.attachments[1]).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#DELETE_CONVERSATION_ATTACHMENTS', () => {
|
||||
it('delete conversation attachments', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1, attachments: [{ id: 1, message_id: 1 }] }],
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: {
|
||||
1: [{ id: 1, message_id: 1 }],
|
||||
},
|
||||
};
|
||||
const message = {
|
||||
conversation_id: 1,
|
||||
@@ -460,12 +460,15 @@ describe('#mutations', () => {
|
||||
};
|
||||
|
||||
mutations[types.DELETE_CONVERSATION_ATTACHMENTS](state, message);
|
||||
expect(state.allConversations[0].attachments).toHaveLength(0);
|
||||
expect(state.attachments[1]).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should not delete attachments for non-matching message id', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1, attachments: [{ id: 1, message_id: 1 }] }],
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: {
|
||||
1: [{ id: 1, message_id: 1 }],
|
||||
},
|
||||
};
|
||||
const message = {
|
||||
conversation_id: 1,
|
||||
@@ -474,12 +477,13 @@ describe('#mutations', () => {
|
||||
};
|
||||
|
||||
mutations[types.DELETE_CONVERSATION_ATTACHMENTS](state, message);
|
||||
expect(state.allConversations[0].attachments).toHaveLength(1);
|
||||
expect(state.attachments[1]).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should not delete attachments if chat not found', () => {
|
||||
const state = {
|
||||
allConversations: [{ id: 1, attachments: [{ id: 1, message_id: 1 }] }],
|
||||
allConversations: [{ id: 1 }],
|
||||
attachments: { 1: [{ id: 1, message_id: 1 }] },
|
||||
};
|
||||
const message = {
|
||||
conversation_id: 2,
|
||||
@@ -488,7 +492,7 @@ describe('#mutations', () => {
|
||||
};
|
||||
|
||||
mutations[types.DELETE_CONVERSATION_ATTACHMENTS](state, message);
|
||||
expect(state.allConversations[0].attachments).toHaveLength(1);
|
||||
expect(state.attachments[1]).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user