ref #6104 tests created and searchFn fixed
gitea/salix-front/pipeline/head There was a failure building this commit Details

This commit is contained in:
Jorge Penadés 2023-09-26 11:49:57 +02:00
parent bdf288241b
commit ca28ecdd8e
7 changed files with 154 additions and 94 deletions

View File

@ -9,7 +9,7 @@
"lint": "eslint --ext .js,.vue ./", "lint": "eslint --ext .js,.vue ./",
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test:e2e": "cypress open", "test:e2e": "cypress open",
"test:e2e:ci": "cypress run --browser chromium", "test:e2e:ci": "cypress run --browser chrome",
"test": "echo \"See package.json => scripts for available tests.\" && exit 0", "test": "echo \"See package.json => scripts for available tests.\" && exit 0",
"test:unit": "vitest", "test:unit": "vitest",
"test:unit:ci": "vitest run" "test:unit:ci": "vitest run"

View File

@ -15,15 +15,16 @@ import FetchData from '../FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
const stateStore = useStateStore(); const stateStore = useStateStore();
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const validationsStore = useValidationsStore();
const props = defineProps({ const props = defineProps({
model: { model: {
type: String, type: String,
default: null, default: null,
}, },
}); });
const filter = { const filter = {
fields: [ fields: [
'id', 'id',
@ -160,19 +161,21 @@ function getLogs(data) {
let originLog = null; let originLog = null;
let userLog = null; let userLog = null;
let modelLog = null; let modelLog = null;
let prevLog, prevUser, prevModel; let prevLog;
let nLogs; let nLogs;
data.forEach((log) => { data.forEach((log) => {
const locale = validationsStore.validations[log.changedModel]?.locale || {}; const locale = validations[log.changedModel]?.locale || {};
// Origin // Origin
if (!prevLog || prevLog.originFk != log.originFk) { const originChanged = !prevLog || log.originFk != prevLog.originFk;
if (originChanged) {
logs.push((originLog = { originFk: log.originFk, logs: [] })); logs.push((originLog = { originFk: log.originFk, logs: [] }));
prevLog = log; prevLog = log;
} }
// User // User
if (prevUser != log.userFk) { const userChanged = originChanged || log.userFk != prevLog.userFk;
if (userChanged) {
originLog.logs.push( originLog.logs.push(
(userLog = { (userLog = {
user: log.user, user: log.user,
@ -180,15 +183,14 @@ function getLogs(data) {
logs: [], logs: [],
}) })
); );
prevUser = log.userFk;
} }
// Model // Model
if ( const modelChanged =
!prevModel || userChanged ||
prevModel.changedModelId != log.changedModelId || log.changedModel != prevLog.changedModel ||
prevModel.changedModel != log.changedModel || log.changedModelId != prevLog.changedModelId ||
nLogs >= 6 nLogs >= 6;
) { if (modelChanged) {
userLog.logs.push( userLog.logs.push(
(modelLog = { (modelLog = {
model: log.changedModel, model: log.changedModel,
@ -198,10 +200,6 @@ function getLogs(data) {
logs: [], logs: [],
}) })
); );
prevModel = {
changedModelId: log.changedModelId,
changedModel: log.changedModel,
};
nLogs = 0; nLogs = 0;
} }
nLogs++; nLogs++;
@ -224,12 +222,12 @@ async function openPointRecord(id, modelLog) {
pointRecord.value = null; pointRecord.value = null;
const { data } = await axios.get(`${props.model}Logs/${id}/pitInstance`); const { data } = await axios.get(`${props.model}Logs/${id}/pitInstance`);
const propNames = Object.keys(data); const propNames = Object.keys(data);
const locale = validationsStore.validations[modelLog.model]?.locale || {}; const locale = validations[modelLog.model]?.locale || {};
pointRecord.value = parseProps(propNames, locale, data); pointRecord.value = parseProps(propNames, locale, data);
} }
async function setLogTree() { async function setLogTree() {
if (!validations) { if (!validations) {
validations = await validationsStore.fetchModels(); validations = await useValidationsStore();
} }
filter.where = { and: [{ originFk: route.params.id }] }; filter.where = { and: [{ originFk: route.params.id }] };
const { data } = await axios.get(`${props.model}Logs`, { const { data } = await axios.get(`${props.model}Logs`, {
@ -377,7 +375,7 @@ function filterFn(val, update, abortFn, type) {
const needle = val.toLowerCase(); const needle = val.toLowerCase();
if (type === 'actions') if (type === 'actions')
filteredActions.value = actions.value.filter((item) => filteredActions.value = actions.value.filter((item) =>
item.toLowerCase().includes(needle) t(`models.${item}`).toLowerCase().includes(needle)
); );
if (type === 'workers') { if (type === 'workers') {
if (isNaN(needle)) if (isNaN(needle))
@ -417,11 +415,11 @@ setLogTree();
:key="originLogIndex" :key="originLogIndex"
> >
<QItem class="origin-info items-center q-my-md" v-if="logTree.length > 1"> <QItem class="origin-info items-center q-my-md" v-if="logTree.length > 1">
<h6 class="origin-id"> <h6 class="origin-id text-grey">
{{ originLog.modelI18n }} {{ useFirstUpper(validations[props.model].locale.name) }}
#{{ originLog.originFk }} #{{ originLog.originFk }}
</h6> </h6>
<div class="line"></div> <div class="line bg-grey"></div>
</QItem> </QItem>
<div <div
class="user-log q-mb-sm row" class="user-log q-mb-sm row"
@ -686,7 +684,7 @@ setLogTree();
</QItem> </QItem>
</template> </template>
<template #selected-item="{ opt }"> <template #selected-item="{ opt }">
{{ t(opt) }} {{ t(`models.${opt}`) }}
</template> </template>
</QSelect> </QSelect>
</QItem> </QItem>
@ -875,6 +873,9 @@ setLogTree();
margin-top: 0; margin-top: 0;
} }
& > .origin-info { & > .origin-info {
width: 100%;
max-width: 42em;
margin-top: 28px;
gap: 6px; gap: 6px;
& > .origin-id { & > .origin-id {
@ -885,13 +886,13 @@ setLogTree();
} }
& > .line { & > .line {
flex-grow: 1; flex-grow: 1;
background-color: $primary;
height: 2px; height: 2px;
} }
} }
} }
.user-log { .user-log {
width: 40em; width: 100%;
max-width: 40em;
& > .timeline { & > .timeline {
position: relative; position: relative;

View File

@ -14,10 +14,6 @@ a {
color: $orange-4; color: $orange-4;
} }
.rounded--full {
border-radius: 50%;
}
// Removes chrome autofill background // Removes chrome autofill background
input:-webkit-autofill, input:-webkit-autofill,
select:-webkit-autofill { select:-webkit-autofill {

View File

@ -109,7 +109,7 @@ const setData = (entity) => {
<template #value> <template #value>
<span class="link"> <span class="link">
{{ entity.worker.user.name }} {{ entity.worker.user.name }}
<WorkerDescriptorProxy :id="entity.worker.userFk" /> <WorkerDescriptorProxy :id="entity.worker.id" />
</span> </span>
</template> </template>
</VnLv> </VnLv>

View File

@ -1,19 +1,26 @@
import axios from 'axios'; import axios from 'axios';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
export const useValidationsStore = defineStore('validationsStore', { export const useValidationsStore = async () => {
state: () => ({ const validationsStore = defineStore('validationsStore', {
validations: null, state: () => ({
}), validations: null,
actions: { }),
async fetchModels() { actions: {
if (this.validations) return; async fetchModels() {
try { if (this.validations) return;
const { data } = await axios.get('Schemas/modelinfo'); try {
this.validations = data; const { data } = await axios.get('Schemas/modelinfo');
} catch (error) { this.validations = data;
console.error('Error al obtener las validaciones:', error); } catch (error) {
} console.error('Error al obtener las validaciones:', error);
}
},
}, },
}, });
}); const v = validationsStore();
if (!v.validations) {
await v.fetchModels();
}
return v.validations;
};

View File

@ -2,18 +2,40 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper'; import { createWrapper } from 'app/test/vitest/helper';
import VnLog from 'src/components/common/VnLog.vue'; import VnLog from 'src/components/common/VnLog.vue';
const mockValidations = {
Claim: {
locale: {
name: 'reclamación',
},
},
ClaimObservation: {
locale: {
name: 'observación',
},
},
ClaimDms: {
locale: {
name: 'documento',
},
},
ClaimBeginning: {
locale: {
name: 'comienzo',
},
},
};
describe('VnLog', () => { describe('VnLog', () => {
let vm; let vm;
beforeAll(() => { beforeAll(() => {
vm = createWrapper(VnLog, { vm = createWrapper(VnLog, {
global: { global: {
stubs: ['FetchData', 'VnPaginate'], stubs: [],
mocks: { mocks: {},
fetch: vi.fn(),
},
}, },
propsData: { propsData: {
model: "Claim", model: 'Claim',
}, },
}).vm; }).vm;
}); });
@ -22,54 +44,88 @@ describe('VnLog', () => {
vi.clearAllMocks(); vi.clearAllMocks();
}); });
describe('formatValue()', () => { it('should correctly set logTree', async () => {
it('should return Yes if has a true boolean', async () => { const fakeLogTreeData = [
const result = vm.formatValue(true); {
id: 2,
expect(result).toEqual('Yes'); originFk: 1,
}); userFk: 18,
it('should return No if has a true boolean', async () => { action: 'update',
const result = vm.formatValue(false); changedModel: 'ClaimObservation',
oldInstance: {},
expect(result).toEqual('No'); newInstance: {
}); claimFk: 1,
it('should return Nothing if has no params', async () => { text: 'Waiting for customer',
const result = vm.formatValue();
expect(result).toEqual('Nothing');
});
it('should return a string from a string value', async () => {
const result = vm.formatValue('Something');
expect(result).toEqual(`"Something"`);
});
it('should call to format a date', async () => {
vi.mock('src/filters', () => ({
toDate: ()=>{
return "Date formatted"
}, },
})); creationDate: '2023-09-18T12:25:34.000Z',
changedModelId: '1',
const result = vm.formatValue('01-01-1970'); changedModelValue: null,
expect(result).toEqual("Date formatted"); 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: {
hasToPickUp: false,
},
newInstance: {
hasToPickUp: true,
},
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,
},
},
},
];
vm.validations = mockValidations;
vm.logTree = vm.getLogs(fakeLogTreeData);
expect(vm.logTree[0].originFk).toEqual(1);
expect(vm.logTree[0].logs[0].user.name).toEqual('salesPerson');
}); });
describe('actionColor()', () => { it('should correctly set the selectedFilters when filtering', async () => {
it('should return positive if insert', async () => { await vm.$nextTick();
const result = vm.actionColor('insert'); vm.searchInput = '1';
vm.userSelect = '21';
vm.checkboxOptions.insert.selected = true;
vm.checkboxOptions.update.selected = true;
expect(result).toEqual('positive'); vm.selectFilter('search');
}); vm.selectFilter('userSelect');
it('should return positive if update', async () => {
const result = vm.actionColor('update');
expect(result).toEqual('positive'); expect(vm.selectedFilters.changedModelId).toEqual('1');
}); expect(vm.selectedFilters.userFk).toEqual('21');
it('should return negative if delete', async () => { expect(vm.selectedFilters.action).toEqual({ inq: ['insert', 'update'] });
const result = vm.actionColor('delete'); });
expect(result).toEqual('negative'); it('should correctly set the date from', () => {
vm.date = '18-09-2023';
vm.selectFilter('date', 'from');
expect(vm.selectedFilters.creationDate).toEqual({
between: ['2023-09-18T00:00:00.000Z', '2023-09-18T19:59:59.999Z'],
}); });
}); });
}); });

View File

@ -12,7 +12,7 @@ installQuasarPlugin({
Dialog, Dialog,
}, },
}); });
axios.defaults.baseURL = 'http://localhost:9000/api/';
const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false }); const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false });
const mockPush = vi.fn(); const mockPush = vi.fn();