chore: Add missing frontend specs (#2329)

* complete dshboard api specs

* code cleanup

* add conversation mixin spec

* add isadmin mixin spec

* add agent details component spec

* add notification badge spec

* spec for thumbnail exist in agent details

* fix the deprecation warnings

* add agent details spec

* add account selector specs

* code cleanup

* refactor contact spec

* review fixes

* review fixes

* add shared spec helper

* update api spec helper

* review fixes
This commit is contained in:
Muhsin Keloth 2021-05-25 14:00:21 +05:30 committed by GitHub
parent 652d988993
commit cfdf4a12c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1009 additions and 71 deletions

View file

@ -0,0 +1,26 @@
import accountAPI from '../account';
import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#accountAPI', () => {
it('creates correct instance', () => {
expect(accountAPI).toBeInstanceOf(ApiClient);
expect(accountAPI).toHaveProperty('get');
expect(accountAPI).toHaveProperty('show');
expect(accountAPI).toHaveProperty('create');
expect(accountAPI).toHaveProperty('update');
expect(accountAPI).toHaveProperty('delete');
expect(accountAPI).toHaveProperty('createAccount');
});
describeWithAPIMock('API calls', context => {
it('#createAccount', () => {
accountAPI.createAccount({
name: 'Chatwoot',
});
expect(context.axiosMock.post).toHaveBeenCalledWith('/api/v1/accounts', {
name: 'Chatwoot',
});
});
});
});

View file

@ -0,0 +1,26 @@
function apiSpecHelper() {
beforeEach(() => {
this.originalAxios = window.axios;
this.axiosMock = {
post: jest.fn(() => Promise.resolve()),
get: jest.fn(() => Promise.resolve()),
patch: jest.fn(() => Promise.resolve()),
};
window.axios = this.axiosMock;
});
afterEach(() => {
window.axios = this.originalAxios;
});
}
// https://stackoverflow.com/a/59344023/3901856
const sharedWrapper = describe('sharedWrapper', () => {});
export default function describeWithAPIMock(skillName, testFn) {
return describe(skillName, function configureContext() {
function Context() {}
Context.prototype = sharedWrapper.ctx;
this.ctx = new Context();
apiSpecHelper.call(this);
testFn.call(this, this);
});
}

View file

@ -1,5 +1,6 @@
import fbChannel from '../../channel/fbChannel'; import fbChannel from '../../channel/fbChannel';
import ApiClient from '../../ApiClient'; import ApiClient from '../../ApiClient';
import describeWithAPIMock from '../apiSpecHelper';
describe('#FBChannel', () => { describe('#FBChannel', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
@ -10,4 +11,29 @@ describe('#FBChannel', () => {
expect(fbChannel).toHaveProperty('update'); expect(fbChannel).toHaveProperty('update');
expect(fbChannel).toHaveProperty('delete'); expect(fbChannel).toHaveProperty('delete');
}); });
describeWithAPIMock('API calls', context => {
it('#create', () => {
fbChannel.create({ omniauthToken: 'ASFM131CSF@#@$', appId: 'chatwoot' });
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/callbacks/register_facebook_page',
{
omniauthToken: 'ASFM131CSF@#@$',
appId: 'chatwoot',
}
);
});
it('#reauthorize', () => {
fbChannel.reauthorizeFacebookPage({
omniauthToken: 'ASFM131CSF@#@$',
inboxId: 1,
});
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/callbacks/reauthorize_page',
{
omniauth_token: 'ASFM131CSF@#@$',
inbox_id: 1,
}
);
});
});
}); });

View file

@ -0,0 +1,13 @@
import twilioChannel from '../../channel/twilioChannel';
import ApiClient from '../../ApiClient';
describe('#twilioChannel', () => {
it('creates correct instance', () => {
expect(twilioChannel).toBeInstanceOf(ApiClient);
expect(twilioChannel).toHaveProperty('get');
expect(twilioChannel).toHaveProperty('show');
expect(twilioChannel).toHaveProperty('create');
expect(twilioChannel).toHaveProperty('update');
expect(twilioChannel).toHaveProperty('delete');
});
});

View file

