-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
exposes test helper form-data and follow FormData specification
- Loading branch information
Showing
4 changed files
with
176 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Allows to inject and remove a FormData polyfill which supports get() and | ||
* getAll() methods. | ||
* | ||
* Except for Chrome (>= 50) and Firefox (>= 39) major browser engines implement | ||
* only a very basic subset of FormData specification. Especially current Safari, | ||
* IE, Edge and PhantomJS does not support any methods to retrieve data of a | ||
* FormData object. | ||
* This is a hard limitation in testing. E.g. in an ember-cli-mirage route handler | ||
* you are not able to retrieve values of the request. | ||
* | ||
* Implementation follows FormData specification: | ||
* https://xhr.spec.whatwg.org/#interface-formdata | ||
*/ | ||
|
||
import Ember from 'ember'; | ||
|
||
const { isArray, warn } = Ember; | ||
|
||
function TestableFormData() { | ||
this._data = {}; | ||
} | ||
|
||
/* | ||
* Injects FormData polyfill by overriding window.FormData if current browser | ||
* engine does not implement FormData.get method. | ||
* Overriding window.FormData could be forced by passing `true` as first argument. | ||
*/ | ||
TestableFormData.inject = function(force) { | ||
if ( | ||
window && | ||
(force || typeof window.FormData.get === 'undefined') | ||
) { | ||
this.OldFormData = window.FormData; | ||
window.FormData = TestableFormData; | ||
} | ||
}; | ||
|
||
TestableFormData.remove = function() { | ||
if (window && this.OldFormData) { | ||
window.FormData = this.OldFormData; | ||
delete this.OldFormData; | ||
} | ||
}; | ||
|
||
/* | ||
* FormData.append() | ||
* The append(name, value) and append(name, blobValue, filename) methods, when | ||
* invoked, must run these steps: | ||
* 1. Let value be value if given, and blobValue otherwise. | ||
* 2. Let entry be the result of creating an entry with name, value, and | ||
* filename if given. | ||
* 3. Append entry to context object’s list of entries. | ||
* Note: The reason there is an argument named value as well as blobValue is | ||
* due to a limitation of the editing software used to write the XMLHttpRequest | ||
* Standard. | ||
* https://xhr.spec.whatwg.org/#dom-formdata-append | ||
*/ | ||
TestableFormData.prototype.append = function(name, value, filename) { | ||
if (!isArray(this._data[name])) { | ||
this._data[name] = []; | ||
} | ||
/* | ||
* To create an entry for name, value, and optionally a filename, run these steps: | ||
* 3. If value is a Blob object and not a File object, then set value to a | ||
* new File object, representing the same bytes, whose name attribute | ||
* value is "blob". | ||
* 4. If value is (now) a File object and filename is given, then set value | ||
* to a new File object, representing the same bytes, whose name attribute | ||
* value is filename. | ||
* https://xhr.spec.whatwg.org/#create-an-entry | ||
*/ | ||
if ( | ||
// it's a Blob | ||
value instanceof Blob && | ||
// but it's not a File yet | ||
!(value instanceof File) && | ||
// File is supported by current engine | ||
typeof File === 'function' | ||
) { | ||
value = new File([value], filename || 'blob'); | ||
} | ||
this._data[name].push(value); | ||
}; | ||
|
||
/* | ||
* FormData.get() | ||
* The get(name) method, when invoked, must return the value of the first entry | ||
* whose name is name, and null otherwise. | ||
* https://xhr.spec.whatwg.org/#dom-formdata-get | ||
*/ | ||
TestableFormData.prototype.get = function(name) { | ||
let values = this._data[name]; | ||
return ( isArray(values) && values.length > 0 ) ? values[0] : null; | ||
}; | ||
|
||
/* | ||
* FormData.getAll() | ||
* The getAll(name) method, when invoked, must return the values of all entries | ||
* whose name is name, in list order, and the empty sequence otherwise. | ||
* https://xhr.spec.whatwg.org/#dom-formdata-getall | ||
*/ | ||
TestableFormData.prototype.getAll = function(name) { | ||
let value = this._data[name]; | ||
return isArray(value) ? value : []; | ||
}; | ||
|
||
export default TestableFormData; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import Ember from 'ember'; | ||
import TestableFormData from 'dummy/tests/helpers/form-data'; | ||
|
||
const { isArray, warn } = Ember; | ||
|
||
module("test helper | FormData"); | ||
|
||
test('supports empty value', function(assert) { | ||
expect(3); | ||
let formData = new TestableFormData(); | ||
strictEqual(formData.get('not-existing'), null, 'get returns null'); | ||
ok(isArray(formData.getAll('not-existing')), 'getAll returns an array'); | ||
equal(formData.getAll('not-existing').length, 0, 'array returned by getAll is empty'); | ||
}); | ||
|
||
test('supports single value', function(assert) { | ||
expect(3); | ||
let formData = new TestableFormData(); | ||
formData.append('foo', 'a'); | ||
strictEqual(formData.get('foo'), 'a', 'get returns value'); | ||
ok(isArray(formData.getAll('foo')), 'getAll returns an array'); | ||
equal(formData.getAll('foo')[0], 'a', 'array returned by getAll contains value'); | ||
}); | ||
|
||
test('supports multiple values', function(assert) { | ||
expect(4); | ||
let formData = new TestableFormData(); | ||
formData.append('foo', 'a'); | ||
formData.append('foo', 'b'); | ||
strictEqual(formData.get('foo'), 'a', 'get returns value which was set as first'); | ||
ok(isArray(formData.getAll('foo')), 'getAll returns an array'); | ||
equal(formData.getAll('foo')[0], 'a', 'array returned by getAll contains first value'); | ||
equal(formData.getAll('foo')[1], 'b', 'array returned by getAll contains second value'); | ||
}) | ||
|
||
test('supports appending Blob', function(assert) { | ||
let formData = new TestableFormData(); | ||
formData.append('foo', new Blob([])); | ||
ok(isArray(formData.getAll('foo')), 'getAll returns an array'); | ||
ok(formData.getAll('foo')[0] instanceof Blob, 'array returned by getAll contains value'); | ||
}); | ||
|
||
test('supports appending File', function(assert) { | ||
if (typeof File !== 'function') { | ||
warn('Skipping File tests since File not supported by current engine'); | ||
expect(0); | ||
return; | ||
} | ||
expect(5); | ||
let formData = new TestableFormData(); | ||
let fileObject = new File([], 'untouched'); | ||
formData.append('foo', new Blob([])); | ||
formData.append('foo', fileObject); | ||
formData.append('foo', new Blob([]), 'test.jpg'); | ||
ok(formData.getAll('foo')[0] instanceof File, 'converts Blob to File object'); | ||
equal(formData.getAll('foo')[0].name, 'blob', 'sets name to blob if no name is given'); | ||
strictEqual(formData.getAll('foo')[1], fileObject, 'File object does not get changed'); | ||
ok(formData.getAll('foo')[2] instanceof File, 'converts Blob to File object'); | ||
equal(formData.getAll('foo')[2].name, 'test.jpg', 'supports specifing name'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters