From c08b3648f248b304216f3299a26b5ebaf3e2e656 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 3 Apr 2025 01:36:30 +0200 Subject: [PATCH] test: arrayData --- .../__tests__/useArrayData.spec.js | 141 ++++++++---------- src/composables/useArrayData.js | 3 +- 2 files changed, 66 insertions(+), 78 deletions(-) diff --git a/src/composables/__tests__/useArrayData.spec.js b/src/composables/__tests__/useArrayData.spec.js index fb5b99ff6..a3fbbdd5d 100644 --- a/src/composables/__tests__/useArrayData.spec.js +++ b/src/composables/__tests__/useArrayData.spec.js @@ -1,16 +1,39 @@ import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; -import axios from 'axios'; -import { flushPromises } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; import { useArrayData } from 'composables/useArrayData'; import { useRouter } from 'vue-router'; import * as vueRouter from 'vue-router'; +import { setActivePinia, createPinia } from 'pinia'; describe('useArrayData', () => { const filter = '{"limit":20,"skip":0}'; const params = { supplierFk: 2 }; + beforeEach(() => { - vi.spyOn(useRouter(), 'replace'); - vi.spyOn(useRouter(), 'push'); + setActivePinia(createPinia()); + + // Mock route + vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ + path: 'mockSection/list', + matched: [], + query: {}, + params: {}, + meta: { moduleName: 'mockName' }, + }); + + // Mock router + vi.spyOn(vueRouter, 'useRouter').mockReturnValue({ + push: vi.fn(), + replace: vi.fn(), + currentRoute: { + value: { + path: 'mockSection/list', + params: { id: 1 }, + meta: { moduleName: 'mockName' }, + matched: [{ path: 'mockName/:id' }], + }, + }, + }); }); afterEach(() => { @@ -18,103 +41,69 @@ describe('useArrayData', () => { }); it('should fetch and replace url with new params', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] }); + vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: [] }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl' }); + const arrayData = useArrayData('ArrayData', { + url: 'mockUrl', + searchUrl: 'params', + }); arrayData.store.userParams = params; - arrayData.fetch({}); + await arrayData.fetch({}); - await flushPromises(); - let routerReplace = useRouter().replace; - routerReplace = routerReplace.mock.calls[0][0]; - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, + const routerReplace = useRouter().replace.mock.calls[0][0]; + + expect(axios.get).toHaveBeenCalledWith('mockUrl', { + signal: expect.any(Object), + params: { + filter, + supplierFk: 2, + }, }); - expect(routerReplace.path).toEqual('mockSection/list'); + + expect(routerReplace.path).toBe('mockSection/list'); expect(JSON.parse(routerReplace.query.params)).toEqual( expect.objectContaining(params), ); }); - it('should get data and send new URL without keeping parameters, if there is only one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }] }); + it('should redirect to detail when single record is returned with navigation', async () => { + vi.spyOn(axios, 'get').mockResolvedValueOnce({ + data: [{ id: 1 }], + }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} }); + const arrayData = useArrayData('ArrayData', { + url: 'mockUrl', + navigate: {}, + }); arrayData.store.userParams = params; - arrayData.fetch({}); + await arrayData.fetch({}); - await flushPromises(); const routerPush = useRouter().push.mock.calls[0][0]; - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, - }); - expect(routerPush.path).toEqual('mockName/1'); + expect(routerPush.path).toBe('mockName/1'); expect(routerPush.query).toBeUndefined(); }); - it('should get data and send new URL keeping parameters, if you have more than one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }, { id: 2 }] }); - - vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ - matched: [], - query: {}, - params: {}, - meta: { moduleName: 'mockName' }, - path: 'mockName/1', - }); - vi.spyOn(vueRouter, 'useRouter').mockReturnValue({ - push: vi.fn(), - replace: vi.fn(), - currentRoute: { - value: { - params: { - id: 1, - }, - meta: { moduleName: 'mockName' }, - matched: [{ path: 'mockName/:id' }], - }, - }, - }); - - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} }); - - arrayData.store.userParams = params; - arrayData.fetch({}); - - await flushPromises(); - const routerPush = useRouter().push.mock.calls[0][0]; - - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, - }); - expect(routerPush.path).toEqual('mockName/'); - expect(routerPush.query.params).toBeDefined(); - }); - - it('should return one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ + it('should return one record when oneRecord is true', async () => { + vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: [ { id: 1, name: 'Entity 1' }, { id: 2, name: 'Entity 2' }, ], }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true }); + + const arrayData = useArrayData('ArrayData', { + url: 'mockUrl', + oneRecord: true, + }); + await arrayData.fetch({}); - expect(arrayData.store.data).toEqual({ id: 1, name: 'Entity 1' }); - }); - - it('should handle empty data gracefully if has to return one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true }); - await arrayData.fetch({}); - - expect(arrayData.store.data).toBeUndefined(); + expect(arrayData.store.data).toEqual({ + id: 1, + name: 'Entity 1', + }); }); }); diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index a17730754..2e880a16d 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -5,12 +5,11 @@ import { useArrayDataStore } from 'stores/useArrayDataStore'; import { buildFilter } from 'filters/filterPanel'; import { isDialogOpened } from 'src/filters'; -const arrayDataStore = useArrayDataStore(); - export function useArrayData(key, userOptions) { key ??= useRoute().meta.moduleName; if (!key) throw new Error('ArrayData: A key is required to use this composable'); + const arrayDataStore = useArrayDataStore(); // Move inside function if (!arrayDataStore.get(key)) arrayDataStore.set(key);