@ -1,9 +1,14 @@
import TwitterClient from '../../channel/twitterClient'; import twitterClient from '../../channel/twitterClient';
import ApiClient from '../../ApiClient'; import ApiClient from '../../ApiClient';
describe('#TwitterClient', () => { describe('#TwitterClient', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(TwitterClient).toBeInstanceOf(ApiClient); expect(twitterClient).toBeInstanceOf(ApiClient);
expect(TwitterClient).toHaveProperty('generateAuthorization'); expect(twitterClient).toHaveProperty('get');
expect(twitterClient).toHaveProperty('show');
expect(twitterClient).toHaveProperty('create');
expect(twitterClient).toHaveProperty('update');
expect(twitterClient).toHaveProperty('delete');
expect(twitterClient).toHaveProperty('generateAuthorization');
}); });
}); });

View file

@ -0,0 +1,13 @@
import webChannelClient from '../../channel/webChannel';
import ApiClient from '../../ApiClient';
describe('#webChannelClient', () => {
it('creates correct instance', () => {
expect(webChannelClient).toBeInstanceOf(ApiClient);
expect(webChannelClient).toHaveProperty('get');
expect(webChannelClient).toHaveProperty('show');
expect(webChannelClient).toHaveProperty('create');
expect(webChannelClient).toHaveProperty('update');
expect(webChannelClient).toHaveProperty('delete');
});
});

View file

@ -1,14 +1,44 @@
import contacts from '../contacts'; import contactAPI from '../contacts';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#ContactsAPI', () => { describe('#ContactsAPI', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(contacts).toBeInstanceOf(ApiClient); expect(contactAPI).toBeInstanceOf(ApiClient);
expect(contacts).toHaveProperty('get'); expect(contactAPI).toHaveProperty('get');
expect(contacts).toHaveProperty('show'); expect(contactAPI).toHaveProperty('show');
expect(contacts).toHaveProperty('create'); expect(contactAPI).toHaveProperty('create');
expect(contacts).toHaveProperty('update'); expect(contactAPI).toHaveProperty('update');
expect(contacts).toHaveProperty('delete'); expect(contactAPI).toHaveProperty('delete');
expect(contacts).toHaveProperty('getConversations'); expect(contactAPI).toHaveProperty('getConversations');
});
describeWithAPIMock('API calls', context => {
it('#get', () => {
contactAPI.get(1, 'name');
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/contacts?page=1&sort=name'
);
});
it('#getConversations', () => {
contactAPI.getConversations(1);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/contacts/1/conversations'
);
});
it('#getContactableInboxes', () => {
contactAPI.getContactableInboxes(1);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/contacts/1/contactable_inboxes'
);
});
it('#search', () => {
contactAPI.search('leads', 1, 'date');
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/contacts/search?q=leads&page=1&sort=date'
);
});
}); });
}); });

View file

@ -1,15 +1,36 @@
import conversations from '../conversations'; import conversationsAPI from '../conversations';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#ConversationApi', () => { describe('#ConversationApi', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(conversations).toBeInstanceOf(ApiClient); expect(conversationsAPI).toBeInstanceOf(ApiClient);
expect(conversations).toHaveProperty('get'); expect(conversationsAPI).toHaveProperty('get');
expect(conversations).toHaveProperty('show'); expect(conversationsAPI).toHaveProperty('show');
expect(conversations).toHaveProperty('create'); expect(conversationsAPI).toHaveProperty('create');
expect(conversations).toHaveProperty('update'); expect(conversationsAPI).toHaveProperty('update');
expect(conversations).toHaveProperty('delete'); expect(conversationsAPI).toHaveProperty('delete');
expect(conversations).toHaveProperty('getLabels'); expect(conversationsAPI).toHaveProperty('getLabels');
expect(conversations).toHaveProperty('updateLabels'); expect(conversationsAPI).toHaveProperty('updateLabels');
});
describeWithAPIMock('API calls', context => {
it('#getLabels', () => {
conversationsAPI.getLabels(1);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/conversations/1/labels'
);
});
it('#updateLabels', () => {
const labels = ['support-query'];
conversationsAPI.updateLabels(1, labels);
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/conversations/1/labels',
{
labels,
}
);
});
}); });
}); });

