Initial commit: Add logistics and order_detail message types
Some checks failed
Lock Threads / action (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Run Linux nightly installer / nightly (push) Has been cancelled

- Add Logistics component with progress tracking
- Add OrderDetail component for order information
- Support data-driven steps and actions
- Add blue color scale to widget SCSS
- Fix node overflow and progress bar rendering issues
- Add English translations for dashboard components

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Liang XJ
2026-01-26 11:16:56 +08:00
commit 092fb2e083
7646 changed files with 975643 additions and 0 deletions

View File

@@ -0,0 +1,434 @@
import { actions } from '../../conversation/actions';
import getUuid from '../../../../helpers/uuid';
import { API } from 'widget/helpers/axios';
vi.mock('../../../../helpers/uuid');
vi.mock('widget/helpers/axios');
const commit = vi.fn();
const dispatch = vi.fn();
describe('#actions', () => {
describe('#createConversation', () => {
it('sends correct mutations', async () => {
API.post.mockResolvedValue({
data: {
contact: { name: 'contact-name' },
messages: [{ id: 1, content: 'This is a test message' }],
},
});
let windowSpy = vi.spyOn(window, 'window', 'get');
windowSpy.mockImplementation(() => ({
WOOT_WIDGET: {
$root: {
$i18n: {
locale: 'el',
},
},
},
location: {
search: '?param=1',
},
}));
await actions.createConversation(
{ commit },
{ contact: {}, message: 'This is a test message' }
);
expect(commit.mock.calls).toEqual([
['setConversationUIFlag', { isCreating: true }],
[
'pushMessageToConversation',
{ id: 1, content: 'This is a test message' },
],
['setConversationUIFlag', { isCreating: false }],
]);
windowSpy.mockRestore();
});
});
describe('#addOrUpdateMessage', () => {
it('sends correct actions for non-deleted message', () => {
actions.addOrUpdateMessage(
{ commit },
{
id: 1,
content: 'Hey',
content_attributes: {},
}
);
expect(commit).toBeCalledWith('pushMessageToConversation', {
id: 1,
content: 'Hey',
content_attributes: {},
});
});
it('sends correct actions for non-deleted message', () => {
actions.addOrUpdateMessage(
{ commit },
{
id: 1,
content: 'Hey',
content_attributes: { deleted: true },
}
);
expect(commit).toBeCalledWith('deleteMessage', 1);
});
it('plays audio when agent sends a message', () => {
actions.addOrUpdateMessage({ commit }, { id: 1, message_type: 1 });
expect(commit).toBeCalledWith('pushMessageToConversation', {
id: 1,
message_type: 1,
});
});
});
describe('#toggleAgentTyping', () => {
it('sends correct mutations', () => {
actions.toggleAgentTyping({ commit }, { status: true });
expect(commit).toBeCalledWith('toggleAgentTypingStatus', {
status: true,
});
});
});
describe('#sendMessage', () => {
it('sends correct mutations', async () => {
const mockDate = new Date(1466424490000);
getUuid.mockImplementationOnce(() => '1111');
const spy = vi.spyOn(global, 'Date').mockImplementation(() => mockDate);
const windowSpy = vi.spyOn(window, 'window', 'get');
windowSpy.mockImplementation(() => ({
WOOT_WIDGET: {
$root: {
$i18n: {
locale: 'ar',
},
},
},
location: {
search: '?param=1',
},
}));
await actions.sendMessage(
{ commit, dispatch },
{ content: 'hello', replyTo: 124 }
);
spy.mockRestore();
windowSpy.mockRestore();
expect(dispatch).toBeCalledWith('sendMessageWithData', {
attachments: undefined,
content: 'hello',
created_at: 1466424490,
id: '1111',
message_type: 0,
replyTo: 124,
status: 'in_progress',
});
});
});
describe('#sendAttachment', () => {
it('sends correct mutations', () => {
const mockDate = new Date(1466424490000);
getUuid.mockImplementationOnce(() => '1111');
const spy = vi.spyOn(global, 'Date').mockImplementation(() => mockDate);
const thumbUrl = '';
const attachment = { thumbUrl, fileType: 'file' };
actions.sendAttachment(
{ commit, dispatch },
{ attachment, replyTo: 135 }
);
spy.mockRestore();
expect(commit).toBeCalledWith('pushMessageToConversation', {
id: '1111',
content: undefined,
status: 'in_progress',
created_at: 1466424490,
message_type: 0,
replyTo: 135,
attachments: [
{
thumb_url: '',
data_url: '',
file_type: 'file',
status: 'in_progress',
},
],
});
});
});
describe('#setUserLastSeen', () => {
it('sends correct mutations', async () => {
API.post.mockResolvedValue({ data: { success: true } });
await actions.setUserLastSeen({
commit,
getters: { getConversationSize: 2 },
});
expect(commit.mock.calls[0][0]).toEqual('setMetaUserLastSeenAt');
});
it('sends correct mutations', async () => {
API.post.mockResolvedValue({ data: { success: true } });
await actions.setUserLastSeen({
commit,
getters: { getConversationSize: 0 },
});
expect(commit.mock.calls).toEqual([]);
});
});
describe('#clearConversations', () => {
it('sends correct mutations', () => {
actions.clearConversations({ commit });
expect(commit).toBeCalledWith('clearConversations');
});
});
describe('#fetchOldConversations', () => {
it('sends correct actions', async () => {
API.get.mockResolvedValue({
data: {
payload: [
{
id: 1,
text: 'hey',
content_attributes: {},
},
{
id: 2,
text: 'welcome',
content_attributes: { deleted: true },
},
],
meta: {
contact_last_seen_at: 1466424490,
},
},
});
await actions.fetchOldConversations({ commit }, {});
expect(commit.mock.calls).toEqual([
['setConversationListLoading', true],
['conversation/setMetaUserLastSeenAt', 1466424490, { root: true }],
[
'setMessagesInConversation',
[
{
id: 1,
text: 'hey',
content_attributes: {},
},
],
],
['setConversationListLoading', false],
]);
});
});
describe('#syncLatestMessages', () => {
it('latest message should append to end of list', async () => {
const state = {
uiFlags: { allMessagesLoaded: false },
conversations: {
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682244355, // Sunday, 23 April 2023 10:05:55
conversation_id: 20,
},
463: {
id: 463,
content: 'ss',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682490729, // Wednesday, 26 April 2023 06:32:09
conversation_id: 20,
},
},
lastMessageId: 463,
};
API.get.mockResolvedValue({
data: {
payload: [
{
id: 465,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682504326, // Wednesday, 26 April 2023 10:18:46
conversation_id: 20,
},
],
meta: {
contact_last_seen_at: 1466424490,
},
},
});
await actions.syncLatestMessages({ state, commit }, {});
expect(commit.mock.calls).toEqual([
['conversation/setMetaUserLastSeenAt', 1466424490, { root: true }],
[
'setMissingMessagesInConversation',
{
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682244355,
conversation_id: 20,
},
463: {
id: 463,
content: 'ss',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682490729,
conversation_id: 20,
},
465: {
id: 465,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682504326,
conversation_id: 20,
},
},
],
]);
});
it('old message should insert to exact position', async () => {
const state = {
uiFlags: { allMessagesLoaded: false },
conversations: {
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682244355, // Sunday, 23 April 2023 10:05:55
conversation_id: 20,
},
463: {
id: 463,
content: 'ss',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682490729, // Wednesday, 26 April 2023 06:32:09
conversation_id: 20,
},
},
lastMessageId: 463,
};
API.get.mockResolvedValue({
data: {
payload: [
{
id: 460,
content: 'Hi how are you',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682417926, // Tuesday, 25 April 2023 10:18:46
conversation_id: 20,
},
],
meta: {
contact_last_seen_at: 14664223490,
},
},
});
await actions.syncLatestMessages({ state, commit }, {});
expect(commit.mock.calls).toEqual([
['conversation/setMetaUserLastSeenAt', 14664223490, { root: true }],
[
'setMissingMessagesInConversation',
{
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682244355,
conversation_id: 20,
},
460: {
id: 460,
content: 'Hi how are you',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682417926,
conversation_id: 20,
},
463: {
id: 463,
content: 'ss',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682490729,
conversation_id: 20,
},
},
],
]);
});
it('abort syncing if there is no missing messages ', async () => {
const state = {
uiFlags: { allMessagesLoaded: false },
conversation: {
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682244355, // Sunday, 23 April 2023 10:05:55
conversation_id: 20,
},
463: {
id: 463,
content: 'ss',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682490729, // Wednesday, 26 April 2023 06:32:09
conversation_id: 20,
},
},
lastMessageId: 463,
};
API.get.mockResolvedValue({
data: {
payload: [],
meta: {
contact_last_seen_at: 14664223490,
},
},
});
await actions.syncLatestMessages({ state, commit }, {});
expect(commit.mock.calls).toEqual([]);
});
});
});

