diff --git a/addon/components/file-field.js b/addon/components/file-field.js index 2dd76a3..e9ffbb5 100644 --- a/addon/components/file-field.js +++ b/addon/components/file-field.js @@ -1,6 +1,8 @@ import Ember from 'ember'; -export default Ember.Component.extend(Ember.Evented, { +const { Component, Evented } = Ember; + +export default Component.extend(Evented, { tagName: 'input', type: 'file', attributeBindings: [ @@ -14,7 +16,20 @@ export default Ember.Component.extend(Ember.Evented, { 'multiple' ], multiple: false, - change (event) { + + didInsertElement (...args) { + this._super(...args); + + this.$().on('change', (event) => { this.handleChange(event); }); + }, + + willDestroyElement (...args) { + this._super(...args); + + this.$().off('change'); + }, + + handleChange (event) { const input = event.target; if (!Ember.isEmpty(input.files)) { this.trigger('filesDidChange', input.files); diff --git a/addon/uploaders/base.js b/addon/uploaders/base.js index b2185e5..9e51b39 100644 --- a/addon/uploaders/base.js +++ b/addon/uploaders/base.js @@ -86,7 +86,8 @@ export default Ember.Object.extend(Ember.Evented, { } } - if (files.constructor === FileList) { + // if is a array of files ... + if (files.constructor === FileList || files.constructor === Array) { const paramKey = `${this.toNamespacedParam(this.paramName)}[]`; for (let i = 0; i < files.length; i++) { diff --git a/addon/uploaders/s3.js b/addon/uploaders/s3.js index 785d34f..c3d5f4e 100644 --- a/addon/uploaders/s3.js +++ b/addon/uploaders/s3.js @@ -33,7 +33,7 @@ export default Uploader.extend({ /** * Request signed upload policy and upload file(s) and any extra data * - * @param {object|array} files One file object or one array of files object + * @param {object} file A file object * @param {object} extra Extra data to be sent with the upload * @return {object} Returns a Ember.RSVP.Promise wrapping the signing * request object @@ -61,7 +61,7 @@ export default Uploader.extend({ /** * Request signed upload policy * - * @param {object|array} files One file object or one array of files object + * @param {object} file A file object * @param {object} extra Extra data to be sent with the upload * @return {object} Returns a Ember.RSVP.Promise wrapping the signing * request object diff --git a/package.json b/package.json index 201c078..50717c8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "Ember Uploader", "name": "ember-uploader", - "version": "1.2.2", + "version": "1.2.3", "description": "Ember.js addon to facilitate uploading", "homepage": "https://github.com/benefitcloud/ember-uploader", "license": "MIT", diff --git a/tests/dummy/app/mirage/config.js b/tests/dummy/app/mirage/config.js index 967299e..5151c0a 100644 --- a/tests/dummy/app/mirage/config.js +++ b/tests/dummy/app/mirage/config.js @@ -2,7 +2,7 @@ import Mirage from 'ember-cli-mirage'; export default function() { this.get('/sign', { bucket: 'testbucket' }); - this.post('http://testbucket.s3.amazonaws.com'); + this.post('http://testbucket.s3.amazonaws.com', { message: 'OK' }, 201); this.post('/upload', { message: 'OK' }, 201); this.post('/invalid', { message: 'Not Found' }, 404); } diff --git a/tests/integration/components/file-field-test.js b/tests/integration/components/file-field-test.js new file mode 100644 index 0000000..07e1d1e --- /dev/null +++ b/tests/integration/components/file-field-test.js @@ -0,0 +1,102 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; +import sinon from 'sinon'; +import jQuery from 'jquery'; + + +moduleForComponent('file-field', 'Integration | Component | file field', { + integration: true +}); + +function fillInFileInput(selector, file) { + // Get the input + let input = jQuery(selector); + + // Get out file options + let { fileName, type, content } = file; + + // Create a custom event for change and inject target + let event = jQuery.Event('change', { + target: { files: [{ fileName, type }] } + }); + + // Trigger event + input.trigger(event); +} + +test('renders input with multiple attributes', function(assert) { + assert.expect(7); + + this.render(hbs`{{file-field + type='file' + disabled=true + name='My name' + autofocus=true + required=true + multiple=true + form='formId' + accept='audio/*|video/*|image/*' + }}`); + + assert.equal( + this.$('input').attr('disabled'), + 'disabled', + 'File field is disabled' + ); + + assert.equal( + this.$('input').attr('name'), + 'My name', + 'File field has name' + ); + + assert.equal( + this.$('input').attr('autofocus'), + 'autofocus', + 'File field has autofocus' + ); + + assert.equal( + this.$('input').attr('required'), + 'required', + 'File field has required' + ); + + assert.equal( + this.$('input').attr('multiple'), + 'multiple', + 'File field has multiple' + ); + + assert.equal( + this.$('input').attr('form'), + 'formId', + 'File field is associated with a form' + ); + + assert.equal( + this.$('input').attr('accept'), + 'audio/*|video/*|image/*', + 'File field accept types as: audio, video and image' + ); + +}); + +test('file upload works correcly', function(assert) { + let filesDidChange = sinon.spy(); + + let fileName = 'surprise.png'; + let content = 'data:image/png;base64,no-surprises-here'; + let type = 'image/png'; + + + this.set('filesDidChange', filesDidChange); + this.render(hbs` + {{file-field id="file-input" filesDidChange=filesDidChange}} + `); + + fillInFileInput('#file-input', { fileName, content, type }); + + assert.ok(filesDidChange.calledOnce, 'Hook `filesDidChange` should be called once.'); + assert.ok(filesDidChange.calledWithExactly([{fileName, type}]), 'Hook `filesDidChange` should be called with exact arguments'); +}); diff --git a/tests/unit/file-field-test.js b/tests/unit/file-field-test.js index e1acb4e..00ab6ac 100644 --- a/tests/unit/file-field-test.js +++ b/tests/unit/file-field-test.js @@ -11,7 +11,7 @@ test('it triggers `filesDidChange` on change', () => { result = files; } }).create(); - fileField.change({ target: { files: [ 'foo' ] }}); + fileField.handleChange({ target: { files: [ 'foo' ] }}); deepEqual(result, [ 'foo' ], 'it returns the files that changed'); });