import RNTest from './react-native-testkit/' import React from 'react' import RNFetchBlob from 'react-native-fetch-blob' import Timer from 'react-timer-mixin' import { StyleSheet, Text, View, ScrollView, CameraRoll, Platform, Dimensions, Image, } from 'react-native'; const fs = RNFetchBlob.fs const Blob = RNFetchBlob.polyfill.Blob window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest window.Blob = Blob window.ProgressEvent = RNFetchBlob.polyfill.ProgressEvent const { Assert, Comparer, Info, prop } = RNTest const describe = RNTest.config({ group : 'XMLHttpRequest', run : true, expand : false, timeout : 20000, }) const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop() const dirs = RNFetchBlob.fs.dirs let prefix = ((Platform.OS === 'android') ? 'file://' : '') let file = RNTest.prop('image') /** * Test cases are based on W3C github repository. * {@link https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/} */ describe('unsent state test', (report, done) => { let xhr = new XMLHttpRequest() try { xhr.setRequestHeader('x-test', 'test') } catch(err) { report( <Assert key="should throw InvalidState if setRequestHeader()" actual={/invalidstate/i.test(err)} expect={true} />) } try { let xhr = new XMLHttpRequest() xhr.send(null) } catch(err) { report( <Assert key="should throw InvalidState if send()" actual={/invalidstate/i.test(err)} expect={true} />) } try { report( <Assert key="status is 0" expect={0} actual={xhr.status} />, <Assert key="statusText is empty" expect={''} actual={xhr.statusText} />, <Assert key="responseHeaders is empty" expect={''} actual={xhr.getAllResponseHeaders()} />, <Assert key="response header should not be set" expect={null} actual={xhr.getResponseHeader('x-test')} />, <Assert key="readyState should correct" expect={XMLHttpRequest.UNSENT} actual={xhr.readyState} /> ) done() } catch(err) { console.log(err.stack) } }) describe('HTTP error should not throw error event', (report, done) => { onError('GET', 200) onError('GET', 400) onError('GET', 401) onError('GET', 404) onError('GET', 410) onError('GET', 500) onError('GET', 699) onError('HEAD', 200) onError('HEAD', 404) onError('HEAD', 500) onError('HEAD', 699) onError('POST', 200) onError('POST', 404) onError('POST', 500) onError('POST', 699) onError('PUT', 200) onError('PUT', 404) onError('PUT', 500) onError('PUT', 699) done() let count = 0 function onError(method, code) { let xhr = new XMLHttpRequest() xhr.open(method, `${TEST_SERVER_URL}/xhr-code/${code}`) xhr.onreadystatechange = function() { count++ if(this.readyState == XMLHttpRequest.DONE) { report( <Assert key={`#${count} response data of ${method} ${code} should be empty`} expect="" actual={xhr.response}/>, <Assert key={`#${count} status of ${method} ${code} should be ${code}`} expect={code} actual={xhr.status}/> ) } } xhr.onerror = function() { report( <Assert key={`HTTP error ${code} should not throw error event`} expect={false} actual={true}/>) } xhr.send() } }) describe('request headers records should be cleared by open()', (report, done) => { let xhr = new XMLHttpRequest() xhr.open('GET', `${TEST_SERVER_URL}/xhr-header`) xhr.setRequestHeader('value', '100') xhr.open('GET', `${TEST_SERVER_URL}/xhr-header`) xhr.setRequestHeader('value', '200') xhr.send() xhr.onreadystatechange = function() { if(this.readyState == 4) { report(<Assert key="headers should be cleared by open()" expect={'200'} actual={this.response.value}/>) done() } } }) /** * {@link https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/setrequestheader-bogus-name.htm} */ describe('invalid characters should not exists in header field', (report, done) => { function try_name(name) { try { let client = new XMLHttpRequest() client.open("GET", `${TEST_SERVER_URL}/public/github.png`) client.setRequestHeader(name, '123') } catch(err) { report( <Assert key={`invalid header type ${name} should throw SyntaxError`} actual={/syntaxerror/i.test(err)} expect={true} />) } } function try_byte_string(name) { try { let client = new XMLHttpRequest() client.open("GET", `${TEST_SERVER_URL}/public/github.png`) client.setRequestHeader(name, '123') } catch(err) { report( <Assert key={`invalid header field ${name} type should throw TypeError`} actual={/typeerror/i.test(err)} expect={true} />) } } var invalid_headers = ["(", ")", "<", ">", "@", ",", ";", ":", "\\", "\"", "/", "[", "]", "?", "=", "{", "}", " ", "\u007f", "", "t\rt", "t\nt", "t: t", "t:t", "t<t", "t t", " tt", ":tt", "\ttt", "\vtt", "t\0t", "t\"t", "t,t", "t;t", "()[]{}", "a?B", "a=B"] var invalid_byte_strings = ["テスト", "X-テスト"] for (var i = 0; i < 32; ++i) { invalid_headers.push(String.fromCharCode(i)) } for (var i = 0; i < invalid_headers.length; ++i) { try_name(invalid_headers[i]) } for (var i = 0; i < invalid_byte_strings.length; ++i) { try_byte_string(invalid_byte_strings[i]) } done() }) describe('invoke setRequestHeader() before open()', (report, done) => { try { let xhr = new XMLHttpRequest() xhr.setRequestHeader('foo', 'bar') } catch(err) { report( <Info key="error message"> <Text>{err}</Text> </Info>, <Assert key="should throw InvalidStateError" expect={true} actual={/invalidstateerror/i.test(err)}/>) done() } }) describe('upload progress event test', (report, done) => { let xhr = new XMLHttpRequest() let time = Date.now() let msg = `time=${time}` xhr.upload.onprogress = function(e) { report( <Assert key="event object is an instance of ProgressEvent" expect={true} actual={e instanceof ProgressEvent}/>) } xhr.onreadystatechange = function() { if(this.readyState == XMLHttpRequest.DONE) { report( <Assert key="reponse should correct" expect={time} actual={Math.floor(xhr.response.time)}/>, <Assert key="responseType should correct" expect={'json'} actual={xhr.responseType}/>) done() } } xhr.open('POST', `${TEST_SERVER_URL}/upload`) xhr.overrideMimeType('application/x-www-form-urlencoded') xhr.send(msg) }) describe('timeout event catchable', (report, done) => { let xhr = new XMLHttpRequest() let count = 0 xhr.timeout = 1 xhr.ontimeout = function() { report( <Info key="event should only trigger once" uid="1000"> <Text>{count}</Text> </Info>, <Assert key="event catchable" expect={true} actual={true}/>) done() } xhr.open('GET', `${TEST_SERVER_URL}/timeout/`) xhr.send() }) describe('upload progress event should not be triggered when body is empty', (report, done) => { let xhr = new XMLHttpRequest() let count = 0 xhr.upload.onloadstart = function() { report( <Assert key="loadstart event should not triggered" uid="aaa" expect={true} actual={false}/>) } xhr.upload.onprogress = function() { report( <Assert key="progress event should not triggered" uid="bbb" expect={true} actual={false}/>) } xhr.onreadystatechange = function() { if(this.readyState == XMLHttpRequest.DONE) { count++ report( <Assert key="Great! upload event not triggered" uid="ccc" expect={true} actual={true}/>, <Assert key="This should not triggered multiple times" uid="ddd" expect={1} actual={count}/>) done() } } xhr.open('GET', `${TEST_SERVER_URL}/public/github.png`) xhr.send() })