summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js')
-rw-r--r--spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js99
1 files changed, 75 insertions, 24 deletions
diff --git a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
index b3cdbccb271..21e9b401215 100644
--- a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
+++ b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
jest.mock('~/flash');
@@ -15,6 +16,7 @@ describe('Upload dropzone component', () => {
const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]');
const findIcon = () => wrapper.find(GlIcon);
const findUploadText = () => wrapper.find('[data-testid="upload-text"]').text();
+ const findFileInput = () => wrapper.find('input[type="file"]');
function createComponent({ slots = {}, data = {}, props = {} } = {}) {
wrapper = shallowMount(UploadDropzone, {
@@ -84,47 +86,40 @@ describe('Upload dropzone component', () => {
${'contains text'} | ${mockDragEvent({ types: ['text'] })}
${'contains files and text'} | ${mockDragEvent({ types: ['Files', 'text'] })}
${'contains files'} | ${mockDragEvent({ types: ['Files'] })}
- `('renders correct template when drag event $description', ({ eventPayload }) => {
+ `('renders correct template when drag event $description', async ({ eventPayload }) => {
createComponent();
wrapper.trigger('dragenter', eventPayload);
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.element).toMatchSnapshot();
- });
+ await nextTick();
+ expect(wrapper.element).toMatchSnapshot();
});
- it('renders correct template when dragging stops', () => {
+ it('renders correct template when dragging stops', async () => {
createComponent();
wrapper.trigger('dragenter');
- return wrapper.vm
- .$nextTick()
- .then(() => {
- wrapper.trigger('dragleave');
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- expect(wrapper.element).toMatchSnapshot();
- });
+
+ await nextTick();
+ wrapper.trigger('dragleave');
+
+ await nextTick();
+ expect(wrapper.element).toMatchSnapshot();
});
});
describe('when dropping', () => {
- it('emits upload event', () => {
+ it('emits upload event', async () => {
createComponent();
const mockFile = { name: 'test', type: 'image/jpg' };
const mockEvent = mockDragEvent({ files: [mockFile] });
wrapper.trigger('dragenter', mockEvent);
- return wrapper.vm
- .$nextTick()
- .then(() => {
- wrapper.trigger('drop', mockEvent);
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- expect(wrapper.emitted().change[0]).toEqual([[mockFile]]);
- });
+
+ await nextTick();
+ wrapper.trigger('drop', mockEvent);
+
+ await nextTick();
+ expect(wrapper.emitted().change[0]).toEqual([[mockFile]]);
});
});
@@ -203,4 +198,60 @@ describe('Upload dropzone component', () => {
expect(wrapper.element).toMatchSnapshot();
});
+
+ describe('file input form name', () => {
+ it('applies inputFieldName as file input name', () => {
+ createComponent({ props: { inputFieldName: 'test_field_name' } });
+ expect(findFileInput().attributes('name')).toBe('test_field_name');
+ });
+
+ it('uses default file input name if no inputFieldName provided', () => {
+ createComponent();
+ expect(findFileInput().attributes('name')).toBe('upload_file');
+ });
+ });
+
+ describe('updates file input files value', () => {
+ // NOTE: the component assigns dropped files from the drop event to the
+ // input.files property. There's a restriction that nothing but a FileList
+ // can be assigned to this property. While FileList can't be created
+ // manually: it has no constructor. And currently there's no good workaround
+ // for jsdom. So we have to stub the file input in vm.$refs to ensure that
+ // the files property is updated. This enforces following tests to know a
+ // bit too much about the SUT internals See this thread for more details on
+ // FileList in jsdom: https://github.com/jsdom/jsdom/issues/1272
+ function stubFileInputOnWrapper() {
+ const fakeFileInput = { files: [] };
+ wrapper.vm.$refs.fileUpload = fakeFileInput;
+ }
+
+ it('assigns dragged files to the input files property', async () => {
+ const mockFile = { name: 'test', type: 'image/jpg' };
+ const mockEvent = mockDragEvent({ files: [mockFile] });
+ createComponent({ props: { shouldUpdateInputOnFileDrop: true } });
+ stubFileInputOnWrapper();
+
+ wrapper.trigger('dragenter', mockEvent);
+ await nextTick();
+ wrapper.trigger('drop', mockEvent);
+ await nextTick();
+
+ expect(wrapper.vm.$refs.fileUpload.files).toEqual([mockFile]);
+ });
+
+ it('throws an error when multiple files are dropped on a single file input dropzone', async () => {
+ const mockFile = { name: 'test', type: 'image/jpg' };
+ const mockEvent = mockDragEvent({ files: [mockFile, mockFile] });
+ createComponent({ props: { shouldUpdateInputOnFileDrop: true, singleFileSelection: true } });
+ stubFileInputOnWrapper();
+
+ wrapper.trigger('dragenter', mockEvent);
+ await nextTick();
+ wrapper.trigger('drop', mockEvent);
+ await nextTick();
+
+ expect(wrapper.vm.$refs.fileUpload.files).toEqual([]);
+ expect(wrapper.emitted('error')).toHaveLength(1);
+ });
+ });
});