View file

@ -0,0 +1,13 @@
import endPoints from '../endPoints';
describe('#endPoints', () => {
it('it should return register url details if register page passed ', () => {
expect(endPoints('register')).toEqual({ url: 'api/v1/accounts.json' });
});
it('it should inbox url details if getInbox page passed', () => {
expect(endPoints('getInbox')).toEqual({
url: 'api/v1/conversations.json',
params: { inbox_id: null },
});
});
});

View file

@ -1,5 +1,6 @@
import conversationAPI from '../../inbox/conversation'; import conversationAPI from '../../inbox/conversation';
import ApiClient from '../../ApiClient'; import ApiClient from '../../ApiClient';
import describeWithAPIMock from '../apiSpecHelper';
describe('#ConversationAPI', () => { describe('#ConversationAPI', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
@ -20,27 +21,143 @@ describe('#ConversationAPI', () => {
expect(conversationAPI).toHaveProperty('sendEmailTranscript'); expect(conversationAPI).toHaveProperty('sendEmailTranscript');
}); });
describe('API calls', () => { describeWithAPIMock('API calls', context => {
let originalAxios = null; it('#get conversations', () => {
let axiosMock = null; conversationAPI.get({
inboxId: 1,
beforeEach(() => { status: 'open',
originalAxios = window.axios; assigneeType: 'me',
axiosMock = { post: jest.fn(() => Promise.resolve()) }; page: 1,
labels: [],
window.axios = axiosMock; teamId: 1,
});
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/conversations',
{
params: {
inbox_id: 1,
team_id: 1,
status: 'open',
assignee_type: 'me',
page: 1,
labels: [],
},
}
);
}); });
afterEach(() => { it('#search', () => {
window.axios = originalAxios; conversationAPI.search({
q: 'leads',
page: 1,
});
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/conversations/search',
{
params: {
q: 'leads',
page: 1,
},
}
);
});
it('#toggleStatus', () => {
conversationAPI.toggleStatus({ conversationId: 12, status: 'online' });
expect(context.axiosMock.post).toHaveBeenCalledWith(
`/api/v1/conversations/12/toggle_status`,
{
status: 'online',
}
);
});
it('#assignAgent', () => {
conversationAPI.assignAgent({ conversationId: 12, agentId: 34 });
expect(context.axiosMock.post).toHaveBeenCalledWith(
`/api/v1/conversations/12/assignments?assignee_id=34`,
{}
);
});
it('#assignTeam', () => {
conversationAPI.assignTeam({ conversationId: 12, teamId: 1 });
expect(context.axiosMock.post).toHaveBeenCalledWith(
`/api/v1/conversations/12/assignments`,
{
team_id: 1,
}
);
});
it('#markMessageRead', () => {
conversationAPI.markMessageRead({ id: 12 });
expect(context.axiosMock.post).toHaveBeenCalledWith(
`/api/v1/conversations/12/update_last_seen`
);
});
it('#toggleTyping', () => {
conversationAPI.toggleTyping({
conversationId: 12,
status: 'typing_on',
});
expect(context.axiosMock.post).toHaveBeenCalledWith(
`/api/v1/conversations/12/toggle_typing_status`,
{
typing_status: 'typing_on',
}
);
});
it('#mute', () => {
conversationAPI.mute(45);
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/conversations/45/mute'
);
}); });
it('#unmute', () => { it('#unmute', () => {
conversationAPI.unmute(45); conversationAPI.unmute(45);
expect(context.axiosMock.post).toHaveBeenCalledWith(
expect(axiosMock.post).toHaveBeenCalledWith(
'/api/v1/conversations/45/unmute' '/api/v1/conversations/45/unmute'
); );
}); });
it('#meta', () => {
conversationAPI.meta({
inboxId: 1,
status: 'open',
assigneeType: 'me',
labels: [],
teamId: 1,
});
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/conversations/meta',
{
params: {
inbox_id: 1,
team_id: 1,
status: 'open',
assignee_type: 'me',
labels: [],
},
}
);
});
it('#sendEmailTranscript', () => {
conversationAPI.sendEmailTranscript({
conversationId: 45,
email: 'john@acme.inc',
});
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/conversations/45/transcript',
{
email: 'john@acme.inc',
}
);
});
}); });
}); });