View File

@@ -0,0 +1,477 @@
import { getters } from '../../conversation/getters';
describe('#getters', () => {
it('getConversation', () => {
const state = {
conversations: {
1: {
content: 'hello',
},
},
};
expect(getters.getConversation(state)).toEqual({
1: {
content: 'hello',
},
});
});
it('getIsCreating', () => {
const state = { uiFlags: { isCreating: true } };
expect(getters.getIsCreating(state)).toEqual(true);
});
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,
isAgentTyping: false,
},
};
expect(getters.getAllMessagesLoaded(state)).toEqual(false);
expect(getters.getIsFetchingList(state)).toEqual(false);
expect(getters.getIsAgentTyping(state)).toEqual(false);
});
it('getGroupedConversation', () => {
expect(
getters.getGroupedConversation({
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 0,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
3: {
id: 3,
content: 'Hey',
created_at: 1574092218,
message_type: 1,
},
4: {
id: 4,
content: 'Hey',
created_at: 1576340623,
},
5: {
id: 5,
content: 'How may I help you',
created_at: 1576340626,
},
},
})
).toEqual([
{
date: 'Nov 18, 2019',
messages: [
{
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
showAvatar: false,
message_type: 0,
},
{
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
showAvatar: true,
message_type: 0,
},
{
id: 3,
content: 'Hey',
created_at: 1574092218,
showAvatar: true,
message_type: 1,
},
],
},
{
date: 'Dec 14, 2019',
messages: [
{
id: 4,
content: 'Hey',
created_at: 1576340623,
showAvatar: false,
},
{
id: 5,
content: 'How may I help you',
created_at: 1576340626,
showAvatar: true,
},
],
},
]);
expect(
getters.getGroupedConversation({
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 0,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
3: {
id: 3,
content: 'Hey',
created_at: 1574092218,
message_type: 1,
},
4: {
id: 4,
content: 'Hey',
created_at: 1576340623,
},
5: {
id: 5,
content: 'How may I help you',
created_at: 1576340626,
message_type: 2,
content_type: 'form',
content_attributes: {
submitted_values: [{ name: 'text', value: 'sample text' }],
},
},
6: {
id: 6,
content: 'How may I help you',
created_at: 1576340626,
message_type: 2,
content_type: 'form',
},
7: {
id: 7,
content: 'How may I help you',
created_at: 1576340626,
message_type: 2,
content_type: 'form',
content_attributes: {
submitted_values: [{ name: 'text', value: 'sample text' }],
},
},
},
})
).toEqual([
{
date: 'Nov 18, 2019',
messages: [
{
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
showAvatar: false,
message_type: 0,
},
{
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
showAvatar: true,
message_type: 0,
},
{
id: 3,
content: 'Hey',
created_at: 1574092218,
showAvatar: true,
message_type: 1,
},
],
},
{
date: 'Dec 14, 2019',
messages: [
{
id: 4,
content: 'Hey',
created_at: 1576340623,
showAvatar: true,
},
{
id: 5,
content: 'How may I help you',
created_at: 1576340626,
message_type: 2,
content_type: 'form',
content_attributes: {
submitted_values: [{ name: 'text', value: 'sample text' }],
},
showAvatar: false,
},
{
id: 6,
content: 'How may I help you',
created_at: 1576340626,
message_type: 2,
content_type: 'form',
showAvatar: true,
},
{
id: 7,
content: 'How may I help you',
created_at: 1576340626,
message_type: 2,
content_type: 'form',
content_attributes: {
submitted_values: [{ name: 'text', value: 'sample text' }],
},
showAvatar: false,
},
],
},
]);
});
describe('getUnreadMessageCount returns', () => {
it('0 if there are no messages and last seen is undefined', () => {
const state = {
conversations: {},
meta: {
userLastSeenAt: undefined,
},
};
expect(getters.getUnreadMessageCount(state)).toEqual(0);
});
it('0 if there are no messages and last seen is present', () => {
const state = {
conversations: {},
meta: {
userLastSeenAt: Date.now(),
},
};
expect(getters.getUnreadMessageCount(state)).toEqual(0);
});
it('unread count if there are messages and last seen is before messages created-at', () => {
const state = {
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 1,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 1,
},
},
meta: {
userLastSeenAt: 1474075964,
},
};
expect(getters.getUnreadMessageCount(state)).toEqual(2);
});
it('unread count if there are messages and last seen is after messages created-at', () => {
const state = {
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 1,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 1,
},
3: {
id: 3,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
},
meta: {
userLastSeenAt: 1674075964,
},
};
expect(getters.getUnreadMessageCount(state)).toEqual(0);
});
});
describe('getUnreadTextMessages returns', () => {
it('no messages if there are no messages and last seen is undefined', () => {
const state = {
conversations: {},
meta: {
userLastSeenAt: undefined,
},
};
expect(
getters.getUnreadTextMessages(state, { getUnreadMessageCount: 0 })
).toEqual([]);
});
it('0 if there are no messages and last seen is present', () => {
const state = {
conversations: {},
meta: {
userLastSeenAt: Date.now(),
},
};
expect(
getters.getUnreadTextMessages(state, { getUnreadMessageCount: 0 })
).toEqual([]);
});
it('only unread text messages from agent if there are messages and last seen is before messages created-at', () => {
const state = {
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 1,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
},
};
expect(
getters.getUnreadTextMessages(state, { getUnreadMessageCount: 1 })
).toEqual([
{
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 1,
},
]);
});
it('unread messages omitting seen messages ', () => {
const state = {
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 1,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1674075965,
message_type: 1,
},
3: {
id: 3,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
},
meta: {
userLastSeenAt: 1674075964,
},
};
expect(
getters.getUnreadTextMessages(state, { getUnreadMessageCount: 1 })
).toEqual([
{
id: 2,
content: 'Yes, It makes sense',
created_at: 1674075965,
message_type: 1,
},
]);
});
});
it('getMessageCount', () => {
const state = {
conversations: {
1: {
content: 'hey, how are you?',
},
},
};
expect(getters.getMessageCount(state)).toEqual(1);
});
it('getLastMessage', () => {
const state = {
conversations: {
1: {
id: 1,
content: 'Thanks for the help',
created_at: 1574075964,
message_type: 1,
},
2: {
id: 2,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 1,
},
3: {
id: 3,
content: 'Yes, It makes sense',
created_at: 1574092218,
message_type: 0,
},
},
meta: {
userLastSeenAt: 1674075964,
},
};
expect(getters.getLastMessage(state).id).toEqual(3);
});
});

