From ea9828328ecd370a76dbff1430afcf6cb33ffad6 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 13 Feb 2023 15:19:43 +0100 Subject: [PATCH 01/10] feat(claim): migrate photos section --- .eslintrc.js | 1 + .../ui/{Confirm.vue => VnConfirm.vue} | 27 ++- src/pages/Claim/Card/ClaimPhoto.vue | 207 ++++++++++++++++++ src/router/modules/claim.js | 11 +- 4 files changed, 240 insertions(+), 6 deletions(-) rename src/components/ui/{Confirm.vue => VnConfirm.vue} (62%) create mode 100644 src/pages/Claim/Card/ClaimPhoto.vue diff --git a/.eslintrc.js b/.eslintrc.js index d2fe165a5..09dc09c1e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -57,6 +57,7 @@ module.exports = { // add your custom rules here rules: { 'prefer-promise-reject-errors': 'off', + 'no-unused-vars': 'warn', // allow debugger during development only 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', diff --git a/src/components/ui/Confirm.vue b/src/components/ui/VnConfirm.vue similarity index 62% rename from src/components/ui/Confirm.vue rename to src/components/ui/VnConfirm.vue index bd261f7b4..2c84eeac3 100644 --- a/src/components/ui/Confirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -4,13 +4,17 @@ import { useDialogPluginComponent } from 'quasar'; import { useI18n } from 'vue-i18n'; const $props = defineProps({ - question: { + icon: { type: String, default: '', }, + question: { + type: String, + default: 'Confirm', + }, message: { type: String, - default: '', + default: 'Are you sure you want to continue?', }, }); @@ -20,13 +24,21 @@ const { dialogRef, onDialogOK } = useDialogPluginComponent(); const { t } = useI18n(); const question = ref($props.question); -const message = ref($props.question); +const message = ref($props.message); const isLoading = ref(false); \ No newline at end of file + diff --git a/src/pages/Claim/Card/ClaimPhoto.vue b/src/pages/Claim/Card/ClaimPhoto.vue index 354787878..8d269bbce 100644 --- a/src/pages/Claim/Card/ClaimPhoto.vue +++ b/src/pages/Claim/Card/ClaimPhoto.vue @@ -25,6 +25,10 @@ const claimDms = ref([ }, ]); const client = ref({}); + +const inputFile = ref(); +const files = ref({}); + const claimDmsRef = ref(); const dmsType = ref({}); const config = ref({}); @@ -96,20 +100,11 @@ function setClaimDms(data) { client.value = data.client; } -async function uploadFile() { - const element = document.createElement('input'); - element.setAttribute('type', 'file'); - element.setAttribute('multiple', true); - element.click(); - - element.addEventListener('change', () => { - create(element.files).then(() => claimDmsRef.value.fetch()); - }); -} - -async function create(files) { +async function create() { const formData = new FormData(); - for (let i = 0; i < files.length; i++) formData.append(files[i].name, files[i]); + const inputFiles = files.value; + for (let i = 0; i < inputFiles.length; i++) + formData.append(inputFiles[i].name, inputFiles[i]); const query = `claims/${claimId.value}/uploadFile`; @@ -127,10 +122,7 @@ async function create(files) { }).toUpperCase(), }; - await axios({ - method: 'POST', - url: query, - data: formData, + await axios.post(query, formData, { params: dms, }); @@ -139,11 +131,14 @@ async function create(files) { type: 'positive', icon: 'check', }); + console.log(claimDmsRef); + claimDmsRef.value.fetch(); } function onDrop($data) { dragFile.value = false; - create($data.dataTransfer.files).then(() => claimDmsRef.value.fetch()); + files.value = $data.dataTransfer.files; + create(); } function onDrag() { @@ -190,7 +185,7 @@ function onDrag() {
@@ -245,16 +240,36 @@ function onDrag() {
- - {{ t('globals.add') }} - +
- + diff --git a/test/cypress/integration/claimPhoto.spec.js b/test/cypress/integration/claimPhoto.spec.js index a11f7208b..a6b4286cb 100755 --- a/test/cypress/integration/claimPhoto.spec.js +++ b/test/cypress/integration/claimPhoto.spec.js @@ -3,13 +3,14 @@ describe('ClaimPhoto', () => { beforeEach(() => { const claimId = 1; cy.viewport(1280, 720); - cy.login('developer'); - cy.visit(`/#/claim/${claimId}/photos`); + cy.login('developer').then(() => { + cy.visit(`/#/claim/${claimId}/photos`); + }); }); - xit('should add new file', () => { - cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click(); - cy.get('.container').selectFile('test/cypress/fixtures/image.jpg', { + it('should add new file', () => { + cy.get('label > .q-btn').click(); + cy.get('label > .q-btn input').selectFile('test/cypress/fixtures/image.jpg', { force: true, }); cy.get('.q-notification__message').should('have.text', 'Data saved'); diff --git a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js index 4aba572c7..e09d15474 100644 --- a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js +++ b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js @@ -1,9 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { ref } from 'vue'; -import { mount } from '@vue/test-utils'; import { createWrapper, axios } from 'app/test/vitest/helper'; import ClaimPhoto from 'pages/Claim/Card/ClaimPhoto.vue'; -import * as FormData from 'form-data'; describe('ClaimPhoto', () => { let vm; @@ -27,6 +24,7 @@ describe('ClaimPhoto', () => { stubs: ['FetchData', 'TeleportSlot'], mocks: { claimDms: [{ dmsFk: 1 }], + claimDmsRef: { hola: 'hola' }, }, }, }).vm; @@ -43,6 +41,9 @@ describe('ClaimPhoto', () => { await vm.deleteDms(0); + expect(axios.post).toHaveBeenCalledWith( + `ClaimDms/${claimMock.claimDms[0].dmsFk}/removeFile` + ); expect(vm.quasar.notify).toHaveBeenCalledWith( expect.objectContaining({ type: 'positive' }) ); @@ -86,15 +87,17 @@ describe('ClaimPhoto', () => { }); }); - describe.skip('create()', () => { + describe('create()', () => { it('should upload file and call quasar notify', async () => { const files = [{ name: 'firstFile' }]; + + vi.mock('claimDmsRef', {}); vi.spyOn(axios, 'post').mockResolvedValue({ data: true }); vi.spyOn(vm.quasar, 'notify'); await vm.create(files); - expect(axios).toHaveBeenCalledWith( + expect(axios.post).toHaveBeenCalledWith( expect.objectContaining({ type: 'positive' }) ); expect(vm.quasar.notify).toHaveBeenCalledWith( diff --git a/test/vitest/helper.js b/test/vitest/helper.js index 795879ebd..c22d9b0c9 100644 --- a/test/vitest/helper.js +++ b/test/vitest/helper.js @@ -30,36 +30,36 @@ vi.mock('vue-router', () => ({ }), })); -// class FormDataMock { -// append() { -// vi.fn(); -// } -// delete() { -// vi.fn(); -// } -// get() { -// vi.fn(); -// } -// getAll() { -// vi.fn(); -// } -// has() { -// vi.fn(); -// } -// set() { -// vi.fn(); -// } -// forEach() { -// vi.fn(); -// } -// } +class FormDataMock { + append() { + vi.fn(); + } + delete() { + vi.fn(); + } + get() { + vi.fn(); + } + getAll() { + vi.fn(); + } + has() { + vi.fn(); + } + set() { + vi.fn(); + } + forEach() { + vi.fn(); + } +} +global.FormData = FormDataMock; export function createWrapper(component, options) { const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false }); const defaultOptions = { global: { - // FormData: FormDataMock, plugins: [i18n, pinia], }, }; From c1059bdb2d47c2daaa3edeb488eadcf7e683071f Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 24 Feb 2023 12:51:29 +0100 Subject: [PATCH 10/10] test: front and e2e --- src/pages/Claim/Card/ClaimCard.vue | 14 -------------- src/pages/Claim/Card/ClaimPhoto.vue | 15 +++++++++++++-- test/cypress/integration/claimPhoto.spec.js | 16 ++++++++++------ test/cypress/support/commands.js | 2 +- .../__tests__/pages/Claims/ClaimPhoto.spec.js | 15 ++++++++++----- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/pages/Claim/Card/ClaimCard.vue b/src/pages/Claim/Card/ClaimCard.vue index 2308a5e14..f66af86cb 100644 --- a/src/pages/Claim/Card/ClaimCard.vue +++ b/src/pages/Claim/Card/ClaimCard.vue @@ -11,20 +11,6 @@ const state = useState(); - - - - - - - Detalles - - diff --git a/src/pages/Claim/Card/ClaimPhoto.vue b/src/pages/Claim/Card/ClaimPhoto.vue index 8d269bbce..ba974ca87 100644 --- a/src/pages/Claim/Card/ClaimPhoto.vue +++ b/src/pages/Claim/Card/ClaimPhoto.vue @@ -13,6 +13,7 @@ import FetchData from 'components/FetchData.vue'; const router = useRouter(); const { t } = useI18n(); + const session = useSession(); const token = session.getToken(); const quasar = useQuasar(); @@ -131,7 +132,7 @@ async function create() { type: 'positive', icon: 'check', }); - console.log(claimDmsRef); + claimDmsRef.value.fetch(); } @@ -269,7 +270,17 @@ function onDrag() { @click="inputFile.nativeEl.click()" icon="add_circle" :label="t('globals.add')" - /> + > + + {{ t('globals.add') }} + diff --git a/test/cypress/integration/claimPhoto.spec.js b/test/cypress/integration/claimPhoto.spec.js index a6b4286cb..e5ea2ce25 100755 --- a/test/cypress/integration/claimPhoto.spec.js +++ b/test/cypress/integration/claimPhoto.spec.js @@ -2,10 +2,8 @@ describe('ClaimPhoto', () => { beforeEach(() => { const claimId = 1; - cy.viewport(1280, 720); - cy.login('developer').then(() => { - cy.visit(`/#/claim/${claimId}/photos`); - }); + cy.login('developer'); + cy.visit(`/#/claim/${claimId}/photos`); }); it('should add new file', () => { @@ -41,9 +39,15 @@ describe('ClaimPhoto', () => { ); }); - it('should remove first file', () => { + it('should remove third and fourth file', () => { cy.get( - '.multimediaParent > :nth-child(1) > .q-btn > .q-btn__content > .q-icon' + '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' + ).click(); + cy.get('.q-btn--standard > .q-btn__content > .block').click(); + cy.get('.q-notification__message').should('have.text', 'Data deleted'); + + cy.get( + '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' ).click(); cy.get('.q-btn--standard > .q-btn__content > .block').click(); cy.get('.q-notification__message').should('have.text', 'Data deleted'); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 4ab3ae23f..a3a61c423 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -28,7 +28,7 @@ // Imports Quasar Cypress AE predefined commands // import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress'; Cypress.Commands.add('login', (user) => { - cy.visit('/#/login'); + //cy.visit('/#/login'); cy.request({ method: 'POST', url: '/api/accounts/login', diff --git a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js index e09d15474..33862445d 100644 --- a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js +++ b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js @@ -21,10 +21,9 @@ describe('ClaimPhoto', () => { beforeAll(() => { vm = createWrapper(ClaimPhoto, { global: { - stubs: ['FetchData', 'TeleportSlot'], + stubs: ['FetchData', 'TeleportSlot', 'vue-i18n'], mocks: { - claimDms: [{ dmsFk: 1 }], - claimDmsRef: { hola: 'hola' }, + fetch: vi.fn(), }, }, }).vm; @@ -91,18 +90,24 @@ describe('ClaimPhoto', () => { it('should upload file and call quasar notify', async () => { const files = [{ name: 'firstFile' }]; - vi.mock('claimDmsRef', {}); 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( - expect.objectContaining({ type: 'positive' }) + '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(); }); }); });