test: improve test
gitea/salix-front/pipeline/pr-dev There was a failure building this commit Details

This commit is contained in:
Javier Segarra 2025-02-24 02:10:19 +01:00
parent e1173c2ab1
commit 66d327a552
7 changed files with 185 additions and 239 deletions

View File

@ -2,7 +2,7 @@
import { ref } from 'vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import split from './components/split';
import { splitTicket } from './components/split';
const emit = defineEmits(['ticketTransfered']);
const $props = defineProps({
@ -12,6 +12,8 @@ const $props = defineProps({
},
});
const { split } = splitTicket();
const splitDate = ref(Date.vnNew());
const splitSelectedRows = async () => {

View File

@ -1,25 +1,24 @@
import axios from 'axios';
import notifyResults from 'src/utils/notifyResults';
import { showResultsAsTable } from 'src/composables/showResultsTable';
import HandleSplitDialog from 'src/pages/Ticket/Negative/components/HandleSplitDialog.vue';
export default async function (data, date) {
const reducedData = data.reduce((acc, item) => {
const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
if (existing) {
existing.sales.push(item.saleFk);
} else {
acc.push({ ticketFk: item.id, sales: [item.saleFk], date });
}
return acc;
}, []);
const promises = reducedData.map((params) => axios.post(`Tickets/split`, params));
export function splitTicket() {
const { openTable } = showResultsAsTable();
const results = await Promise.allSettled(promises);
openTable(HandleSplitDialog, result, 'ticketFk', 'changeState');
async function split(data, date) {
const reducedData = data.reduce((acc, item) => {
const existing = acc.find(({ ticketFk }) => ticketFk === item.ticketFk);
if (existing) {
existing.sales.push(item.saleFk);
} else {
acc.push({ ticketFk: item.ticketFk, sales: [item.saleFk], landed: date });
}
return acc;
}, []);
notifyResults(results, 'ticketFk');
const promises = reducedData.map((params) => axios.post(`Tickets/split`, params));
return results;
const result = await Promise.allSettled(promises);
openTable(HandleSplitDialog, result, 'ticket', 'split');
}
return { split };
}

View File

@ -1,18 +1,12 @@
<script setup>
import { ref } from 'vue';
import axios from 'axios';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import VnSelect from 'src/components/common/VnSelect.vue';
import notifyResults from 'src/utils/notifyResults';
import { showResultsAsTable } from 'src/composables/showResultsTable';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import HandleSplitDialog from './HandleSplitDialog.vue';
const { openTable } = showResultsAsTable();
const emit = defineEmits(['update-item']);
const quasar = useQuasar();
const { t } = useI18n();
const showChangeItemDialog = ref(false);
const newItem = ref(null);
@ -37,7 +31,6 @@ const updateItem = async () => {
const result = await Promise.allSettled(rowsToUpdate);
openTable(HandleSplitDialog, result, 'ticketFk', 'changeItem');
// notifyResults(result, 'saleFk');
emit('update-item', newItem.value);
} catch (err) {
console.error('Error updating item:', err);

View File

@ -2,7 +2,6 @@
import { ref } from 'vue';
import axios from 'axios';
import VnInput from 'src/components/common/VnInput.vue';
// import notifyResults from 'src/utils/notifyResults';
import { showResultsAsTable } from 'src/composables/showResultsTable';
import HandleSplitDialog from './HandleSplitDialog.vue';
const { openTable } = showResultsAsTable();
@ -16,24 +15,17 @@ const $props = defineProps({
});
const emit = defineEmits(['update-quantity']);
const updateQuantity = async () => {
try {
showChangeQuantityDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ saleFk }) =>
axios.post(`Sales/${saleFk}/updateQuantity`, {
saleFk,
quantity: +newQuantity.value,
}),
);
showChangeQuantityDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ saleFk }) =>
axios.post(`Sales/${saleFk}/updateQuantity`, {
saleFk,
quantity: +newQuantity.value,
}),
);
const result = await Promise.allSettled(rowsToUpdate);
openTable(HandleSplitDialog, result, 'ticketFk', 'changeQuantity');
// notifyResults(result, 'saleFk');
emit('update-quantity', newQuantity.value);
} catch (err) {
return err;
}
const result = await Promise.allSettled(rowsToUpdate);
openTable(HandleSplitDialog, result, 'ticketFk', 'changeQuantity');
emit('update-quantity', newQuantity.value);
};
</script>

View File

