From 12715adbdbf5dbbb884f2c3450abba01c1db9a4f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 31 Dec 2024 14:03:03 +0100 Subject: [PATCH] test: refs #7058 improve methods --- src/components/__tests__/Leftmenu.spec.js | 422 ++++++++++++++++------ 1 file changed, 314 insertions(+), 108 deletions(-) diff --git a/src/components/__tests__/Leftmenu.spec.js b/src/components/__tests__/Leftmenu.spec.js index 54f6d3554..874c3c81b 100644 --- a/src/components/__tests__/Leftmenu.spec.js +++ b/src/components/__tests__/Leftmenu.spec.js @@ -1,9 +1,11 @@ import { vi, describe, expect, it, beforeAll, beforeEach } 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: [ { @@ -44,126 +46,330 @@ vi.mock('src/router/modules', () => ({ }, ], })); + function mount(source) { - return createWrapper(Leftmenu, { + 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('Leftmenu', () => { - let vm; - let navigation; +describe('Leftmenu as card', () => { beforeAll(() => { - vi.spyOn(axios, 'get').mockResolvedValue({ - data: [], - }); - vm = mount('main').vm; - vi.spyOn(vm, 'getCardRoutes'); - - navigation = useNavigationStore(); - navigation.fetchPinned = vi.fn().mockReturnValue(Promise.resolve(true)); - navigation.getModules = vi.fn().mockReturnValue({ - value: [ + vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ + matched: [ { - name: 'customer', - title: 'customer.pageTitles.customers', - icon: 'vn:customer', - module: 'customer', + 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', + }, }, ], + query: {}, + params: {}, + meta: { moduleName: 'mockName' }, + path: 'mockName/1', + name: 'Customer', }); + + vm = mount('card').vm; + vm.getCardRoutes = vi.fn().mockReturnValue(() => vi.fn); }); - describe.only(' its card', () => { - it('getRoutes', () => { - vm.props.source = 'card'; - vm.getRoutes(); - expect(useNavigationStore().getModules).toHaveBeenCalled(); - }); - }); - describe(' its main', () => { - beforeAll(() => { - vm = mount('main').vm; - }); - - it('should return a proper formated object with two child items', async () => { - const expectedMenuItem = [ - { - children: null, - name: 'CustomerList', - title: 'globals.pageTitles.list', - icon: 'view_list', - }, - { - children: null, - name: 'CustomerCreate', - title: 'globals.pageTitles.createCustomer', - icon: 'vn:addperson', - }, - ]; - const firstMenuItem = vm.items[0]; - expect(firstMenuItem.children).toEqual( - expect.arrayContaining(expectedMenuItem) - ); - }); - - it('should initialize with default props', () => { - expect(vm.source).toBe('main'); - }); - - it('should filter items based on search input', async () => { - vm.search = 'Rou'; - await vm.$nextTick(); - // expect(vm.filterItems).toHaveBeenCalled(); - expect(vm.filterItems()).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.skip('should add children to navigation', () => { - const module = 'module1'; - const route = { - meta: { menu: 'child1' }, - children: [ - { name: 'child1', children: [] }, - { name: 'child2', children: [] }, - ], - }; - const parent = 'parent1'; - vm.addChildren(module, route, parent); - expect(useNavigationStore().addMenuItem).toHaveBeenCalledWith( - module, - { name: 'child1', children: [] }, - parent - ); - }); - - it('should get routes for main source', () => { - vm.props.source = 'main'; - vm.getRoutes(); - expect(useNavigationStore().getModules).toHaveBeenCalled(); - }); + it('should get routes for card source', () => { + const spyGetCardRoutes = vi.spyOn(vm, 'getCardRoutes'); + vm.getCardRoutes(); + console.log('spyGetCardRoutes', spyGetCardRoutes.mock.calls); + expect(spyGetCardRoutes.mock.calls).toHaveLength(1); + }); +}); +describe('Leftmenu as main', () => { + beforeAll(() => { + vm = mount('main').vm; + }); + + it('should return a proper formated object with two child items', async () => { + const expectedMenuItem = [ + { + children: null, + name: 'CustomerList', + title: 'globals.pageTitles.list', + icon: 'view_list', + }, + { + children: null, + name: 'CustomerCreate', + title: 'globals.pageTitles.createCustomer', + icon: 'vn:addperson', + }, + ]; + const firstMenuItem = vm.items[0]; + expect(firstMenuItem.children).toEqual(expect.arrayContaining(expectedMenuItem)); + }); + + it('should initialize with default props', () => { + expect(vm.source).toBe('main'); + }); + + it('should filter items based on search input', async () => { + vm.search = 'Rou'; + await vm.$nextTick(); + // expect(vm.filterItems).toHaveBeenCalled(); + expect(vm.filterItems()).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 an empty matched array', () => { + const result = vm.betaGetRoutes(); + + expect(result).toBeUndefined(); + }); + + it.skip('should handle a single matched route with a menu', () => { + const route = { + matched: [{ meta: { menu: 'menu1' } }], + }; + + const result = vm.betaGetRoutes(); + + expect(result).toEqual(route.matched[0]); + }); + it('should get routes for main source', () => { + vm.props.source = 'main'; + vm.getRoutes(); + expect(useNavigationStore().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); + }); +}); + +// WIP +describe.skip('addChildren', () => { + it('should add menu items to parent if matches are found', () => { + const module = 'testModule'; + const route = { + meta: { menu: 'child1' }, + children: [{ name: 'child1' }, { name: 'child2' }], + }; + const parent = []; + + vm.addChildren(module, route, parent); + + expect(useNavigationStore().addMenuItem).toHaveBeenCalledWith( + module, + { name: 'child1' }, + parent + ); + }); + + it.skip('should not add menu items if no matches are found', () => { + const module = 'testModule'; + const route = { + meta: { menu: 'child3' }, + children: [{ name: 'child1' }, { name: 'child2' }], + }; + const parent = []; + + vm.addChildren(module, route, parent); + + expect(useNavigationStore().addMenuItem).not.toHaveBeenCalled(); + }); + + it.skip('should handle routes with no meta menu', () => { + const module = 'testModule'; + const route = { + menus: { main: 'child1' }, + children: [{ name: 'child1' }, { name: 'child2' }], + }; + const parent = []; + + vm.addChildren(module, route, parent); + + expect(useNavigationStore().addMenuItem).toHaveBeenCalledWith( + module, + { name: 'child1' }, + parent + ); + }); + + it.skip('should handle routes with no matches', () => { + const module = 'testModule'; + const route = { + meta: { menu: 'child3' }, + children: [{ name: 'child1' }, { name: 'child2' }], + }; + const parent = []; + + vm.addChildren(module, route, parent); + + expect(useNavigationStore().addMenuItem).not.toHaveBeenCalled(); + }); + + it.skip('should handle empty parent array', () => { + const module = 'testModule'; + const route = { + meta: { menu: 'child1' }, + children: [{ name: 'child1' }, { name: 'child2' }], + }; + const parent = []; + + vm.addChildren(module, route, parent); + + expect(useNavigationStore().addMenuItem).toHaveBeenCalledWith( + module, + { name: 'child1' }, + parent + ); }); });