From 81256327280f85a4c2da1b3175b9c1b5e8eda0d2 Mon Sep 17 00:00:00 2001 From: David Tsay <3614296+davetsay@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:25:18 -0800 Subject: [PATCH] Allow form file input to accept other MIME types (#6089) * allow non json raw files upload * add e2e test * compress image --- e2e/helper/addInitFileInputObject.js | 76 ++++++++++++++++++ e2e/test-data/rick.jpg | Bin 0 -> 10259 bytes e2e/tests/functional/forms.e2e.spec.js | 37 +++++++++ .../forms/components/controls/FileInput.vue | 32 +++++++- 4 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 e2e/helper/addInitFileInputObject.js create mode 100644 e2e/test-data/rick.jpg diff --git a/e2e/helper/addInitFileInputObject.js b/e2e/helper/addInitFileInputObject.js new file mode 100644 index 0000000000..257492be74 --- /dev/null +++ b/e2e/helper/addInitFileInputObject.js @@ -0,0 +1,76 @@ +class DomainObjectViewProvider { + constructor(openmct) { + this.key = 'doViewProvider'; + this.name = 'Domain Object View Provider'; + this.openmct = openmct; + } + + canView(domainObject) { + return domainObject.type === 'imageFileInput' + || domainObject.type === 'jsonFileInput'; + } + + view(domainObject, objectPath) { + let content; + + return { + show: function (element) { + const body = domainObject.selectFile.body; + const type = typeof body; + + content = document.createElement('div'); + content.id = 'file-input-type'; + content.textContent = JSON.stringify(type); + element.appendChild(content); + }, + destroy: function (element) { + element.removeChild(content); + content = undefined; + } + }; + } +} + +document.addEventListener('DOMContentLoaded', () => { + const openmct = window.openmct; + + openmct.types.addType('jsonFileInput', { + key: 'jsonFileInput', + name: "JSON File Input Object", + creatable: true, + form: [ + { + name: 'Upload File', + key: 'selectFile', + control: 'file-input', + required: true, + text: 'Select File...', + type: 'application/json', + property: [ + "selectFile" + ] + } + ] + }); + + openmct.types.addType('imageFileInput', { + key: 'imageFileInput', + name: "Image File Input Object", + creatable: true, + form: [ + { + name: 'Upload File', + key: 'selectFile', + control: 'file-input', + required: true, + text: 'Select File...', + type: 'image/*', + property: [ + "selectFile" + ] + } + ] + }); + + openmct.objectViews.addProvider(new DomainObjectViewProvider(openmct)); +}); diff --git a/e2e/test-data/rick.jpg b/e2e/test-data/rick.jpg new file mode 100644 index 0000000000000000000000000000000000000000..98340f6304bac2e1b8131a26c18a12903a5370e0 GIT binary patch literal 10259 zcmbVydt6gzy6(yqh@glI3#d~-gKJ^2To#CzX#*I{6>|Zqk?BTInngEOwDvYzCxD=? zQi~7~;-xXHBwRbSMn|jNgATD?nhv=@6|Fy|9oo{{wrXd_?iu#`Eu5Ki&R^%8_={xa zw$}H3&-=X3^L&}QK6M9+Ruw7>F&+=Y6z~t5x{IxozeZPKm{yCWVi*>V@p&~MY*|Ga>gjPYml1haWlL)epW zMIs(|<30xe@%RFvNE{X(A(;VhI28?-E)ejA0+9%vhPM-5$Aq&*F-aMD;yL<_Vac_4 zX5E3~;S2LmT!=OJ|7%fJ#kTqg$=oO6;uEAPiwQE7%FbDqyL?5#YI)%rg;HfKE-8I( z-Fj2yrp;9^nCa^6FYkEe)z@BsqhWVr)1JNinASGy!S+KPoi;}o>vXxhdwSnL={a@! zcW2IiaPbdA-b)`{zH&7X42_I_di}=O-SN-A_|wFfUwu7!@5lQO9{%*_zx?$P8W+sx z^swOn>5=^(Mjk8j=FZ3x|N{qr^jU&2dXv?!O#EvKmRi6fRH6aUY*sm}nGPfd+skpdoo zNiZ9G7CWbw$99XBlJYbxg>W#KiE!G5j+Q`GorLyGX2>r2i@efATt{cAWfAhUIJ?+J zbWzxDL&ZCVMEozv)O<%LBg? zTrbCPs~)~*>Eolcoc3lNUtdU?F&2HADbq7TDQ?j5^L0^EXq&AHp!-t8exz z6(UC~gOvrU7!_tB346svbHJbzoK)IW1aEsGO|X1;MlYLTQ<3n5+E#;O-v-TaI=C#% z(cWs2s9>z*cBLF!I=Refe*FHKzIkuuFyfU|C+mz|mU_Wf7BB=Ro+PT814gx^?84P& zsVc|qtfJe*mop6-zwOPBO@aokqKxhAq6{TvrB6^*txUxNTb9;gncK<`(R!skeJ%qR zWoDgr{vpZ=7g;FJVX#-sz8prlGPyZuwue=uw7s|l)%#lKph_hNfI-XK3PmE#E88`sIn=G60 zZ*?L;46`Hsz1TEs3!5Oz&}I&-{_#<1QQ^Lsv@F*dQ@j4#FR6Qpmr_+JuWR!+XU|Lj zC25^g`}d8``?ChtFy!^6&(=C4cUGs

<0)DAyL07Bs9M96vUnVZD`wOn>X65qsYJ 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 { test('Required Field indicators appear if title is empty and can be corrected', async ({ page }) => { @@ -68,6 +70,41 @@ test.describe('Form Validation Behavior', () => { }); }); +test.describe('Form File Input Behavior', () => { + test.beforeEach(async ({ page }) => { + // eslint-disable-next-line no-undef + await page.addInitScript({ path: path.join(__dirname, '../../helper', 'addInitFileInputObject.js') }); + }); + + test('Can select a JSON file type', async ({ page }) => { + await page.goto('./', { waitUntil: 'networkidle' }); + + await page.getByRole('button', { name: ' Create ' }).click(); + await page.getByRole('menuitem', { name: 'JSON File Input Object' }).click(); + + await page.setInputFiles('#fileElem', jsonFilePath); + + await page.getByRole('button', { name: 'Save' }).click(); + + const type = await page.locator('#file-input-type').textContent(); + await expect(type).toBe(`"string"`); + }); + + test('Can select an image file type', async ({ page }) => { + await page.goto('./', { waitUntil: 'networkidle' }); + + await page.getByRole('button', { name: ' Create ' }).click(); + await page.getByRole('menuitem', { name: 'Image File Input Object' }).click(); + + await page.setInputFiles('#fileElem', imageFilePath); + + await page.getByRole('button', { name: 'Save' }).click(); + + const type = await page.locator('#file-input-type').textContent(); + await expect(type).toBe(`"object"`); + }); +}); + test.describe('Persistence operations @addInit', () => { // add non persistable root item test.beforeEach(async ({ page }) => { diff --git a/src/api/forms/components/controls/FileInput.vue b/src/api/forms/components/controls/FileInput.vue index ef9a6a3b86..90dfe75c2d 100644 --- a/src/api/forms/components/controls/FileInput.vue +++ b/src/api/forms/components/controls/FileInput.vue @@ -30,7 +30,7 @@ id="fileElem" ref="fileInput" type="file" - accept=".json" + :accept="acceptableFileTypes" style="display:none" >