diff --git a/package.json b/package.json index f25e570a3..eaffd8d85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-front", - "version": "24.36.0", + "version": "24.40.0", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", @@ -62,4 +62,4 @@ "vite": "^5.1.4", "vitest": "^0.31.1" } -} +} \ No newline at end of file diff --git a/src/components/CreateBankEntityForm.vue b/src/components/CreateBankEntityForm.vue index c46ac7752..1117225c7 100644 --- a/src/components/CreateBankEntityForm.vue +++ b/src/components/CreateBankEntityForm.vue @@ -1,5 +1,5 @@ + + + +es: + New expense: Nuevo gasto + It's a withholding: Es una retención + diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue index a426ac2b4..4c44d29e2 100644 --- a/src/components/CreateNewPostcodeForm.vue +++ b/src/components/CreateNewPostcodeForm.vue @@ -105,7 +105,7 @@ async function setProvince(id, data) { option-label="name" option-value="id" :rules="validate('postcode.city')" - :roles-allowed-to-create="['deliveryAssistant']" + :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]" :emit-value="false" clearable > diff --git a/src/components/FetchData.vue b/src/components/FetchData.vue index 2a0864d3e..3038aa88e 100644 --- a/src/components/FetchData.vue +++ b/src/components/FetchData.vue @@ -44,7 +44,7 @@ onMounted(async () => { async function fetch(fetchFilter = {}) { try { - const filter = Object.assign(fetchFilter, $props.filter); // eslint-disable-line vue/no-dupe-keys + const filter = { ...fetchFilter, ...$props.filter }; // eslint-disable-line vue/no-dupe-keys if ($props.where && !fetchFilter.where) filter.where = $props.where; if ($props.sortBy) filter.order = $props.sortBy; if ($props.limit) filter.limit = $props.limit; diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue index 213c08d7e..03fe11a85 100644 --- a/src/components/LeftMenu.vue +++ b/src/components/LeftMenu.vue @@ -1,6 +1,6 @@ + @@ -691,17 +723,16 @@ watch( - - - - + diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue index 7f7c29f5d..17f893255 100644 --- a/src/components/common/VnSelectDialog.vue +++ b/src/components/common/VnSelectDialog.vue @@ -1,6 +1,7 @@ diff --git a/src/pages/Wagon/Type/WagonTypeEdit.vue b/src/pages/Wagon/Type/WagonTypeEdit.vue new file mode 100644 index 000000000..eb8205d72 --- /dev/null +++ b/src/pages/Wagon/Type/WagonTypeEdit.vue @@ -0,0 +1,293 @@ + + + + + + + + en: + tray: Tray + wagonColor: Wagon color + Select a tray: Select a tray + es: + tray: Bandeja + wagonColor: Color de la bandeja + Select a tray: Seleccione una bandeja + Create new Wagon type: Crear nuevo tipo de vagón + Add new tray: Añadir nueva bandeja + Height: Altura + Tray added successfully: Bandeja añadida correctamente + Tray deleted successfully: Bandeja eliminada correctamente + diff --git a/src/pages/Wagon/Type/WagonTypeList.vue b/src/pages/Wagon/Type/WagonTypeList.vue index b7bbf8c5d..7615dea02 100644 --- a/src/pages/Wagon/Type/WagonTypeList.vue +++ b/src/pages/Wagon/Type/WagonTypeList.vue @@ -1,4 +1,5 @@ @@ -43,8 +48,9 @@ async function remove(row) {
@@ -54,12 +60,19 @@ async function remove(row) { :key="row.id" :title="(row.name || '').toString()" :id="row.id" - @click="navigate(row.id)" + @click="navigate(row.id, row.name)" > + + + +en: + nameNotEmpty: The name cannot be empty +es: + Create new Wagon type: Crear nuevo tipo de vagón + Name: Nombre + nameNotEmpty: El nombre no puede estar vacío + diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue index 8d7f4f683..be30537df 100644 --- a/src/pages/Worker/Card/WorkerDescriptor.vue +++ b/src/pages/Worker/Card/WorkerDescriptor.vue @@ -151,7 +151,7 @@ const refetch = async () => await cardDescriptorRef.value.getData();
diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue index f19fc8ae6..4a19e472c 100644 --- a/src/pages/Worker/Card/WorkerLocker.vue +++ b/src/pages/Worker/Card/WorkerLocker.vue @@ -3,13 +3,13 @@ import { ref, computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import axios from 'axios'; -import { useRole } from 'src/composables/useRole'; +import { useAcl } from 'src/composables/useAcl'; import FormModel from 'components/FormModel.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import { useArrayData } from 'src/composables/useArrayData'; import FetchData from 'components/FetchData.vue'; -const { hasAny } = useRole(); +const { hasAny } = useAcl(); const { t } = useI18n(); const fetchData = ref(); const originaLockerId = ref(); @@ -57,7 +57,11 @@ const init = async (data) => { option-label="code" option-value="id" hide-selected - :readonly="!hasAny(['productionBoss', 'hr'])" + :readonly=" + !hasAny([ + { model: 'Worker', props: '__get__locker', accessType: 'READ' }, + ]) + " /> diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index f68614575..abf60a078 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -13,6 +13,7 @@ import WorkerTimeControlCalendar from 'pages/Worker/Card/WorkerTimeControlCalend import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; import { useRole } from 'src/composables/useRole'; +import { useAcl } from 'src/composables/useAcl'; import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useStateStore } from 'stores/useStateStore'; import { useState } from 'src/composables/useState'; @@ -26,7 +27,6 @@ import { date } from 'quasar'; const route = useRoute(); const { t, locale } = useI18n(); const { notify } = useNotify(); -const { hasAny } = useRole(); const _state = useState(); const user = _state.getUser(); const stateStore = useStateStore(); @@ -66,9 +66,11 @@ const arrayData = useArrayData('workerData'); const worker = computed(() => arrayData.store?.data); -const isHr = computed(() => hasAny(['hr'])); +const isHr = computed(() => useRole().hasAny(['hr'])); -const isHimSelf = computed(() => user.value.id === Number(route.params.id)); +const canSend = computed(() => useAcl().hasAny('WorkerTimeControl', 'sendMail', 'WRITE')); + +const isHimself = computed(() => user.value.id === Number(route.params.id)); const columns = computed(() => { return weekdayStore.getLocales?.map((day, index) => { @@ -447,7 +449,7 @@ onMounted(async () => {
{ @click="isSatisfied()" /> { { diff --git a/src/pages/Worker/Card/WorkerTimeReasonForm.vue b/src/pages/Worker/Card/WorkerTimeReasonForm.vue index 5c1ab9118..23bdba15e 100644 --- a/src/pages/Worker/Card/WorkerTimeReasonForm.vue +++ b/src/pages/Worker/Card/WorkerTimeReasonForm.vue @@ -9,7 +9,7 @@ const $props = defineProps({ type: String, default: '', }, - isHimSelf: { + isHimself: { type: Boolean, default: false, }, @@ -40,7 +40,7 @@ const closeForm = () => { v-model="reasonFormData" type="textarea" autogrow - :disable="!isHimSelf" + :disable="!isHimself" /> diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue index 91d96a162..b8ef3f9d8 100644 --- a/src/pages/Worker/WorkerList.vue +++ b/src/pages/Worker/WorkerList.vue @@ -262,7 +262,7 @@ async function autofillBic(worker) { { + const hasRequiredAcls = matches.every((route) => { const meta = route.meta; - if (meta && meta.roles) return useRole().hasAny(meta.roles); - return true; + if (!meta?.acls) return true; + return useAcl().hasAny(meta.acls); }); - - if (!hasRequiredRoles) { - return next({ path: '/' }); - } + if (!hasRequiredAcls) return next({ path: '/' }); } next(); diff --git a/src/router/modules/account.js b/src/router/modules/account.js index 34f804b18..7200131da 100644 --- a/src/router/modules/account.js +++ b/src/router/modules/account.js @@ -80,7 +80,7 @@ export default { meta: { title: 'accounts', icon: 'accessibility', - roles: ['itManagement'], + acls: [{ model: 'Account', props: '*', accessType: '*' }], }, component: () => import('src/pages/Account/AccountAccounts.vue'), }, @@ -90,7 +90,7 @@ export default { meta: { title: 'ldap', icon: 'account_tree', - roles: ['itManagement'], + acls: [{ model: 'LdapConfig', props: '*', accessType: '*' }], }, component: () => import('src/pages/Account/AccountLdap.vue'), }, @@ -100,7 +100,7 @@ export default { meta: { title: 'samba', icon: 'preview', - roles: ['itManagement'], + acls: [{ model: 'SambaConfig', props: '*', accessType: '*' }], }, component: () => import('src/pages/Account/AccountSamba.vue'), }, diff --git a/src/router/modules/claim.js b/src/router/modules/claim.js index d597267b2..b58a58e8d 100644 --- a/src/router/modules/claim.js +++ b/src/router/modules/claim.js @@ -62,7 +62,7 @@ export default { meta: { title: 'basicData', icon: 'vn:settings', - roles: ['salesPerson'], + acls: [{ model: 'Claim', props: 'findById', accessType: 'READ' }], }, component: () => import('src/pages/Claim/Card/ClaimBasicData.vue'), }, @@ -99,7 +99,13 @@ export default { meta: { title: 'development', icon: 'vn:traceability', - roles: ['claimManager'], + acls: [ + { + model: 'ClaimDevelopment', + props: '*', + accessType: 'WRITE', + }, + ], }, component: () => import('src/pages/Claim/Card/ClaimDevelopment.vue'), }, diff --git a/src/router/modules/invoiceIn.js b/src/router/modules/invoiceIn.js index 906db8a58..168d64f37 100644 --- a/src/router/modules/invoiceIn.js +++ b/src/router/modules/invoiceIn.js @@ -1,5 +1,5 @@ import { RouterView } from 'vue-router'; - +import { setRectificative } from 'src/pages/InvoiceIn/composables/setRectificative'; export default { path: '/invoice-in', name: 'InvoiceIn', @@ -63,6 +63,10 @@ export default { path: ':id', component: () => import('src/pages/InvoiceIn/Card/InvoiceInCard.vue'), redirect: { name: 'InvoiceInSummary' }, + beforeEnter: async (to, from, next) => { + await setRectificative(to); + next(); + }, children: [ { name: 'InvoiceInSummary', @@ -80,7 +84,6 @@ export default { meta: { title: 'basicData', icon: 'vn:settings', - roles: ['salesPerson'], }, component: () => import('src/pages/InvoiceIn/Card/InvoiceInBasicData.vue'), diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js index 70145dfb4..b7f50a3b6 100644 --- a/src/router/modules/shelving.js +++ b/src/router/modules/shelving.js @@ -76,7 +76,6 @@ export default { meta: { title: 'basicData', icon: 'vn:settings', - roles: ['salesPerson'], }, component: () => import('pages/Shelving/Card/ShelvingForm.vue'), }, diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js index 0f6fc9b22..dcc238f95 100644 --- a/src/router/modules/ticket.js +++ b/src/router/modules/ticket.js @@ -54,7 +54,6 @@ export default { meta: { title: 'createTicket', icon: 'vn:ticketAdd', - roles: ['developer'], }, component: () => import('src/pages/Ticket/TicketCreate.vue'), }, diff --git a/src/router/modules/wagon.js b/src/router/modules/wagon.js index d3d14a888..e25e585eb 100644 --- a/src/router/modules/wagon.js +++ b/src/router/modules/wagon.js @@ -11,7 +11,7 @@ export default { component: RouterView, redirect: { name: 'WagonMain' }, menus: { - main: ['WagonList', 'WagonTypeList', 'WagonCounter'], + main: ['WagonList', 'WagonTypeList', 'WagonCounter', 'WagonTray'], card: [], }, children: [ @@ -81,7 +81,7 @@ export default { title: 'typeCreate', icon: 'create', }, - component: () => import('src/pages/Wagon/Type/WagonTypeCreate.vue'), + component: () => import('src/pages/Wagon/Type/WagonTypeList.vue'), }, { path: ':id/edit', @@ -90,7 +90,7 @@ export default { title: 'typeEdit', icon: 'edit', }, - component: () => import('src/pages/Wagon/Type/WagonTypeCreate.vue'), + component: () => import('src/pages/Wagon/Type/WagonTypeEdit.vue'), }, ], }, diff --git a/src/stores/useNavigationStore.js b/src/stores/useNavigationStore.js index 4589426f8..4a819bf19 100644 --- a/src/stores/useNavigationStore.js +++ b/src/stores/useNavigationStore.js @@ -2,7 +2,7 @@ import axios from 'axios'; import { ref } from 'vue'; import { defineStore } from 'pinia'; import { toLowerCamel } from 'src/filters'; -import { useRole } from 'src/composables/useRole'; +import { useAcl } from 'src/composables/useAcl'; import routes from 'src/router/modules'; export const useNavigationStore = defineStore('navigationStore', () => { @@ -26,7 +26,7 @@ export const useNavigationStore = defineStore('navigationStore', () => { 'zone', ]; const pinnedModules = ref([]); - const role = useRole(); + const acl = useAcl(); function getModules() { const modulesRoutes = ref([]); @@ -56,6 +56,7 @@ export const useNavigationStore = defineStore('navigationStore', () => { function addMenuItem(module, route, parent) { const { meta } = route; let { menuChildren = null } = meta; + if (meta.hidden) return; if (menuChildren) menuChildren = menuChildren.map(({ name, title, icon }) => ({ name, @@ -63,7 +64,7 @@ export const useNavigationStore = defineStore('navigationStore', () => { title: `globals.pageTitles.${title}`, })); - if (meta && meta.roles && role.hasAny(meta.roles) === false) return; + if (meta && meta.acls && acl.hasAny(meta.acls) === false) return; const item = { name: route.name, diff --git a/test/cypress/integration/claim/claimDevelopment.spec.js b/test/cypress/integration/claim/claimDevelopment.spec.js index 903f58d4b..3b73a24d9 100755 --- a/test/cypress/integration/claim/claimDevelopment.spec.js +++ b/test/cypress/integration/claim/claimDevelopment.spec.js @@ -8,6 +8,8 @@ describe('ClaimDevelopment', () => { cy.viewport(1920, 1080); cy.login('developer'); cy.visit(`/#/claim/${claimId}/development`); + cy.intercept('GET', /\/api\/Workers\/search/).as('workers'); + cy.intercept('GET', /\/api\/Workers\/search/).as('workers'); cy.waitForElement('tbody'); }); @@ -32,10 +34,19 @@ describe('ClaimDevelopment', () => { }); it('should add and remove new line', () => { + cy.wait(['@workers', '@workers']); cy.addCard(); + cy.get(thirdRow).should('exist'); - const rowData = [false, 'Novato', 'Roces', 'Compradores', 'employeeNick', 'Tour']; + const rowData = [ + false, + 'Novato', + 'Roces', + 'Compradores', + 'administrativeNick', + 'Tour', + ]; cy.fillRow(thirdRow, rowData); cy.saveCard(); diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js index 77a11969b..e1939fe5a 100644 --- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js @@ -36,8 +36,7 @@ describe('InvoiceInBasicData', () => { }); it('should throw an error creating a new dms if a file is not attached', () => { - cy.get(formInputs).eq(5).click(); - cy.get(formInputs).eq(5).type('{selectall}{backspace}'); + cy.get(formInputs).eq(7).type('{selectall}{backspace}'); cy.get(documentBtns).eq(0).click(); cy.get(dialogActionBtns).eq(1).click(); cy.get('.q-notification__message').should( diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js index 018ae7a53..b84d743d1 100644 --- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js @@ -3,13 +3,14 @@ describe('InvoiceInVat', () => { const thirdRow = 'tbody > :nth-child(3)'; const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)'; const dialogInputs = '.q-dialog label input'; - const dialogBtns = '.q-dialog button'; - const acrossInput = 'tbody tr:nth-child(1) td:nth-child(2) .default-icon'; + const addBtn = 'tbody tr:nth-child(1) td:nth-child(2) .--add-icon'; const randomInt = Math.floor(Math.random() * 100); beforeEach(() => { cy.login('developer'); cy.visit(`/#/invoice-in/1/vat`); + cy.intercept('GET', '/api/InvoiceIns/1/getTotals').as('lastCall'); + cy.wait('@lastCall'); }); it('should edit the sage iva', () => { @@ -26,22 +27,15 @@ describe('InvoiceInVat', () => { }); it('should remove the first line', () => { - cy.removeRow(2); - }); - - it('should throw an error if there are fields undefined', () => { - cy.get(acrossInput).click(); - cy.get(dialogBtns).eq(2).click(); - cy.get('.q-notification__message').should('have.text', "The code can't be empty"); + cy.removeRow(1); }); it('should correctly handle expense addition', () => { - cy.get(acrossInput).click(); + cy.get(addBtn).click(); cy.get(dialogInputs).eq(0).type(randomInt); - cy.get(dialogInputs).eq(1).click(); cy.get(dialogInputs).eq(1).type('This is a dummy expense'); - cy.get(dialogBtns).eq(2).click(); - cy.get('.q-notification__message').should('have.text', 'Data saved'); + cy.get('button[type="submit"]').click(); + cy.get('.q-notification__message').should('have.text', 'Data created'); }); }); diff --git a/test/cypress/integration/outLogin/login.spec.js b/test/cypress/integration/outLogin/login.spec.js index f8a9f5c64..3db223cdb 100755 --- a/test/cypress/integration/outLogin/login.spec.js +++ b/test/cypress/integration/outLogin/login.spec.js @@ -52,9 +52,9 @@ describe('Login', () => { cy.url().should('contain', '/login'); }); - it(`should get redirected to dashboard since employee can't create tickets`, () => { - cy.visit('/#/ticket/create', { failOnStatusCode: false }); - cy.url().should('contain', '/#/login?redirect=/ticket/create'); + it(`should be redirected to dashboard since the employee is not enabled to see ldap`, () => { + cy.visit('/#/account/ldap', { failOnStatusCode: false }); + cy.url().should('contain', '/#/login?redirect=/account/ldap'); cy.get('input[aria-label="Username"]').type('employee'); cy.get('input[aria-label="Password"]').type('nightmare'); cy.get('button[type="submit"]').click(); diff --git a/test/cypress/integration/ticket/ticketDescriptor.spec.js b/test/cypress/integration/ticket/ticketDescriptor.spec.js index 9bd7c6053..516b0f13d 100644 --- a/test/cypress/integration/ticket/ticketDescriptor.spec.js +++ b/test/cypress/integration/ticket/ticketDescriptor.spec.js @@ -1,19 +1,18 @@ /// describe('Ticket descriptor', () => { const toCloneOpt = '[role="menu"] .q-list > :nth-child(5)'; + const setWeightOpt = '[role="menu"] .q-list > :nth-child(6)'; const warehouseValue = ':nth-child(1) > :nth-child(6) > .value > span'; const summaryHeader = '.summaryHeader > div'; - + const weight = 25; + const weightValue = ':nth-child(10) > .value > span'; beforeEach(() => { - const ticketId = 1; - cy.login('developer'); - cy.visit(`/#/ticket/${ticketId}/summary`); - cy.waitForElement('.q-page', 7000); + cy.viewport(1920, 1080); }); it('should clone the ticket without warehouse', () => { - cy.openLeftMenu(); + cy.visit('/#/ticket/1/summary'); cy.openActionsDescriptor(); cy.get(toCloneOpt).click(); cy.clickConfirm(); @@ -25,4 +24,15 @@ describe('Ticket descriptor', () => { cy.wrap(owner.trim()).should('eq', 'Bruce Wayne (1101)'); }); }); + + it('should set the weight of the ticket', () => { + cy.visit('/#/ticket/10/summary'); + cy.openActionsDescriptor(); + cy.get(setWeightOpt).click(); + cy.intercept('POST', /\/api\/Tickets\/\d+\/setWeight/).as('weight'); + cy.get('.q-dialog input').type(weight); + cy.clickConfirm(); + cy.wait('@weight'); + cy.get(weightValue).contains(weight); + }); }); diff --git a/test/cypress/integration/wagonType/wagonTypeCreate.spec.js b/test/cypress/integration/wagonType/wagonTypeCreate.spec.js index 5e8b6b888..cd7ffa58f 100644 --- a/test/cypress/integration/wagonType/wagonTypeCreate.spec.js +++ b/test/cypress/integration/wagonType/wagonTypeCreate.spec.js @@ -6,50 +6,12 @@ describe('WagonTypeCreate', () => { cy.waitForElement('.q-page', 6000); }); - function chooseColor(color) { - cy.get('div.shelving-down').eq(1).click(); - cy.get('div.q-color-picker__cube').eq(color).click(); - cy.get('div.q-card__section').find('button').click(); - } - - function addTray(position) { - cy.get('div.action-button').last().find('button').click(); - cy.focused().type(position); - cy.focused().blur(); - } - - it('should create and delete a new wagon type', () => { + it('should create a new wagon type', () => { + cy.get('.q-page-sticky > div > .q-btn').click(); cy.get('input').first().type('Example for testing'); - cy.get('div.q-checkbox__bg').click(); - chooseColor(1); - - // Insert invalid position (not minimal height) - addTray(20); - cy.get('div[role="alert"]').should('exist'); - chooseColor(2); - addTray(150); - chooseColor(3); - addTray(100); - - // Insert invalid position (max height reached) - addTray(210); - cy.get('div[role="alert"]').should('exist'); - - // Save cy.get('button[type="submit"]').click(); - - // Check data has been saved successfully - cy.get(':nth-child(1) > :nth-child(1) > .justify-between > .flex > .title') - .contains('Example for testing') - .click(); - cy.get('input').first().should('have.value', 'Example for testing'); - cy.get('div.wagon-tray').should('have.length', 4); - cy.get('div.position').eq(0).find('input').should('have.value', '150'); - cy.get('div.position').eq(1).find('input').should('have.value', '100'); - cy.get('div.position').eq(2).find('input').should('have.value', '50'); - - // Delete wagon type created - cy.go('back'); + }); + it('delete a wagon type', () => { cy.get( ':nth-child(2) > :nth-child(1) > .card-list-body > .actions > .q-btn--standard' ).click(); diff --git a/test/cypress/integration/wagonType/wagonTypeEdit.spec.js b/test/cypress/integration/wagonType/wagonTypeEdit.spec.js new file mode 100644 index 000000000..6e5816e51 --- /dev/null +++ b/test/cypress/integration/wagonType/wagonTypeEdit.spec.js @@ -0,0 +1,27 @@ +describe('WagonTypeEdit', () => { + const trayColorRow = + '.q-select > .q-field__inner > .q-field__control > .q-field__control-container'; + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit('/#/wagon/type/2/edit'); + }); + + it('should edit the name and the divisible field of the wagon type', () => { + cy.get('.q-card'); + cy.get('input').first().type(' changed'); + cy.get('div.q-checkbox__bg').first().click(); + cy.get('.q-btn--standard').click(); + }); + + it('should create a tray', () => { + cy.get('.action-button > .q-btn > .q-btn__content > .q-icon').click(); + cy.get('input').last().type('150'); + cy.get(trayColorRow).type('{downArrow}{downArrow}{enter}'); + }); + + it('should delete a tray', () => { + cy.get('.action-button > .q-btn > .q-btn__content > .q-icon').first().click(); + cy.reload(); + }); +}); diff --git a/test/vitest/__tests__/composables/useAcl.spec.js b/test/vitest/__tests__/composables/useAcl.spec.js index a2b44b5e7..6cb29984c 100644 --- a/test/vitest/__tests__/composables/useAcl.spec.js +++ b/test/vitest/__tests__/composables/useAcl.spec.js @@ -48,40 +48,62 @@ describe('useAcl', () => { describe('hasAny', () => { it('should return false if no roles matched', async () => { - expect(acl.hasAny('Worker', 'updateAttributes', 'WRITE')).toBeFalsy(); + expect( + acl.hasAny([ + { model: 'Worker', props: 'updateAttributes', accessType: 'WRITE' }, + ]) + ).toBeFalsy(); }); it('should return false if no roles matched', async () => { - expect(acl.hasAny('Worker', 'holidays', 'READ')).toBeTruthy(); + expect( + acl.hasAny([{ model: 'Worker', props: 'holidays', accessType: 'READ' }]) + ).toBeTruthy(); }); describe('*', () => { it('should return true if an acl matched', async () => { - expect(acl.hasAny('Address', '*', 'WRITE')).toBeTruthy(); + expect( + acl.hasAny([{ model: 'Address', props: '*', accessType: 'WRITE' }]) + ).toBeTruthy(); }); it('should return false if no acls matched', async () => { - expect(acl.hasAny('Worker', '*', 'READ')).toBeFalsy(); + expect( + acl.hasAny([{ model: 'Worker', props: '*', accessType: 'READ' }]) + ).toBeFalsy(); }); }); describe('$authenticated', () => { it('should return false if no acls matched', async () => { - expect(acl.hasAny('Url', 'getByUser', '*')).toBeFalsy(); + expect( + acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: '*' }]) + ).toBeFalsy(); }); it('should return true if an acl matched', async () => { - expect(acl.hasAny('Url', 'getByUser', 'READ')).toBeTruthy(); + expect( + acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: 'READ' }]) + ).toBeTruthy(); }); }); describe('$everyone', () => { it('should return false if no acls matched', async () => { - expect(acl.hasAny('TpvTransaction', 'start', 'READ')).toBeFalsy(); + expect( + acl.hasAny([ + { model: 'TpvTransaction', props: 'start', accessType: 'READ' }, + ]) + ).toBeFalsy(); }); it('should return false if an acl matched', async () => { - expect(acl.hasAny('TpvTransaction', 'start', 'WRITE')).toBeTruthy(); + expect( + acl.hasAny([ + { model: 'TpvTransaction', props: 'start', accessType: 'WRITE' }, + ]) + ).toBeTruthy(); }); }); }); diff --git a/test/vitest/__tests__/pages/Wagons/WagonTypeCreate.spec.js b/test/vitest/__tests__/pages/Wagons/WagonTypeCreate.spec.js deleted file mode 100644 index 60c199b73..000000000 --- a/test/vitest/__tests__/pages/Wagons/WagonTypeCreate.spec.js +++ /dev/null @@ -1,271 +0,0 @@ -import { axios, createWrapper } from 'app/test/vitest/helper'; -import WagonTypeCreate from 'pages/Wagon/Type/WagonTypeCreate.vue'; -import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; - -describe('WagonTypeCreate', () => { - let vmCreate, vmEdit; - const entityId = 1; - - beforeAll(() => { - vmEdit = createWrapper(WagonTypeCreate, {propsData: { - id: entityId, - }}).vm; - vmCreate = createWrapper(WagonTypeCreate).vm; - vmEdit.wagonConfig = vmCreate.wagonConfig = {maxTrays: 2 ,minHeightBetweenTrays: 50, maxWagonHeight: 200 }; - vmEdit.wagonTypeColors = vmCreate.wagonTypeColors = [{id: 1, color:'white', rgb:'#000000'}]; - }); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('addTray()', () => { - it('should throw message if there are uncomplete trays', async () => { - vi.spyOn(vmEdit.quasar, 'notify'); - vmEdit.wagon = [{ - id: 1, - position: null, - color: vmEdit.wagonTypeColors[0] - }]; - - await vmEdit.addTray(); - - expect(vmEdit.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - type: 'warning', - }) - ); - }); - - it('should create a new tray if the limit has not been reached', async () => { - vmEdit.wagon = [{ - id: 1, - position: 0, - color: vmEdit.wagonTypeColors[0] - }]; - - await vmEdit.addTray(); - expect(vmEdit.wagon.length).toEqual(2); - }); - - it('should throw message if there are uncomplete trays', async () => { - vi.spyOn(vmEdit.quasar, 'notify'); - vmEdit.wagon = [{ - id: 1, - position: 0, - color: vmEdit.wagonTypeColors[0] - },{ - id: 2, - position: 50, - color: vmEdit.wagonTypeColors[0] - }]; - - await vmEdit.addTray(); - - expect(vmEdit.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - type: 'warning', - }) - ); - }); - }); - - describe('deleteTray() reorderIds()', () => { - it('should delete a tray and reorder the ids', async () => { - const trayToDelete = { - id: 1, - position: 0, - color: vmEdit.wagonTypeColors[0] - }; - const trayMaintained = { - id: 2, - position: 50, - color: vmEdit.wagonTypeColors[0] - }; - vmEdit.wagon = [trayToDelete,trayMaintained]; - - await vmEdit.deleteTray(trayToDelete); - - expect(vmEdit.wagon.length).toEqual(1); - expect(vmEdit.wagon[0].id).toEqual(0); - expect(vmEdit.wagon[0].position).toEqual(50); - - }); - }); - - describe('onSubmit()', () => { - it('should make a patch to editWagonType if have id', async () => { - vi.spyOn(axios, 'patch').mockResolvedValue({ data: true }); - const wagon = { - id: entityId, - name: "Mock name", - divisible: true, - trays: [{ - id: 1, - position: 0, - color: vmEdit.wagonTypeColors[0] - }] - } - vmEdit.name = wagon.name; - vmEdit.divisible = wagon.divisible; - vmEdit.wagon = wagon.trays; - - await vmEdit.onSubmit(); - - expect(axios.patch).toHaveBeenCalledWith( - `WagonTypes/editWagonType`, wagon - ); - }); - - it('should make a patch to createtWagonType if not have id', async () => { - vi.spyOn(axios, 'patch').mockResolvedValue({ data: true }); - const wagon = { - name: "Mock name", - divisible: true, - trays: [{ - id: 1, - position: 0, - color: vmCreate.wagonTypeColors[0] - }] - } - vmCreate.name = wagon.name; - vmCreate.divisible = wagon.divisible; - vmCreate.wagon = wagon.trays; - - await vmCreate.onSubmit(); - - expect(axios.patch).toHaveBeenCalledWith( - `WagonTypes/createWagonType`, wagon - ); - }); - }); - - describe('onReset()', () => { - it('should reset if have id', async () => { - vmEdit.name = 'Changed name'; - vmEdit.divisible = false; - vmEdit.wagon = []; - vmEdit.originalData = { - name: 'Original name', - divisible: true, - trays: [{ - id: 1, - position: 0, - color: vmEdit.wagonTypeColors[0] - },{ - id: 2, - position: 50, - color: vmEdit.wagonTypeColors[0] - }] - }; - - vmEdit.onReset(); - - expect(vmEdit.name).toEqual(vmEdit.originalData.name); - expect(vmEdit.divisible).toEqual(vmEdit.originalData.divisible); - expect(vmEdit.wagon).toEqual(vmEdit.originalData.trays); - }); - - it('should reset if not have id', async () => { - vmCreate.name = 'Changed name'; - vmCreate.divisible = false; - vmCreate.wagon = []; - - vmCreate.onReset(); - - expect(vmCreate.name).toEqual(null); - expect(vmCreate.divisible).toEqual(false); - expect(vmCreate.wagon.length).toEqual(1); - }); - }); - - describe('onPositionBlur()', () => { - it('should set position null if position is negative', async () => { - const negativeTray = { - id: 1, - position: -1, - color: vmCreate.wagonTypeColors[0] - }; - - vmCreate.onPositionBlur(negativeTray); - - expect(negativeTray.position).toEqual(null); - }); - - it('should set position and reorder array', async () => { - const trays = [{ - id: 0, - position: 100, - color: vmCreate.wagonTypeColors[0] - },{ - id: 1, - position: 0, - color: vmCreate.wagonTypeColors[0] - }]; - const newTray = { - id: 2, - position: 50, - color: vmCreate.wagonTypeColors[0] - }; - trays.push(newTray); - vmCreate.wagon = trays; - - vmCreate.onPositionBlur(newTray); - - expect(vmCreate.wagon[0].position).toEqual(100); - expect(vmCreate.wagon[1].position).toEqual(50); - expect(vmCreate.wagon[2].position).toEqual(0); - }); - - it('should throw message if not have min height between trays and should set new adequate positions', async () => { - vi.spyOn(vmCreate.quasar, 'notify'); - const trays = [{ - id: 0, - position: 0, - color: vmCreate.wagonTypeColors[0] - }]; - const newTray = { - id: 1, - position: 20, - color: vmCreate.wagonTypeColors[0] - }; - trays.push(newTray); - vmCreate.wagon = trays; - - vmCreate.onPositionBlur(newTray); - - expect(vmCreate.wagon[0].position).toEqual(50); - expect(vmCreate.wagon[1].position).toEqual(0); - expect(vmCreate.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - type: 'warning', - }) - ); - }); - - it('should throw message if max height has been exceed', async () => { - vi.spyOn(vmCreate.quasar, 'notify'); - const trays = [{ - id: 0, - position: 0, - color: vmCreate.wagonTypeColors[0] - }]; - const newTray = { - id: 1, - position: 210, - color: vmCreate.wagonTypeColors[0] - }; - trays.push(newTray); - vmCreate.wagon = trays; - - vmCreate.onPositionBlur(newTray); - - expect(vmCreate.wagon.length).toEqual(1); - expect(vmCreate.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ - type: 'warning', - }) - ); - }); - }); -});