From 3fb9b0de47521752bf39c8f39acf1e44184fe349 Mon Sep 17 00:00:00 2001 From: provira Date: Thu, 19 Dec 2024 12:32:15 +0100 Subject: [PATCH 1/3] refactor: refs #8320 moved front tests to their respective sections --- src/boot/specs/axios.spec.js | 65 ++++++ src/components/VnTable/specs/VnTable.spec.js | 47 ++++ .../common/specs/VnChangePassword.spec.js | 70 ++++++ .../common/specs/VnDiscount.spec.js | 28 +++ src/components/common/specs/VnLog.spec.js | 134 +++++++++++ .../common/specs/VnSmsDialog.spec.js | 58 +++++ src/components/specs/CrudModel.spec.js | 120 ++++++++++ src/components/specs/Leftmenu.spec.js | 94 ++++++++ src/components/ui/specs/Paginate.spec.js | 118 ++++++++++ src/components/ui/specs/VnLinkPhone.spec.js | 50 +++++ src/components/ui/specs/VnSms.spec.js | 25 +++ src/composables/specs/downloadFile.spec.js | 36 +++ src/composables/specs/getExchange.spec.js | 45 ++++ src/composables/specs/getTotal.spec.js | 55 +++++ .../specs/useAccountShortToStandard.spec.js | 9 + src/composables/specs/useAcl.spec.js | 110 +++++++++ src/composables/specs/useArrayData.spec.js | 98 ++++++++ src/composables/specs/useRole.spec.js | 73 ++++++ src/composables/specs/useSession.spec.js | 211 ++++++++++++++++++ src/composables/specs/useTokenConfig.spec.js | 31 +++ .../Card/specs/ClaimDescriptorMenu.spec.js | 33 +++ src/pages/Claim/Card/specs/ClaimLines.spec.js | 75 +++++++ .../Claim/Card/specs/ClaimLinesImport.spec.js | 47 ++++ src/pages/Claim/Card/specs/ClaimPhoto.spec.js | 114 ++++++++++ .../Payments/specs/CustomerPayments.spec.js | 38 ++++ src/pages/Login/specs/Login.spec.js | 49 ++++ .../Ticket/Card/specs/TicketBoxing.spec.js | 50 +++++ src/pages/Ticket/specs/TicketAdvance.spec.js | 120 ++++++++++ src/pages/Wagon/specs/WagonCreate.spec.js | 97 ++++++++ .../specs/WorkerNotificationsManager.spec.js | 33 +++ src/stores/specs/useStateQueryStore.spec.js | 58 +++++ 31 files changed, 2191 insertions(+) create mode 100644 src/boot/specs/axios.spec.js create mode 100644 src/components/VnTable/specs/VnTable.spec.js create mode 100644 src/components/common/specs/VnChangePassword.spec.js create mode 100644 src/components/common/specs/VnDiscount.spec.js create mode 100644 src/components/common/specs/VnLog.spec.js create mode 100644 src/components/common/specs/VnSmsDialog.spec.js create mode 100644 src/components/specs/CrudModel.spec.js create mode 100644 src/components/specs/Leftmenu.spec.js create mode 100644 src/components/ui/specs/Paginate.spec.js create mode 100644 src/components/ui/specs/VnLinkPhone.spec.js create mode 100644 src/components/ui/specs/VnSms.spec.js create mode 100644 src/composables/specs/downloadFile.spec.js create mode 100644 src/composables/specs/getExchange.spec.js create mode 100644 src/composables/specs/getTotal.spec.js create mode 100644 src/composables/specs/useAccountShortToStandard.spec.js create mode 100644 src/composables/specs/useAcl.spec.js create mode 100644 src/composables/specs/useArrayData.spec.js create mode 100644 src/composables/specs/useRole.spec.js create mode 100644 src/composables/specs/useSession.spec.js create mode 100644 src/composables/specs/useTokenConfig.spec.js create mode 100644 src/pages/Claim/Card/specs/ClaimDescriptorMenu.spec.js create mode 100644 src/pages/Claim/Card/specs/ClaimLines.spec.js create mode 100644 src/pages/Claim/Card/specs/ClaimLinesImport.spec.js create mode 100644 src/pages/Claim/Card/specs/ClaimPhoto.spec.js create mode 100644 src/pages/Customer/Payments/specs/CustomerPayments.spec.js create mode 100644 src/pages/Login/specs/Login.spec.js create mode 100644 src/pages/Ticket/Card/specs/TicketBoxing.spec.js create mode 100644 src/pages/Ticket/specs/TicketAdvance.spec.js create mode 100644 src/pages/Wagon/specs/WagonCreate.spec.js create mode 100644 src/pages/Worker/Card/specs/WorkerNotificationsManager.spec.js create mode 100644 src/stores/specs/useStateQueryStore.spec.js diff --git a/src/boot/specs/axios.spec.js b/src/boot/specs/axios.spec.js new file mode 100644 index 000000000..b3b6f98c6 --- /dev/null +++ b/src/boot/specs/axios.spec.js @@ -0,0 +1,65 @@ +import { onRequest, onResponseError } from 'src/boot/axios'; +import { describe, expect, it, vi } from 'vitest'; + +vi.mock('src/composables/useSession', () => ({ + useSession: () => ({ + getToken: () => 'DEFAULT_TOKEN', + isLoggedIn: () => vi.fn(), + destroy: () => vi.fn(), + }), +})); + +vi.mock('src/stores/useStateQueryStore', () => ({ + useStateQueryStore: () => ({ + add: () => vi.fn(), + remove: () => vi.fn(), + }), +})); + +describe('Axios boot', () => { + describe('onRequest()', async () => { + it('should set the "Authorization" property on the headers', async () => { + const config = { headers: {} }; + + const resultConfig = onRequest(config); + + expect(resultConfig).toEqual( + expect.objectContaining({ + headers: { + 'Accept-Language': 'en-US', + Authorization: 'DEFAULT_TOKEN', + }, + }) + ); + }); + }); + + describe('onResponseError()', async () => { + it('should call to the Notify plugin with a message error for an status code "500"', async () => { + const error = { + response: { + status: 500, + }, + }; + + const result = onResponseError(error); + expect(result).rejects.toEqual(expect.objectContaining(error)); + }); + + it('should call to the Notify plugin with a message from the response property', async () => { + const error = { + response: { + status: 401, + data: { + error: { + message: 'Invalid user or password', + }, + }, + }, + }; + + const result = onResponseError(error); + expect(result).rejects.toEqual(expect.objectContaining(error)); + }); + }); +}); diff --git a/src/components/VnTable/specs/VnTable.spec.js b/src/components/VnTable/specs/VnTable.spec.js new file mode 100644 index 000000000..162df727d --- /dev/null +++ b/src/components/VnTable/specs/VnTable.spec.js @@ -0,0 +1,47 @@ +import { describe, expect, it, beforeAll, beforeEach } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import VnTable from 'src/components/VnTable/VnTable.vue'; + +describe('VnTable', () => { + let wrapper; + let vm; + + beforeAll(() => { + wrapper = createWrapper(VnTable, { + propsData: { + columns: [], + }, + }); + vm = wrapper.vm; + }); + + beforeEach(() => (vm.selected = [])); + + describe('handleSelection()', () => { + const rows = [{ $index: 0 }, { $index: 1 }, { $index: 2 }]; + const selectedRows = [{ $index: 1 }]; + it('should add rows to selected when shift key is pressed and rows are added except last one', () => { + vm.handleSelection( + { evt: { shiftKey: true }, added: true, rows: selectedRows }, + rows + ); + expect(vm.selected).toEqual([{ $index: 0 }]); + }); + + it('should not add rows to selected when shift key is not pressed', () => { + vm.handleSelection( + { evt: { shiftKey: false }, added: true, rows: selectedRows }, + rows + ); + expect(vm.selected).toEqual([]); + }); + + it('should not add rows to selected when rows are not added', () => { + vm.handleSelection( + { evt: { shiftKey: true }, added: false, rows: selectedRows }, + rows + ); + expect(vm.selected).toEqual([]); + }); + }); +}); diff --git a/src/components/common/specs/VnChangePassword.spec.js b/src/components/common/specs/VnChangePassword.spec.js new file mode 100644 index 000000000..f5a967bb5 --- /dev/null +++ b/src/components/common/specs/VnChangePassword.spec.js @@ -0,0 +1,70 @@ +import { createWrapper, axios } from 'app/test/vitest/helper'; +import VnChangePassword from 'src/components/common/VnChangePassword.vue'; +import { vi, beforeEach, afterEach, beforeAll, describe, expect, it } from 'vitest'; +import { Notify } from 'quasar'; + +describe('VnSmsDialog', () => { + let vm; + + beforeAll(() => { + vi.spyOn(axios, 'get').mockResolvedValue({ + data: [], + }); + vm = createWrapper(VnChangePassword, { + propsData: { + submitFn: vi.fn(), + }, + }).vm; + }); + + beforeEach(() => { + Notify.create = vi.fn(); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should notify when new password is empty', async () => { + vm.passwords.newPassword = ''; + vm.passwords.repeatPassword = 'password'; + + await vm.validate(); + expect(Notify.create).toHaveBeenCalledWith( + expect.objectContaining({ + message: 'You must enter a new password', + type: 'negative', + }) + ); + }); + + it("should notify when passwords don't match", async () => { + vm.passwords.newPassword = 'password1'; + vm.passwords.repeatPassword = 'password2'; + await vm.validate(); + expect(Notify.create).toHaveBeenCalledWith( + expect.objectContaining({ + message: `Passwords don't match`, + type: 'negative', + }) + ); + }); + + describe('if passwords match', () => { + it('should call submitFn and emit password', async () => { + vm.passwords.newPassword = 'password'; + vm.passwords.repeatPassword = 'password'; + await vm.validate(); + expect(vm.props.submitFn).toHaveBeenCalledWith('password', undefined); + }); + + it('should call submitFn and emit password and old password', async () => { + vm.passwords.newPassword = 'password'; + vm.passwords.repeatPassword = 'password'; + vm.passwords.oldPassword = 'oldPassword'; + + await vm.validate(); + expect(vm.props.submitFn).toHaveBeenCalledWith('password', 'oldPassword'); + }); + }); +}); diff --git a/src/components/common/specs/VnDiscount.spec.js b/src/components/common/specs/VnDiscount.spec.js new file mode 100644 index 000000000..5d5be61ac --- /dev/null +++ b/src/components/common/specs/VnDiscount.spec.js @@ -0,0 +1,28 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import VnDiscount from 'components/common/vnDiscount.vue'; + +describe('VnDiscount', () => { + let vm; + + beforeAll(() => { + vm = createWrapper(VnDiscount, { + props: { + data: {}, + price: 100, + quantity: 2, + discount: 10, + } + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('total', () => { + it('should calculate total correctly', () => { + expect(vm.total).toBe(180); + }); + }); +}); \ No newline at end of file diff --git a/src/components/common/specs/VnLog.spec.js b/src/components/common/specs/VnLog.spec.js new file mode 100644 index 000000000..53d2732a0 --- /dev/null +++ b/src/components/common/specs/VnLog.spec.js @@ -0,0 +1,134 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import VnLog from 'src/components/common/VnLog.vue'; + +describe('VnLog', () => { + let vm; + const fakeLogTreeData = [ + { + id: 2, + originFk: 1, + userFk: 18, + action: 'update', + changedModel: 'ClaimObservation', + oldInstance: {}, + newInstance: { + claimFk: 1, + text: 'Waiting for customer', + }, + creationDate: '2023-09-18T12:25:34.000Z', + changedModelId: '1', + changedModelValue: null, + description: null, + user: { + id: 18, + name: 'salesPerson', + nickname: 'salesPersonNick', + image: '4fa3ada0-3ac4-11eb-9ab8-27f6fc3b85fd', + worker: { + id: 18, + userFk: 18, + }, + }, + }, + { + id: 1, + originFk: 1, + userFk: 18, + action: 'update', + changedModel: 'Claim', + oldInstance: { + pickup: null, + }, + newInstance: { + pickup: 'agency', + }, + creationDate: '2023-09-18T12:25:34.000Z', + changedModelId: '1', + changedModelValue: null, + description: null, + user: { + id: 18, + name: 'salesPerson', + nickname: 'salesPersonNick', + image: '4fa3ada0-3ac4-11eb-9ab8-27f6fc3b85fd', + worker: { + id: 18, + userFk: 18, + }, + }, + }, + ]; + const mockValidations = { + Claim: { + locale: { + name: 'reclamación', + }, + }, + ClaimObservation: { + locale: { + name: 'observación', + }, + }, + ClaimDms: { + locale: { + name: 'documento', + }, + }, + ClaimBeginning: { + locale: { + name: 'comienzo', + }, + }, + }; + + beforeAll(async () => { + axios.get.mockImplementation(() => { + return { data: fakeLogTreeData }; + }); + + vm = createWrapper(VnLog, { + global: { + stubs: [], + mocks: {}, + }, + propsData: { + model: 'Claim', + }, + }).vm; + vm.validations = mockValidations; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should correctly set logTree', async () => { + vm.logTree = vm.getLogTree(fakeLogTreeData); + expect(vm.logTree[0].originFk).toEqual(1); + expect(vm.logTree[0].logs[0].user.name).toEqual('salesPerson'); + }); + + it('should correctly set the selectedFilters when filtering', () => { + vm.searchInput = '1'; + vm.userSelect = '21'; + vm.checkboxOptions.insert.selected = true; + vm.checkboxOptions.update.selected = true; + + vm.selectFilter('search'); + vm.selectFilter('userSelect'); + + expect(vm.selectedFilters.changedModelId).toEqual('1'); + expect(vm.selectedFilters.userFk).toEqual('21'); + expect(vm.selectedFilters.action).toEqual({ inq: ['insert', 'update'] }); + }); + + it('should correctly set the date from', () => { + vm.dateFrom = '18-09-2023'; + vm.selectFilter('date', 'from'); + expect(vm.selectedFilters.creationDate.between).toEqual([ + new Date('2023-09-18T00:00:00.000Z'), + new Date('2023-09-18T21:59:59.999Z'), + ]); + }); +}); diff --git a/src/components/common/specs/VnSmsDialog.spec.js b/src/components/common/specs/VnSmsDialog.spec.js new file mode 100644 index 000000000..0b3473982 --- /dev/null +++ b/src/components/common/specs/VnSmsDialog.spec.js @@ -0,0 +1,58 @@ +import { createWrapper } from 'app/test/vitest/helper'; +import VnSmsDialog from 'components/common/VnSmsDialog.vue'; +import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest'; + + +describe('VnSmsDialog', () => { + let vm; + const orderId = 1; + const shipped = new Date(); + const phone = '012345678'; + const promise = (response) => {return response;}; + const template = 'minAmount'; + const locale = 'en'; + + beforeAll(() => { + vm = createWrapper(VnSmsDialog, { + propsData: { + data: { + orderId, + shipped + }, + template, + locale, + phone, + promise + } + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('updateMessage()', () => { + it('should update the message value with the correct template and parameters', () => { + vm.updateMessage(); + + expect(vm.message).toEqual(`A minimum amount of 50€ (VAT excluded) is required for your order ${orderId} of ${shipped} to receive it without additional shipping costs.`); + }); + }); + + describe('send()', async () => { + it('should send the message', async () => { + vi.spyOn(vm.props, 'promise'); + vm.message = 'Example message'; + const response = { + orderId, + shipped, + destination: phone, + message: vm.message + }; + await vm.send(); + + expect(vm.isLoading).toEqual(false); + expect(vm.props.promise).toHaveBeenCalledWith(response); + }); + }); +}); diff --git a/src/components/specs/CrudModel.spec.js b/src/components/specs/CrudModel.spec.js new file mode 100644 index 000000000..6ce93e59c --- /dev/null +++ b/src/components/specs/CrudModel.spec.js @@ -0,0 +1,120 @@ +import { createWrapper } from 'app/test/vitest/helper'; +import CrudModel from 'components/CrudModel.vue'; +import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest'; + +describe('CrudModel', () => { + let vm; + beforeAll(() => { + vm = createWrapper(CrudModel, { + global: { + stubs: [ + 'vnPaginate', + 'useState', + 'arrayData', + 'useStateStore', + 'vue-i18n', + ], + mocks: { + validate: vi.fn(), + }, + }, + propsData: { + dataRequired: { + fk: 1, + }, + dataKey: 'crudModelKey', + model: 'crudModel', + url: 'crudModelUrl', + }, + }).vm; + }); + + beforeEach(() => { + vm.fetch([]); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('insert()', () => { + it('should new element in list with index 0 if formData not has data', () => { + vm.insert(); + + expect(vm.formData.length).toEqual(1); + expect(vm.formData[0].fk).toEqual(1); + expect(vm.formData[0].$index).toEqual(0); + }); + }); + + describe('getChanges()', () => { + it('should return correct updates and creates', async () => { + vm.fetch([ + { id: 1, name: 'New name one' }, + { id: 2, name: 'New name two' }, + { id: 3, name: 'Bruce Wayne' }, + ]); + + vm.originalData = [ + { id: 1, name: 'Tony Starks' }, + { id: 2, name: 'Jessica Jones' }, + { id: 3, name: 'Bruce Wayne' }, + ]; + + vm.insert(); + const result = vm.getChanges(); + + const expected = { + creates: [ + { + $index: 3, + fk: 1, + }, + ], + updates: [ + { + data: { + name: 'New name one', + }, + where: { + id: 1, + }, + }, + { + data: { + name: 'New name two', + }, + where: { + id: 2, + }, + }, + ], + }; + + expect(result).toEqual(expected); + }); + }); + + describe('getDifferences()', () => { + it('should return the differences between two objects', async () => { + const obj1 = { + a: 1, + b: 2, + c: 3, + }; + const obj2 = { + a: null, + b: 4, + d: 5, + }; + + const result = vm.getDifferences(obj1, obj2); + + expect(result).toEqual({ + a: null, + b: 4, + d: 5, + }); + }); + }); +}); diff --git a/src/components/specs/Leftmenu.spec.js b/src/components/specs/Leftmenu.spec.js new file mode 100644 index 000000000..10d9d66fb --- /dev/null +++ b/src/components/specs/Leftmenu.spec.js @@ -0,0 +1,94 @@ +import { vi, describe, expect, it, beforeAll } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import Leftmenu from 'components/LeftMenu.vue'; + +import { useNavigationStore } from 'src/stores/useNavigationStore'; + +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', + children: [ + { + path: 'list', + name: 'CustomerList', + meta: { + title: 'list', + icon: 'view_list', + }, + }, + { + path: 'create', + name: 'CustomerCreate', + meta: { + title: 'createCustomer', + icon: 'vn:addperson', + }, + }, + ], + }, + ], + }, + ], +})); + +describe('Leftmenu', () => { + let vm; + let navigation; + beforeAll(() => { + vi.spyOn(axios, 'get').mockResolvedValue({ + data: [], + }); + + vm = createWrapper(Leftmenu, { + propsData: { + source: 'main', + }, + }).vm; + + 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', + }, + ], + }); + }); + + 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)); + }); +}); diff --git a/src/components/ui/specs/Paginate.spec.js b/src/components/ui/specs/Paginate.spec.js new file mode 100644 index 000000000..a67dfcdc6 --- /dev/null +++ b/src/components/ui/specs/Paginate.spec.js @@ -0,0 +1,118 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import VnPaginate from 'src/components/ui/VnPaginate.vue'; + +describe('VnPaginate', () => { + const expectedUrl = '/api/customers'; + const defaultData = [ + { id: 1, name: 'Tony Stark' }, + { id: 2, name: 'Jessica Jones' }, + { id: 3, name: 'Bruce Wayne' }, + ]; + let vm; + beforeAll(() => { + const options = { + attrs: { + url: expectedUrl, + dataKey: 'CustomerList', + order: 'id DESC', + limit: 3, + }, + }; + vm = createWrapper(VnPaginate, options).vm; + }); + + afterEach(() => { + vm.store.data = []; + vm.store.skip = 0; + vm.pagination.page = 1; + vm.hasMoreData = true; + }); + + describe('paginate()', () => { + it('should call to the paginate() method and set the data on the rows property', async () => { + vi.spyOn(vm.arrayData, 'loadMore'); + vm.store.data = defaultData; + + await vm.paginate(); + + expect(vm.arrayData.loadMore).toHaveBeenCalledWith(); + expect(vm.store.data.length).toEqual(3); + }); + + it('should call to the paginate() method and then call it again to paginate', async () => { + vi.spyOn(axios, 'get').mockResolvedValue({ + data: defaultData, + }); + vm.store.hasMoreData = true; + await vm.$nextTick(); + + vm.store.data = defaultData; + + await vm.paginate(); + + expect(vm.store.skip).toEqual(3); + expect(vm.store.data.length).toEqual(6); + + vi.spyOn(axios, 'get').mockResolvedValue({ + data: [ + { id: 4, name: 'Peter Parker' }, + { id: 5, name: 'Clark Kent' }, + { id: 6, name: 'Barry Allen' }, + ], + }); + await vm.paginate(); + + expect(vm.store.skip).toEqual(6); + expect(vm.store.data.length).toEqual(9); + }); + }); + + describe('onLoad()', () => { + it('should call to the done() callback and not increment the pagination', async () => { + const index = 1; + const done = vi.fn(); + + await vm.onLoad(index, done); + + expect(vm.pagination.page).toEqual(1); + expect(done).toHaveBeenCalledWith(false); + }); + + it('should increment the pagination and then call to the done() callback', async () => { + expect(vm.pagination.page).toEqual(1); + + const index = 1; + const done = vi.fn(); + vm.store.data = defaultData; + + await vm.onLoad(index, done); + + expect(vm.pagination.page).toEqual(2); + expect(done).toHaveBeenCalledWith(false); + }); + + it('should call to the done() callback with true as argument to finish pagination', async () => { + vi.spyOn(axios, 'get').mockResolvedValue({ + data: [ + { id: 1, name: 'Tony Stark' }, + { id: 2, name: 'Jessica Jones' }, + ], + }); + + vm.store.data = defaultData; + + expect(vm.pagination.page).toEqual(1); + + const index = 1; + const done = vi.fn(); + + vm.hasMoreData = false; + + await vm.onLoad(index, done); + + expect(vm.pagination.page).toEqual(2); + expect(done).toHaveBeenCalledWith(false); + }); + }); +}); diff --git a/src/components/ui/specs/VnLinkPhone.spec.js b/src/components/ui/specs/VnLinkPhone.spec.js new file mode 100644 index 000000000..a34ef90a5 --- /dev/null +++ b/src/components/ui/specs/VnLinkPhone.spec.js @@ -0,0 +1,50 @@ +import { describe, it, expect, beforeAll, vi } from 'vitest'; +import { axios } from 'app/test/vitest/helper'; +import parsePhone from 'src/filters/parsePhone'; + +describe('parsePhone filter', () => { + beforeAll(async () => { + vi.spyOn(axios, 'get').mockReturnValue({ data: { prefix: '34' } }); + }); + + it('no phone', async () => { + const phone = await parsePhone(null, '34'); + expect(phone).toBe(undefined); + }); + + it("adds prefix +34 if it doesn't have one", async () => { + const phone = await parsePhone('123456789', '34'); + expect(phone).toBe('34123456789'); + }); + + it('maintains prefix +34 if it is already correct', async () => { + const phone = await parsePhone('+34123456789', '34'); + expect(phone).toBe('34123456789'); + }); + + it('converts prefix 0034 to +34', async () => { + const phone = await parsePhone('0034123456789', '34'); + expect(phone).toBe('34123456789'); + }); + + it('converts prefix 34 without symbol to +34', async () => { + const phone = await parsePhone('34123456789', '34'); + expect(phone).toBe('34123456789'); + }); + + it('replaces incorrect prefix with the correct one', async () => { + const phone = await parsePhone('+44123456789', '34'); + expect(phone).toBe('44123456789'); + }); + + it('adds default prefix on error', async () => { + vi.spyOn(axios, 'get').mockImplementation((url) => { + if (url.includes('Prefixes')) + return Promise.reject(new Error('Network error')); + else if (url.includes('PbxConfigs')) + return Promise.resolve({ data: { defaultPrefix: '39' } }); + }); + const phone = await parsePhone('123456789', '34'); + expect(phone).toBe('39123456789'); + }); +}); diff --git a/src/components/ui/specs/VnSms.spec.js b/src/components/ui/specs/VnSms.spec.js new file mode 100644 index 000000000..e0f8c1868 --- /dev/null +++ b/src/components/ui/specs/VnSms.spec.js @@ -0,0 +1,25 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import VnSms from 'src/components/ui/VnSms.vue'; + +describe('VnSms', () => { + let vm; + + beforeAll(() => { + vm = createWrapper(VnSms, { + global: { + stubs: ['VnPaginate'], + mocks: {}, + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should format number correctly', () => { + const formattedNumber = vm.formatNumber('123456789012'); + expect(formattedNumber).toBe('1234 56789012'); + }); +}); diff --git a/src/composables/specs/downloadFile.spec.js b/src/composables/specs/downloadFile.spec.js new file mode 100644 index 000000000..f53b56b3e --- /dev/null +++ b/src/composables/specs/downloadFile.spec.js @@ -0,0 +1,36 @@ +import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; +import { axios } from 'app/test/vitest/helper'; +import { downloadFile } from 'src/composables/downloadFile'; +import { useSession } from 'src/composables/useSession'; +const session = useSession(); +const token = session.getToken(); + +describe('downloadFile', () => { + const baseUrl = 'http://localhost:9000'; + let defaulCreateObjectURL; + + beforeAll(() => { + defaulCreateObjectURL = window.URL.createObjectURL; + window.URL.createObjectURL = vi.fn(() => 'blob:http://localhost:9000/blob-id'); + }); + + afterAll(() => (window.URL.createObjectURL = defaulCreateObjectURL)); + + it('should open a new window to download the file', async () => { + const res = { + data: new Blob(['file content'], { type: 'application/octet-stream' }), + headers: { 'content-disposition': 'attachment; filename="test-file.txt"' }, + }; + vi.spyOn(axios, 'get').mockImplementation((url) => { + if (url == 'Urls/getUrl') return Promise.resolve({ data: baseUrl }); + else if (url.includes('downloadFile')) return Promise.resolve(res); + }); + + await downloadFile(1); + + expect(axios.get).toHaveBeenCalledWith( + `${baseUrl}/api/dms/1/downloadFile?access_token=${token}`, + { responseType: 'blob' } + ); + }); +}); diff --git a/src/composables/specs/getExchange.spec.js b/src/composables/specs/getExchange.spec.js new file mode 100644 index 000000000..dba31458e --- /dev/null +++ b/src/composables/specs/getExchange.spec.js @@ -0,0 +1,45 @@ +import { describe, expect, it, vi } from 'vitest'; +import axios from 'axios'; +import { getExchange } from 'src/composables/getExchange'; + +vi.mock('axios'); + +describe('getExchange()', () => { + it('should return the correct exchange rate', async () => { + axios.get.mockResolvedValue({ + data: { value: 1.2 }, + }); + + const amount = 100; + const currencyFk = 1; + const dated = '2023-01-01'; + const result = await getExchange(amount, currencyFk, dated); + + expect(result).toBe('83.33'); + }); + + it('should return the correct exchange rate with custom decimal places', async () => { + axios.get.mockResolvedValue({ + data: { value: 1.2 }, + }); + + const amount = 100; + const currencyFk = 1; + const dated = '2023-01-01'; + const decimalPlaces = 3; + const result = await getExchange(amount, currencyFk, dated, decimalPlaces); + + expect(result).toBe('83.333'); + }); + + it('should return null if the API call fails', async () => { + axios.get.mockRejectedValue(new Error('Network error')); + + const amount = 100; + const currencyFk = 1; + const dated = '2023-01-01'; + const result = await getExchange(amount, currencyFk, dated); + + expect(result).toBeNull(); + }); +}); diff --git a/src/composables/specs/getTotal.spec.js b/src/composables/specs/getTotal.spec.js new file mode 100644 index 000000000..789e3fbcf --- /dev/null +++ b/src/composables/specs/getTotal.spec.js @@ -0,0 +1,55 @@ +import { vi, describe, expect, it } from 'vitest'; +import { getTotal } from 'src/composables/getTotal'; + +vi.mock('src/filters', () => ({ + toCurrency: vi.fn((value, currency) => `${currency} ${value.toFixed(2)}`), +})); + +describe('getTotal()', () => { + const rows = [ + { amount: 10.5, tax: 2.1 }, + { amount: 20.75, tax: 3.25 }, + { amount: 30.25, tax: 4.75 }, + ]; + + it('should calculate the total for a given key', () => { + const total = getTotal(rows, 'amount'); + expect(total).toBe('61.50'); + }); + + it('should calculate the total with a callback function', () => { + const total = getTotal(rows, null, { cb: (row) => row.amount + row.tax }); + expect(total).toBe('71.60'); + }); + + it('should format the total as currency', () => { + const total = getTotal(rows, 'amount', { currency: 'USD' }); + expect(total).toBe('USD 61.50'); + }); + + it('should format the total as currency with default currency', () => { + const total = getTotal(rows, 'amount', { currency: 'default' }); + expect(total).toBe('undefined 61.50'); + }); + + it('should calculate the total with integer formatting', () => { + const total = getTotal(rows, 'amount', { decimalPlaces: 0 }); + expect(total).toBe('62'); + }); + + it('should calculate the total with custom decimal places', () => { + const total = getTotal(rows, 'amount', { decimalPlaces: 1 }); + expect(total).toBe('61.5'); + }); + + it('should handle rows with missing keys', () => { + const rowsWithMissingKeys = [{ amount: 10.5 }, { amount: 20.75 }, {}]; + const total = getTotal(rowsWithMissingKeys, 'amount'); + expect(total).toBe('31.25'); + }); + + it('should handle empty rows', () => { + const total = getTotal([], 'amount'); + expect(total).toBe('0.00'); + }); +}); diff --git a/src/composables/specs/useAccountShortToStandard.spec.js b/src/composables/specs/useAccountShortToStandard.spec.js new file mode 100644 index 000000000..d24585812 --- /dev/null +++ b/src/composables/specs/useAccountShortToStandard.spec.js @@ -0,0 +1,9 @@ +import { describe, expect, it } from 'vitest'; +import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard'; + +describe('useAccountShortToStandard()', () => { + it('should pad the decimal part with zeros for short numbers', () => { + expect(useAccountShortToStandard('123.45')).toBe('1230000045'); + expect(useAccountShortToStandard('123.')).toBe('1230000000'); + }); +}); diff --git a/src/composables/specs/useAcl.spec.js b/src/composables/specs/useAcl.spec.js new file mode 100644 index 000000000..6cb29984c --- /dev/null +++ b/src/composables/specs/useAcl.spec.js @@ -0,0 +1,110 @@ +import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; +import { axios, flushPromises } from 'app/test/vitest/helper'; +import { useAcl } from 'src/composables/useAcl'; + +describe('useAcl', () => { + const acl = useAcl(); + const mockAcls = [ + { + model: 'Address', + property: '*', + accessType: '*', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: 'employee', + }, + { + model: 'Worker', + property: 'holidays', + accessType: 'READ', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: 'employee', + }, + { + model: 'Url', + property: 'getByUser', + accessType: 'READ', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: '$everyone', + }, + { + model: 'TpvTransaction', + property: 'start', + accessType: 'WRITE', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: '$authenticated', + }, + ]; + + beforeAll(async () => { + vi.spyOn(axios, 'get').mockResolvedValue({ data: mockAcls }); + await acl.fetch(); + }); + + afterAll(async () => await flushPromises()); + + describe('hasAny', () => { + it('should return false if no roles matched', async () => { + expect( + acl.hasAny([ + { model: 'Worker', props: 'updateAttributes', accessType: 'WRITE' }, + ]) + ).toBeFalsy(); + }); + + it('should return false if no roles matched', async () => { + expect( + acl.hasAny([{ model: 'Worker', props: 'holidays', accessType: 'READ' }]) + ).toBeTruthy(); + }); + + describe('*', () => { + it('should return true if an acl matched', async () => { + expect( + acl.hasAny([{ model: 'Address', props: '*', accessType: 'WRITE' }]) + ).toBeTruthy(); + }); + + it('should return false if no acls matched', async () => { + expect( + acl.hasAny([{ model: 'Worker', props: '*', accessType: 'READ' }]) + ).toBeFalsy(); + }); + }); + + describe('$authenticated', () => { + it('should return false if no acls matched', async () => { + expect( + acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: '*' }]) + ).toBeFalsy(); + }); + + it('should return true if an acl matched', async () => { + expect( + acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: 'READ' }]) + ).toBeTruthy(); + }); + }); + + describe('$everyone', () => { + it('should return false if no acls matched', async () => { + expect( + acl.hasAny([ + { model: 'TpvTransaction', props: 'start', accessType: 'READ' }, + ]) + ).toBeFalsy(); + }); + + it('should return false if an acl matched', async () => { + expect( + acl.hasAny([ + { model: 'TpvTransaction', props: 'start', accessType: 'WRITE' }, + ]) + ).toBeTruthy(); + }); + }); + }); +}); diff --git a/src/composables/specs/useArrayData.spec.js b/src/composables/specs/useArrayData.spec.js new file mode 100644 index 000000000..d4c5d0949 --- /dev/null +++ b/src/composables/specs/useArrayData.spec.js @@ -0,0 +1,98 @@ +import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; +import { axios, flushPromises } from 'app/test/vitest/helper'; +import { useArrayData } from 'composables/useArrayData'; +import { useRouter } from 'vue-router'; +import * as vueRouter from 'vue-router'; + +describe('useArrayData', () => { + const filter = '{"limit":20,"skip":0}'; + const params = { supplierFk: 2 }; + beforeEach(() => { + vi.spyOn(useRouter(), 'replace'); + vi.spyOn(useRouter(), 'push'); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should fetch and repalce url with new params', async () => { + vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] }); + + const arrayData = useArrayData('ArrayData', { url: 'mockUrl' }); + + arrayData.store.userParams = params; + arrayData.fetch({}); + + await flushPromises(); + const routerReplace = useRouter().replace.mock.calls[0][0]; + + expect(axios.get.mock.calls[0][1].params).toEqual({ + filter, + supplierFk: 2, + }); + expect(routerReplace.path).toEqual('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 }] }); + + 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/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(); + }); +}); diff --git a/src/composables/specs/useRole.spec.js b/src/composables/specs/useRole.spec.js new file mode 100644 index 000000000..d0bca5342 --- /dev/null +++ b/src/composables/specs/useRole.spec.js @@ -0,0 +1,73 @@ +import { vi, describe, expect, it } from 'vitest'; +import { axios, flushPromises } from 'app/test/vitest/helper'; +import { useRole } from 'composables/useRole'; +const role = useRole(); + +describe('useRole', () => { + describe('fetch', () => { + it('should call setUser and setRoles of the state with the expected data', async () => { + const rolesData = [ + { + role: { + name: 'salesPerson', + }, + }, + { + role: { + name: 'admin', + }, + }, + ]; + const fetchedUser = { + id: 999, + name: `T'Challa`, + nickname: 'Black Panther', + lang: 'en', + }; + const expectedUser = { + id: 999, + name: `T'Challa`, + nickname: 'Black Panther', + lang: 'en', + }; + const expectedRoles = ['salesPerson', 'admin']; + vi.spyOn(axios, 'get') + .mockResolvedValueOnce({ + data: { roles: rolesData, user: fetchedUser }, + }) + + vi.spyOn(role.state, 'setUser'); + vi.spyOn(role.state, 'setRoles'); + + role.fetch(); + + await flushPromises(); + + expect(role.state.setUser).toHaveBeenCalledWith(expectedUser); + expect(role.state.setRoles).toHaveBeenCalledWith(expectedRoles); + + role.state.setRoles([]); + }); + }); + + describe('hasAny', () => { + it('should return true if a role matched', async () => { + role.state.setRoles(['admin']); + const hasRole = role.hasAny(['admin']); + + await flushPromises(); + + expect(hasRole).toBe(true); + + role.state.setRoles([]); + }); + + it('should return false if no roles matched', async () => { + const hasRole = role.hasAny(['admin']); + + await flushPromises(); + + expect(hasRole).toBe(false); + }); + }); +}); diff --git a/src/composables/specs/useSession.spec.js b/src/composables/specs/useSession.spec.js new file mode 100644 index 000000000..789b149ec --- /dev/null +++ b/src/composables/specs/useSession.spec.js @@ -0,0 +1,211 @@ +import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'; +import { axios } from 'app/test/vitest/helper'; +import { useSession } from 'composables/useSession'; +import { useState } from 'composables/useState'; + +const session = useSession(); +const state = useState(); + +describe('session', () => { + describe('getToken / setToken', () => { + it('should return an empty string if no token is found in local or session storage', async () => { + const expectedToken = ''; + + const token = session.getToken(); + + expect(token).toEqual(expectedToken); + }); + + it('should return the token stored in local or session storage', async () => { + const expectedToken = 'myToken'; + const data = { + token: expectedToken, + keepLogin: false, + }; + session.setToken(data); + + const token = session.getToken(); + + expect(token).toEqual(expectedToken); + }); + }); + + describe('destroy', () => { + it('should remove the token from the local storage and set a blank user', async () => { + const previousUser = { + id: 999, + name: `T'Challa`, + nickname: 'Black Panther', + lang: 'en', + darkMode: false, + }; + const expectedUser = { + id: 0, + name: '', + nickname: '', + lang: '', + darkMode: null, + }; + let user = state.getUser(); + + localStorage.setItem('token', 'tokenToBeGone'); + state.setUser(previousUser); + + expect(localStorage.getItem('token')).toEqual('tokenToBeGone'); + expect(user.value).toEqual(previousUser); + + vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); + vi.spyOn(axios, 'get').mockResolvedValue({ data: true }); + await session.destroy(); + + user = state.getUser(); + expect(localStorage.getItem('token')).toBeNull(); + expect(user.value).toEqual(expectedUser); + }); + }); + + describe( + 'login', + () => { + const expectedUser = { + id: 999, + name: `T'Challa`, + nickname: 'Black Panther', + lang: 'en', + userConfig: { + darkMode: false, + }, + }; + const rolesData = [ + { + role: { + name: 'salesPerson', + }, + }, + { + role: { + name: 'admin', + }, + }, + ]; + beforeEach(() => { + vi.spyOn(axios, 'get').mockImplementation((url) => { + if (url === 'VnUsers/acls') return Promise.resolve({ data: [] }); + return Promise.resolve({ + data: { roles: rolesData, user: expectedUser }, + }); + }); + }); + + it('should fetch the user roles and then set token in the sessionStorage', async () => { + const expectedRoles = ['salesPerson', 'admin']; + const expectedToken = 'mySessionToken'; + const expectedTokenMultimedia = 'mySessionTokenMultimedia'; + const keepLogin = false; + + await session.login({ + token: expectedToken, + tokenMultimedia: expectedTokenMultimedia, + keepLogin, + }); + + const roles = state.getRoles(); + const localToken = localStorage.getItem('token'); + const sessionToken = sessionStorage.getItem('token'); + + expect(roles.value).toEqual(expectedRoles); + expect(localToken).toBeNull(); + expect(sessionToken).toEqual(expectedToken); + + await session.destroy(); // this clears token and user for any other test + }); + + it('should fetch the user roles and then set token in the localStorage', async () => { + const expectedRoles = ['salesPerson', 'admin']; + const expectedToken = 'myLocalToken'; + const expectedTokenMultimedia = 'myLocalTokenMultimedia'; + const keepLogin = true; + + await session.login({ + token: expectedToken, + tokenMultimedia: expectedTokenMultimedia, + keepLogin, + }); + + const roles = state.getRoles(); + const localToken = localStorage.getItem('token'); + const sessionToken = sessionStorage.getItem('token'); + + expect(roles.value).toEqual(expectedRoles); + expect(localToken).toEqual(expectedToken); + expect(sessionToken).toBeNull(); + + await session.destroy(); // this clears token and user for any other test + }); + }, + {} + ); + + describe('RenewToken', () => { + const expectedToken = 'myToken'; + const expectedTokenMultimedia = 'myTokenMultimedia'; + const currentDate = new Date(); + beforeAll(() => { + const tokenConfig = { + id: 1, + renewPeriod: 21600, + courtesyTime: 60, + renewInterval: 300, + }; + state.setTokenConfig(tokenConfig); + sessionStorage.setItem('renewPeriod', 1); + }); + it('NOT Should renewToken', async () => { + const data = { + token: expectedToken, + tokenMultimedia: expectedTokenMultimedia, + keepLogin: false, + ttl: 1, + created: Date.now(), + }; + session.setSession(data); + expect(sessionStorage.getItem('keepLogin')).toBeFalsy(); + expect(sessionStorage.getItem('created')).toBeDefined(); + expect(sessionStorage.getItem('ttl')).toEqual(1); + await session.checkValidity(); + expect(sessionStorage.getItem('token')).toEqual(expectedToken); + expect(sessionStorage.getItem('tokenMultimedia')).toEqual( + expectedTokenMultimedia + ); + }); + it('Should renewToken', async () => { + currentDate.setMinutes(currentDate.getMinutes() - 100); + const data = { + token: expectedToken, + tokenMultimedia: expectedTokenMultimedia, + keepLogin: false, + ttl: 1, + created: currentDate, + }; + session.setSession(data); + + vi.spyOn(axios, 'post') + .mockResolvedValueOnce({ + data: { id: '' }, + }) + .mockResolvedValueOnce({ + data: { + id: '', + }, + }); + expect(sessionStorage.getItem('keepLogin')).toBeFalsy(); + expect(sessionStorage.getItem('created')).toBeDefined(); + expect(sessionStorage.getItem('ttl')).toEqual(1); + await session.checkValidity(); + expect(sessionStorage.getItem('token')).not.toEqual(expectedToken); + expect(sessionStorage.getItem('tokenMultimedia')).not.toEqual( + expectedTokenMultimedia + ); + }); + }); +}); diff --git a/src/composables/specs/useTokenConfig.spec.js b/src/composables/specs/useTokenConfig.spec.js new file mode 100644 index 000000000..a25a4abb1 --- /dev/null +++ b/src/composables/specs/useTokenConfig.spec.js @@ -0,0 +1,31 @@ +import { vi, describe, expect, it } from 'vitest'; +import { axios, flushPromises } from 'app/test/vitest/helper'; +import { useTokenConfig } from 'composables/useTokenConfig'; +const tokenConfig = useTokenConfig(); + +describe('useTokenConfig', () => { + describe('fetch', () => { + it('should call setTokenConfig of the state with the expected data', async () => { + const data = { + id: 1, + renewPeriod: 21600, + courtesyTime: 60, + renewInterval: 300, + }; + vi.spyOn(axios, 'get').mockResolvedValueOnce({ + data, + }); + + vi.spyOn(tokenConfig.state, 'setTokenConfig'); + + tokenConfig.fetch(); + + await flushPromises(); + + expect(tokenConfig.state.setTokenConfig).toHaveBeenCalledWith(data); + + const renewPeriod = sessionStorage.getItem('renewPeriod'); + expect(renewPeriod).toEqual(data.renewPeriod); + }); + }); +}); diff --git a/src/pages/Claim/Card/specs/ClaimDescriptorMenu.spec.js b/src/pages/Claim/Card/specs/ClaimDescriptorMenu.spec.js new file mode 100644 index 000000000..b208f1704 --- /dev/null +++ b/src/pages/Claim/Card/specs/ClaimDescriptorMenu.spec.js @@ -0,0 +1,33 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue'; + +describe('ClaimDescriptorMenu', () => { + let vm; + beforeAll(() => { + vm = createWrapper(ClaimDescriptorMenu, { + propsData: { + claim: { + id: 1, + }, + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('remove()', () => { + it('should delete the claim', async () => { + vi.spyOn(axios, 'delete').mockResolvedValue({ data: true }); + vi.spyOn(vm.quasar, 'notify'); + + await vm.remove(); + + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ type: 'positive' }) + ); + }); + }); +}); diff --git a/src/pages/Claim/Card/specs/ClaimLines.spec.js b/src/pages/Claim/Card/specs/ClaimLines.spec.js new file mode 100644 index 000000000..2f2c0e298 --- /dev/null +++ b/src/pages/Claim/Card/specs/ClaimLines.spec.js @@ -0,0 +1,75 @@ +import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import ClaimLines from '/src/pages/Claim/Card/ClaimLines.vue'; + +describe('ClaimLines', () => { + let vm; + + beforeAll(() => { + vm = createWrapper(ClaimLines, { + global: { + stubs: ['FetchData', 'VnPaginate'], + mocks: { + fetch: vi.fn(), + }, + }, + }).vm; + }); + + beforeEach(() => { + vm.claim = { + id: 1, + ticketFk: 1, + }; + vm.store.data = [ + { + id: 1, + quantity: 10, + sale: { + id: 1, + discount: 0, + }, + }, + ]; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('updateDiscount()', () => { + it('should make a POST request to endpoint "updateDiscount"', async () => { + vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); + vi.spyOn(vm.quasar, 'notify'); + + const canceller = new AbortController(); + await vm.updateDiscount({ saleFk: 1, discount: 5, canceller }); + + const expectedData = { salesIds: [1], newDiscount: 5 }; + expect(axios.post).toHaveBeenCalledWith( + 'Tickets/1/updateDiscount', + expectedData, + { + signal: canceller.signal, + } + ); + }); + }); + + describe('onUpdateDiscount()', () => { + it('should make a POST request and then set the discount on the original row', async () => { + vi.spyOn(vm.quasar, 'notify'); + + vm.onUpdateDiscount({ discount: 5, rowIndex: 0 }); + const firstRow = vm.store.data[0]; + + expect(firstRow.sale.discount).toEqual(5); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ + message: 'Discount updated', + type: 'positive', + }) + ); + }); + }); +}); diff --git a/src/pages/Claim/Card/specs/ClaimLinesImport.spec.js b/src/pages/Claim/Card/specs/ClaimLinesImport.spec.js new file mode 100644 index 000000000..d93c96132 --- /dev/null +++ b/src/pages/Claim/Card/specs/ClaimLinesImport.spec.js @@ -0,0 +1,47 @@ +import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import ClaimLinesImport from 'pages/Claim/Card/ClaimLinesImport.vue'; + +describe('ClaimLinesImport', () => { + let vm; + + beforeAll(() => { + vm = createWrapper(ClaimLinesImport, { + global: { + stubs: ['FetchData'], + mocks: { + fetch: vi.fn(), + }, + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('importLines()', () => { + it('should make a POST request and then call to the quasar notify() method', async () => { + vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); + vi.spyOn(vm.quasar, 'notify'); + + vm.selected = [{ id: 1, saleFk: 1, claimFk: 1 }]; + + vm.route.params.id = 1; + + await vm.importLines(); + const expectedData = [{ saleFk: 1, claimFk: 1 }]; + + expect(axios.post).toHaveBeenCalledWith('ClaimBeginnings', expectedData, { + signal: expect.any(Object), + }); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ + message: 'Lines added to claim', + type: 'positive', + }) + ); + expect(vm.canceller).toEqual(null); + }); + }); +}); diff --git a/src/pages/Claim/Card/specs/ClaimPhoto.spec.js b/src/pages/Claim/Card/specs/ClaimPhoto.spec.js new file mode 100644 index 000000000..c38852af1 --- /dev/null +++ b/src/pages/Claim/Card/specs/ClaimPhoto.spec.js @@ -0,0 +1,114 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import ClaimPhoto from 'pages/Claim/Card/ClaimPhoto.vue'; + +describe('ClaimPhoto', () => { + let vm; + + const claimMock = { + claimDms: [ + { + dmsFk: 1, + dms: { + contentType: 'contentType', + }, + }, + ], + client: { + id: '1', + }, + }; + beforeAll(() => { + vm = createWrapper(ClaimPhoto, { + global: { + stubs: ['FetchData', 'vue-i18n'], + mocks: { + fetch: vi.fn(), + }, + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('deleteDms()', () => { + it('should delete dms and call quasar notify', async () => { + vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); + vi.spyOn(vm.quasar, 'notify'); + + await vm.deleteDms({ index: 0 }); + + expect(axios.post).toHaveBeenCalledWith( + `ClaimDms/${claimMock.claimDms[0].dmsFk}/removeFile` + ); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ type: 'positive' }) + ); + }); + }); + + describe('viewDeleteDms()', () => { + it('should call quasar dialog', async () => { + vi.spyOn(vm.quasar, 'dialog'); + + await vm.viewDeleteDms(1); + + expect(vm.quasar.dialog).toHaveBeenCalledWith( + expect.objectContaining({ + componentProps: { + title: 'This file will be deleted', + icon: 'delete', + data: { index: 1 }, + promise: vm.deleteDms + }, + }) + ); + }); + }); + + describe('setClaimDms()', () => { + it('should assign claimDms and client from data', async () => { + await vm.setClaimDms(claimMock); + + expect(vm.claimDms).toEqual([ + { + dmsFk: 1, + dms: { + contentType: 'contentType', + }, + isVideo: false, + url: '/api/Claims/1/downloadFile?access_token=', + }, + ]); + + expect(vm.client).toEqual(claimMock.client); + }); + }); + + describe('create()', () => { + it('should upload file and call quasar notify', async () => { + const files = [{ name: 'firstFile' }]; + + vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); + vi.spyOn(vm.quasar, 'notify'); + vi.spyOn(vm.claimDmsRef, 'fetch'); + + await vm.create(files); + + expect(axios.post).toHaveBeenCalledWith( + 'claims/1/uploadFile', + new FormData(), + expect.objectContaining({ + params: expect.objectContaining({ hasFile: false }), + }) + ); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ type: 'positive' }) + ); + + expect(vm.claimDmsRef.fetch).toHaveBeenCalledOnce(); + }); + }); +}); diff --git a/src/pages/Customer/Payments/specs/CustomerPayments.spec.js b/src/pages/Customer/Payments/specs/CustomerPayments.spec.js new file mode 100644 index 000000000..466a544b4 --- /dev/null +++ b/src/pages/Customer/Payments/specs/CustomerPayments.spec.js @@ -0,0 +1,38 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import CustomerPayments from 'src/pages/Customer/Payments/CustomerPayments.vue'; + +describe('CustomerPayments', () => { + let vm; + + beforeAll(() => { + vm = createWrapper(CustomerPayments, { + global: { + stubs: ['VnPaginate'], + mocks: { + fetch: vi.fn(), + }, + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('confirmTransaction()', () => { + it('should make a POST request and then call to quasar notify method', async () => { + vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); + vi.spyOn(vm.quasar, 'notify'); + + await vm.confirmTransaction({ id: 1 }); + + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ + message: 'Payment confirmed', + type: 'positive', + }) + ); + }); + }); +}); diff --git a/src/pages/Login/specs/Login.spec.js b/src/pages/Login/specs/Login.spec.js new file mode 100644 index 000000000..e90a8ee53 --- /dev/null +++ b/src/pages/Login/specs/Login.spec.js @@ -0,0 +1,49 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import Login from 'pages/Login/LoginMain.vue'; + +describe('Login', () => { + let vm; + beforeAll(() => { + vm = createWrapper(Login).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should successfully set the token into session', async () => { + const expectedUser = { + id: 999, + name: `T'Challa`, + nickname: 'Black Panther', + lang: 'en', + userConfig: { + darkMode: false, + }, + }; + vi.spyOn(axios, 'post').mockResolvedValueOnce({ data: { token: 'token' } }); + vi.spyOn(axios, 'get').mockImplementation((url) => { + if (url === 'VnUsers/acls') return Promise.resolve({ data: [] }); + return Promise.resolve({ + data: { + roles: [], + user: expectedUser, + multimediaToken: { id: 'multimediaToken' }, + }, + }); + }); + + expect(vm.session.getToken()).toEqual(''); + + await vm.onSubmit(); + + expect(vm.session.getToken()).toEqual('token'); + await vm.session.destroy(); + }); + + it('should not set the token into session if any error occurred', async () => { + vi.spyOn(axios, 'post').mockReturnValue({ data: null }); + await vm.onSubmit(); + }); +}); diff --git a/src/pages/Ticket/Card/specs/TicketBoxing.spec.js b/src/pages/Ticket/Card/specs/TicketBoxing.spec.js new file mode 100644 index 000000000..8fd62d8c2 --- /dev/null +++ b/src/pages/Ticket/Card/specs/TicketBoxing.spec.js @@ -0,0 +1,50 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import TicketBoxing from 'pages/Ticket/Card/TicketBoxing.vue'; + +// #4836 - Investigate how to test q-drawer outside +// q-layout or how to teleport q-drawer inside +describe('TicketBoxing', () => { + let vm; + beforeAll(() => { + vm = createWrapper(TicketBoxing).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('getVideoList()', () => { + it('should when response videoList use to list', async () => { + const expeditionId = 1; + const timed = { + min: 1, + max: 2, + }; + const videoList = ['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4']; + + vi.spyOn(axios, 'get').mockResolvedValue({ data: videoList }); + vi.spyOn(vm.quasar, 'notify'); + + await vm.getVideoList(expeditionId, timed); + + expect(vm.videoList.length).toEqual(videoList.length); + expect(vm.slide).toEqual(videoList.reverse()[0]); + }); + + it('should if not have video show notify', async () => { + const expeditionId = 1; + const timed = { + min: 1, + max: 2, + }; + + vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); + vi.spyOn(vm.quasar, 'notify'); + + await vm.getVideoList(expeditionId, timed); + + expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'negative' })); + }); + }); +}); diff --git a/src/pages/Ticket/specs/TicketAdvance.spec.js b/src/pages/Ticket/specs/TicketAdvance.spec.js new file mode 100644 index 000000000..ab1a47544 --- /dev/null +++ b/src/pages/Ticket/specs/TicketAdvance.spec.js @@ -0,0 +1,120 @@ +import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import TicketAdvance from 'pages/Ticket/TicketAdvance.vue'; +import { Notify } from 'quasar'; +import { nextTick } from 'vue'; + +describe('TicketAdvance', () => { + let wrapper; + let vm; + + beforeAll(() => { + vi.spyOn(axios, 'get').mockImplementation(() => ({ data: [] })); + wrapper = createWrapper(TicketAdvance); + vm = wrapper.vm; + vi.spyOn(vm.vnTableRef, 'reload').mockImplementation(() => vi.fn()); + vm.vnTableRef.value = { params: {} }; + }); + beforeEach(() => { + Notify.create = vi.fn(); + }); + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('requestComponentUpdate()', () => { + const mockTicket = { + futureId: 1, + futureClientFk: 1, + nickname: 'test', + futureAddressFk: 1, + futureAgencyModeFk: 1, + futureWarehouseFk: 1, + futureCompanyFk: 1, + landed: '2023-01-02', + zoneFk: 1, + }; + const mockParams = { + clientFk: 1, + nickname: 'test', + agencyModeFk: 1, + addressFk: 1, + zoneFk: 1, + warehouseFk: 1, + companyFk: 1, + landed: '2023-01-02', + shipped: '2023-01-01', + isDeleted: false, + isWithoutNegatives: false, + newTicket: undefined, + keepPrice: true, + }; + const queryResult = 'tickets/1/componentUpdate'; + + it('should return query and params when ticket has no landed', async () => { + vm.vnTableRef.params.dateToAdvance = '2023-01-01'; + await nextTick(); + + const mockLanded = { landed: '2023-01-02', zoneFk: 1 }; + vi.spyOn(vm, 'getLanded').mockResolvedValue(mockLanded); + + const { query, params } = await vm.requestComponentUpdate(mockTicket, false); + + expect(query).toBe(queryResult); + expect(params).toEqual(mockParams); + }); + + it('should return query and params when ticket has landed', async () => { + const { query, params } = await vm.requestComponentUpdate(mockTicket, false); + + expect(query).toBe(queryResult); + expect(params).toEqual(mockParams); + }); + }); + + describe('moveTicketsAdvance()', () => { + it('should move tickets and notify success', async () => { + const tickets = [ + { + id: 1, + futureId: 2, + futureShipped: '2023-01-01', + shipped: '2023-01-02', + workerFk: 1, + }, + { + id: 2, + futureId: 3, + futureShipped: '2023-01-01', + shipped: '2023-01-02', + workerFk: 1, + }, + ]; + vm.selectedTickets = tickets; + vi.spyOn(axios, 'post').mockResolvedValue({}); + await vm.moveTicketsAdvance(); + + expect(axios.post).toHaveBeenCalledOnce('Tickets/merge', { + tickets: [ + { + originId: 2, + destinationId: 1, + originShipped: '2023-01-01', + destinationShipped: '2023-01-02', + workerFk: 1, + }, + { + originId: 3, + destinationId: 2, + originShipped: '2023-01-01', + destinationShipped: '2023-01-02', + workerFk: 1, + }, + ], + }); + expect(vm.vnTableRef.reload).toHaveBeenCalled(); + expect(Notify.create).toHaveBeenCalled(); + expect(vm.selectedTickets).toEqual([]); + }); + }); +}); diff --git a/src/pages/Wagon/specs/WagonCreate.spec.js b/src/pages/Wagon/specs/WagonCreate.spec.js new file mode 100644 index 000000000..f195c183f --- /dev/null +++ b/src/pages/Wagon/specs/WagonCreate.spec.js @@ -0,0 +1,97 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import WagonCreate from 'pages/Wagon/WagonCreate.vue'; + +describe('WagonCreate', () => { + let vmEdit, vmCreate; + const entityId = 1; + + beforeAll(() => { + vmEdit = createWrapper(WagonCreate, { + propsData: { + id: entityId, + }, + }).vm; + vmCreate = createWrapper(WagonCreate).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('onSubmit()', () => { + it('should create a wagon', async () => { + vi.spyOn(axios, 'patch').mockResolvedValue({ data: true }); + vmCreate.wagon = { + label: 1234, + plate: 'MOCK PLATE', + volume: 50, + typeFk: 1, + }; + + await vmCreate.onSubmit(); + + expect(axios.patch).toHaveBeenCalledWith(`Wagons`, vmCreate.wagon); + }); + + it('should update a wagon', async () => { + vi.spyOn(axios, 'patch').mockResolvedValue({ data: true }); + vmEdit.wagon = { + id: entityId, + label: 1234, + plate: 'MOCK PLATE', + volume: 50, + typeFk: 1, + }; + + await vmEdit.onSubmit(); + + expect(axios.patch).toHaveBeenCalledWith(`Wagons`, vmEdit.wagon); + }); + }); + + describe('onReset()', () => { + it('should reset wagon if have id', async () => { + vmEdit.originalData = { + label: 1234, + plate: 'Original', + volume: 200, + typeFk: 1, + }; + vmEdit.wagon = { + label: 4321, + plate: 'Edited', + volume: 50, + typeFk: 2, + }; + + await vmEdit.onReset(); + + expect(vmEdit.wagon).toEqual(vmEdit.originalData); + }); + + it('should reset wagon if not have id', async () => { + vmCreate.wagon = { + label: 4321, + plate: 'Edited', + volume: 50, + typeFk: 2, + }; + + await vmCreate.onReset(); + + expect(vmCreate.wagon).toEqual({}); + }); + }); + + describe('fetch()', () => { + it('should fetch data', async () => { + vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); + + await vmEdit.fetch(); + + expect(axios.get).toHaveBeenCalledWith(`WagonTypes`); + expect(axios.get).toHaveBeenCalledWith(`Wagons/${entityId}`); + }); + }); +}); diff --git a/src/pages/Worker/Card/specs/WorkerNotificationsManager.spec.js b/src/pages/Worker/Card/specs/WorkerNotificationsManager.spec.js new file mode 100644 index 000000000..35ce91e61 --- /dev/null +++ b/src/pages/Worker/Card/specs/WorkerNotificationsManager.spec.js @@ -0,0 +1,33 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import WorkerNotificationsManager from 'src/pages/Worker/Card/WorkerNotificationsManager.vue'; +import { ref } from 'vue'; + +describe('WorkerNotificationsManager', () => { + let vm; + + beforeAll(() => { + vm = createWrapper(WorkerNotificationsManager, { + global: { + stubs: ['CrudModel'], + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('swapEntry()', () => { + it('should swap notification', async () => { + const from = ref(new Map()); + const to = ref(new Map()); + from.value.set(1, { notificationFk: 1 }); + to.value.set(2, { notificationFk: 2 }); + + await vm.swapEntry(from.value, to.value, 1); + expect(to.value.size).toBe(2); + expect(from.value.size).toBe(0); + }); + }); +}); diff --git a/src/stores/specs/useStateQueryStore.spec.js b/src/stores/specs/useStateQueryStore.spec.js new file mode 100644 index 000000000..ab3afb007 --- /dev/null +++ b/src/stores/specs/useStateQueryStore.spec.js @@ -0,0 +1,58 @@ +import { describe, expect, it, beforeEach, beforeAll } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; + +import { useStateQueryStore } from 'src/stores/useStateQueryStore'; + +describe('useStateQueryStore', () => { + beforeAll(() => { + createWrapper({}, {}); + }); + + const stateQueryStore = useStateQueryStore(); + const { add, isLoading, remove, reset } = useStateQueryStore(); + const firstQuery = { url: 'myQuery' }; + + function getQueries() { + return stateQueryStore.queries; + } + + beforeEach(() => { + reset(); + expect(getQueries().size).toBeFalsy(); + }); + + it('should add two queries', async () => { + expect(getQueries().size).toBeFalsy(); + add(firstQuery); + + expect(getQueries().size).toBeTruthy(); + expect(getQueries().has(firstQuery)).toBeTruthy(); + + add(); + expect(getQueries().size).toBe(2); + }); + + it('should add and remove loading state', async () => { + expect(isLoading().value).toBeFalsy(); + add(firstQuery); + expect(isLoading().value).toBeTruthy(); + remove(firstQuery); + expect(isLoading().value).toBeFalsy(); + }); + + it('should add and remove query', async () => { + const secondQuery = { ...firstQuery }; + const thirdQuery = { ...firstQuery }; + + add(firstQuery); + add(secondQuery); + + const beforeCount = getQueries().size; + add(thirdQuery); + expect(getQueries().has(thirdQuery)).toBeTruthy(); + + remove(thirdQuery); + expect(getQueries().has(thirdQuery)).toBeFalsy(); + expect(getQueries().size).toBe(beforeCount); + }); +}); From a09d0004959346fcdfa9325ce57b74fa897def8f Mon Sep 17 00:00:00 2001 From: provira Date: Thu, 19 Dec 2024 12:32:29 +0100 Subject: [PATCH 2/3] refactor: refs #8320 moved front tests to their respective sections --- test/vitest/__tests__/boot/axios.spec.js | 65 ------ .../__tests__/components/Leftmenu.spec.js | 94 -------- .../__tests__/components/Paginate.spec.js | 118 ---------- .../__tests__/components/VnTable.spec.js | 47 ---- .../components/common/CrudModel.spec.js | 120 ---------- .../common/VnChangePassword.spec.js | 70 ------ .../components/common/VnDiscount.spec.js | 28 --- .../components/common/VnLinkPhone.spec.js | 50 ----- .../__tests__/components/common/VnLog.spec.js | 134 ----------- .../__tests__/components/common/VnSms.spec.js | 25 --- .../components/common/VnSmsDialog.spec.js | 58 ----- .../composables/downloadFile.spec.js | 36 --- .../__tests__/composables/getExchange.spec.js | 45 ---- .../__tests__/composables/getTotal.spec.js | 55 ----- .../useAccountShortToStandard.spec.js | 9 - .../__tests__/composables/useAcl.spec.js | 110 --------- .../composables/useArrayData.spec.js | 98 -------- .../__tests__/composables/useRole.spec.js | 73 ------ .../__tests__/composables/useSession.spec.js | 211 ------------------ .../composables/useTokenConfig.spec.js | 31 --- .../pages/Claims/ClaimDescriptorMenu.spec.js | 33 --- .../__tests__/pages/Claims/ClaimLines.spec.js | 75 ------- .../pages/Claims/ClaimLinesImport.spec.js | 47 ---- .../__tests__/pages/Claims/ClaimPhoto.spec.js | 114 ---------- .../pages/Customer/CustomerPayments.spec.js | 38 ---- .../__tests__/pages/Login/Login.spec.js | 49 ---- .../pages/Tickets/TicketAdvance.spec.js | 120 ---------- .../pages/Tickets/TicketBoxing.spec.js | 50 ----- .../pages/Wagons/WagonCreate.spec.js | 97 -------- .../Worker/WorkerNotificationsManager.spec.js | 33 --- .../stores/useStateQueryStore.spec.js | 58 ----- vitest.config.js | 2 +- 32 files changed, 1 insertion(+), 2192 deletions(-) delete mode 100644 test/vitest/__tests__/boot/axios.spec.js delete mode 100644 test/vitest/__tests__/components/Leftmenu.spec.js delete mode 100644 test/vitest/__tests__/components/Paginate.spec.js delete mode 100644 test/vitest/__tests__/components/VnTable.spec.js delete mode 100644 test/vitest/__tests__/components/common/CrudModel.spec.js delete mode 100644 test/vitest/__tests__/components/common/VnChangePassword.spec.js delete mode 100644 test/vitest/__tests__/components/common/VnDiscount.spec.js delete mode 100644 test/vitest/__tests__/components/common/VnLinkPhone.spec.js delete mode 100644 test/vitest/__tests__/components/common/VnLog.spec.js delete mode 100644 test/vitest/__tests__/components/common/VnSms.spec.js delete mode 100644 test/vitest/__tests__/components/common/VnSmsDialog.spec.js delete mode 100644 test/vitest/__tests__/composables/downloadFile.spec.js delete mode 100644 test/vitest/__tests__/composables/getExchange.spec.js delete mode 100644 test/vitest/__tests__/composables/getTotal.spec.js delete mode 100644 test/vitest/__tests__/composables/useAccountShortToStandard.spec.js delete mode 100644 test/vitest/__tests__/composables/useAcl.spec.js delete mode 100644 test/vitest/__tests__/composables/useArrayData.spec.js delete mode 100644 test/vitest/__tests__/composables/useRole.spec.js delete mode 100644 test/vitest/__tests__/composables/useSession.spec.js delete mode 100644 test/vitest/__tests__/composables/useTokenConfig.spec.js delete mode 100644 test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js delete mode 100644 test/vitest/__tests__/pages/Claims/ClaimLines.spec.js delete mode 100644 test/vitest/__tests__/pages/Claims/ClaimLinesImport.spec.js delete mode 100644 test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js delete mode 100644 test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js delete mode 100644 test/vitest/__tests__/pages/Login/Login.spec.js delete mode 100644 test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js delete mode 100644 test/vitest/__tests__/pages/Tickets/TicketBoxing.spec.js delete mode 100644 test/vitest/__tests__/pages/Wagons/WagonCreate.spec.js delete mode 100644 test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js delete mode 100644 test/vitest/__tests__/stores/useStateQueryStore.spec.js diff --git a/test/vitest/__tests__/boot/axios.spec.js b/test/vitest/__tests__/boot/axios.spec.js deleted file mode 100644 index b3b6f98c6..000000000 --- a/test/vitest/__tests__/boot/axios.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -import { onRequest, onResponseError } from 'src/boot/axios'; -import { describe, expect, it, vi } from 'vitest'; - -vi.mock('src/composables/useSession', () => ({ - useSession: () => ({ - getToken: () => 'DEFAULT_TOKEN', - isLoggedIn: () => vi.fn(), - destroy: () => vi.fn(), - }), -})); - -vi.mock('src/stores/useStateQueryStore', () => ({ - useStateQueryStore: () => ({ - add: () => vi.fn(), - remove: () => vi.fn(), - }), -})); - -describe('Axios boot', () => { - describe('onRequest()', async () => { - it('should set the "Authorization" property on the headers', async () => { - const config = { headers: {} }; - - const resultConfig = onRequest(config); - - expect(resultConfig).toEqual( - expect.objectContaining({ - headers: { - 'Accept-Language': 'en-US', - Authorization: 'DEFAULT_TOKEN', - }, - }) - ); - }); - }); - - describe('onResponseError()', async () => { - it('should call to the Notify plugin with a message error for an status code "500"', async () => { - const error = { - response: { - status: 500, - }, - }; - - const result = onResponseError(error); - expect(result).rejects.toEqual(expect.objectContaining(error)); - }); - - it('should call to the Notify plugin with a message from the response property', async () => { - const error = { - response: { - status: 401, - data: { - error: { - message: 'Invalid user or password', - }, - }, - }, - }; - - const result = onResponseError(error); - expect(result).rejects.toEqual(expect.objectContaining(error)); - }); - }); -}); diff --git a/test/vitest/__tests__/components/Leftmenu.spec.js b/test/vitest/__tests__/components/Leftmenu.spec.js deleted file mode 100644 index 10d9d66fb..000000000 --- a/test/vitest/__tests__/components/Leftmenu.spec.js +++ /dev/null @@ -1,94 +0,0 @@ -import { vi, describe, expect, it, beforeAll } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import Leftmenu from 'components/LeftMenu.vue'; - -import { useNavigationStore } from 'src/stores/useNavigationStore'; - -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', - children: [ - { - path: 'list', - name: 'CustomerList', - meta: { - title: 'list', - icon: 'view_list', - }, - }, - { - path: 'create', - name: 'CustomerCreate', - meta: { - title: 'createCustomer', - icon: 'vn:addperson', - }, - }, - ], - }, - ], - }, - ], -})); - -describe('Leftmenu', () => { - let vm; - let navigation; - beforeAll(() => { - vi.spyOn(axios, 'get').mockResolvedValue({ - data: [], - }); - - vm = createWrapper(Leftmenu, { - propsData: { - source: 'main', - }, - }).vm; - - 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', - }, - ], - }); - }); - - 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)); - }); -}); diff --git a/test/vitest/__tests__/components/Paginate.spec.js b/test/vitest/__tests__/components/Paginate.spec.js deleted file mode 100644 index a67dfcdc6..000000000 --- a/test/vitest/__tests__/components/Paginate.spec.js +++ /dev/null @@ -1,118 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; - -describe('VnPaginate', () => { - const expectedUrl = '/api/customers'; - const defaultData = [ - { id: 1, name: 'Tony Stark' }, - { id: 2, name: 'Jessica Jones' }, - { id: 3, name: 'Bruce Wayne' }, - ]; - let vm; - beforeAll(() => { - const options = { - attrs: { - url: expectedUrl, - dataKey: 'CustomerList', - order: 'id DESC', - limit: 3, - }, - }; - vm = createWrapper(VnPaginate, options).vm; - }); - - afterEach(() => { - vm.store.data = []; - vm.store.skip = 0; - vm.pagination.page = 1; - vm.hasMoreData = true; - }); - - describe('paginate()', () => { - it('should call to the paginate() method and set the data on the rows property', async () => { - vi.spyOn(vm.arrayData, 'loadMore'); - vm.store.data = defaultData; - - await vm.paginate(); - - expect(vm.arrayData.loadMore).toHaveBeenCalledWith(); - expect(vm.store.data.length).toEqual(3); - }); - - it('should call to the paginate() method and then call it again to paginate', async () => { - vi.spyOn(axios, 'get').mockResolvedValue({ - data: defaultData, - }); - vm.store.hasMoreData = true; - await vm.$nextTick(); - - vm.store.data = defaultData; - - await vm.paginate(); - - expect(vm.store.skip).toEqual(3); - expect(vm.store.data.length).toEqual(6); - - vi.spyOn(axios, 'get').mockResolvedValue({ - data: [ - { id: 4, name: 'Peter Parker' }, - { id: 5, name: 'Clark Kent' }, - { id: 6, name: 'Barry Allen' }, - ], - }); - await vm.paginate(); - - expect(vm.store.skip).toEqual(6); - expect(vm.store.data.length).toEqual(9); - }); - }); - - describe('onLoad()', () => { - it('should call to the done() callback and not increment the pagination', async () => { - const index = 1; - const done = vi.fn(); - - await vm.onLoad(index, done); - - expect(vm.pagination.page).toEqual(1); - expect(done).toHaveBeenCalledWith(false); - }); - - it('should increment the pagination and then call to the done() callback', async () => { - expect(vm.pagination.page).toEqual(1); - - const index = 1; - const done = vi.fn(); - vm.store.data = defaultData; - - await vm.onLoad(index, done); - - expect(vm.pagination.page).toEqual(2); - expect(done).toHaveBeenCalledWith(false); - }); - - it('should call to the done() callback with true as argument to finish pagination', async () => { - vi.spyOn(axios, 'get').mockResolvedValue({ - data: [ - { id: 1, name: 'Tony Stark' }, - { id: 2, name: 'Jessica Jones' }, - ], - }); - - vm.store.data = defaultData; - - expect(vm.pagination.page).toEqual(1); - - const index = 1; - const done = vi.fn(); - - vm.hasMoreData = false; - - await vm.onLoad(index, done); - - expect(vm.pagination.page).toEqual(2); - expect(done).toHaveBeenCalledWith(false); - }); - }); -}); diff --git a/test/vitest/__tests__/components/VnTable.spec.js b/test/vitest/__tests__/components/VnTable.spec.js deleted file mode 100644 index 162df727d..000000000 --- a/test/vitest/__tests__/components/VnTable.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, expect, it, beforeAll, beforeEach } from 'vitest'; -import { createWrapper } from 'app/test/vitest/helper'; -import VnTable from 'src/components/VnTable/VnTable.vue'; - -describe('VnTable', () => { - let wrapper; - let vm; - - beforeAll(() => { - wrapper = createWrapper(VnTable, { - propsData: { - columns: [], - }, - }); - vm = wrapper.vm; - }); - - beforeEach(() => (vm.selected = [])); - - describe('handleSelection()', () => { - const rows = [{ $index: 0 }, { $index: 1 }, { $index: 2 }]; - const selectedRows = [{ $index: 1 }]; - it('should add rows to selected when shift key is pressed and rows are added except last one', () => { - vm.handleSelection( - { evt: { shiftKey: true }, added: true, rows: selectedRows }, - rows - ); - expect(vm.selected).toEqual([{ $index: 0 }]); - }); - - it('should not add rows to selected when shift key is not pressed', () => { - vm.handleSelection( - { evt: { shiftKey: false }, added: true, rows: selectedRows }, - rows - ); - expect(vm.selected).toEqual([]); - }); - - it('should not add rows to selected when rows are not added', () => { - vm.handleSelection( - { evt: { shiftKey: true }, added: false, rows: selectedRows }, - rows - ); - expect(vm.selected).toEqual([]); - }); - }); -}); diff --git a/test/vitest/__tests__/components/common/CrudModel.spec.js b/test/vitest/__tests__/components/common/CrudModel.spec.js deleted file mode 100644 index 6ce93e59c..000000000 --- a/test/vitest/__tests__/components/common/CrudModel.spec.js +++ /dev/null @@ -1,120 +0,0 @@ -import { createWrapper } from 'app/test/vitest/helper'; -import CrudModel from 'components/CrudModel.vue'; -import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest'; - -describe('CrudModel', () => { - let vm; - beforeAll(() => { - vm = createWrapper(CrudModel, { - global: { - stubs: [ - 'vnPaginate', - 'useState', - 'arrayData', - 'useStateStore', - 'vue-i18n', - ], - mocks: { - validate: vi.fn(), - }, - }, - propsData: { - dataRequired: { - fk: 1, - }, - dataKey: 'crudModelKey', - model: 'crudModel', - url: 'crudModelUrl', - }, - }).vm; - }); - - beforeEach(() => { - vm.fetch([]); - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('insert()', () => { - it('should new element in list with index 0 if formData not has data', () => { - vm.insert(); - - expect(vm.formData.length).toEqual(1); - expect(vm.formData[0].fk).toEqual(1); - expect(vm.formData[0].$index).toEqual(0); - }); - }); - - describe('getChanges()', () => { - it('should return correct updates and creates', async () => { - vm.fetch([ - { id: 1, name: 'New name one' }, - { id: 2, name: 'New name two' }, - { id: 3, name: 'Bruce Wayne' }, - ]); - - vm.originalData = [ - { id: 1, name: 'Tony Starks' }, - { id: 2, name: 'Jessica Jones' }, - { id: 3, name: 'Bruce Wayne' }, - ]; - - vm.insert(); - const result = vm.getChanges(); - - const expected = { - creates: [ - { - $index: 3, - fk: 1, - }, - ], - updates: [ - { - data: { - name: 'New name one', - }, - where: { - id: 1, - }, - }, - { - data: { - name: 'New name two', - }, - where: { - id: 2, - }, - }, - ], - }; - - expect(result).toEqual(expected); - }); - }); - - describe('getDifferences()', () => { - it('should return the differences between two objects', async () => { - const obj1 = { - a: 1, - b: 2, - c: 3, - }; - const obj2 = { - a: null, - b: 4, - d: 5, - }; - - const result = vm.getDifferences(obj1, obj2); - - expect(result).toEqual({ - a: null, - b: 4, - d: 5, - }); - }); - }); -}); diff --git a/test/vitest/__tests__/components/common/VnChangePassword.spec.js b/test/vitest/__tests__/components/common/VnChangePassword.spec.js deleted file mode 100644 index f5a967bb5..000000000 --- a/test/vitest/__tests__/components/common/VnChangePassword.spec.js +++ /dev/null @@ -1,70 +0,0 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; -import VnChangePassword from 'src/components/common/VnChangePassword.vue'; -import { vi, beforeEach, afterEach, beforeAll, describe, expect, it } from 'vitest'; -import { Notify } from 'quasar'; - -describe('VnSmsDialog', () => { - let vm; - - beforeAll(() => { - vi.spyOn(axios, 'get').mockResolvedValue({ - data: [], - }); - vm = createWrapper(VnChangePassword, { - propsData: { - submitFn: vi.fn(), - }, - }).vm; - }); - - beforeEach(() => { - Notify.create = vi.fn(); - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - it('should notify when new password is empty', async () => { - vm.passwords.newPassword = ''; - vm.passwords.repeatPassword = 'password'; - - await vm.validate(); - expect(Notify.create).toHaveBeenCalledWith( - expect.objectContaining({ - message: 'You must enter a new password', - type: 'negative', - }) - ); - }); - - it("should notify when passwords don't match", async () => { - vm.passwords.newPassword = 'password1'; - vm.passwords.repeatPassword = 'password2'; - await vm.validate(); - expect(Notify.create).toHaveBeenCalledWith( - expect.objectContaining({ - message: `Passwords don't match`, - type: 'negative', - }) - ); - }); - - describe('if passwords match', () => { - it('should call submitFn and emit password', async () => { - vm.passwords.newPassword = 'password'; - vm.passwords.repeatPassword = 'password'; - await vm.validate(); - expect(vm.props.submitFn).toHaveBeenCalledWith('password', undefined); - }); - - it('should call submitFn and emit password and old password', async () => { - vm.passwords.newPassword = 'password'; - vm.passwords.repeatPassword = 'password'; - vm.passwords.oldPassword = 'oldPassword'; - - await vm.validate(); - expect(vm.props.submitFn).toHaveBeenCalledWith('password', 'oldPassword'); - }); - }); -}); diff --git a/test/vitest/__tests__/components/common/VnDiscount.spec.js b/test/vitest/__tests__/components/common/VnDiscount.spec.js deleted file mode 100644 index 5d5be61ac..000000000 --- a/test/vitest/__tests__/components/common/VnDiscount.spec.js +++ /dev/null @@ -1,28 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper } from 'app/test/vitest/helper'; -import VnDiscount from 'components/common/vnDiscount.vue'; - -describe('VnDiscount', () => { - let vm; - - beforeAll(() => { - vm = createWrapper(VnDiscount, { - props: { - data: {}, - price: 100, - quantity: 2, - discount: 10, - } - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('total', () => { - it('should calculate total correctly', () => { - expect(vm.total).toBe(180); - }); - }); -}); \ No newline at end of file diff --git a/test/vitest/__tests__/components/common/VnLinkPhone.spec.js b/test/vitest/__tests__/components/common/VnLinkPhone.spec.js deleted file mode 100644 index a34ef90a5..000000000 --- a/test/vitest/__tests__/components/common/VnLinkPhone.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { describe, it, expect, beforeAll, vi } from 'vitest'; -import { axios } from 'app/test/vitest/helper'; -import parsePhone from 'src/filters/parsePhone'; - -describe('parsePhone filter', () => { - beforeAll(async () => { - vi.spyOn(axios, 'get').mockReturnValue({ data: { prefix: '34' } }); - }); - - it('no phone', async () => { - const phone = await parsePhone(null, '34'); - expect(phone).toBe(undefined); - }); - - it("adds prefix +34 if it doesn't have one", async () => { - const phone = await parsePhone('123456789', '34'); - expect(phone).toBe('34123456789'); - }); - - it('maintains prefix +34 if it is already correct', async () => { - const phone = await parsePhone('+34123456789', '34'); - expect(phone).toBe('34123456789'); - }); - - it('converts prefix 0034 to +34', async () => { - const phone = await parsePhone('0034123456789', '34'); - expect(phone).toBe('34123456789'); - }); - - it('converts prefix 34 without symbol to +34', async () => { - const phone = await parsePhone('34123456789', '34'); - expect(phone).toBe('34123456789'); - }); - - it('replaces incorrect prefix with the correct one', async () => { - const phone = await parsePhone('+44123456789', '34'); - expect(phone).toBe('44123456789'); - }); - - it('adds default prefix on error', async () => { - vi.spyOn(axios, 'get').mockImplementation((url) => { - if (url.includes('Prefixes')) - return Promise.reject(new Error('Network error')); - else if (url.includes('PbxConfigs')) - return Promise.resolve({ data: { defaultPrefix: '39' } }); - }); - const phone = await parsePhone('123456789', '34'); - expect(phone).toBe('39123456789'); - }); -}); diff --git a/test/vitest/__tests__/components/common/VnLog.spec.js b/test/vitest/__tests__/components/common/VnLog.spec.js deleted file mode 100644 index 53d2732a0..000000000 --- a/test/vitest/__tests__/components/common/VnLog.spec.js +++ /dev/null @@ -1,134 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import VnLog from 'src/components/common/VnLog.vue'; - -describe('VnLog', () => { - let vm; - const fakeLogTreeData = [ - { - id: 2, - originFk: 1, - userFk: 18, - action: 'update', - changedModel: 'ClaimObservation', - oldInstance: {}, - newInstance: { - claimFk: 1, - text: 'Waiting for customer', - }, - creationDate: '2023-09-18T12:25:34.000Z', - changedModelId: '1', - changedModelValue: null, - description: null, - user: { - id: 18, - name: 'salesPerson', - nickname: 'salesPersonNick', - image: '4fa3ada0-3ac4-11eb-9ab8-27f6fc3b85fd', - worker: { - id: 18, - userFk: 18, - }, - }, - }, - { - id: 1, - originFk: 1, - userFk: 18, - action: 'update', - changedModel: 'Claim', - oldInstance: { - pickup: null, - }, - newInstance: { - pickup: 'agency', - }, - creationDate: '2023-09-18T12:25:34.000Z', - changedModelId: '1', - changedModelValue: null, - description: null, - user: { - id: 18, - name: 'salesPerson', - nickname: 'salesPersonNick', - image: '4fa3ada0-3ac4-11eb-9ab8-27f6fc3b85fd', - worker: { - id: 18, - userFk: 18, - }, - }, - }, - ]; - const mockValidations = { - Claim: { - locale: { - name: 'reclamación', - }, - }, - ClaimObservation: { - locale: { - name: 'observación', - }, - }, - ClaimDms: { - locale: { - name: 'documento', - }, - }, - ClaimBeginning: { - locale: { - name: 'comienzo', - }, - }, - }; - - beforeAll(async () => { - axios.get.mockImplementation(() => { - return { data: fakeLogTreeData }; - }); - - vm = createWrapper(VnLog, { - global: { - stubs: [], - mocks: {}, - }, - propsData: { - model: 'Claim', - }, - }).vm; - vm.validations = mockValidations; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - it('should correctly set logTree', async () => { - vm.logTree = vm.getLogTree(fakeLogTreeData); - expect(vm.logTree[0].originFk).toEqual(1); - expect(vm.logTree[0].logs[0].user.name).toEqual('salesPerson'); - }); - - it('should correctly set the selectedFilters when filtering', () => { - vm.searchInput = '1'; - vm.userSelect = '21'; - vm.checkboxOptions.insert.selected = true; - vm.checkboxOptions.update.selected = true; - - vm.selectFilter('search'); - vm.selectFilter('userSelect'); - - expect(vm.selectedFilters.changedModelId).toEqual('1'); - expect(vm.selectedFilters.userFk).toEqual('21'); - expect(vm.selectedFilters.action).toEqual({ inq: ['insert', 'update'] }); - }); - - it('should correctly set the date from', () => { - vm.dateFrom = '18-09-2023'; - vm.selectFilter('date', 'from'); - expect(vm.selectedFilters.creationDate.between).toEqual([ - new Date('2023-09-18T00:00:00.000Z'), - new Date('2023-09-18T21:59:59.999Z'), - ]); - }); -}); diff --git a/test/vitest/__tests__/components/common/VnSms.spec.js b/test/vitest/__tests__/components/common/VnSms.spec.js deleted file mode 100644 index e0f8c1868..000000000 --- a/test/vitest/__tests__/components/common/VnSms.spec.js +++ /dev/null @@ -1,25 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import VnSms from 'src/components/ui/VnSms.vue'; - -describe('VnSms', () => { - let vm; - - beforeAll(() => { - vm = createWrapper(VnSms, { - global: { - stubs: ['VnPaginate'], - mocks: {}, - }, - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - it('should format number correctly', () => { - const formattedNumber = vm.formatNumber('123456789012'); - expect(formattedNumber).toBe('1234 56789012'); - }); -}); diff --git a/test/vitest/__tests__/components/common/VnSmsDialog.spec.js b/test/vitest/__tests__/components/common/VnSmsDialog.spec.js deleted file mode 100644 index 0b3473982..000000000 --- a/test/vitest/__tests__/components/common/VnSmsDialog.spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import { createWrapper } from 'app/test/vitest/helper'; -import VnSmsDialog from 'components/common/VnSmsDialog.vue'; -import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest'; - - -describe('VnSmsDialog', () => { - let vm; - const orderId = 1; - const shipped = new Date(); - const phone = '012345678'; - const promise = (response) => {return response;}; - const template = 'minAmount'; - const locale = 'en'; - - beforeAll(() => { - vm = createWrapper(VnSmsDialog, { - propsData: { - data: { - orderId, - shipped - }, - template, - locale, - phone, - promise - } - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('updateMessage()', () => { - it('should update the message value with the correct template and parameters', () => { - vm.updateMessage(); - - expect(vm.message).toEqual(`A minimum amount of 50€ (VAT excluded) is required for your order ${orderId} of ${shipped} to receive it without additional shipping costs.`); - }); - }); - - describe('send()', async () => { - it('should send the message', async () => { - vi.spyOn(vm.props, 'promise'); - vm.message = 'Example message'; - const response = { - orderId, - shipped, - destination: phone, - message: vm.message - }; - await vm.send(); - - expect(vm.isLoading).toEqual(false); - expect(vm.props.promise).toHaveBeenCalledWith(response); - }); - }); -}); diff --git a/test/vitest/__tests__/composables/downloadFile.spec.js b/test/vitest/__tests__/composables/downloadFile.spec.js deleted file mode 100644 index f53b56b3e..000000000 --- a/test/vitest/__tests__/composables/downloadFile.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; -import { axios } from 'app/test/vitest/helper'; -import { downloadFile } from 'src/composables/downloadFile'; -import { useSession } from 'src/composables/useSession'; -const session = useSession(); -const token = session.getToken(); - -describe('downloadFile', () => { - const baseUrl = 'http://localhost:9000'; - let defaulCreateObjectURL; - - beforeAll(() => { - defaulCreateObjectURL = window.URL.createObjectURL; - window.URL.createObjectURL = vi.fn(() => 'blob:http://localhost:9000/blob-id'); - }); - - afterAll(() => (window.URL.createObjectURL = defaulCreateObjectURL)); - - it('should open a new window to download the file', async () => { - const res = { - data: new Blob(['file content'], { type: 'application/octet-stream' }), - headers: { 'content-disposition': 'attachment; filename="test-file.txt"' }, - }; - vi.spyOn(axios, 'get').mockImplementation((url) => { - if (url == 'Urls/getUrl') return Promise.resolve({ data: baseUrl }); - else if (url.includes('downloadFile')) return Promise.resolve(res); - }); - - await downloadFile(1); - - expect(axios.get).toHaveBeenCalledWith( - `${baseUrl}/api/dms/1/downloadFile?access_token=${token}`, - { responseType: 'blob' } - ); - }); -}); diff --git a/test/vitest/__tests__/composables/getExchange.spec.js b/test/vitest/__tests__/composables/getExchange.spec.js deleted file mode 100644 index dba31458e..000000000 --- a/test/vitest/__tests__/composables/getExchange.spec.js +++ /dev/null @@ -1,45 +0,0 @@ -import { describe, expect, it, vi } from 'vitest'; -import axios from 'axios'; -import { getExchange } from 'src/composables/getExchange'; - -vi.mock('axios'); - -describe('getExchange()', () => { - it('should return the correct exchange rate', async () => { - axios.get.mockResolvedValue({ - data: { value: 1.2 }, - }); - - const amount = 100; - const currencyFk = 1; - const dated = '2023-01-01'; - const result = await getExchange(amount, currencyFk, dated); - - expect(result).toBe('83.33'); - }); - - it('should return the correct exchange rate with custom decimal places', async () => { - axios.get.mockResolvedValue({ - data: { value: 1.2 }, - }); - - const amount = 100; - const currencyFk = 1; - const dated = '2023-01-01'; - const decimalPlaces = 3; - const result = await getExchange(amount, currencyFk, dated, decimalPlaces); - - expect(result).toBe('83.333'); - }); - - it('should return null if the API call fails', async () => { - axios.get.mockRejectedValue(new Error('Network error')); - - const amount = 100; - const currencyFk = 1; - const dated = '2023-01-01'; - const result = await getExchange(amount, currencyFk, dated); - - expect(result).toBeNull(); - }); -}); diff --git a/test/vitest/__tests__/composables/getTotal.spec.js b/test/vitest/__tests__/composables/getTotal.spec.js deleted file mode 100644 index 789e3fbcf..000000000 --- a/test/vitest/__tests__/composables/getTotal.spec.js +++ /dev/null @@ -1,55 +0,0 @@ -import { vi, describe, expect, it } from 'vitest'; -import { getTotal } from 'src/composables/getTotal'; - -vi.mock('src/filters', () => ({ - toCurrency: vi.fn((value, currency) => `${currency} ${value.toFixed(2)}`), -})); - -describe('getTotal()', () => { - const rows = [ - { amount: 10.5, tax: 2.1 }, - { amount: 20.75, tax: 3.25 }, - { amount: 30.25, tax: 4.75 }, - ]; - - it('should calculate the total for a given key', () => { - const total = getTotal(rows, 'amount'); - expect(total).toBe('61.50'); - }); - - it('should calculate the total with a callback function', () => { - const total = getTotal(rows, null, { cb: (row) => row.amount + row.tax }); - expect(total).toBe('71.60'); - }); - - it('should format the total as currency', () => { - const total = getTotal(rows, 'amount', { currency: 'USD' }); - expect(total).toBe('USD 61.50'); - }); - - it('should format the total as currency with default currency', () => { - const total = getTotal(rows, 'amount', { currency: 'default' }); - expect(total).toBe('undefined 61.50'); - }); - - it('should calculate the total with integer formatting', () => { - const total = getTotal(rows, 'amount', { decimalPlaces: 0 }); - expect(total).toBe('62'); - }); - - it('should calculate the total with custom decimal places', () => { - const total = getTotal(rows, 'amount', { decimalPlaces: 1 }); - expect(total).toBe('61.5'); - }); - - it('should handle rows with missing keys', () => { - const rowsWithMissingKeys = [{ amount: 10.5 }, { amount: 20.75 }, {}]; - const total = getTotal(rowsWithMissingKeys, 'amount'); - expect(total).toBe('31.25'); - }); - - it('should handle empty rows', () => { - const total = getTotal([], 'amount'); - expect(total).toBe('0.00'); - }); -}); diff --git a/test/vitest/__tests__/composables/useAccountShortToStandard.spec.js b/test/vitest/__tests__/composables/useAccountShortToStandard.spec.js deleted file mode 100644 index d24585812..000000000 --- a/test/vitest/__tests__/composables/useAccountShortToStandard.spec.js +++ /dev/null @@ -1,9 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard'; - -describe('useAccountShortToStandard()', () => { - it('should pad the decimal part with zeros for short numbers', () => { - expect(useAccountShortToStandard('123.45')).toBe('1230000045'); - expect(useAccountShortToStandard('123.')).toBe('1230000000'); - }); -}); diff --git a/test/vitest/__tests__/composables/useAcl.spec.js b/test/vitest/__tests__/composables/useAcl.spec.js deleted file mode 100644 index 6cb29984c..000000000 --- a/test/vitest/__tests__/composables/useAcl.spec.js +++ /dev/null @@ -1,110 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; -import { useAcl } from 'src/composables/useAcl'; - -describe('useAcl', () => { - const acl = useAcl(); - const mockAcls = [ - { - model: 'Address', - property: '*', - accessType: '*', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: 'employee', - }, - { - model: 'Worker', - property: 'holidays', - accessType: 'READ', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: 'employee', - }, - { - model: 'Url', - property: 'getByUser', - accessType: 'READ', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: '$everyone', - }, - { - model: 'TpvTransaction', - property: 'start', - accessType: 'WRITE', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: '$authenticated', - }, - ]; - - beforeAll(async () => { - vi.spyOn(axios, 'get').mockResolvedValue({ data: mockAcls }); - await acl.fetch(); - }); - - afterAll(async () => await flushPromises()); - - describe('hasAny', () => { - it('should return false if no roles matched', async () => { - expect( - acl.hasAny([ - { model: 'Worker', props: 'updateAttributes', accessType: 'WRITE' }, - ]) - ).toBeFalsy(); - }); - - it('should return false if no roles matched', async () => { - expect( - acl.hasAny([{ model: 'Worker', props: 'holidays', accessType: 'READ' }]) - ).toBeTruthy(); - }); - - describe('*', () => { - it('should return true if an acl matched', async () => { - expect( - acl.hasAny([{ model: 'Address', props: '*', accessType: 'WRITE' }]) - ).toBeTruthy(); - }); - - it('should return false if no acls matched', async () => { - expect( - acl.hasAny([{ model: 'Worker', props: '*', accessType: 'READ' }]) - ).toBeFalsy(); - }); - }); - - describe('$authenticated', () => { - it('should return false if no acls matched', async () => { - expect( - acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: '*' }]) - ).toBeFalsy(); - }); - - it('should return true if an acl matched', async () => { - expect( - acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: 'READ' }]) - ).toBeTruthy(); - }); - }); - - describe('$everyone', () => { - it('should return false if no acls matched', async () => { - expect( - acl.hasAny([ - { model: 'TpvTransaction', props: 'start', accessType: 'READ' }, - ]) - ).toBeFalsy(); - }); - - it('should return false if an acl matched', async () => { - expect( - acl.hasAny([ - { model: 'TpvTransaction', props: 'start', accessType: 'WRITE' }, - ]) - ).toBeTruthy(); - }); - }); - }); -}); diff --git a/test/vitest/__tests__/composables/useArrayData.spec.js b/test/vitest/__tests__/composables/useArrayData.spec.js deleted file mode 100644 index d4c5d0949..000000000 --- a/test/vitest/__tests__/composables/useArrayData.spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; -import { useArrayData } from 'composables/useArrayData'; -import { useRouter } from 'vue-router'; -import * as vueRouter from 'vue-router'; - -describe('useArrayData', () => { - const filter = '{"limit":20,"skip":0}'; - const params = { supplierFk: 2 }; - beforeEach(() => { - vi.spyOn(useRouter(), 'replace'); - vi.spyOn(useRouter(), 'push'); - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - it('should fetch and repalce url with new params', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] }); - - const arrayData = useArrayData('ArrayData', { url: 'mockUrl' }); - - arrayData.store.userParams = params; - arrayData.fetch({}); - - await flushPromises(); - const routerReplace = useRouter().replace.mock.calls[0][0]; - - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, - }); - expect(routerReplace.path).toEqual('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 }] }); - - 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/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(); - }); -}); diff --git a/test/vitest/__tests__/composables/useRole.spec.js b/test/vitest/__tests__/composables/useRole.spec.js deleted file mode 100644 index d0bca5342..000000000 --- a/test/vitest/__tests__/composables/useRole.spec.js +++ /dev/null @@ -1,73 +0,0 @@ -import { vi, describe, expect, it } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; -import { useRole } from 'composables/useRole'; -const role = useRole(); - -describe('useRole', () => { - describe('fetch', () => { - it('should call setUser and setRoles of the state with the expected data', async () => { - const rolesData = [ - { - role: { - name: 'salesPerson', - }, - }, - { - role: { - name: 'admin', - }, - }, - ]; - const fetchedUser = { - id: 999, - name: `T'Challa`, - nickname: 'Black Panther', - lang: 'en', - }; - const expectedUser = { - id: 999, - name: `T'Challa`, - nickname: 'Black Panther', - lang: 'en', - }; - const expectedRoles = ['salesPerson', 'admin']; - vi.spyOn(axios, 'get') - .mockResolvedValueOnce({ - data: { roles: rolesData, user: fetchedUser }, - }) - - vi.spyOn(role.state, 'setUser'); - vi.spyOn(role.state, 'setRoles'); - - role.fetch(); - - await flushPromises(); - - expect(role.state.setUser).toHaveBeenCalledWith(expectedUser); - expect(role.state.setRoles).toHaveBeenCalledWith(expectedRoles); - - role.state.setRoles([]); - }); - }); - - describe('hasAny', () => { - it('should return true if a role matched', async () => { - role.state.setRoles(['admin']); - const hasRole = role.hasAny(['admin']); - - await flushPromises(); - - expect(hasRole).toBe(true); - - role.state.setRoles([]); - }); - - it('should return false if no roles matched', async () => { - const hasRole = role.hasAny(['admin']); - - await flushPromises(); - - expect(hasRole).toBe(false); - }); - }); -}); diff --git a/test/vitest/__tests__/composables/useSession.spec.js b/test/vitest/__tests__/composables/useSession.spec.js deleted file mode 100644 index 789b149ec..000000000 --- a/test/vitest/__tests__/composables/useSession.spec.js +++ /dev/null @@ -1,211 +0,0 @@ -import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'; -import { axios } from 'app/test/vitest/helper'; -import { useSession } from 'composables/useSession'; -import { useState } from 'composables/useState'; - -const session = useSession(); -const state = useState(); - -describe('session', () => { - describe('getToken / setToken', () => { - it('should return an empty string if no token is found in local or session storage', async () => { - const expectedToken = ''; - - const token = session.getToken(); - - expect(token).toEqual(expectedToken); - }); - - it('should return the token stored in local or session storage', async () => { - const expectedToken = 'myToken'; - const data = { - token: expectedToken, - keepLogin: false, - }; - session.setToken(data); - - const token = session.getToken(); - - expect(token).toEqual(expectedToken); - }); - }); - - describe('destroy', () => { - it('should remove the token from the local storage and set a blank user', async () => { - const previousUser = { - id: 999, - name: `T'Challa`, - nickname: 'Black Panther', - lang: 'en', - darkMode: false, - }; - const expectedUser = { - id: 0, - name: '', - nickname: '', - lang: '', - darkMode: null, - }; - let user = state.getUser(); - - localStorage.setItem('token', 'tokenToBeGone'); - state.setUser(previousUser); - - expect(localStorage.getItem('token')).toEqual('tokenToBeGone'); - expect(user.value).toEqual(previousUser); - - vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); - vi.spyOn(axios, 'get').mockResolvedValue({ data: true }); - await session.destroy(); - - user = state.getUser(); - expect(localStorage.getItem('token')).toBeNull(); - expect(user.value).toEqual(expectedUser); - }); - }); - - describe( - 'login', - () => { - const expectedUser = { - id: 999, - name: `T'Challa`, - nickname: 'Black Panther', - lang: 'en', - userConfig: { - darkMode: false, - }, - }; - const rolesData = [ - { - role: { - name: 'salesPerson', - }, - }, - { - role: { - name: 'admin', - }, - }, - ]; - beforeEach(() => { - vi.spyOn(axios, 'get').mockImplementation((url) => { - if (url === 'VnUsers/acls') return Promise.resolve({ data: [] }); - return Promise.resolve({ - data: { roles: rolesData, user: expectedUser }, - }); - }); - }); - - it('should fetch the user roles and then set token in the sessionStorage', async () => { - const expectedRoles = ['salesPerson', 'admin']; - const expectedToken = 'mySessionToken'; - const expectedTokenMultimedia = 'mySessionTokenMultimedia'; - const keepLogin = false; - - await session.login({ - token: expectedToken, - tokenMultimedia: expectedTokenMultimedia, - keepLogin, - }); - - const roles = state.getRoles(); - const localToken = localStorage.getItem('token'); - const sessionToken = sessionStorage.getItem('token'); - - expect(roles.value).toEqual(expectedRoles); - expect(localToken).toBeNull(); - expect(sessionToken).toEqual(expectedToken); - - await session.destroy(); // this clears token and user for any other test - }); - - it('should fetch the user roles and then set token in the localStorage', async () => { - const expectedRoles = ['salesPerson', 'admin']; - const expectedToken = 'myLocalToken'; - const expectedTokenMultimedia = 'myLocalTokenMultimedia'; - const keepLogin = true; - - await session.login({ - token: expectedToken, - tokenMultimedia: expectedTokenMultimedia, - keepLogin, - }); - - const roles = state.getRoles(); - const localToken = localStorage.getItem('token'); - const sessionToken = sessionStorage.getItem('token'); - - expect(roles.value).toEqual(expectedRoles); - expect(localToken).toEqual(expectedToken); - expect(sessionToken).toBeNull(); - - await session.destroy(); // this clears token and user for any other test - }); - }, - {} - ); - - describe('RenewToken', () => { - const expectedToken = 'myToken'; - const expectedTokenMultimedia = 'myTokenMultimedia'; - const currentDate = new Date(); - beforeAll(() => { - const tokenConfig = { - id: 1, - renewPeriod: 21600, - courtesyTime: 60, - renewInterval: 300, - }; - state.setTokenConfig(tokenConfig); - sessionStorage.setItem('renewPeriod', 1); - }); - it('NOT Should renewToken', async () => { - const data = { - token: expectedToken, - tokenMultimedia: expectedTokenMultimedia, - keepLogin: false, - ttl: 1, - created: Date.now(), - }; - session.setSession(data); - expect(sessionStorage.getItem('keepLogin')).toBeFalsy(); - expect(sessionStorage.getItem('created')).toBeDefined(); - expect(sessionStorage.getItem('ttl')).toEqual(1); - await session.checkValidity(); - expect(sessionStorage.getItem('token')).toEqual(expectedToken); - expect(sessionStorage.getItem('tokenMultimedia')).toEqual( - expectedTokenMultimedia - ); - }); - it('Should renewToken', async () => { - currentDate.setMinutes(currentDate.getMinutes() - 100); - const data = { - token: expectedToken, - tokenMultimedia: expectedTokenMultimedia, - keepLogin: false, - ttl: 1, - created: currentDate, - }; - session.setSession(data); - - vi.spyOn(axios, 'post') - .mockResolvedValueOnce({ - data: { id: '' }, - }) - .mockResolvedValueOnce({ - data: { - id: '', - }, - }); - expect(sessionStorage.getItem('keepLogin')).toBeFalsy(); - expect(sessionStorage.getItem('created')).toBeDefined(); - expect(sessionStorage.getItem('ttl')).toEqual(1); - await session.checkValidity(); - expect(sessionStorage.getItem('token')).not.toEqual(expectedToken); - expect(sessionStorage.getItem('tokenMultimedia')).not.toEqual( - expectedTokenMultimedia - ); - }); - }); -}); diff --git a/test/vitest/__tests__/composables/useTokenConfig.spec.js b/test/vitest/__tests__/composables/useTokenConfig.spec.js deleted file mode 100644 index a25a4abb1..000000000 --- a/test/vitest/__tests__/composables/useTokenConfig.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import { vi, describe, expect, it } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; -import { useTokenConfig } from 'composables/useTokenConfig'; -const tokenConfig = useTokenConfig(); - -describe('useTokenConfig', () => { - describe('fetch', () => { - it('should call setTokenConfig of the state with the expected data', async () => { - const data = { - id: 1, - renewPeriod: 21600, - courtesyTime: 60, - renewInterval: 300, - }; - vi.spyOn(axios, 'get').mockResolvedValueOnce({ - data, - }); - - vi.spyOn(tokenConfig.state, 'setTokenConfig'); - - tokenConfig.fetch(); - - await flushPromises(); - - expect(tokenConfig.state.setTokenConfig).toHaveBeenCalledWith(data); - - const renewPeriod = sessionStorage.getItem('renewPeriod'); - expect(renewPeriod).toEqual(data.renewPeriod); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js b/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js deleted file mode 100644 index b208f1704..000000000 --- a/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue'; - -describe('ClaimDescriptorMenu', () => { - let vm; - beforeAll(() => { - vm = createWrapper(ClaimDescriptorMenu, { - propsData: { - claim: { - id: 1, - }, - }, - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('remove()', () => { - it('should delete the claim', async () => { - vi.spyOn(axios, 'delete').mockResolvedValue({ data: true }); - vi.spyOn(vm.quasar, 'notify'); - - await vm.remove(); - - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ type: 'positive' }) - ); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Claims/ClaimLines.spec.js b/test/vitest/__tests__/pages/Claims/ClaimLines.spec.js deleted file mode 100644 index 2f2c0e298..000000000 --- a/test/vitest/__tests__/pages/Claims/ClaimLines.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import ClaimLines from '/src/pages/Claim/Card/ClaimLines.vue'; - -describe('ClaimLines', () => { - let vm; - - beforeAll(() => { - vm = createWrapper(ClaimLines, { - global: { - stubs: ['FetchData', 'VnPaginate'], - mocks: { - fetch: vi.fn(), - }, - }, - }).vm; - }); - - beforeEach(() => { - vm.claim = { - id: 1, - ticketFk: 1, - }; - vm.store.data = [ - { - id: 1, - quantity: 10, - sale: { - id: 1, - discount: 0, - }, - }, - ]; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('updateDiscount()', () => { - it('should make a POST request to endpoint "updateDiscount"', async () => { - vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); - vi.spyOn(vm.quasar, 'notify'); - - const canceller = new AbortController(); - await vm.updateDiscount({ saleFk: 1, discount: 5, canceller }); - - const expectedData = { salesIds: [1], newDiscount: 5 }; - expect(axios.post).toHaveBeenCalledWith( - 'Tickets/1/updateDiscount', - expectedData, - { - signal: canceller.signal, - } - ); - }); - }); - - describe('onUpdateDiscount()', () => { - it('should make a POST request and then set the discount on the original row', async () => { - vi.spyOn(vm.quasar, 'notify'); - - vm.onUpdateDiscount({ discount: 5, rowIndex: 0 }); - const firstRow = vm.store.data[0]; - - expect(firstRow.sale.discount).toEqual(5); - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - message: 'Discount updated', - type: 'positive', - }) - ); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Claims/ClaimLinesImport.spec.js b/test/vitest/__tests__/pages/Claims/ClaimLinesImport.spec.js deleted file mode 100644 index d93c96132..000000000 --- a/test/vitest/__tests__/pages/Claims/ClaimLinesImport.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import ClaimLinesImport from 'pages/Claim/Card/ClaimLinesImport.vue'; - -describe('ClaimLinesImport', () => { - let vm; - - beforeAll(() => { - vm = createWrapper(ClaimLinesImport, { - global: { - stubs: ['FetchData'], - mocks: { - fetch: vi.fn(), - }, - }, - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('importLines()', () => { - it('should make a POST request and then call to the quasar notify() method', async () => { - vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); - vi.spyOn(vm.quasar, 'notify'); - - vm.selected = [{ id: 1, saleFk: 1, claimFk: 1 }]; - - vm.route.params.id = 1; - - await vm.importLines(); - const expectedData = [{ saleFk: 1, claimFk: 1 }]; - - expect(axios.post).toHaveBeenCalledWith('ClaimBeginnings', expectedData, { - signal: expect.any(Object), - }); - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - message: 'Lines added to claim', - type: 'positive', - }) - ); - expect(vm.canceller).toEqual(null); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js deleted file mode 100644 index c38852af1..000000000 --- a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js +++ /dev/null @@ -1,114 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import ClaimPhoto from 'pages/Claim/Card/ClaimPhoto.vue'; - -describe('ClaimPhoto', () => { - let vm; - - const claimMock = { - claimDms: [ - { - dmsFk: 1, - dms: { - contentType: 'contentType', - }, - }, - ], - client: { - id: '1', - }, - }; - beforeAll(() => { - vm = createWrapper(ClaimPhoto, { - global: { - stubs: ['FetchData', 'vue-i18n'], - mocks: { - fetch: vi.fn(), - }, - }, - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('deleteDms()', () => { - it('should delete dms and call quasar notify', async () => { - vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); - vi.spyOn(vm.quasar, 'notify'); - - await vm.deleteDms({ index: 0 }); - - expect(axios.post).toHaveBeenCalledWith( - `ClaimDms/${claimMock.claimDms[0].dmsFk}/removeFile` - ); - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ type: 'positive' }) - ); - }); - }); - - describe('viewDeleteDms()', () => { - it('should call quasar dialog', async () => { - vi.spyOn(vm.quasar, 'dialog'); - - await vm.viewDeleteDms(1); - - expect(vm.quasar.dialog).toHaveBeenCalledWith( - expect.objectContaining({ - componentProps: { - title: 'This file will be deleted', - icon: 'delete', - data: { index: 1 }, - promise: vm.deleteDms - }, - }) - ); - }); - }); - - describe('setClaimDms()', () => { - it('should assign claimDms and client from data', async () => { - await vm.setClaimDms(claimMock); - - expect(vm.claimDms).toEqual([ - { - dmsFk: 1, - dms: { - contentType: 'contentType', - }, - isVideo: false, - url: '/api/Claims/1/downloadFile?access_token=', - }, - ]); - - expect(vm.client).toEqual(claimMock.client); - }); - }); - - describe('create()', () => { - it('should upload file and call quasar notify', async () => { - const files = [{ name: 'firstFile' }]; - - vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); - vi.spyOn(vm.quasar, 'notify'); - vi.spyOn(vm.claimDmsRef, 'fetch'); - - await vm.create(files); - - expect(axios.post).toHaveBeenCalledWith( - 'claims/1/uploadFile', - new FormData(), - expect.objectContaining({ - params: expect.objectContaining({ hasFile: false }), - }) - ); - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ type: 'positive' }) - ); - - expect(vm.claimDmsRef.fetch).toHaveBeenCalledOnce(); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js b/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js deleted file mode 100644 index 466a544b4..000000000 --- a/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js +++ /dev/null @@ -1,38 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import CustomerPayments from 'src/pages/Customer/Payments/CustomerPayments.vue'; - -describe('CustomerPayments', () => { - let vm; - - beforeAll(() => { - vm = createWrapper(CustomerPayments, { - global: { - stubs: ['VnPaginate'], - mocks: { - fetch: vi.fn(), - }, - }, - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('confirmTransaction()', () => { - it('should make a POST request and then call to quasar notify method', async () => { - vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); - vi.spyOn(vm.quasar, 'notify'); - - await vm.confirmTransaction({ id: 1 }); - - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - message: 'Payment confirmed', - type: 'positive', - }) - ); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Login/Login.spec.js b/test/vitest/__tests__/pages/Login/Login.spec.js deleted file mode 100644 index e90a8ee53..000000000 --- a/test/vitest/__tests__/pages/Login/Login.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import Login from 'pages/Login/LoginMain.vue'; - -describe('Login', () => { - let vm; - beforeAll(() => { - vm = createWrapper(Login).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - it('should successfully set the token into session', async () => { - const expectedUser = { - id: 999, - name: `T'Challa`, - nickname: 'Black Panther', - lang: 'en', - userConfig: { - darkMode: false, - }, - }; - vi.spyOn(axios, 'post').mockResolvedValueOnce({ data: { token: 'token' } }); - vi.spyOn(axios, 'get').mockImplementation((url) => { - if (url === 'VnUsers/acls') return Promise.resolve({ data: [] }); - return Promise.resolve({ - data: { - roles: [], - user: expectedUser, - multimediaToken: { id: 'multimediaToken' }, - }, - }); - }); - - expect(vm.session.getToken()).toEqual(''); - - await vm.onSubmit(); - - expect(vm.session.getToken()).toEqual('token'); - await vm.session.destroy(); - }); - - it('should not set the token into session if any error occurred', async () => { - vi.spyOn(axios, 'post').mockReturnValue({ data: null }); - await vm.onSubmit(); - }); -}); diff --git a/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js b/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js deleted file mode 100644 index ab1a47544..000000000 --- a/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js +++ /dev/null @@ -1,120 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import TicketAdvance from 'pages/Ticket/TicketAdvance.vue'; -import { Notify } from 'quasar'; -import { nextTick } from 'vue'; - -describe('TicketAdvance', () => { - let wrapper; - let vm; - - beforeAll(() => { - vi.spyOn(axios, 'get').mockImplementation(() => ({ data: [] })); - wrapper = createWrapper(TicketAdvance); - vm = wrapper.vm; - vi.spyOn(vm.vnTableRef, 'reload').mockImplementation(() => vi.fn()); - vm.vnTableRef.value = { params: {} }; - }); - beforeEach(() => { - Notify.create = vi.fn(); - }); - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('requestComponentUpdate()', () => { - const mockTicket = { - futureId: 1, - futureClientFk: 1, - nickname: 'test', - futureAddressFk: 1, - futureAgencyModeFk: 1, - futureWarehouseFk: 1, - futureCompanyFk: 1, - landed: '2023-01-02', - zoneFk: 1, - }; - const mockParams = { - clientFk: 1, - nickname: 'test', - agencyModeFk: 1, - addressFk: 1, - zoneFk: 1, - warehouseFk: 1, - companyFk: 1, - landed: '2023-01-02', - shipped: '2023-01-01', - isDeleted: false, - isWithoutNegatives: false, - newTicket: undefined, - keepPrice: true, - }; - const queryResult = 'tickets/1/componentUpdate'; - - it('should return query and params when ticket has no landed', async () => { - vm.vnTableRef.params.dateToAdvance = '2023-01-01'; - await nextTick(); - - const mockLanded = { landed: '2023-01-02', zoneFk: 1 }; - vi.spyOn(vm, 'getLanded').mockResolvedValue(mockLanded); - - const { query, params } = await vm.requestComponentUpdate(mockTicket, false); - - expect(query).toBe(queryResult); - expect(params).toEqual(mockParams); - }); - - it('should return query and params when ticket has landed', async () => { - const { query, params } = await vm.requestComponentUpdate(mockTicket, false); - - expect(query).toBe(queryResult); - expect(params).toEqual(mockParams); - }); - }); - - describe('moveTicketsAdvance()', () => { - it('should move tickets and notify success', async () => { - const tickets = [ - { - id: 1, - futureId: 2, - futureShipped: '2023-01-01', - shipped: '2023-01-02', - workerFk: 1, - }, - { - id: 2, - futureId: 3, - futureShipped: '2023-01-01', - shipped: '2023-01-02', - workerFk: 1, - }, - ]; - vm.selectedTickets = tickets; - vi.spyOn(axios, 'post').mockResolvedValue({}); - await vm.moveTicketsAdvance(); - - expect(axios.post).toHaveBeenCalledOnce('Tickets/merge', { - tickets: [ - { - originId: 2, - destinationId: 1, - originShipped: '2023-01-01', - destinationShipped: '2023-01-02', - workerFk: 1, - }, - { - originId: 3, - destinationId: 2, - originShipped: '2023-01-01', - destinationShipped: '2023-01-02', - workerFk: 1, - }, - ], - }); - expect(vm.vnTableRef.reload).toHaveBeenCalled(); - expect(Notify.create).toHaveBeenCalled(); - expect(vm.selectedTickets).toEqual([]); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Tickets/TicketBoxing.spec.js b/test/vitest/__tests__/pages/Tickets/TicketBoxing.spec.js deleted file mode 100644 index 8fd62d8c2..000000000 --- a/test/vitest/__tests__/pages/Tickets/TicketBoxing.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import TicketBoxing from 'pages/Ticket/Card/TicketBoxing.vue'; - -// #4836 - Investigate how to test q-drawer outside -// q-layout or how to teleport q-drawer inside -describe('TicketBoxing', () => { - let vm; - beforeAll(() => { - vm = createWrapper(TicketBoxing).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('getVideoList()', () => { - it('should when response videoList use to list', async () => { - const expeditionId = 1; - const timed = { - min: 1, - max: 2, - }; - const videoList = ['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4']; - - vi.spyOn(axios, 'get').mockResolvedValue({ data: videoList }); - vi.spyOn(vm.quasar, 'notify'); - - await vm.getVideoList(expeditionId, timed); - - expect(vm.videoList.length).toEqual(videoList.length); - expect(vm.slide).toEqual(videoList.reverse()[0]); - }); - - it('should if not have video show notify', async () => { - const expeditionId = 1; - const timed = { - min: 1, - max: 2, - }; - - vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); - vi.spyOn(vm.quasar, 'notify'); - - await vm.getVideoList(expeditionId, timed); - - expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'negative' })); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Wagons/WagonCreate.spec.js b/test/vitest/__tests__/pages/Wagons/WagonCreate.spec.js deleted file mode 100644 index f195c183f..000000000 --- a/test/vitest/__tests__/pages/Wagons/WagonCreate.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import WagonCreate from 'pages/Wagon/WagonCreate.vue'; - -describe('WagonCreate', () => { - let vmEdit, vmCreate; - const entityId = 1; - - beforeAll(() => { - vmEdit = createWrapper(WagonCreate, { - propsData: { - id: entityId, - }, - }).vm; - vmCreate = createWrapper(WagonCreate).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('onSubmit()', () => { - it('should create a wagon', async () => { - vi.spyOn(axios, 'patch').mockResolvedValue({ data: true }); - vmCreate.wagon = { - label: 1234, - plate: 'MOCK PLATE', - volume: 50, - typeFk: 1, - }; - - await vmCreate.onSubmit(); - - expect(axios.patch).toHaveBeenCalledWith(`Wagons`, vmCreate.wagon); - }); - - it('should update a wagon', async () => { - vi.spyOn(axios, 'patch').mockResolvedValue({ data: true }); - vmEdit.wagon = { - id: entityId, - label: 1234, - plate: 'MOCK PLATE', - volume: 50, - typeFk: 1, - }; - - await vmEdit.onSubmit(); - - expect(axios.patch).toHaveBeenCalledWith(`Wagons`, vmEdit.wagon); - }); - }); - - describe('onReset()', () => { - it('should reset wagon if have id', async () => { - vmEdit.originalData = { - label: 1234, - plate: 'Original', - volume: 200, - typeFk: 1, - }; - vmEdit.wagon = { - label: 4321, - plate: 'Edited', - volume: 50, - typeFk: 2, - }; - - await vmEdit.onReset(); - - expect(vmEdit.wagon).toEqual(vmEdit.originalData); - }); - - it('should reset wagon if not have id', async () => { - vmCreate.wagon = { - label: 4321, - plate: 'Edited', - volume: 50, - typeFk: 2, - }; - - await vmCreate.onReset(); - - expect(vmCreate.wagon).toEqual({}); - }); - }); - - describe('fetch()', () => { - it('should fetch data', async () => { - vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); - - await vmEdit.fetch(); - - expect(axios.get).toHaveBeenCalledWith(`WagonTypes`); - expect(axios.get).toHaveBeenCalledWith(`Wagons/${entityId}`); - }); - }); -}); diff --git a/test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js b/test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js deleted file mode 100644 index 35ce91e61..000000000 --- a/test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper } from 'app/test/vitest/helper'; -import WorkerNotificationsManager from 'src/pages/Worker/Card/WorkerNotificationsManager.vue'; -import { ref } from 'vue'; - -describe('WorkerNotificationsManager', () => { - let vm; - - beforeAll(() => { - vm = createWrapper(WorkerNotificationsManager, { - global: { - stubs: ['CrudModel'], - }, - }).vm; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('swapEntry()', () => { - it('should swap notification', async () => { - const from = ref(new Map()); - const to = ref(new Map()); - from.value.set(1, { notificationFk: 1 }); - to.value.set(2, { notificationFk: 2 }); - - await vm.swapEntry(from.value, to.value, 1); - expect(to.value.size).toBe(2); - expect(from.value.size).toBe(0); - }); - }); -}); diff --git a/test/vitest/__tests__/stores/useStateQueryStore.spec.js b/test/vitest/__tests__/stores/useStateQueryStore.spec.js deleted file mode 100644 index ab3afb007..000000000 --- a/test/vitest/__tests__/stores/useStateQueryStore.spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import { describe, expect, it, beforeEach, beforeAll } from 'vitest'; -import { createWrapper } from 'app/test/vitest/helper'; - -import { useStateQueryStore } from 'src/stores/useStateQueryStore'; - -describe('useStateQueryStore', () => { - beforeAll(() => { - createWrapper({}, {}); - }); - - const stateQueryStore = useStateQueryStore(); - const { add, isLoading, remove, reset } = useStateQueryStore(); - const firstQuery = { url: 'myQuery' }; - - function getQueries() { - return stateQueryStore.queries; - } - - beforeEach(() => { - reset(); - expect(getQueries().size).toBeFalsy(); - }); - - it('should add two queries', async () => { - expect(getQueries().size).toBeFalsy(); - add(firstQuery); - - expect(getQueries().size).toBeTruthy(); - expect(getQueries().has(firstQuery)).toBeTruthy(); - - add(); - expect(getQueries().size).toBe(2); - }); - - it('should add and remove loading state', async () => { - expect(isLoading().value).toBeFalsy(); - add(firstQuery); - expect(isLoading().value).toBeTruthy(); - remove(firstQuery); - expect(isLoading().value).toBeFalsy(); - }); - - it('should add and remove query', async () => { - const secondQuery = { ...firstQuery }; - const thirdQuery = { ...firstQuery }; - - add(firstQuery); - add(secondQuery); - - const beforeCount = getQueries().size; - add(thirdQuery); - expect(getQueries().has(thirdQuery)).toBeTruthy(); - - remove(thirdQuery); - expect(getQueries().has(thirdQuery)).toBeFalsy(); - expect(getQueries().size).toBe(beforeCount); - }); -}); diff --git a/vitest.config.js b/vitest.config.js index ca9f6c1fe..a465f0e2d 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -13,7 +13,7 @@ export default defineConfig({ include: [ // Matches vitest tests in any subfolder of 'src' or into 'test/vitest/__tests__' // Matches all files with extension 'js', 'jsx', 'ts' and 'tsx' - 'test/vitest/__tests__/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', + 'src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', ], }, plugins: [ From 77d7c2261ecd263fc13f034a0003512f920f15b9 Mon Sep 17 00:00:00 2001 From: provira Date: Fri, 20 Dec 2024 09:19:49 +0100 Subject: [PATCH 3/3] refactor: refs #8320 changed folder names from "specs" to "__tests__" --- src/boot/{specs => __tests__}/axios.spec.js | 0 src/components/VnTable/{specs => __tests__}/VnTable.spec.js | 0 src/components/{specs => __tests__}/CrudModel.spec.js | 0 src/components/{specs => __tests__}/Leftmenu.spec.js | 0 .../common/{specs => __tests__}/VnChangePassword.spec.js | 0 src/components/common/{specs => __tests__}/VnDiscount.spec.js | 0 src/components/common/{specs => __tests__}/VnLog.spec.js | 0 src/components/common/{specs => __tests__}/VnSmsDialog.spec.js | 0 src/components/ui/{specs => __tests__}/Paginate.spec.js | 0 src/components/ui/{specs => __tests__}/VnLinkPhone.spec.js | 0 src/components/ui/{specs => __tests__}/VnSms.spec.js | 0 src/composables/{specs => __tests__}/downloadFile.spec.js | 0 src/composables/{specs => __tests__}/getExchange.spec.js | 0 src/composables/{specs => __tests__}/getTotal.spec.js | 0 .../{specs => __tests__}/useAccountShortToStandard.spec.js | 0 src/composables/{specs => __tests__}/useAcl.spec.js | 0 src/composables/{specs => __tests__}/useArrayData.spec.js | 0 src/composables/{specs => __tests__}/useRole.spec.js | 0 src/composables/{specs => __tests__}/useSession.spec.js | 0 src/composables/{specs => __tests__}/useTokenConfig.spec.js | 0 .../Claim/Card/{specs => __tests__}/ClaimDescriptorMenu.spec.js | 0 src/pages/Claim/Card/{specs => __tests__}/ClaimLines.spec.js | 0 .../Claim/Card/{specs => __tests__}/ClaimLinesImport.spec.js | 0 src/pages/Claim/Card/{specs => __tests__}/ClaimPhoto.spec.js | 0 .../Payments/{specs => __tests__}/CustomerPayments.spec.js | 0 src/pages/Login/{specs => __tests__}/Login.spec.js | 0 src/pages/Ticket/Card/{specs => __tests__}/TicketBoxing.spec.js | 0 src/pages/Ticket/{specs => __tests__}/TicketAdvance.spec.js | 0 src/pages/Wagon/{specs => __tests__}/WagonCreate.spec.js | 0 .../Card/{specs => __tests__}/WorkerNotificationsManager.spec.js | 0 src/stores/{specs => __tests__}/useStateQueryStore.spec.js | 0 31 files changed, 0 insertions(+), 0 deletions(-) rename src/boot/{specs => __tests__}/axios.spec.js (100%) rename src/components/VnTable/{specs => __tests__}/VnTable.spec.js (100%) rename src/components/{specs => __tests__}/CrudModel.spec.js (100%) rename src/components/{specs => __tests__}/Leftmenu.spec.js (100%) rename src/components/common/{specs => __tests__}/VnChangePassword.spec.js (100%) rename src/components/common/{specs => __tests__}/VnDiscount.spec.js (100%) rename src/components/common/{specs => __tests__}/VnLog.spec.js (100%) rename src/components/common/{specs => __tests__}/VnSmsDialog.spec.js (100%) rename src/components/ui/{specs => __tests__}/Paginate.spec.js (100%) rename src/components/ui/{specs => __tests__}/VnLinkPhone.spec.js (100%) rename src/components/ui/{specs => __tests__}/VnSms.spec.js (100%) rename src/composables/{specs => __tests__}/downloadFile.spec.js (100%) rename src/composables/{specs => __tests__}/getExchange.spec.js (100%) rename src/composables/{specs => __tests__}/getTotal.spec.js (100%) rename src/composables/{specs => __tests__}/useAccountShortToStandard.spec.js (100%) rename src/composables/{specs => __tests__}/useAcl.spec.js (100%) rename src/composables/{specs => __tests__}/useArrayData.spec.js (100%) rename src/composables/{specs => __tests__}/useRole.spec.js (100%) rename src/composables/{specs => __tests__}/useSession.spec.js (100%) rename src/composables/{specs => __tests__}/useTokenConfig.spec.js (100%) rename src/pages/Claim/Card/{specs => __tests__}/ClaimDescriptorMenu.spec.js (100%) rename src/pages/Claim/Card/{specs => __tests__}/ClaimLines.spec.js (100%) rename src/pages/Claim/Card/{specs => __tests__}/ClaimLinesImport.spec.js (100%) rename src/pages/Claim/Card/{specs => __tests__}/ClaimPhoto.spec.js (100%) rename src/pages/Customer/Payments/{specs => __tests__}/CustomerPayments.spec.js (100%) rename src/pages/Login/{specs => __tests__}/Login.spec.js (100%) rename src/pages/Ticket/Card/{specs => __tests__}/TicketBoxing.spec.js (100%) rename src/pages/Ticket/{specs => __tests__}/TicketAdvance.spec.js (100%) rename src/pages/Wagon/{specs => __tests__}/WagonCreate.spec.js (100%) rename src/pages/Worker/Card/{specs => __tests__}/WorkerNotificationsManager.spec.js (100%) rename src/stores/{specs => __tests__}/useStateQueryStore.spec.js (100%) diff --git a/src/boot/specs/axios.spec.js b/src/boot/__tests__/axios.spec.js similarity index 100% rename from src/boot/specs/axios.spec.js rename to src/boot/__tests__/axios.spec.js diff --git a/src/components/VnTable/specs/VnTable.spec.js b/src/components/VnTable/__tests__/VnTable.spec.js similarity index 100% rename from src/components/VnTable/specs/VnTable.spec.js rename to src/components/VnTable/__tests__/VnTable.spec.js diff --git a/src/components/specs/CrudModel.spec.js b/src/components/__tests__/CrudModel.spec.js similarity index 100% rename from src/components/specs/CrudModel.spec.js rename to src/components/__tests__/CrudModel.spec.js diff --git a/src/components/specs/Leftmenu.spec.js b/src/components/__tests__/Leftmenu.spec.js similarity index 100% rename from src/components/specs/Leftmenu.spec.js rename to src/components/__tests__/Leftmenu.spec.js diff --git a/src/components/common/specs/VnChangePassword.spec.js b/src/components/common/__tests__/VnChangePassword.spec.js similarity index 100% rename from src/components/common/specs/VnChangePassword.spec.js rename to src/components/common/__tests__/VnChangePassword.spec.js diff --git a/src/components/common/specs/VnDiscount.spec.js b/src/components/common/__tests__/VnDiscount.spec.js similarity index 100% rename from src/components/common/specs/VnDiscount.spec.js rename to src/components/common/__tests__/VnDiscount.spec.js diff --git a/src/components/common/specs/VnLog.spec.js b/src/components/common/__tests__/VnLog.spec.js similarity index 100% rename from src/components/common/specs/VnLog.spec.js rename to src/components/common/__tests__/VnLog.spec.js diff --git a/src/components/common/specs/VnSmsDialog.spec.js b/src/components/common/__tests__/VnSmsDialog.spec.js similarity index 100% rename from src/components/common/specs/VnSmsDialog.spec.js rename to src/components/common/__tests__/VnSmsDialog.spec.js diff --git a/src/components/ui/specs/Paginate.spec.js b/src/components/ui/__tests__/Paginate.spec.js similarity index 100% rename from src/components/ui/specs/Paginate.spec.js rename to src/components/ui/__tests__/Paginate.spec.js diff --git a/src/components/ui/specs/VnLinkPhone.spec.js b/src/components/ui/__tests__/VnLinkPhone.spec.js similarity index 100% rename from src/components/ui/specs/VnLinkPhone.spec.js rename to src/components/ui/__tests__/VnLinkPhone.spec.js diff --git a/src/components/ui/specs/VnSms.spec.js b/src/components/ui/__tests__/VnSms.spec.js similarity index 100% rename from src/components/ui/specs/VnSms.spec.js rename to src/components/ui/__tests__/VnSms.spec.js diff --git a/src/composables/specs/downloadFile.spec.js b/src/composables/__tests__/downloadFile.spec.js similarity index 100% rename from src/composables/specs/downloadFile.spec.js rename to src/composables/__tests__/downloadFile.spec.js diff --git a/src/composables/specs/getExchange.spec.js b/src/composables/__tests__/getExchange.spec.js similarity index 100% rename from src/composables/specs/getExchange.spec.js rename to src/composables/__tests__/getExchange.spec.js diff --git a/src/composables/specs/getTotal.spec.js b/src/composables/__tests__/getTotal.spec.js similarity index 100% rename from src/composables/specs/getTotal.spec.js rename to src/composables/__tests__/getTotal.spec.js diff --git a/src/composables/specs/useAccountShortToStandard.spec.js b/src/composables/__tests__/useAccountShortToStandard.spec.js similarity index 100% rename from src/composables/specs/useAccountShortToStandard.spec.js rename to src/composables/__tests__/useAccountShortToStandard.spec.js diff --git a/src/composables/specs/useAcl.spec.js b/src/composables/__tests__/useAcl.spec.js similarity index 100% rename from src/composables/specs/useAcl.spec.js rename to src/composables/__tests__/useAcl.spec.js diff --git a/src/composables/specs/useArrayData.spec.js b/src/composables/__tests__/useArrayData.spec.js similarity index 100% rename from src/composables/specs/useArrayData.spec.js rename to src/composables/__tests__/useArrayData.spec.js diff --git a/src/composables/specs/useRole.spec.js b/src/composables/__tests__/useRole.spec.js similarity index 100% rename from src/composables/specs/useRole.spec.js rename to src/composables/__tests__/useRole.spec.js diff --git a/src/composables/specs/useSession.spec.js b/src/composables/__tests__/useSession.spec.js similarity index 100% rename from src/composables/specs/useSession.spec.js rename to src/composables/__tests__/useSession.spec.js diff --git a/src/composables/specs/useTokenConfig.spec.js b/src/composables/__tests__/useTokenConfig.spec.js similarity index 100% rename from src/composables/specs/useTokenConfig.spec.js rename to src/composables/__tests__/useTokenConfig.spec.js diff --git a/src/pages/Claim/Card/specs/ClaimDescriptorMenu.spec.js b/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js similarity index 100% rename from src/pages/Claim/Card/specs/ClaimDescriptorMenu.spec.js rename to src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js diff --git a/src/pages/Claim/Card/specs/ClaimLines.spec.js b/src/pages/Claim/Card/__tests__/ClaimLines.spec.js similarity index 100% rename from src/pages/Claim/Card/specs/ClaimLines.spec.js rename to src/pages/Claim/Card/__tests__/ClaimLines.spec.js diff --git a/src/pages/Claim/Card/specs/ClaimLinesImport.spec.js b/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js similarity index 100% rename from src/pages/Claim/Card/specs/ClaimLinesImport.spec.js rename to src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js diff --git a/src/pages/Claim/Card/specs/ClaimPhoto.spec.js b/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js similarity index 100% rename from src/pages/Claim/Card/specs/ClaimPhoto.spec.js rename to src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js diff --git a/src/pages/Customer/Payments/specs/CustomerPayments.spec.js b/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js similarity index 100% rename from src/pages/Customer/Payments/specs/CustomerPayments.spec.js rename to src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js diff --git a/src/pages/Login/specs/Login.spec.js b/src/pages/Login/__tests__/Login.spec.js similarity index 100% rename from src/pages/Login/specs/Login.spec.js rename to src/pages/Login/__tests__/Login.spec.js diff --git a/src/pages/Ticket/Card/specs/TicketBoxing.spec.js b/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js similarity index 100% rename from src/pages/Ticket/Card/specs/TicketBoxing.spec.js rename to src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js diff --git a/src/pages/Ticket/specs/TicketAdvance.spec.js b/src/pages/Ticket/__tests__/TicketAdvance.spec.js similarity index 100% rename from src/pages/Ticket/specs/TicketAdvance.spec.js rename to src/pages/Ticket/__tests__/TicketAdvance.spec.js diff --git a/src/pages/Wagon/specs/WagonCreate.spec.js b/src/pages/Wagon/__tests__/WagonCreate.spec.js similarity index 100% rename from src/pages/Wagon/specs/WagonCreate.spec.js rename to src/pages/Wagon/__tests__/WagonCreate.spec.js diff --git a/src/pages/Worker/Card/specs/WorkerNotificationsManager.spec.js b/src/pages/Worker/Card/__tests__/WorkerNotificationsManager.spec.js similarity index 100% rename from src/pages/Worker/Card/specs/WorkerNotificationsManager.spec.js rename to src/pages/Worker/Card/__tests__/WorkerNotificationsManager.spec.js diff --git a/src/stores/specs/useStateQueryStore.spec.js b/src/stores/__tests__/useStateQueryStore.spec.js similarity index 100% rename from src/stores/specs/useStateQueryStore.spec.js rename to src/stores/__tests__/useStateQueryStore.spec.js