@ -5,7 +5,6 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import FetchData from 'components/FetchData.vue';
import { showResultsAsTable } from 'src/composables/showResultsTable';
import HandleSplitDialog from './HandleSplitDialog.vue';
// import notifyResults from 'src/utils/notifyResults';
const { openTable } = showResultsAsTable();
const emit = defineEmits(['update-state']);
@ -19,7 +18,6 @@ const $props = defineProps({
},
});
const updateState = async () => {
try {
showChangeStateDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ ticketFk }) =>
axios.post(`Tickets/state`, {
@ -27,15 +25,11 @@ const updateState = async () => {
code: newState.value,
}),
);
const result = await Promise.allSettled(rowsToUpdate);
openTable(HandleSplitDialog, result, 'ticketFk', 'changeState');
// notifyResults(result, 'ticketFk');
emit('update-state', newState.value);
} catch (err) {
return err;
}
};
</script>

View File

@ -6,7 +6,6 @@ import FetchData from 'components/FetchData.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
const { t } = useI18n();
const newState = ref(null);
const $props = defineProps({
results: {
type: Array,
@ -25,10 +24,8 @@ const $props = defineProps({
default: '',
},
});
console.error($props.tag, 'results', $props.results);
const results = ref($props.results);
// const rowsSelected = ref([]);
const states = ref([]);
const columns = computed(() => [
{
@ -44,30 +41,18 @@ const columns = computed(() => [
sortable: true,
align: 'center',
},
// {
// name: 'newTicket',
// label: t('negative.split.newTicket'),
// field: ({ newTicket }) => newTicket,
// sortable: true,
// },
{
name: 'statusText',
label: t('negative.split.message'),
sortable: true,
align: 'center',
},
// {
// name: 'actions',
// align: 'center',
// label: t('negative.split.actions'),
// // style: 'padding-left: 100px',
// // headerStyle: 'padding-left: 100px',
// },
]);
function handleMessage(value) {
const actions = {
changeState: {},
};
function getState(value) {
return states.value.find((state) => state.id === value)?.name;
}
function getTicketRejected(row) {
return JSON.parse(row.reason.config.data)?.ticketFk;
}
function getIcon(value) {
const icons = {
@ -86,19 +71,17 @@ function getIcon(value) {
};
return icons[value];
}
const states = ref([]);
</script>
<template>
<QDialog ref="dialogRef" @hide="onDialogHide">
<QDialog ref="dialogRef" @hide="onDialogHide" data-cy="handleSplitDialog">
<FetchData
v-if="$props.action === 'changeState'"
url="States"
@on-fetch="(data) => (states = data)"
auto-load
/>
<QCard class="q-pa-sm">
<QCard class="q-pa-sm" style="width: 60vw; max-width: 80vw">
<QCardSection class="row items-center q-pb-none">
<QAvatar
:icon="icon"
@ -107,12 +90,13 @@ const states = ref([]);
size="xl"
v-if="icon"
/>
<span class="text-h6 text-grey">{{ t($props.title) }}</span>
<span class="text-h6 text-grey"
>{{ t($props.title) }} ({{ $props.action }})
</span>
<QSpace />
<QBtn icon="close" flat round dense v-close-popup />
</QCardSection>
<QCardSection class="row items-center justify-center column items-stretch">
{{ results }}
<QTable
:rows="results"
:columns="columns"
@ -124,9 +108,7 @@ const states = ref([]);
auto-load
>
<template #header="props">
<!-- {{ props }} -->
<QTr :props="props">
<!-- <QTh></QTh> -->
<QTh v-for="col in props.cols" :key="col.name" :props="props">
{{ t(col.label) }}
</QTh>
@ -146,18 +128,21 @@ const states = ref([]);
<template #body-cell-value="{ row }">
<QTd align="center">
<div class="link" @click.stop>
<span v-if="row.status === 'fulfilled'">
*{{ row.value.data[$props.tag] }}
<TicketDescriptorProxy
:id="row.value.data[$props.tag]"
>
</TicketDescriptorProxy>
</span>
<div v-if="row.status === 'fulfilled'">
<span v-if="$props.action !== 'changeItem'">
{{ row.value.data[$props.tag] }}
<TicketDescriptorProxy
:id="row.value.data[$props.tag]"
>
</TicketDescriptorProxy>
</span>
<span v-else>
{{ JSON.parse(row.value.config.data).ticketFk }}
</span>
</div>
<span v-else>
{{ JSON.parse(row.reason.config.data)?.ticketFk
}}<TicketDescriptorProxy
:id="JSON.parse(row.reason.config.data)?.ticketFk"
>
{{ getTicketRejected(row)
}}<TicketDescriptorProxy :id="getTicketRejected(row)">
</TicketDescriptorProxy
></span>
</div>
@ -167,18 +152,11 @@ const states = ref([]);
<QTd align="center">
<div v-if="row.status === 'fulfilled'">
<div v-if="$props.action === 'changeState'">
{{
states.find(
(state) =>
state.id === row.value.data.stateFk,
)?.name
}}
{{ getState(row.value.data.stateFk) }}
</div>
<div v-if="$props.action === 'split'">
<span class="link" @click.stop>
{{ value }}
<TicketDescriptorProxy :id="value">
</TicketDescriptorProxy>
<span>
{{ row.value.data.status }}
</span>
</div>
<div v-if="$props.action === 'changeItem'">
@ -197,43 +175,6 @@ const states = ref([]);
</template>
</QTable>
</QCardSection>
<QCardActions align="right">
<QBtn
:label="t('globals.cancel')"
color="primary"
flat
v-close-popup
/> </QCardActions
></QCard>
</QCard>
</QDialog>
</template>
<style lang="scss" scoped>
.splitRow {
border: 1px solid #ec8916;
border-width: 1px 0 1px 0;
}
.list {
max-height: 100%;
padding: 15px;
width: 100%;
}
.grid-style-transition {
transition:
transform 0.28s,
background-color 0.28s;
}
#true {
background-color: $positive;
}
#false {
background-color: $negative;
}
div.q-dialog__inner > div {
max-width: fit-content !important;
}
</style>

View File

@ -1,8 +1,8 @@
/// <reference types="cypress" />
const firstRow = 'tr.cursor-pointer > :nth-child(1)';
describe('Ticket Lack detail', () => {
beforeEach(() => {
cy.viewport(1280, 720);
cy.login('developer');
cy.intercept('GET', /\/api\/Tickets\/itemLack\/88.*$/).as('getItemLack');
cy.visit('/#/ticket/negative/88');
@ -16,23 +16,22 @@ describe('Ticket Lack detail', () => {
cy.domContentLoad();
cy.waitForElement('.q-table');
});
describe.skip('Table detail', () => {
describe('Table detail', () => {
it('should open descriptors', () => {
cy.get('.q-table').should('be.visible');
cy.get('[data-col-field="nickname"]').click();
cy.dataCy('customerDescriptorProxy').should('be.visible');
cy.get('.q-item > .q-item__label').should('have.text', ' #1 content_copy');
cy.get('[data-col-field="zoneName"]').click();
cy.dataCy('zoneDescriptorProxy').should('be.visible');
cy.get('.q-item > .q-item__label').should('have.text', ' #1 content_copy');
cy.get('.q-item > .q-item__label').should('have.text', ' #1');
cy.get('[data-col-field="ticketFk"]').click();
cy.dataCy('ticketDescriptorProxy').should('be.visible');
cy.get('.q-item > .q-item__label').should(
'have.text',
' #1000000 content_copy',
);
cy.get('.q-item > .q-item__label').should('have.text', ' #1000000');
cy.get('[data-col-field="nickname"] > .no-padding > .link').click();
cy.waitForElement('[data-cy="customerDescriptorProxy"]');
cy.dataCy('customerDescriptorProxy').should('be.visible');
cy.get('.q-item > .q-item__label').should('have.text', ' #1');
});
it.only('should display only one row in the lack list', () => {
it('should display only one row in the lack list', () => {
cy.get('[data-cy="changeItem"]').should('be.disabled');
cy.get('[data-cy="changeState"]').should('be.disabled');
cy.get('[data-cy="changeQuantity"]').should('be.disabled');
@ -47,94 +46,130 @@ describe('Ticket Lack detail', () => {
});
});
describe.only('Item proposal', () => {
describe('Split', () => {
beforeEach(() => {
cy.get('tr.cursor-pointer > :nth-child(1)').click();
cy.get(firstRow).click();
cy.get('[data-cy="transferLines"]').click();
});
it('Split', () => {
cy.get('[data-cy="ticketTransferPopup"] > .flex > .q-btn').click();
cy.get('.q-notification').should('be.visible');
cy.get('.q-notification').find('.q-btn').click();
cy.get('.q-notification').should('not.be.visible');
cy.get('[data-cy="handleSplitDialog"]').should('be.visible');
cy.get('[data-cy="handleSplitDialog"]').find(
'tbody > tr > :nth-child(1) > .q-icon',
);
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div')
.should('have.class', 'link');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div.link > div > span')
.should('have.text', '1000000 ');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(3) > div')
.should('have.text', 'noSplit');
});
});
describe('Change Item', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.get('[data-cy="changeItem"]').click();
});
it('Change failed', () => {
cy.get('[data-cy="New item_select"]').click();
cy.get('.q-item').contains('Palito rojo').click();
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
cy.waitForElement('.q-notification');
cy.get('.q-notification').should('be.visible');
cy.get('.q-notification').find('.q-btn').click();
cy.get('[data-cy="handleSplitDialog"]').should('be.visible');
cy.get('[data-cy="handleSplitDialog"]').find(
'tbody > tr > :nth-child(1) > .q-icon',
);
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div')
.should('have.class', 'link');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div.link > span')
.should('have.text', '1000000');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(3) > div')
.should('have.text', 'price retrieval failed');
});
});
describe('Change state', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.get('[data-cy="changeState"]').click();
});
it('Change success', () => {
cy.get('[data-cy="New state_select"]').click();
cy.get('.q-item').contains('OK').click();
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
cy.waitForElement('.q-notification');
cy.get('.q-notification').should('be.visible');
cy.get('.q-notification').find('.q-btn').click();
cy.get('[data-cy="handleSplitDialog"]').should('be.visible');
cy.get('[data-cy="handleSplitDialog"]').find(
'tbody > tr > :nth-child(1) > .q-icon',
);
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div')
.should('have.class', 'link');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div.link > div > span')
.should('have.text', '1000000 ');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(3) > div')
.should('have.text', 'OK');
});
});
describe('change quantity', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.get('[data-cy="changeQuantity"]').click();
});
it('Change success', () => {
cy.get('[data-cy="New quantity_input"]').type(10);
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
cy.waitForElement('.q-notification');
cy.get('.q-notification').should('be.visible');
cy.get('.q-notification').find('.q-btn').click();
cy.get('[data-cy="handleSplitDialog"]').should('be.visible');
cy.get('[data-cy="handleSplitDialog"]').find(
'tbody > tr > :nth-child(1) > .q-icon',
);
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div')
.should('have.class', 'link');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(2) > div.link > div > span')
.should('have.text', '1000000 ');
cy.get('[data-cy="handleSplitDialog"]')
.find('tbody > tr > :nth-child(3) > div')
.should('have.text', '10');
});
});
describe('Item proposal', () => {
beforeEach(() => {
cy.get(firstRow).click();
// cy.intercept('GET', /\/api\/Items\/getSimilar\?.*$/, {
// statusCode: 200,
// body: [
// {
// id: 1,
// longName: 'Ranged weapon longbow 50cm',
// subName: 'Stark Industries',
// tag5: 'Color',
// value5: 'Brown',
// match5: 0,
// match6: 0,
// match7: 0,
// match8: 1,
// tag6: 'Categoria',
// value6: '+1 precission',
// tag7: 'Tallos',
// value7: '1',
// tag8: null,
// value8: null,
// available: 20,
// calc_id: 6,
// counter: 0,
// minQuantity: 1,
// visible: null,
// price2: 1,
// },
// {
// id: 2,
// longName: 'Ranged weapon longbow 100cm',
// subName: 'Stark Industries',
// tag5: 'Color',
// value5: 'Brown',
// match5: 0,
// match6: 1,
// match7: 0,
// match8: 1,
// tag6: 'Categoria',
// value6: '+1 precission',
// tag7: 'Tallos',
// value7: '1',
// tag8: null,
// value8: null,
// available: 50,
// calc_id: 6,
// counter: 1,
// minQuantity: 5,
// visible: null,
// price2: 10,
// },
// {
// id: 3,
// longName: 'Ranged weapon longbow 200cm',
// subName: 'Stark Industries',
// tag5: 'Color',
// value5: 'Brown',
// match5: 1,
// match6: 1,
// match7: 1,
// match8: 1,
// tag6: 'Categoria',
// value6: '+1 precission',
// tag7: 'Tallos',
// value7: '1',
// tag8: null,
// value8: null,
// available: 185,
// calc_id: 6,
// counter: 10,
// minQuantity: 10,
// visible: null,
// price2: 100,
// },
// ],
// }).as('getItemGetSimilar');
cy.get('[data-cy="itemProposal"]').click();
// cy.wait('@getItemGetSimilar');
});
describe('Replace item if', () => {
it('Quantity is less than available', () => {
cy.get(':nth-child(1) > .text-right > .q-btn').click();
});
/* ==== Test Created with Cypress Studio ==== */
it.only('item proposal cells', function () {
it('item proposal cells', () => {
cy.get(
':nth-child(1) > .q-table--col-auto-width > .q-btn > .q-btn__content > .q-icon',
).should('not.be.visible');
@ -152,16 +187,6 @@ describe('Ticket Lack detail', () => {
':nth-child(2) > [data-col-field="tag6"] > .no-padding > .match',
).should('have.class', 'match');
cy.get(':nth-child(2) > [data-col-field="tag7"]').click();
cy.get(
':nth-child(2) > .q-table--col-auto-width > .q-btn > .q-btn__content > .q-icon',
).should('be.visible');
cy.get(':nth-child(2) > .q-table--col-auto-width > .q-btn')
.should('be.enabled')
.click();
// cy.get('.q-notification__message').should(
// 'have.text',
// 'Operación (1) 43 completada con éxito.',
// );
});
});
});