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
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:
@@ -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([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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: {},
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user