View File

@@ -0,0 +1,81 @@
import {
findUndeliveredMessage,
createTemporaryMessage,
getNonDeletedMessages,
} from '../../conversation/helpers';
describe('#findUndeliveredMessage', () => {
it('returns message objects if exist', () => {
const conversation = {
1: {
id: 1,
content: 'Hello',
status: 'in_progress',
},
2: {
id: 2,
content: 'Hello',
status: 'sent',
},
3: {
id: 3,
content: 'How may I help you',
status: 'sent',
},
};
expect(
findUndeliveredMessage(conversation, { content: 'Hello' })
).toStrictEqual([{ id: 1, content: 'Hello', status: 'in_progress' }]);
});
});
describe('#createTemporaryMessage', () => {
it('returns message object', () => {
const message = createTemporaryMessage({ content: 'hello' });
expect(message.content).toBe('hello');
expect(message.status).toBe('in_progress');
});
it('returns message object with reply to', () => {
const message = createTemporaryMessage({
content: 'hello',
replyTo: 124,
});
expect(message.content).toBe('hello');
expect(message.status).toBe('in_progress');
expect(message.replyTo).toBe(124);
});
});
describe('#getNonDeletedMessages', () => {
it('returns non-deleted messages', () => {
const messages = [
{
id: 1,
content: 'Hello',
content_attributes: {},
},
{
id: 2,
content: 'Hey',
content_attributes: { deleted: true },
},
{
id: 3,
content: 'How may I help you',
content_attributes: {},
},
];
expect(getNonDeletedMessages({ messages })).toStrictEqual([
{
id: 1,
content: 'Hello',
content_attributes: {},
},
{
id: 3,
content: 'How may I help you',
content_attributes: {},
},
]);
});
});

