UNPKG

dojo

Version:

Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.

702 lines (607 loc) 16.5 kB
define([ 'intern!object', 'intern/chai!assert', '../../../request/xhr', '../../../errors/RequestTimeoutError', '../../../errors/CancelError', 'dojo/promise/all', 'dojo/query', 'require', '../../../has' ], function(registerSuite, assert, xhr, RequestTimeoutError, CancelError, all, query, require, has){ var global = this; var hasFormData = 'FormData' in this && typeof FormData === 'function'; var hasResponseType = typeof XMLHttpRequest !== 'undefined' && typeof new XMLHttpRequest().responseType !== 'undefined'; var formData; function hasFile(){ if (typeof File !== 'undefined') { try { new File(); } catch (e) { // File is not a constructor. } } return false; } registerSuite({ name: 'dojo/request/xhr', '.get': function(){ var promise = xhr.get('/__services/request/xhr', { preventCache: true, handleAs: 'json' }); assert.isFunction(promise.then); assert.isFunction(promise.cancel); assert.isObject(promise.response); assert.isFunction(promise.response.then); assert.isFunction(promise.response.cancel); return promise.response.then(function(response){ assert.strictEqual(response.data.method, 'GET'); assert.strictEqual(response.xhr.readyState, 4); return response; }); }, '.get 404': function(){ var def = this.async(), promise = xhr.get(require.toUrl('./xhr_blarg.html'), { preventCache: true }); promise.response.then( def.reject, def.callback(function(error){ assert.strictEqual(error.response.status, 404); }) ); }, '.get json with truthy value': function(){ var def = this.async(), promise = xhr.get(require.toUrl('./support/truthy.json'), { preventCache: true, handleAs: 'json' }); promise.then( def.callback(function(response){ assert.strictEqual(response, true); }) ); }, '.get json with falsy value': function(){ var def = this.async(), promise = xhr.get(require.toUrl('./support/falsy.json'), { preventCache: true, handleAs: 'json' }); promise.then( def.callback(function(response){ assert.strictEqual(response, false); }) ); }, '.get with progress': function(){ var def = this.async(), promise = xhr.get(require.toUrl('./support/truthy.json'), { handleAs: 'json', preventCache: true }); promise.then(def.callback( function(){ }), function(error){ assert.isTrue(false, error); }, def.callback(function(event){ assert.strictEqual(event.transferType, 'download'); })); return def.promise; }, '.get with query': function(){ var def = this.async(), promise = xhr.get('/__services/request/xhr?color=blue', { query: { foo: ['bar', 'baz'], thud: 'thonk', xyzzy: 3 }, handleAs: 'json' }); promise.response.then(def.callback(function(response){ assert.strictEqual(response.data.method, 'GET'); var query = response.data.query; assert.ok(query.color && query.foo && query.foo.length && query.thud && query.xyzzy); assert.strictEqual(query.color, 'blue'); assert.strictEqual(query.foo.length, 2); assert.strictEqual(query.thud, 'thonk'); assert.strictEqual(query.xyzzy, '3'); assert.strictEqual(response.url, '/__services/request/xhr?color=blue&foo=bar&foo=baz&thud=thonk&xyzzy=3'); })); }, '.post': function(){ var def = this.async(), promise = xhr.post('/__services/request/xhr', { data: {color: 'blue'}, handleAs: 'json' }); promise.response.then( def.callback(function(response){ assert.strictEqual(response.data.method, 'POST'); var payload = response.data.payload; assert.ok(payload && payload.color); assert.strictEqual(payload.color, 'blue'); }), def.reject ); }, '.post ArrayBuffer': function(){ if (has('native-arraybuffer')) { var def = this.async(), str = 'foo', arrbuff = new ArrayBuffer(str.length), i8array = new Uint8Array(arrbuff); for (var i = 0; i < str.length; i++) { i8array[i] = str.charCodeAt(i); } var promise = xhr.post('/__services/request/xhr', { data: arrbuff, handleAs: 'json', headers: { 'Content-Type': 'text/plain' } }); promise.response.then( def.callback(function(response){ assert.strictEqual(response.data.method, 'POST'); var payload = response.data.payload; assert.deepEqual(payload, {'foo': ''}); }), def.reject ); } else { this.skip('ArrayBuffer not available'); } }, '.post Blob': function(){ if (has('native-blob')) { var def = this.async(), str = 'foo', blob = new Blob([str], {type: 'text/plain'}); var promise = xhr.post('/__services/request/xhr', { data: blob, handleAs: 'json', headers: { 'Content-Type': 'text/plain' } }); promise.response.then( def.callback(function(response){ assert.strictEqual(response.data.method, 'POST'); var payload = response.data.payload; assert.deepEqual(payload, {'foo': ''}); }), def.reject ); } else { this.skip('Blob not available'); } }, '.post File': function(){ if (hasFile()) { var def = this.async(), str = 'foo', file = new File([str], 'bar.txt', {type: 'text/plain'}); var promise = xhr.post('/__services/request/xhr', { data: file, handleAs: 'json', headers: { 'Content-Type': 'text/plain' } }); promise.response.then( def.callback(function(response){ assert.strictEqual(response.data.method, 'POST'); var payload = response.data.payload; assert.deepEqual(payload, {'foo': ''}); }), def.reject ); } else { this.skip('File or File constructor not available'); } }, '.post File with upload progress': function(){ if (hasFile()) { var def = this.async(), str = 'foo', file = new File([str], 'bar.txt', {type: 'text/plain'}); var promise = xhr.post('/__services/request/xhr', { data: file, handleAs: 'json', uploadProgress: true, query: { simulateProgress: true }, headers: { 'Content-Type': 'text/plain' } }); promise.then(null, def.reject, def.callback(function(progressEvent){ assert.isDefined(progressEvent.xhr); assert.deepEqual(progressEvent.transferType, 'upload'); })); } else { this.skip('File or File constructor not available'); } }, '.post with query': function(){ var def = this.async(), promise = xhr.post('/__services/request/xhr', { query: { foo: ['bar', 'baz'], thud: 'thonk', xyzzy: 3 }, data: {color: 'blue'}, handleAs: 'json' }); promise.then( def.callback(function(data){ assert.strictEqual(data.method, 'POST'); var query = data.query, payload = data.payload; assert.ok(query); assert.deepEqual(query.foo, ['bar', 'baz']); assert.strictEqual(query.thud, 'thonk'); assert.strictEqual(query.xyzzy, '3'); assert.ok(payload); assert.strictEqual(payload.color, 'blue'); }), def.reject ); }, '.post string payload': function(){ var def = this.async(), promise = xhr.post('/__services/request/xhr', { data: 'foo=bar&color=blue&height=average', handleAs: 'json' }); promise.then( def.callback(function(data){ assert.strictEqual(data.method, 'POST'); var payload = data.payload; assert.ok(payload); assert.strictEqual(payload.foo, 'bar'); assert.strictEqual(payload.color, 'blue'); assert.strictEqual(payload.height, 'average'); }), def.reject ); }, '.put': function(){ var def = this.async(), promise = xhr.put('/__services/request/xhr', { query: {foo: 'bar'}, data: {color: 'blue'}, handleAs: 'json' }); promise.then( def.callback(function(data){ assert.strictEqual(data.method, 'PUT'); assert.ok(data.payload); assert.strictEqual(data.payload.color, 'blue'); assert.ok(data.query); assert.strictEqual(data.query.foo, 'bar'); }), def.reject ); }, '.del': function(){ var def = this.async(), promise = xhr.del('/__services/request/xhr', { query: {foo: 'bar'}, handleAs: 'json' }); promise.then( def.callback(function(data){ assert.strictEqual(data.method, 'DELETE'); assert.strictEqual(data.query.foo, 'bar'); }), def.reject ); }, 'timeout': function(){ var def = this.async(), promise = xhr.get('/__services/request/xhr', { query: { delay: '3000' }, timeout: 1000 }); promise.then( def.reject, def.callback(function(error){ assert.instanceOf(error, RequestTimeoutError); }) ); }, cancel: function(){ var def = this.async(), promise = xhr.get('/__services/request/xhr', { query: { delay: '3000' } }); promise.then( def.reject, def.callback(function(error){ assert.instanceOf(error, CancelError); }) ); promise.cancel(); }, sync: function(){ var called = false; xhr.get('/__services/request/xhr', { sync: true }).then(function(){ called = true; }); assert.ok(called); }, 'cross-domain fails': function(){ var def = this.async(); xhr.get('http://dojotoolkit.org').response.then( def.reject, function(){ def.resolve(true); } ); }, 'has Content-Type with data': function(){ var def = this.async(); xhr.post('/__services/request/xhr', { data: 'testing', handleAs: 'json' }).then( def.callback(function(response){ assert.equal(response.headers['content-type'], 'application/x-www-form-urlencoded'); }), def.reject ); }, 'no Content-Type with no data': function(){ var def = this.async(); xhr.get('/__services/request/xhr', { handleAs: 'json' }).then( def.callback(function(response){ assert.isUndefined(response.headers['content-type']); }), def.reject ); }, headers: function(){ var def = this.async(); xhr.get('/__services/request/xhr').response.then( def.callback(function(response){ assert.notEqual(response.getHeader('Content-Type'), null); }), def.reject ); }, 'custom Content-Type': function(){ var def = this.async(), expectedContentType = 'application/x-test-xhr'; function post(headers){ return xhr.post('/__services/request/xhr', { query: { 'header-test': 'true' }, headers: headers, data: 'testing', handleAs: 'json' }); } all({ lowercase: post({ 'content-type': expectedContentType }), uppercase: post({ 'CONTENT-TYPE': expectedContentType }) }).then( def.callback(function(results){ assert.match( results.lowercase.headers['content-type'], /^application\/x-test-xhr(?:;.*)?$/ ); assert.match( results.uppercase.headers['content-type'], /^application\/x-test-xhr(?:;.*)?$/ ); }), def.reject ); }, 'queryable xml': function(){ var def = this.async(); xhr.get('/__services/request/xhr/xml', { handleAs: 'xml' }).then( def.callback(function(xmlDoc){ var results = query('bar', xmlDoc); assert.strictEqual(results.length, 2); }), def.reject ); }, 'strip fragment': function(){ var def = this.async(), promise = xhr.get('/__services/request/xhr?color=blue#some-hash', { handleAs: 'json' }); promise.response.then(def.callback(function(response){ assert.strictEqual(response.data.method, 'GET'); assert.strictEqual(response.data.url, '/__services/request/xhr?color=blue'); })); }, 'form data': { setup: function(){ if (!hasFormData) { return; } formData = new FormData(); formData.append('foo', 'bar'); formData.append('baz', 'blah'); }, post: function(){ if (!hasFormData) { this.skip('No FormData to test'); } var def = this.async(); xhr.post('/__services/request/xhr/multipart', { data: formData, handleAs: 'json' }).then( def.callback(function(data){ assert.deepEqual(data, {foo: 'bar', baz: 'blah'}); }), def.reject ); }, teardown: function(){ formData = null; } }, 'response type': { 'Blob': function(){ if (!hasResponseType) { this.skip('No responseType to test'); } return xhr.get('/__services/request/xhr/responseTypeGif', { handleAs: 'blob' }).then(function(response){ assert.strictEqual(response.constructor, Blob); }); }, 'Blob POST': function(){ if (!hasResponseType) { this.skip('No responseType to test'); } return xhr.post('/__services/request/xhr/responseTypeGif', { handleAs: 'blob' }).then(function(response){ assert.strictEqual(response.constructor, Blob); }); }, 'ArrayBuffer': function(){ if (has('native-arraybuffer') && hasResponseType) { return xhr.get('/__services/request/xhr/responseTypeGif', { handleAs: 'arraybuffer' }).then(function(response){ assert.strictEqual(response.constructor, ArrayBuffer); }); } else { this.skip('No responseType to test'); } }, 'ArrayBuffer POST': function(){ if (has('native-arraybuffer') && hasResponseType) { return xhr.post('/__services/request/xhr/responseTypeGif', { handleAs: 'arraybuffer' }).then(function(response){ assert.strictEqual(response.constructor, ArrayBuffer); }); } else { this.skip('No responseType to test'); } }, 'document': function(){ if (!hasResponseType) { this.skip('No responseType to test'); } return xhr.get('/__services/request/xhr/responseTypeDoc', { handleAs: 'document' }).then(function(response){ assert.strictEqual(response.constructor, document.constructor); }); }, 'document POST': function(){ if (!hasResponseType) { this.skip('No responseType to test'); } return xhr.post('/__services/request/xhr/responseTypeDoc', { handleAs: 'document' }).then(function(response){ assert.strictEqual(response.constructor, document.constructor); }); } }, 'Web Workers': { 'from blob': function(){ if (!('URL' in global)) { this.skip('URL is not supported'); } if (!('Worker' in global)) { this.skip('Worker is not supported'); } if (!('Blob' in global)) { this.skip('Blob is not supported'); } if (!URL.createObjectURL) { this.skip('URL.createObjectURL is not supported'); } var dfd = this.async(); var baseUrl = location.origin + '/' + require.toUrl('testing'); var testUrl = location.origin + '/' + require.toUrl('./support/truthy.json'); var workerFunction = function(){ self.addEventListener('message', function(event){ if (event.data.baseUrl) { testXhr(event.data.baseUrl, event.data.testUrl); } }); dojoConfig = {async: true}; function testXhr(baseUrl, testUrl){ var xhr = new XMLHttpRequest(); dojoConfig.baseUrl = baseUrl; xhr.onreadystatechange = function(){ if (xhr.readyState === 4 && xhr.status === 200) { var blob = new Blob([xhr.response], {type: 'application/javascript'}); var blobURL = URL.createObjectURL(blob); importScripts(blobURL); require([ 'dojo/request/xhr' ], function(xhr){ xhr.get(testUrl).then(function(response){ if (response === 'true') { self.postMessage('success'); } else { throw new Error(response); } }, function(error){ throw error; }); }); } }; xhr.open('GET', baseUrl + '/dojo.js', true); xhr.send(); } }; var blob = new Blob(['(' + workerFunction.toString() + ')()'], {type: 'application/javascript'}); var worker = new Worker(URL.createObjectURL(blob)); worker.addEventListener('error', function(error){ dfd.reject(error); }); worker.addEventListener('message', function(message){ if (message.data === 'success') { dfd.resolve(); } else { dfd.reject(message); } }); worker.postMessage({ baseUrl: baseUrl, testUrl: testUrl }); } } }); });