View file

@ -0,0 +1,32 @@
import messageAPI from '../../inbox/message';
import ApiClient from '../../ApiClient';
import describeWithAPIMock from '../apiSpecHelper';
describe('#ConversationAPI', () => {
it('creates correct instance', () => {
expect(messageAPI).toBeInstanceOf(ApiClient);
expect(messageAPI).toHaveProperty('get');
expect(messageAPI).toHaveProperty('show');
expect(messageAPI).toHaveProperty('create');
expect(messageAPI).toHaveProperty('update');
expect(messageAPI).toHaveProperty('delete');
expect(messageAPI).toHaveProperty('getPreviousMessages');
});
describeWithAPIMock('API calls', context => {
it('#getPreviousMessages', () => {
messageAPI.getPreviousMessages({
conversationId: 12,
before: 4573,
});
expect(context.axiosMock.get).toHaveBeenCalledWith(
`/api/v1/conversations/12/messages`,
{
params: {
before: 4573,
},
}
);
});
});
});

View file

@ -1,13 +1,31 @@
import inboxes from '../inboxes'; import inboxesAPI from '../inboxes';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#InboxesAPI', () => { describe('#InboxesAPI', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(inboxes).toBeInstanceOf(ApiClient); expect(inboxesAPI).toBeInstanceOf(ApiClient);
expect(inboxes).toHaveProperty('get'); expect(inboxesAPI).toHaveProperty('get');
expect(inboxes).toHaveProperty('show'); expect(inboxesAPI).toHaveProperty('show');
expect(inboxes).toHaveProperty('create'); expect(inboxesAPI).toHaveProperty('create');
expect(inboxes).toHaveProperty('update'); expect(inboxesAPI).toHaveProperty('update');
expect(inboxes).toHaveProperty('delete'); expect(inboxesAPI).toHaveProperty('delete');
expect(inboxesAPI).toHaveProperty('getAssignableAgents');
expect(inboxesAPI).toHaveProperty('getCampaigns');
});
describeWithAPIMock('API calls', context => {
it('#getAssignableAgents', () => {
inboxesAPI.getAssignableAgents(1);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/inboxes/1/assignable_agents'
);
});
it('#getCampaigns', () => {
inboxesAPI.getCampaigns(2);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/inboxes/2/campaigns'
);
});
}); });
}); });

View file

@ -1,13 +1,54 @@
import notifications from '../notifications'; import notificationsAPI from '../notifications';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#NotificationAPI', () => { describe('#NotificationAPI', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(notifications).toBeInstanceOf(ApiClient); expect(notificationsAPI).toBeInstanceOf(ApiClient);
expect(notifications).toHaveProperty('get'); expect(notificationsAPI).toHaveProperty('get');
expect(notifications).toHaveProperty('getNotifications'); expect(notificationsAPI).toHaveProperty('getNotifications');
expect(notifications).toHaveProperty('getUnreadCount'); expect(notificationsAPI).toHaveProperty('getUnreadCount');
expect(notifications).toHaveProperty('read'); expect(notificationsAPI).toHaveProperty('read');
expect(notifications).toHaveProperty('readAll'); expect(notificationsAPI).toHaveProperty('readAll');
});
describeWithAPIMock('API calls', context => {
it('#get', () => {
notificationsAPI.get(1);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/notifications?page=1'
);
});
it('#getNotifications', () => {
notificationsAPI.getNotifications(1);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/notifications/1/notifications'
);
});
it('#getUnreadCount', () => {
notificationsAPI.getUnreadCount();
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/notifications/unread_count'
);
});
it('#read', () => {
notificationsAPI.read(48670, 'Conversation');
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/notifications/read_all',
{
primary_actor_id: 'Conversation',
primary_actor_type: 48670,
}
);
});
it('#readAll', () => {
notificationsAPI.readAll();
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/notifications/read_all'
);
});
}); });
}); });

