diff --git a/etc/fixtures/initial-seed/analyses.json b/etc/fixtures/initial-seed/analyses.json index 2b5b7821..b4adc2d3 100644 --- a/etc/fixtures/initial-seed/analyses.json +++ b/etc/fixtures/initial-seed/analyses.json @@ -217,18 +217,14 @@ ] }, { - "type":"supporting-evidence", + "type":"section-supporting-evidence", "field":"Veterinary Histology Report", - "value":[ - - ] + "value":[] }, { - "type":"supporting-evidence", - "field":"Veterinary Pathology Imaging", - "value":[ - - ] + "type":"section-supporting-evidence", + "field":"Veterinary Pathology Imaging", + "value":[] } ] }, diff --git a/etc/fixtures/migrations/migrate-insert-animal-model-systems.js b/etc/fixtures/migrations/migrate-insert-animal-model-systems.js index fe17e925..9f79d360 100644 --- a/etc/fixtures/migrations/migrate-insert-animal-model-systems.js +++ b/etc/fixtures/migrations/migrate-insert-animal-model-systems.js @@ -94,12 +94,12 @@ const animalModelSystemSection = { "value": [] }, { - "type": "supporting-evidence", + "type": "section-supporting-evidence", "field": "Veterinary Histology Report", "value": [] }, { - "type": "supporting-evidence", + "type": "section-supporting-evidence", "field": "Veterinary Pathology Imaging", "value": [] } diff --git a/frontend/src/components/AnalysisView/SectionBox.vue b/frontend/src/components/AnalysisView/SectionBox.vue index c7b840f3..6ecfafff 100644 --- a/frontend/src/components/AnalysisView/SectionBox.vue +++ b/frontend/src/components/AnalysisView/SectionBox.vue @@ -41,7 +41,8 @@ :writePermissions="this.writePermissions" :data-test="contentRow.field" @update-annotation-image="this.onUpdateImageEmit" - @update:section-text="this.onContentChanged" + @update:section-content="this.onContentChanged" + @download="this.onDownload" /> @@ -50,13 +51,15 @@ diff --git a/frontend/src/components/AnalysisView/SectionSupportingEvidence.vue b/frontend/src/components/AnalysisView/SectionSupportingEvidence.vue new file mode 100644 index 00000000..eacb2455 --- /dev/null +++ b/frontend/src/components/AnalysisView/SectionSupportingEvidence.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/frontend/src/components/AnalysisView/SectionText.vue b/frontend/src/components/AnalysisView/SectionText.vue index bc9b3312..f218c3aa 100644 --- a/frontend/src/components/AnalysisView/SectionText.vue +++ b/frontend/src/components/AnalysisView/SectionText.vue @@ -26,7 +26,7 @@ diff --git a/frontend/test/components/AnalysisView/SectionSupportingEvidence.spec.js b/frontend/test/components/AnalysisView/SectionSupportingEvidence.spec.js new file mode 100644 index 00000000..34c51d35 --- /dev/null +++ b/frontend/test/components/AnalysisView/SectionSupportingEvidence.spec.js @@ -0,0 +1,50 @@ +import {describe, it, expect} from 'vitest'; +import {shallowMount} from '@vue/test-utils'; + +import SectionSupportingEvidence from '@/components/AnalysisView/SectionSupportingEvidence.vue'; +import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'; + +/** + * Helper mounts and returns the rendered component + * @param {props} props props for testing to overwrite default props + * @return {VueWrapper} returns a shallow mounted using props + */ +function getMountedComponent(props) { + const defaultPropsData = { + field: 'Vetrinary Pathology Report', + value: [{ + 'name': 'CPAM0046-NM_170707.3 (LMNA)_ c.745C_T (p.R249W) other 2.PDF', + 'attachment_id': '64dbcfa43d243bf1e782499f', + 'type': 'file', + 'comments': '', + }], + editable: true, + writePermissions: true, + }; + + return shallowMount(SectionSupportingEvidence, { + props: {...defaultPropsData, ...props}, + global: { + components: { + 'font-awesome-icon': FontAwesomeIcon, + }, + }, + }); +} + +describe('SectionSupportingEvidence.vue', () => { + let wrapper; + + it('renders the supporting evidence when the value exists', async () => { + wrapper = getMountedComponent(); + expect(wrapper.html()).to.include('CPAM0046'); + }); + + it('renders an attach button when there is not content to render', () => { + wrapper = getMountedComponent({ + value: [], + }); + const attachButton = wrapper.find('[data-test="attach-button-Vetrinary Pathology Report"]'); + expect(attachButton.exists()).to.be.true; + }); +}); diff --git a/frontend/test/views/AnalysisView.spec.js b/frontend/test/views/AnalysisView.spec.js index 03a8efa0..f03b4125 100644 --- a/frontend/test/views/AnalysisView.spec.js +++ b/frontend/test/views/AnalysisView.spec.js @@ -89,6 +89,8 @@ describe('AnalysisView', () => { let markReadyMock; let updateAnalysisSectionsMock; let mockAuthWritePermissions; + let mockedAttachSectionSupportingEvidence; + let mockedRemoveSectionSupportingEvidenceFile; let wrapper; let sandbox; @@ -105,6 +107,9 @@ describe('AnalysisView', () => { mockedRemoveSupportingEvidence = sandbox.stub(Analyses, 'removeSupportingEvidence'); mockedAttachThirdPartyLink = sandbox.stub(Analyses, 'attachThirdPartyLink'); + mockedAttachSectionSupportingEvidence = sandbox.stub(Analyses, 'attachSectionSupportingEvidence'); + mockedRemoveSectionSupportingEvidenceFile = sandbox.stub(Analyses, 'removeSectionSupportingEvidenceFile'); + markReadyMock = sandbox.stub(Analyses, 'pushAnalysisEvent'); updateAnalysisSectionsMock = sandbox.stub(Analyses, 'updateAnalysisSections'); @@ -143,7 +148,7 @@ describe('AnalysisView', () => { it('provides the expected headings of sections to be used as anchors', () => { const headerComponent = wrapper.get('[data-test="analysis-view-header"]'); expect(headerComponent.attributes('sectionanchors')).to.equal( - 'Brief,Medical Summary,Pedigree,Case Information,Supporting Evidence', + 'Brief,Medical Summary,Mus musculus (Mouse) Model System,Pedigree,Case Information,Supporting Evidence', ); }); @@ -545,6 +550,104 @@ describe('AnalysisView', () => { expect(failureNotificationDialog.exists()).to.be.true; }); }); + + describe('when a section has a field that allows supporting evidence to be attached.', () => { + it('attaches supporting evidence to a field in the section', async () => { + const newAttachmentData = { + name: 'fake-attachment-evidence-name', + data: 'http://sites.uab.edu/cgds', + attachment_id: 'new-failure-id', + type: 'link', + comments: '', + }; + + mockedAttachSectionSupportingEvidence.returns({ + header: 'Mus_musculus (Mouse) Model System', + field: 'Veterinary Pathology Imaging', + field_value: { + type: 'section-supporting-evidence', + field: 'Veterinary Pathology Imaging', + value: [{ + ...newAttachmentData, + attachment_id: 'new-failure-id', + }], + }, + }); + + const mouseSection = wrapper.getComponent('[id=Mus_musculus (Mouse) Model System]'); + + const mouseFieldToUpdate = mouseSection.props('content').find((row) => { + return row.field == 'Veterinary Pathology Imaging'; + }); + + expect(mouseFieldToUpdate.value.length).to.equal(0); + + mouseSection.vm.$emit('update:content-row', { + type: 'supporting-evidence', + operation: 'attach', + header: 'Mus musculus (Mouse) Model System', + field: 'Veterinary Pathology Imaging', + value: {}, + }); + await wrapper.vm.$nextTick(); + + inputDialog.confirmation(newAttachmentData); + + // Needs to cycle through updating the prop in the view and then another + // tick for vuejs to reactively update the supplemental component + await wrapper.vm.$nextTick(); + await wrapper.vm.$nextTick(); + + const updatedMouseSection = wrapper.getComponent('[id=Mus_musculus (Mouse) Model System]'); + const mouseFieldUpdated = updatedMouseSection.props('content').find((row) => { + return row.field == 'Veterinary Pathology Imaging'; + }); + expect(mouseFieldUpdated.value.length).to.equal(1); + }); + + it('removes the supporting evidence', async () => { + mockedRemoveSectionSupportingEvidenceFile.resolves({ + header: 'Mus_musculus (Mouse) Model System', + field: 'Veterinary Histology Report', + field_value: { + type: 'section-supporting-evidence', + field: 'Veterinary Histology Report', + value: [], + }, + }); + + const mouseSection = wrapper.getComponent('[id=Mus_musculus (Mouse) Model System]'); + const mouseFieldToUpdate = mouseSection.props('content').find((row) => { + return row.field == 'Veterinary Histology Report'; + }); + expect(mouseFieldToUpdate.value.length).to.equal(1); + + mouseSection.vm.$emit('update:content-row', { + type: 'supporting-evidence', + operation: 'delete', + header: 'Mus musculus (Mouse) Model System', + field: 'Veterinary Histology Report', + value: { + type: 'file', + attachment_id: 'FJKLJFKLDJSKLFDS', + }, + }); + await wrapper.vm.$nextTick(); + + notificationDialog.confirmation(); + await wrapper.vm.$nextTick(); + + // Neccesary to process several ticks to re-render the section + await wrapper.vm.$nextTick(); + await wrapper.vm.$nextTick(); + + const updatedMouseSection = wrapper.getComponent('[id=Mus_musculus (Mouse) Model System]'); + const mouseFieldUpdated = updatedMouseSection.props('content').find((row) => { + return row.field == 'Veterinary Histology Report'; + }); + expect(mouseFieldUpdated.value.length).to.equal(0); + }); + }); }); describe('Saving and canceling analysis changes displays toasts', () => { @@ -662,6 +765,40 @@ function fixtureData() { }, ], }, + { + header: 'Mus musculus (Mouse) Model System', + content: [ + { + 'type': 'section-text', + 'field': 'Mutation', + 'value': [ + 'NF1 c.2970-2972del (p.Met992del)', + ], + }, + { + 'type': 'section-text', + 'field': 'Pathogenicity Test', + 'value': [ + + ], + }, + { + 'type': 'section-supporting-evidence', + 'field': 'Veterinary Histology Report', + 'value': [{ + 'name': 'CPAM0046-NM_170707.3 (LMNA)_ c.745C_T (p.R249W) other 2.PDF', + 'attachment_id': '64dbcfa43d243bf1e782499f', + 'type': 'file', + 'comments': ' ', + }], + }, + { + 'type': 'section-supporting-evidence', + 'field': 'Veterinary Pathology Imaging', + 'value': [], + }, + ], + }, { header: 'Pedigree', attachment_field: 'Pedigree',