389 lines
11 KiB
JavaScript
389 lines
11 KiB
JavaScript
import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest';
|
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
|
import Leftmenu from 'components/LeftMenu.vue';
|
|
import * as vueRouter from 'vue-router';
|
|
import { useNavigationStore } from 'src/stores/useNavigationStore';
|
|
|
|
let vm;
|
|
let navigation;
|
|
|
|
vi.mock('src/router/modules', () => ({
|
|
default: [
|
|
{
|
|
path: '/customer',
|
|
name: 'Customer',
|
|
meta: {
|
|
title: 'customers',
|
|
icon: 'vn:client',
|
|
},
|
|
menus: {
|
|
main: ['CustomerList', 'CustomerCreate'],
|
|
card: ['CustomerBasicData'],
|
|
},
|
|
children: [
|
|
{
|
|
path: '',
|
|
name: 'CustomerMain',
|
|
meta: {
|
|
menu: 'Customer',
|
|
menuChildren: [
|
|
{
|
|
name: 'CustomerCreditContracts',
|
|
title: 'creditContracts',
|
|
icon: 'vn:solunion',
|
|
},
|
|
],
|
|
},
|
|
children: [
|
|
{
|
|
path: 'list',
|
|
name: 'CustomerList',
|
|
meta: {
|
|
title: 'list',
|
|
icon: 'view_list',
|
|
menuChildren: [
|
|
{
|
|
name: 'CustomerCreditContracts',
|
|
title: 'creditContracts',
|
|
icon: 'vn:solunion',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
path: 'create',
|
|
name: 'CustomerCreate',
|
|
meta: {
|
|
title: 'createCustomer',
|
|
icon: 'vn:addperson',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}));
|
|
vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
|
|
matched: [
|
|
{
|
|
path: '/',
|
|
redirect: {
|
|
name: 'Dashboard',
|
|
},
|
|
name: 'Main',
|
|
meta: {},
|
|
props: {
|
|
default: false,
|
|
},
|
|
children: [
|
|
{
|
|
path: '/dashboard',
|
|
name: 'Dashboard',
|
|
meta: {
|
|
title: 'dashboard',
|
|
icon: 'dashboard',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
path: '/customer',
|
|
redirect: {
|
|
name: 'CustomerMain',
|
|
},
|
|
name: 'Customer',
|
|
meta: {
|
|
title: 'customers',
|
|
icon: 'vn:client',
|
|
moduleName: 'Customer',
|
|
keyBinding: 'c',
|
|
menu: 'customer',
|
|
},
|
|
},
|
|
],
|
|
query: {},
|
|
params: {},
|
|
meta: { moduleName: 'mockName' },
|
|
path: 'mockName/1',
|
|
name: 'Customer',
|
|
});
|
|
function mount(source = 'main') {
|
|
vi.spyOn(axios, 'get').mockResolvedValue({
|
|
data: [],
|
|
});
|
|
const wrapper = createWrapper(Leftmenu, {
|
|
propsData: {
|
|
source,
|
|
},
|
|
});
|
|
|
|
navigation = useNavigationStore();
|
|
navigation.fetchPinned = vi.fn().mockReturnValue(Promise.resolve(true));
|
|
navigation.getModules = vi.fn().mockReturnValue({
|
|
value: [
|
|
{
|
|
name: 'customer',
|
|
title: 'customer.pageTitles.customers',
|
|
icon: 'vn:customer',
|
|
module: 'customer',
|
|
},
|
|
],
|
|
});
|
|
return wrapper;
|
|
}
|
|
|
|
describe('getRoutes', () => {
|
|
afterEach(() => vi.clearAllMocks());
|
|
const getRoutes = vi.fn().mockImplementation((props, getMethodA, getMethodB) => {
|
|
const handleRoutes = {
|
|
methodA: getMethodA,
|
|
methodB: getMethodB,
|
|
};
|
|
try {
|
|
handleRoutes[props.source]();
|
|
} catch (error) {
|
|
throw Error('Method not defined');
|
|
}
|
|
});
|
|
|
|
const getMethodA = vi.fn();
|
|
const getMethodB = vi.fn();
|
|
const fn = (props) => getRoutes(props, getMethodA, getMethodB);
|
|
|
|
it('should call getMethodB when source is card', () => {
|
|
let props = { source: 'methodB' };
|
|
fn(props);
|
|
|
|
expect(getMethodB).toHaveBeenCalled();
|
|
expect(getMethodA).not.toHaveBeenCalled();
|
|
});
|
|
it('should call getMethodA when source is main', () => {
|
|
let props = { source: 'methodA' };
|
|
fn(props);
|
|
|
|
expect(getMethodA).toHaveBeenCalled();
|
|
expect(getMethodB).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call getMethodA when source is not exists or undefined', () => {
|
|
let props = { source: 'methodC' };
|
|
expect(() => fn(props)).toThrowError('Method not defined');
|
|
|
|
expect(getMethodA).not.toHaveBeenCalled();
|
|
expect(getMethodB).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('Leftmenu as card', () => {
|
|
beforeAll(() => {
|
|
vm = mount('card').vm;
|
|
});
|
|
|
|
it('should get routes for card source', async () => {
|
|
vm.getRoutes();
|
|
});
|
|
});
|
|
describe('Leftmenu as main', () => {
|
|
beforeEach(() => {
|
|
vm = mount().vm;
|
|
});
|
|
|
|
it('should initialize with default props', () => {
|
|
expect(vm.source).toBe('main');
|
|
});
|
|
|
|
it('should filter items based on search input', async () => {
|
|
vm.search = 'cust';
|
|
await vm.$nextTick();
|
|
expect(vm.filteredItems[0].name).toEqual('customer');
|
|
expect(vm.filteredItems[0].module).toEqual('customer');
|
|
});
|
|
it('should filter items based on search input', async () => {
|
|
vm.search = 'Rou';
|
|
await vm.$nextTick();
|
|
expect(vm.filteredItems).toEqual([]);
|
|
});
|
|
|
|
it('should return pinned items', () => {
|
|
vm.items = [
|
|
{ name: 'Item 1', isPinned: false },
|
|
{ name: 'Item 2', isPinned: true },
|
|
];
|
|
expect(vm.pinnedModules).toEqual(
|
|
new Map([['Item 2', { name: 'Item 2', isPinned: true }]]),
|
|
);
|
|
});
|
|
|
|
it('should find matches in routes', () => {
|
|
const search = 'child1';
|
|
const item = {
|
|
children: [
|
|
{ name: 'child1', children: [] },
|
|
{ name: 'child2', children: [] },
|
|
],
|
|
};
|
|
const matches = vm.findMatches(search, item);
|
|
expect(matches).toEqual([{ name: 'child1', children: [] }]);
|
|
});
|
|
it('should not proceed if event is already prevented', async () => {
|
|
const item = { module: 'testModule', isPinned: false };
|
|
const event = {
|
|
preventDefault: vi.fn(),
|
|
stopPropagation: vi.fn(),
|
|
defaultPrevented: true,
|
|
};
|
|
|
|
await vm.togglePinned(item, event);
|
|
|
|
expect(event.preventDefault).not.toHaveBeenCalled();
|
|
expect(event.stopPropagation).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call quasar.notify with success message', async () => {
|
|
const item = { module: 'testModule', isPinned: false };
|
|
const event = {
|
|
preventDefault: vi.fn(),
|
|
stopPropagation: vi.fn(),
|
|
defaultPrevented: false,
|
|
};
|
|
const response = { data: { id: 1 } };
|
|
|
|
vi.spyOn(axios, 'post').mockResolvedValue(response);
|
|
vi.spyOn(vm.quasar, 'notify');
|
|
|
|
await vm.togglePinned(item, event);
|
|
|
|
expect(vm.quasar.notify).toHaveBeenCalledWith({
|
|
message: 'Data saved',
|
|
type: 'positive',
|
|
});
|
|
});
|
|
|
|
it('should handle a single matched route with a menu', () => {
|
|
const route = {
|
|
matched: [{ meta: { menu: 'customer' } }],
|
|
};
|
|
|
|
const result = vm.betaGetRoutes();
|
|
|
|
expect(result.meta.menu).toEqual(route.matched[0].meta.menu);
|
|
});
|
|
it('should get routes for main source', () => {
|
|
vm.props.source = 'main';
|
|
vm.getRoutes();
|
|
expect(navigation.getModules).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should find direct child matches', () => {
|
|
const search = 'child1';
|
|
const item = {
|
|
children: [{ name: 'child1' }, { name: 'child2' }],
|
|
};
|
|
const result = vm.findMatches(search, item);
|
|
expect(result).toEqual([{ name: 'child1' }]);
|
|
});
|
|
|
|
it('should find nested child matches', () => {
|
|
const search = 'child3';
|
|
const item = {
|
|
children: [
|
|
{ name: 'child1' },
|
|
{
|
|
name: 'child2',
|
|
children: [{ name: 'child3' }],
|
|
},
|
|
],
|
|
};
|
|
const result = vm.findMatches(search, item);
|
|
expect(result).toEqual([{ name: 'child3' }]);
|
|
});
|
|
});
|
|
|
|
describe('normalize', () => {
|
|
beforeAll(() => {
|
|
vm = mount('card').vm;
|
|
});
|
|
it('should normalize and lowercase text', () => {
|
|
const input = 'ÁÉÍÓÚáéíóú';
|
|
const expected = 'aeiouaeiou';
|
|
expect(vm.normalize(input)).toBe(expected);
|
|
});
|
|
|
|
it('should handle empty string', () => {
|
|
const input = '';
|
|
const expected = '';
|
|
expect(vm.normalize(input)).toBe(expected);
|
|
});
|
|
|
|
it('should handle text without diacritics', () => {
|
|
const input = 'hello';
|
|
const expected = 'hello';
|
|
expect(vm.normalize(input)).toBe(expected);
|
|
});
|
|
|
|
it('should handle mixed text', () => {
|
|
const input = 'Héllo Wórld!';
|
|
const expected = 'hello world!';
|
|
expect(vm.normalize(input)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe('addChildren', () => {
|
|
const module = 'testModule';
|
|
beforeEach(() => {
|
|
vm = mount().vm;
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('should add menu items to parent if matches are found', () => {
|
|
const parent = 'testParent';
|
|
const route = {
|
|
meta: {
|
|
menu: 'testMenu',
|
|
},
|
|
children: [{ name: 'child1' }, { name: 'child2' }],
|
|
};
|
|
vm.addChildren(module, route, parent);
|
|
|
|
expect(navigation.addMenuItem).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should handle routes with no meta menu', () => {
|
|
const route = {
|
|
meta: {},
|
|
menus: {},
|
|
};
|
|
|
|
const parent = [];
|
|
|
|
vm.addChildren(module, route, parent);
|
|
expect(navigation.addMenuItem).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should handle empty parent array', () => {
|
|
const parent = [];
|
|
const route = {
|
|
meta: {
|
|
menu: 'child11',
|
|
},
|
|
children: [
|
|
{
|
|
name: 'child1',
|
|
meta: {
|
|
menuChildren: [
|
|
{
|
|
name: 'CustomerCreditContracts',
|
|
title: 'creditContracts',
|
|
icon: 'vn:solunion',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
};
|
|
vm.addChildren(module, route, parent);
|
|
expect(navigation.addMenuItem).toHaveBeenCalled();
|
|
});
|
|
});
|