View file

@ -1,17 +1,63 @@
import reports from '../reports'; import reportsAPI from '../reports';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#Reports API', () => { describe('#Reports API', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(reports).toBeInstanceOf(ApiClient); expect(reportsAPI).toBeInstanceOf(ApiClient);
expect(reports.apiVersion).toBe('/api/v2'); expect(reportsAPI.apiVersion).toBe('/api/v2');
expect(reports).toHaveProperty('get'); expect(reportsAPI).toHaveProperty('get');
expect(reports).toHaveProperty('show'); expect(reportsAPI).toHaveProperty('show');
expect(reports).toHaveProperty('create'); expect(reportsAPI).toHaveProperty('create');
expect(reports).toHaveProperty('update'); expect(reportsAPI).toHaveProperty('update');
expect(reports).toHaveProperty('delete'); expect(reportsAPI).toHaveProperty('delete');
expect(reports).toHaveProperty('getAccountReports'); expect(reportsAPI).toHaveProperty('getAccountReports');
expect(reports).toHaveProperty('getAccountSummary'); expect(reportsAPI).toHaveProperty('getAccountSummary');
expect(reports).toHaveProperty('getAgentReports'); expect(reportsAPI).toHaveProperty('getAgentReports');
});
describeWithAPIMock('API calls', context => {
it('#getAccountReports', () => {
reportsAPI.getAccountReports(
'conversations_count',
1621103400,
1621621800
);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v2/reports/account',
{
params: {
metric: 'conversations_count',
since: 1621103400,
until: 1621621800,
},
}
);
});
it('#getAccountSummary', () => {
reportsAPI.getAccountSummary(1621103400, 1621621800);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v2/reports/account_summary',
{
params: {
since: 1621103400,
until: 1621621800,
},
}
);
});
it('#getAgentReports', () => {
reportsAPI.getAgentReports(1621103400, 1621621800);
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v2/reports/agents',
{
params: {
since: 1621103400,
until: 1621621800,
},
}
);
});
}); });
}); });

View file

@ -1,16 +1,49 @@
import teams from '../teams'; import teamsAPI from '../teams';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
import describeWithAPIMock from './apiSpecHelper';
describe('#TeamsAPI', () => { describe('#TeamsAPI', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(teams).toBeInstanceOf(ApiClient); expect(teamsAPI).toBeInstanceOf(ApiClient);
expect(teams).toHaveProperty('get'); expect(teamsAPI).toHaveProperty('get');
expect(teams).toHaveProperty('show'); expect(teamsAPI).toHaveProperty('show');
expect(teams).toHaveProperty('create'); expect(teamsAPI).toHaveProperty('create');
expect(teams).toHaveProperty('update'); expect(teamsAPI).toHaveProperty('update');
expect(teams).toHaveProperty('delete'); expect(teamsAPI).toHaveProperty('delete');
expect(teams).toHaveProperty('getAgents'); expect(teamsAPI).toHaveProperty('getAgents');
expect(teams).toHaveProperty('addAgents'); expect(teamsAPI).toHaveProperty('addAgents');
expect(teams).toHaveProperty('updateAgents'); expect(teamsAPI).toHaveProperty('updateAgents');
});
describeWithAPIMock('API calls', context => {
it('#getAgents', () => {
teamsAPI.getAgents({ teamId: 1 });
expect(context.axiosMock.get).toHaveBeenCalledWith(
'/api/v1/teams/1/team_members'
);
});
it('#addAgents', () => {
teamsAPI.addAgents({ teamId: 1, agentsList: { user_ids: [1, 10, 21] } });
expect(context.axiosMock.post).toHaveBeenCalledWith(
'/api/v1/teams/1/team_members',
{
user_ids: { user_ids: [1, 10, 21] },
}
);
});
it('#updateAgents', () => {
const agentsList = { user_ids: [1, 10, 21] };
teamsAPI.updateAgents({
teamId: 1,
agentsList,
});
expect(context.axiosMock.patch).toHaveBeenCalledWith(
'/api/v1/teams/1/team_members',
{
user_ids: agentsList,
}
);
});
}); });
}); });