View File

@@ -0,0 +1,254 @@
import { mutations } from '../../conversation/mutations';
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('#setConversationUIFlag', () => {
it('set uiFlags correctly', () => {
const state = { uiFlags: { isFetchingList: false } };
mutations.setConversationUIFlag(state, { isCreating: true });
expect(state.uiFlags).toEqual({
isFetchingList: false,
isCreating: 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);
});
});
describe('#toggleAgentTypingStatus', () => {
it('sets isAgentTyping flag to true', () => {
const state = { uiFlags: { isAgentTyping: false } };
mutations.toggleAgentTypingStatus(state, { status: 'on' });
expect(state.uiFlags.isAgentTyping).toEqual(true);
});
it('sets isAgentTyping flag to false', () => {
const state = { uiFlags: { isAgentTyping: true } };
mutations.toggleAgentTypingStatus(state, { status: 'off' });
expect(state.uiFlags.isAgentTyping).toEqual(false);
});
});
describe('#updateAttachmentMessageStatus', () => {
it('Updates status of loading messages if payload is not empty', () => {
const state = {
conversations: {
rand_id_123: {
content: '',
id: 'rand_id_123',
message_type: 0,
status: 'in_progress',
attachment: {
file: '',
file_type: 'image',
},
},
},
};
const message = {
id: '1',
content: '',
status: 'sent',
message_type: 0,
attachments: [
{
file: '',
file_type: 'image',
},
],
};
mutations.updateAttachmentMessageStatus(state, {
message,
tempId: 'rand_id_123',
});
expect(state.conversations).toEqual({
1: {
id: '1',
content: '',
message_type: 0,
status: 'sent',
attachments: [
{
file: '',
file_type: 'image',
},
],
},
});
});
});
describe('#clearConversations', () => {
it('clears the state', () => {
const state = { conversations: { 1: { id: 1 } } };
mutations.clearConversations(state);
expect(state.conversations).toEqual({});
});
});
describe('#deleteMessage', () => {
it('delete the message from conversation', () => {
const state = { conversations: { 1: { id: 1 } } };
mutations.deleteMessage(state, 1);
expect(state.conversations).toEqual({});
});
});
describe('#setMissingMessages', () => {
it('sets messages if payload is not empty', () => {
const state = {
uiFlags: { allMessagesLoaded: false },
conversations: {
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682432667,
conversation_id: 20,
},
464: {
id: 464,
content: 'hey will be back soon',
message_type: 3,
content_type: 'text',
content_attributes: {},
created_at: 1682490729,
conversation_id: 20,
},
},
};
mutations.setMessagesInConversation(state, [
{
id: 455,
content: 'Hey billowing-grass-423 how are you?',
message_type: 3,
content_type: 'text',
content_attributes: {},
created_at: 1682432667,
conversation_id: 20,
},
]);
expect(state.conversations).toEqual({
454: {
id: 454,
content: 'hi',
message_type: 0,
content_type: 'text',
content_attributes: {},
created_at: 1682432667,
conversation_id: 20,
},
455: {
id: 455,
content: 'Hey billowing-grass-423 how are you?',
message_type: 3,
content_type: 'text',
content_attributes: {},
created_at: 1682432667,
conversation_id: 20,
},
464: {
id: 464,
content: 'hey will be back soon',
message_type: 3,
content_type: 'text',
content_attributes: {},
created_at: 1682490729,
conversation_id: 20,
},
});
});
});
});