mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-31 19:17:48 +00:00
chore: Update specs and warnings in console (#7467)
This commit is contained in:
@@ -73,7 +73,7 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: yarn
|
name: yarn
|
||||||
command: yarn install --cache-folder ~/.cache/yarn
|
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
|
||||||
|
|
||||||
# Store yarn / webpacker cache
|
# Store yarn / webpacker cache
|
||||||
- save_cache:
|
- save_cache:
|
||||||
@@ -106,7 +106,6 @@ jobs:
|
|||||||
java -jar ~/tmp/openapi-generator-cli-6.3.0.jar validate -i swagger/swagger.json
|
java -jar ~/tmp/openapi-generator-cli-6.3.0.jar validate -i swagger/swagger.json
|
||||||
|
|
||||||
# Database setup
|
# Database setup
|
||||||
- run: yarn install --check-files
|
|
||||||
- run: bundle exec rake db:create
|
- run: bundle exec rake db:create
|
||||||
- run: bundle exec rake db:schema:load
|
- run: bundle exec rake db:schema:load
|
||||||
|
|
||||||
@@ -126,6 +125,21 @@ jobs:
|
|||||||
name: eslint
|
name: eslint
|
||||||
command: yarn run eslint
|
command: yarn run eslint
|
||||||
|
|
||||||
|
# Run frontend tests
|
||||||
|
- run:
|
||||||
|
name: Run frontend tests
|
||||||
|
command: |
|
||||||
|
mkdir -p ~/tmp/test-results/frontend_specs
|
||||||
|
~/tmp/cc-test-reporter before-build
|
||||||
|
TESTFILES=$(circleci tests glob **/specs/*.spec.js | circleci tests split --split-by=timings)
|
||||||
|
yarn test:coverage --profile 10 \
|
||||||
|
--out ~/tmp/test-results/yarn.xml \
|
||||||
|
-- ${TESTFILES}
|
||||||
|
- run:
|
||||||
|
name: Code Climate Test Coverage
|
||||||
|
command: |
|
||||||
|
~/tmp/cc-test-reporter format-coverage -t lcov -o "coverage/codeclimate.frontend_$CIRCLE_NODE_INDEX.json"
|
||||||
|
|
||||||
# Run rails tests
|
# Run rails tests
|
||||||
- run:
|
- run:
|
||||||
name: Run backend tests
|
name: Run backend tests
|
||||||
@@ -145,20 +159,6 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
~/tmp/cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.$CIRCLE_NODE_INDEX.json"
|
~/tmp/cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.$CIRCLE_NODE_INDEX.json"
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Run frontend tests
|
|
||||||
command: |
|
|
||||||
mkdir -p ~/tmp/test-results/frontend_specs
|
|
||||||
~/tmp/cc-test-reporter before-build
|
|
||||||
TESTFILES=$(circleci tests glob **/specs/*.spec.js | circleci tests split --split-by=timings)
|
|
||||||
yarn test:coverage --profile 10 \
|
|
||||||
--out ~/tmp/test-results/yarn.xml \
|
|
||||||
-- ${TESTFILES}
|
|
||||||
- run:
|
|
||||||
name: Code Climate Test Coverage
|
|
||||||
command: |
|
|
||||||
~/tmp/cc-test-reporter format-coverage -t lcov -o "coverage/codeclimate.frontend_$CIRCLE_NODE_INDEX.json"
|
|
||||||
|
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: coverage
|
root: coverage
|
||||||
paths:
|
paths:
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="column page-top-bar">
|
<div class="column page-top-bar">
|
||||||
<img v-if="headerImage" :src="headerImage" alt="No image" />
|
<img v-if="headerImage" :src="headerImage" alt="No image" />
|
||||||
<h2 class="text-slate-800 text-lg dark:text-slate-100">
|
<h2
|
||||||
|
ref="modalHeaderTitle"
|
||||||
|
class="text-slate-800 text-lg dark:text-slate-100"
|
||||||
|
>
|
||||||
{{ headerTitle }}
|
{{ headerTitle }}
|
||||||
</h2>
|
</h2>
|
||||||
<p v-if="headerContent" class="small-12 column wrap-content">
|
<p
|
||||||
|
v-if="headerContent"
|
||||||
|
ref="modalHeaderContent"
|
||||||
|
class="small-12 column wrap-content"
|
||||||
|
>
|
||||||
{{ headerContent }}
|
{{ headerContent }}
|
||||||
<span v-if="headerContentValue" class="content-value">
|
<span v-if="headerContentValue" class="content-value">
|
||||||
{{ headerContentValue }}
|
{{ headerContentValue }}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<div class="px-8 pt-4 pb-8">
|
<div class="px-8 pt-4 pb-8">
|
||||||
<div
|
<div
|
||||||
v-for="account in currentUser.accounts"
|
v-for="account in currentUser.accounts"
|
||||||
|
:id="`account-${account.id}`"
|
||||||
:key="account.id"
|
:key="account.id"
|
||||||
class="pt-0 pb-0"
|
class="pt-0 pb-0"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import Vuex from 'vuex';
|
|||||||
import VueI18n from 'vue-i18n';
|
import VueI18n from 'vue-i18n';
|
||||||
|
|
||||||
import i18n from 'dashboard/i18n';
|
import i18n from 'dashboard/i18n';
|
||||||
|
|
||||||
import WootModal from 'dashboard/components/Modal';
|
import WootModal from 'dashboard/components/Modal';
|
||||||
import WootModalHeader from 'dashboard/components/ModalHeader';
|
import WootModalHeader from 'dashboard/components/ModalHeader';
|
||||||
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon';
|
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon';
|
||||||
@@ -38,9 +37,7 @@ describe('accountSelctor', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const accountId = 1;
|
|
||||||
const globalConfig = { createNewAccountFromDashboard: false };
|
|
||||||
let store = null;
|
|
||||||
let actions = null;
|
let actions = null;
|
||||||
let modules = null;
|
let modules = null;
|
||||||
|
|
||||||
@@ -49,44 +46,46 @@ describe('accountSelctor', () => {
|
|||||||
modules = {
|
modules = {
|
||||||
auth: {
|
auth: {
|
||||||
getters: {
|
getters: {
|
||||||
getCurrentAccountId: () => accountId,
|
getCurrentAccountId: () => 1,
|
||||||
getCurrentUser: () => currentUser,
|
getCurrentUser: () => currentUser,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
globalConfig: {
|
globalConfig: {
|
||||||
getters: {
|
getters: {
|
||||||
'globalConfig/get': () => globalConfig,
|
'globalConfig/get': () => ({ createNewAccountFromDashboard: false }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
store = new Vuex.Store({
|
let store = new Vuex.Store({ actions, modules });
|
||||||
actions,
|
|
||||||
modules,
|
|
||||||
});
|
|
||||||
accountSelector = mount(AccountSelector, {
|
accountSelector = mount(AccountSelector, {
|
||||||
store,
|
store,
|
||||||
localVue,
|
localVue,
|
||||||
i18n: i18nConfig,
|
i18n: i18nConfig,
|
||||||
propsData: {
|
propsData: { showAccountModal: true },
|
||||||
showAccountModal: true,
|
stubs: { WootButton: { template: '<button />' } },
|
||||||
},
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('title and sub title exist', () => {
|
it('title and sub title exist', () => {
|
||||||
const headerComponent = accountSelector.findComponent(WootModalHeader);
|
const headerComponent = accountSelector.findComponent(WootModalHeader);
|
||||||
const topBar = headerComponent.find('.page-top-bar');
|
const title = headerComponent.findComponent({ ref: 'modalHeaderTitle' });
|
||||||
const titleComponent = topBar.find('.page-sub-title');
|
expect(title.text()).toBe('Switch Account');
|
||||||
expect(titleComponent.text()).toBe('Switch Account');
|
const content = headerComponent.findComponent({
|
||||||
const subTitleComponent = topBar.find('p');
|
ref: 'modalHeaderContent',
|
||||||
expect(subTitleComponent.text()).toBe(
|
});
|
||||||
'Select an account from the following list'
|
expect(content.text()).toBe('Select an account from the following list');
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('first account item is checked', () => {
|
it('first account item is checked', () => {
|
||||||
const accountFirstItem = accountSelector.find('.account-selector svg');
|
const selectedAccountCheckmark = accountSelector.find(
|
||||||
expect(accountFirstItem.exists()).toBe(true);
|
'#account-1 > button > svg'
|
||||||
|
);
|
||||||
|
expect(selectedAccountCheckmark.exists()).toBe(true);
|
||||||
|
|
||||||
|
const otherAccountCheckmark = accountSelector.find(
|
||||||
|
'#account-2 > button > svg'
|
||||||
|
);
|
||||||
|
expect(otherAccountCheckmark.exists()).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ localVue.component('woot-dropdown-menu', WootDropdownMenu);
|
|||||||
localVue.component('woot-dropdown-divider', WootDropdownDivider);
|
localVue.component('woot-dropdown-divider', WootDropdownDivider);
|
||||||
localVue.component('woot-dropdown-item', WootDropdownItem);
|
localVue.component('woot-dropdown-item', WootDropdownItem);
|
||||||
|
|
||||||
const i18nConfig = new VueI18n({
|
const i18nConfig = new VueI18n({ locale: 'en', messages: i18n });
|
||||||
locale: 'en',
|
|
||||||
messages: i18n,
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('AvailabilityStatus', () => {
|
describe('AvailabilityStatus', () => {
|
||||||
const currentAvailability = 'online';
|
const currentAvailability = 'online';
|
||||||
@@ -48,15 +45,13 @@ describe('AvailabilityStatus', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
store = new Vuex.Store({
|
store = new Vuex.Store({ actions, modules });
|
||||||
actions,
|
|
||||||
modules,
|
|
||||||
});
|
|
||||||
|
|
||||||
availabilityStatus = mount(AvailabilityStatus, {
|
availabilityStatus = mount(AvailabilityStatus, {
|
||||||
store,
|
store,
|
||||||
localVue,
|
localVue,
|
||||||
i18n: i18nConfig,
|
i18n: i18nConfig,
|
||||||
|
stubs: { WootSwitch: { template: '<button />' } },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ import SidemenuIcon from '../SidemenuIcon';
|
|||||||
|
|
||||||
describe('SidemenuIcon', () => {
|
describe('SidemenuIcon', () => {
|
||||||
test('matches snapshot', () => {
|
test('matches snapshot', () => {
|
||||||
const wrapper = shallowMount(SidemenuIcon);
|
const wrapper = shallowMount(SidemenuIcon, {
|
||||||
|
stubs: { WootButton: { template: '<button><slot /></button>' } },
|
||||||
|
});
|
||||||
expect(wrapper.vm).toBeTruthy();
|
expect(wrapper.vm).toBeTruthy();
|
||||||
expect(wrapper.element).toMatchSnapshot();
|
expect(wrapper.element).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`SidemenuIcon matches snapshot 1`] = `
|
exports[`SidemenuIcon matches snapshot 1`] = `
|
||||||
<woot-button
|
<button
|
||||||
class="toggle-sidebar"
|
class="-ml-3 text-black-900 dark:text-slate-300"
|
||||||
color-scheme="secondary"
|
color-scheme="secondary"
|
||||||
icon="list"
|
icon="list"
|
||||||
size="small"
|
size="small"
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ localVue.use(VTooltip);
|
|||||||
localVue.component('fluent-icon', FluentIcon);
|
localVue.component('fluent-icon', FluentIcon);
|
||||||
localVue.component('woot-button', Button);
|
localVue.component('woot-button', Button);
|
||||||
|
|
||||||
const i18nConfig = new VueI18n({
|
const i18nConfig = new VueI18n({ locale: 'en', messages: i18n });
|
||||||
locale: 'en',
|
|
||||||
messages: i18n,
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('MoveActions', () => {
|
describe('MoveActions', () => {
|
||||||
let currentChat = { id: 8, muted: false };
|
let currentChat = { id: 8, muted: false };
|
||||||
@@ -47,25 +44,22 @@ describe('MoveActions', () => {
|
|||||||
unmuteConversation = jest.fn(() => Promise.resolve());
|
unmuteConversation = jest.fn(() => Promise.resolve());
|
||||||
|
|
||||||
modules = {
|
modules = {
|
||||||
conversations: {
|
conversations: { actions: { muteConversation, unmuteConversation } },
|
||||||
actions: {
|
|
||||||
muteConversation,
|
|
||||||
unmuteConversation,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getters = {
|
getters = { getSelectedChat: () => currentChat };
|
||||||
getSelectedChat: () => currentChat,
|
|
||||||
};
|
|
||||||
|
|
||||||
store = new Vuex.Store({
|
store = new Vuex.Store({ state, modules, getters });
|
||||||
state,
|
|
||||||
modules,
|
moreActions = mount(MoreActions, {
|
||||||
getters,
|
store,
|
||||||
|
localVue,
|
||||||
|
i18n: i18nConfig,
|
||||||
|
stubs: {
|
||||||
|
WootModal: { template: '<div><slot/> </div>' },
|
||||||
|
WootModalHeader: { template: '<div><slot/> </div>' },
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
moreActions = mount(MoreActions, { store, localVue, i18n: i18nConfig });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('muting discussion', () => {
|
describe('muting discussion', () => {
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ describe('AddReminder', () => {
|
|||||||
wrapper = shallowMount(AddReminder, {
|
wrapper = shallowMount(AddReminder, {
|
||||||
mocks: {
|
mocks: {
|
||||||
$t: x => x,
|
$t: x => x,
|
||||||
$store: {
|
$store: { getters: {}, state: {} },
|
||||||
getters: {},
|
|
||||||
state: {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
stubs: { WootButton: { template: '<button />' } },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,8 @@ describe('dateSeparator', () => {
|
|||||||
dateSeparator = shallowMount(DateSeparator, {
|
dateSeparator = shallowMount(DateSeparator, {
|
||||||
store,
|
store,
|
||||||
localVue,
|
localVue,
|
||||||
propsData: {
|
propsData: { date: 'Nov 18, 2019' },
|
||||||
date: 'Nov 18, 2019',
|
mocks: { $t: msg => msg },
|
||||||
},
|
|
||||||
i18n: i18nConfig,
|
i18n: i18nConfig,
|
||||||
mixins: [darkModeMixin],
|
mixins: [darkModeMixin],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,52 +1,45 @@
|
|||||||
import TemplateParser from '../../../../dashboard/components/widgets/conversation/WhatsappTemplates/TemplateParser.vue';
|
import TemplateParser from '../../../../dashboard/components/widgets/conversation/WhatsappTemplates/TemplateParser.vue';
|
||||||
import { mount, createLocalVue } from '@vue/test-utils';
|
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||||
import { templates } from './fixtures';
|
import { templates } from './fixtures';
|
||||||
const localVue = createLocalVue();
|
const localVue = createLocalVue();
|
||||||
import VueI18n from 'vue-i18n';
|
import VueI18n from 'vue-i18n';
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
import Vuelidate from 'vuelidate';
|
import Vuelidate from 'vuelidate';
|
||||||
Vue.use(Vuelidate);
|
|
||||||
|
|
||||||
import i18n from 'dashboard/i18n';
|
import i18n from 'dashboard/i18n';
|
||||||
|
|
||||||
localVue.use(VueI18n);
|
localVue.use(VueI18n);
|
||||||
|
localVue.use(Vuelidate);
|
||||||
|
|
||||||
const i18nConfig = new VueI18n({
|
const i18nConfig = new VueI18n({ locale: 'en', messages: i18n });
|
||||||
locale: 'en',
|
const config = {
|
||||||
messages: i18n,
|
localVue,
|
||||||
});
|
i18n: i18nConfig,
|
||||||
|
stubs: {
|
||||||
|
WootButton: { template: '<button />' },
|
||||||
|
WootInput: { template: '<input />' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
describe('#WhatsAppTemplates', () => {
|
describe('#WhatsAppTemplates', () => {
|
||||||
it('returns all variables from a template string', () => {
|
it('returns all variables from a template string', () => {
|
||||||
const wrapper = mount(TemplateParser, {
|
const wrapper = shallowMount(TemplateParser, {
|
||||||
localVue,
|
...config,
|
||||||
propsData: {
|
propsData: { template: templates[0] },
|
||||||
template: templates[0],
|
|
||||||
},
|
|
||||||
i18n: i18nConfig,
|
|
||||||
});
|
});
|
||||||
expect(wrapper.vm.variables).toEqual(['{{1}}', '{{2}}', '{{3}}']);
|
expect(wrapper.vm.variables).toEqual(['{{1}}', '{{2}}', '{{3}}']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns no variables from a template string if it does not contain variables', () => {
|
it('returns no variables from a template string if it does not contain variables', () => {
|
||||||
const wrapper = mount(TemplateParser, {
|
const wrapper = shallowMount(TemplateParser, {
|
||||||
localVue,
|
...config,
|
||||||
propsData: {
|
propsData: { template: templates[12] },
|
||||||
template: templates[12],
|
|
||||||
},
|
|
||||||
i18n: i18nConfig,
|
|
||||||
});
|
});
|
||||||
expect(wrapper.vm.variables).toBeNull();
|
expect(wrapper.vm.variables).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the body of a template', () => {
|
it('returns the body of a template', () => {
|
||||||
const wrapper = mount(TemplateParser, {
|
const wrapper = shallowMount(TemplateParser, {
|
||||||
localVue,
|
...config,
|
||||||
propsData: {
|
propsData: { template: templates[1] },
|
||||||
template: templates[1],
|
|
||||||
},
|
|
||||||
i18n: i18nConfig,
|
|
||||||
});
|
});
|
||||||
const expectedOutput = templates[1].components.find(i => i.type === 'BODY')
|
const expectedOutput = templates[1].components.find(i => i.type === 'BODY')
|
||||||
.text;
|
.text;
|
||||||
@@ -54,17 +47,12 @@ describe('#WhatsAppTemplates', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('generates the templates from variable input', async () => {
|
it('generates the templates from variable input', async () => {
|
||||||
const wrapper = mount(TemplateParser, {
|
const wrapper = shallowMount(TemplateParser, {
|
||||||
localVue,
|
...config,
|
||||||
propsData: {
|
propsData: { template: templates[0] },
|
||||||
template: templates[0],
|
|
||||||
},
|
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return { processedParams: {} };
|
||||||
processedParams: {},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
i18n: i18nConfig,
|
|
||||||
});
|
});
|
||||||
await wrapper.setData({
|
await wrapper.setData({
|
||||||
processedParams: { '1': 'abc', '2': 'xyz', '3': 'qwerty' },
|
processedParams: { '1': 'abc', '2': 'xyz', '3': 'qwerty' },
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import GoogleOAuthButton from './Button.vue';
|
|||||||
function getWrapper(showSeparator) {
|
function getWrapper(showSeparator) {
|
||||||
return shallowMount(GoogleOAuthButton, {
|
return shallowMount(GoogleOAuthButton, {
|
||||||
propsData: { showSeparator: showSeparator },
|
propsData: { showSeparator: showSeparator },
|
||||||
methods: {
|
mocks: { $t: text => text },
|
||||||
$t(text) {
|
|
||||||
return text;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user