View file

@ -0,0 +1,13 @@
import webhooksAPI from '../webhooks';
import ApiClient from '../ApiClient';
describe('#webhooksAPI', () => {
it('creates correct instance', () => {
expect(webhooksAPI).toBeInstanceOf(ApiClient);
expect(webhooksAPI).toHaveProperty('get');
expect(webhooksAPI).toHaveProperty('show');
expect(webhooksAPI).toHaveProperty('create');
expect(webhooksAPI).toHaveProperty('update');
expect(webhooksAPI).toHaveProperty('delete');
});
});

View file

@ -0,0 +1,90 @@
import AccountSelector from '../AccountSelector';
import { createLocalVue, mount } from '@vue/test-utils';
import Vuex from 'vuex';
import VueI18n from 'vue-i18n';
import i18n from 'dashboard/i18n';
import WootModal from 'dashboard/components/Modal';
import WootModalHeader from 'dashboard/components/ModalHeader';
const localVue = createLocalVue();
localVue.component('woot-modal', WootModal);
localVue.component('woot-modal-header', WootModalHeader);
localVue.use(Vuex);
localVue.use(VueI18n);
const i18nConfig = new VueI18n({
locale: 'en',
messages: i18n,
});
describe('accountSelctor', () => {
let accountSelector = null;
const currentUser = {
accounts: [
{
id: 1,
name: 'Chatwoot',
role: 'administrator',
},
{
id: 2,
name: 'GitX',
role: 'agent',
},
],
};
const accountId = 1;
const globalConfig = { createNewAccountFromDashboard: false };
let store = null;
let actions = null;
let modules = null;
beforeEach(() => {
actions = {};
modules = {
auth: {
getters: {
getCurrentAccountId: () => accountId,
getCurrentUser: () => currentUser,
},
},
globalConfig: {
getters: {
'globalConfig/get': () => globalConfig,
},
},
};
store = new Vuex.Store({
actions,
modules,
});
accountSelector = mount(AccountSelector, {
store,
localVue,
i18n: i18nConfig,
propsData: {
showAccountModal: true,
},
});
});
it('title and sub title exist', () => {
const headerComponent = accountSelector.findComponent(WootModalHeader);
const topBar = headerComponent.find('.page-top-bar');
const titleComponent = topBar.find('.page-sub-title');
expect(titleComponent.text()).toBe('Switch Account');
const subTitleComponent = topBar.find('p');
expect(subTitleComponent.text()).toBe(
'Select an account from the following list'
);
});
it('first account item is checked', () => {
const accountFirstItem = accountSelector.find('.account-selector .ion');
expect(accountFirstItem.exists()).toBe(true);
});
});

View file

@ -0,0 +1,64 @@
import AgentDetails from '../AgentDetails';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import VueI18n from 'vue-i18n';
import i18n from 'dashboard/i18n';
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
const localVue = createLocalVue();
localVue.use(Vuex);
localVue.use(VueI18n);
localVue.component('thumbnail', Thumbnail);
const i18nConfig = new VueI18n({
locale: 'en',
messages: i18n,
});
describe('agentDetails', () => {
const currentUser = { name: 'Neymar Junior', avatar_url: '' };
const currentRole = 'agent';
let store = null;
let actions = null;
let modules = null;
let agentDetails = null;
beforeEach(() => {
actions = {};
modules = {
auth: {
getters: {
getCurrentUser: () => currentUser,
getCurrentRole: () => currentRole,
},
},
};
store = new Vuex.Store({
actions,
modules,
});
agentDetails = shallowMount(AgentDetails, {
store,
localVue,
i18n: i18nConfig,
});
});
it('shows the agent name', () => {
const agentTitle = agentDetails.find('.current-user--name');
expect(agentTitle.text()).toBe('Neymar Junior');
});
it('shows the agent role', () => {
const agentTitle = agentDetails.find('.current-user--role');
expect(agentTitle.text()).toBe('Agent');
});
it('agent thumbnail exists', () => {
const thumbnailComponent = agentDetails.findComponent(Thumbnail);
expect(thumbnailComponent.exists()).toBe(true);
});
});

View file

@ -0,0 +1,67 @@
import NotificationBell from '../NotificationBell';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import VueI18n from 'vue-i18n';
import i18n from 'dashboard/i18n';
const localVue = createLocalVue();
localVue.use(Vuex);
localVue.use(VueI18n);
const i18nConfig = new VueI18n({
locale: 'en',
messages: i18n,
});
describe('notificationBell', () => {
const accountId = 1;
const notificationMetadata = { unreadCount: 19 };
let store = null;
let actions = null;
let modules = null;
beforeEach(() => {
actions = {
showNotification: jest.fn(),
};
modules = {
auth: {
getters: {
getCurrentAccountId: () => accountId,
},
},
notifications: {
getters: {
'notifications/getMeta': () => notificationMetadata,
},
},
};
store = new Vuex.Store({
actions,
modules,
});
});
it('it should return unread count 19 ', () => {
const notificationBell = shallowMount(NotificationBell, {
store,
localVue,
i18n: i18nConfig,
});
const statusViewTitle = notificationBell.find('.unread-badge');
expect(statusViewTitle.text()).toBe('19');
});
it('it should return unread count 99+ ', async () => {
notificationMetadata.unreadCount = 101;
const notificationBell = shallowMount(NotificationBell, {
store,
localVue,
i18n: i18nConfig,
});
const statusViewTitle = notificationBell.find('.unread-badge');
expect(statusViewTitle.text()).toBe('99+');
});
});

View file

@ -15,7 +15,8 @@ describe(`when there are NO errors loading the thumbnail`, () => {
}, },
}); });
expect(wrapper.find('#image').exists()).toBe(true); expect(wrapper.find('#image').exists()).toBe(true);
expect(wrapper.contains(Avatar)).toBe(false); const avatarComponent = wrapper.findComponent(Avatar);
expect(avatarComponent.exists()).toBe(false);
}); });
}); });
@ -31,8 +32,9 @@ describe(`when there ARE errors loading the thumbnail`, () => {
}; };
}, },
}); });
expect(wrapper.contains('#image')).toBe(false); expect(wrapper.find('#image').exists()).toBe(false);
expect(wrapper.contains(Avatar)).toBe(true); const avatarComponent = wrapper.findComponent(Avatar);
expect(avatarComponent.exists()).toBe(true);
}); });
}); });

View file

@ -0,0 +1,185 @@
export default {
conversation: {
meta: {
sender: {
additional_attributes: {
created_at_ip: '127.0.0.1',
},
availability_status: 'offline',
email: null,
id: 5017687,
name: 'long-flower-143',
phone_number: null,
thumbnail: '',
custom_attributes: {},
},
channel: 'Channel::WebWidget',
assignee: {
account_id: 1,
availability_status: 'offline',
confirmed: true,
email: 'muhsin@chatwoot.com',
available_name: 'Muhsin Keloth',
id: 21,
name: 'Muhsin Keloth',
role: 'administrator',
thumbnail:
'http://0.0.0.0:3000/rails/active_storage/representations/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7b95641540fadebc733ec9b42117d00bc09600be/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCam9MY21WemFYcGxTU0lNTWpVd2VESTFNQVk2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoidmFyaWF0aW9uIn19--c13bd5229b2a2a692444606e22f76ad61c634661/me.jpg',
},
},
id: 5815,
messages: [
{
id: 438072,
content: 'Campaign after 5 seconds',
account_id: 1,
inbox_id: 37,
conversation_id: 5811,
message_type: 1,
created_at: 1620980262,
updated_at: '2021-05-14T08:17:42.041Z',
private: false,
status: 'sent',
source_id: null,
content_type: null,
content_attributes: {},
sender_type: 'User',
sender_id: 1,
external_source_ids: {},
},
{
id: 4382131101,
content: 'Hello',
account_id: 1,
inbox_id: 37,
conversation_id: 5815,
message_type: 0,
created_at: 1621145476,
updated_at: '2021-05-16T05:48:43.910Z',
private: false,
status: 'sent',
source_id: null,
content_type: 'text',
content_attributes: {},
sender_type: null,
sender_id: null,
external_source_ids: {},
},
{
id: 438100,
content: 'Hey',
account_id: 1,
inbox_id: 37,
conversation_id: 5815,
message_type: 0,
created_at: 1621145476,
updated_at: '2021-05-16T05:48:43.910Z',
private: false,
status: 'sent',
source_id: null,
content_type: 'text',
content_attributes: {},
sender_type: null,
sender_id: null,
external_source_ids: {},
},
],
inbox_id: 37,
status: 'open',
muted: false,
can_reply: true,
timestamp: 1621144123,
contact_last_seen_at: 0,
agent_last_seen_at: 1621144123,
unread_count: 0,
additional_attributes: {
browser: {
device_name: 'Unknown',
browser_name: 'Chrome',
platform_name: 'macOS',
browser_version: '90.0.4430.212',
platform_version: '10.15.7',
},
widget_language: null,
browser_language: 'en',
},
account_id: 1,
labels: [],
},
lastMessage: {
id: 438100,
content: 'Hey',
account_id: 1,
inbox_id: 37,
conversation_id: 5815,
message_type: 0,
created_at: 1621145476,
updated_at: '2021-05-16T05:48:43.910Z',
private: false,
status: 'sent',
source_id: null,
content_type: 'text',
content_attributes: {},
sender_type: null,
sender_id: null,
external_source_ids: {},
},
readMessages: [
{
id: 438072,
content: 'Campaign after 5 seconds',
account_id: 1,
inbox_id: 37,
conversation_id: 5811,
message_type: 1,
created_at: 1620980262,
updated_at: '2021-05-14T08:17:42.041Z',
private: false,
status: 'sent',
source_id: null,
content_type: null,
content_attributes: {},
sender_type: 'User',
sender_id: 1,
external_source_ids: {},
},
],
unReadMessages: [
{
id: 4382131101,
content: 'Hello',
account_id: 1,
inbox_id: 37,
conversation_id: 5815,
message_type: 0,
created_at: 1621145476,
updated_at: '2021-05-16T05:48:43.910Z',
private: false,
status: 'sent',
source_id: null,
content_type: 'text',
content_attributes: {},
sender_type: null,
sender_id: null,
external_source_ids: {},
},
{
id: 438100,
content: 'Hey',
account_id: 1,
inbox_id: 37,
conversation_id: 5815,
message_type: 0,
created_at: 1621145476,
updated_at: '2021-05-16T05:48:43.910Z',
private: false,
status: 'sent',
source_id: null,
content_type: 'text',
content_attributes: {},
sender_type: null,
sender_id: null,
external_source_ids: {},
},
],
};

View file

@ -0,0 +1,29 @@
import conversationMixin from '../conversations';
import conversationFixture from './conversationFixtures';
import commonHelpers from '../../helper/commons';
commonHelpers();
describe('#conversationMixin', () => {
it('should return unread message count 2 if conversation is passed', () => {
expect(
conversationMixin.methods.unreadMessagesCount(
conversationFixture.conversation
)
).toEqual(2);
});
it('should return last message if conversation is passed', () => {
expect(
conversationMixin.methods.lastMessage(conversationFixture.conversation)
).toEqual(conversationFixture.lastMessage);
});
it('should return read messages if conversation is passed', () => {
expect(
conversationMixin.methods.readMessages(conversationFixture.conversation)
).toEqual(conversationFixture.readMessages);
});
it('should return read messages if conversation is passed', () => {
expect(
conversationMixin.methods.unReadMessages(conversationFixture.conversation)
).toEqual(conversationFixture.unReadMessages);
});
});

View file

@ -0,0 +1,28 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import isAdminMixin from '../isAdmin';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('isAdminMixin', () => {
let getters;
let store;
beforeEach(() => {
getters = {
getCurrentRole: () => 'administrator',
};
store = new Vuex.Store({ getters });
});
it('set accountId properly', () => {
const Component = {
render() {},
title: 'TestComponent',
mixins: [isAdminMixin],
};
const wrapper = shallowMount(Component, { store, localVue });
expect(wrapper.vm.isAdmin).toBe(true);
});
});