Bez popisu

test-xmlhttp.js 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. import RNTest from './react-native-testkit/'
  2. import React from 'react'
  3. import RNFetchBlob from 'react-native-fetch-blob'
  4. import Timer from 'react-timer-mixin'
  5. import {
  6. StyleSheet,
  7. Text,
  8. View,
  9. ScrollView,
  10. CameraRoll,
  11. Platform,
  12. Dimensions,
  13. Image,
  14. } from 'react-native';
  15. const fs = RNFetchBlob.fs
  16. const Blob = RNFetchBlob.polyfill.Blob
  17. window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
  18. window.Blob = Blob
  19. window.ProgressEvent = RNFetchBlob.polyfill.ProgressEvent
  20. const { Assert, Comparer, Info, prop } = RNTest
  21. const describe = RNTest.config({
  22. group : 'XMLHttpRequest',
  23. run : true,
  24. expand : false,
  25. timeout : 20000,
  26. })
  27. const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop()
  28. const dirs = RNFetchBlob.fs.dirs
  29. let prefix = ((Platform.OS === 'android') ? 'file://' : '')
  30. let file = RNTest.prop('image')
  31. /**
  32. * Test cases are based on W3C github repository.
  33. * {@link https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/}
  34. */
  35. describe('unsent state test', (report, done) => {
  36. let xhr = new XMLHttpRequest()
  37. try {
  38. xhr.setRequestHeader('x-test', 'test')
  39. } catch(err) {
  40. report(
  41. <Assert key="should throw InvalidState if setRequestHeader()"
  42. actual={/invalidstate/i.test(err)}
  43. expect={true}
  44. />)
  45. }
  46. try {
  47. let xhr = new XMLHttpRequest()
  48. xhr.send(null)
  49. } catch(err) {
  50. report(
  51. <Assert key="should throw InvalidState if send()"
  52. actual={/invalidstate/i.test(err)}
  53. expect={true}
  54. />)
  55. }
  56. try {
  57. report(
  58. <Assert key="status is 0"
  59. expect={0}
  60. actual={xhr.status} />,
  61. <Assert key="statusText is empty"
  62. expect={''}
  63. actual={xhr.statusText} />,
  64. <Assert key="responseHeaders is empty"
  65. expect={''}
  66. actual={xhr.getAllResponseHeaders()} />,
  67. <Assert key="response header should not be set"
  68. expect={null}
  69. actual={xhr.getResponseHeader('x-test')} />,
  70. <Assert key="readyState should correct"
  71. expect={XMLHttpRequest.UNSENT}
  72. actual={xhr.readyState} />
  73. )
  74. done()
  75. } catch(err) {
  76. console.log(err.stack)
  77. }
  78. })
  79. describe('HTTP error should not throw error event', (report, done) => {
  80. onError('GET', 200)
  81. onError('GET', 400)
  82. onError('GET', 401)
  83. onError('GET', 404)
  84. onError('GET', 410)
  85. onError('GET', 500)
  86. onError('GET', 699)
  87. onError('HEAD', 200)
  88. onError('HEAD', 404)
  89. onError('HEAD', 500)
  90. onError('HEAD', 699)
  91. onError('POST', 200)
  92. onError('POST', 404)
  93. onError('POST', 500)
  94. onError('POST', 699)
  95. onError('PUT', 200)
  96. onError('PUT', 404)
  97. onError('PUT', 500)
  98. onError('PUT', 699)
  99. done()
  100. let count = 0
  101. function onError(method, code) {
  102. let xhr = new XMLHttpRequest()
  103. xhr.open(method, `${TEST_SERVER_URL}/xhr-code/${code}`)
  104. xhr.onreadystatechange = function() {
  105. count++
  106. if(this.readyState == XMLHttpRequest.DONE) {
  107. report(
  108. <Assert
  109. key={`#${count} response data of ${method} ${code} should be empty`}
  110. expect=""
  111. actual={xhr.response}/>,
  112. <Assert
  113. key={`#${count} status of ${method} ${code} should be ${code}`}
  114. expect={code}
  115. actual={xhr.status}/>
  116. )
  117. }
  118. }
  119. xhr.onerror = function() {
  120. report(
  121. <Assert
  122. key={`HTTP error ${code} should not throw error event`}
  123. expect={false}
  124. actual={true}/>)
  125. }
  126. xhr.send()
  127. }
  128. })
  129. describe('request headers records should be cleared by open()', (report, done) => {
  130. let xhr = new XMLHttpRequest()
  131. xhr.open('GET', `${TEST_SERVER_URL}/xhr-header`)
  132. xhr.setRequestHeader('value', '100')
  133. xhr.setRequestHeader('cache-control', 'no-store')
  134. xhr.open('GET', `${TEST_SERVER_URL}/xhr-header`)
  135. xhr.setRequestHeader('value', '200')
  136. xhr.send()
  137. xhr.onreadystatechange = function() {
  138. if(this.readyState == 4) {
  139. report(<Assert key="headers should be cleared by open()"
  140. expect={"200"}
  141. actual={JSON.parse(this.response).value}/>)
  142. done()
  143. }
  144. }
  145. })
  146. /**
  147. * {@link https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/setrequestheader-bogus-name.htm}
  148. */
  149. describe('invalid characters should not exists in header field', (report, done) => {
  150. function try_name(name) {
  151. try {
  152. let client = new XMLHttpRequest()
  153. client.open("GET", `${TEST_SERVER_URL}/public/github.png`)
  154. client.setRequestHeader(name, '123')
  155. } catch(err) {
  156. report(
  157. <Assert key={`invalid header type ${name} should throw SyntaxError`}
  158. actual={/syntaxerror/i.test(err)}
  159. expect={true}
  160. />)
  161. }
  162. }
  163. function try_byte_string(name) {
  164. try {
  165. let client = new XMLHttpRequest()
  166. client.open("GET", `${TEST_SERVER_URL}/public/github.png`)
  167. client.setRequestHeader(name, '123')
  168. } catch(err) {
  169. report(
  170. <Assert key={`invalid header field ${name} type should throw TypeError`}
  171. actual={/typeerror/i.test(err)}
  172. expect={true}
  173. />)
  174. }
  175. }
  176. var invalid_headers = ["(", ")", "<", ">", "@", ",", ";", ":", "\\",
  177. "\"", "/", "[", "]", "?", "=", "{", "}", " ",
  178. "\u007f", "", "t\rt", "t\nt", "t: t", "t:t",
  179. "t<t", "t t", " tt", ":tt", "\ttt", "\vtt", "t\0t",
  180. "t\"t", "t,t", "t;t", "()[]{}", "a?B", "a=B"]
  181. var invalid_byte_strings = ["テスト", "X-テスト"]
  182. for (var i = 0; i < 32; ++i) {
  183. invalid_headers.push(String.fromCharCode(i))
  184. }
  185. for (var i = 0; i < invalid_headers.length; ++i) {
  186. try_name(invalid_headers[i])
  187. }
  188. for (var i = 0; i < invalid_byte_strings.length; ++i) {
  189. try_byte_string(invalid_byte_strings[i])
  190. }
  191. done()
  192. })
  193. describe('invoke setRequestHeader() before open()', (report, done) => {
  194. try {
  195. let xhr = new XMLHttpRequest()
  196. xhr.setRequestHeader('foo', 'bar')
  197. } catch(err) {
  198. report(
  199. <Info key="error message">
  200. <Text>{err}</Text>
  201. </Info>,
  202. <Assert key="should throw InvalidStateError"
  203. expect={true}
  204. actual={/invalidstateerror/i.test(err)}/>)
  205. done()
  206. }
  207. })
  208. describe('upload progress event test', (report, done) => {
  209. let xhr = new XMLHttpRequest()
  210. let time = Date.now()
  211. let msg = `time=${time}`
  212. xhr.upload.onprogress = function(e) {
  213. report(
  214. <Assert key="event object is an instance of ProgressEvent"
  215. expect={true}
  216. actual={e instanceof ProgressEvent}/>)
  217. }
  218. xhr.onreadystatechange = function() {
  219. if(this.readyState == XMLHttpRequest.DONE) {
  220. report(
  221. <Assert key="reponse should correct"
  222. expect={time}
  223. actual={Math.floor(JSON.parse(xhr.response).time)}/>,
  224. <Assert key="responseType should correct"
  225. expect={'json'}
  226. actual={xhr.responseType}/>)
  227. done()
  228. }
  229. }
  230. xhr.open('POST', `${TEST_SERVER_URL}/upload`)
  231. xhr.overrideMimeType('application/x-www-form-urlencoded')
  232. xhr.send(msg)
  233. })
  234. describe('timeout event catchable', (report, done) => {
  235. let xhr = new XMLHttpRequest()
  236. let count = 0
  237. xhr.timeout = 1
  238. xhr.ontimeout = function() {
  239. report(
  240. <Info key="event should only trigger once" uid="1000">
  241. <Text>{count}</Text>
  242. </Info>,
  243. <Assert key="event catchable"
  244. expect={true}
  245. actual={true}/>)
  246. done()
  247. }
  248. xhr.open('GET', `${TEST_SERVER_URL}/timeout/`)
  249. xhr.send()
  250. })
  251. describe('upload progress event should not be triggered when body is empty', (report, done) => {
  252. let xhr = new XMLHttpRequest()
  253. let count = 0
  254. xhr.upload.onloadstart = function() {
  255. report(
  256. <Assert key="loadstart event should not triggered"
  257. uid="aaa"
  258. expect={true}
  259. actual={false}/>)
  260. }
  261. xhr.upload.onprogress = function() {
  262. report(
  263. <Assert key="progress event should not triggered"
  264. uid="bbb"
  265. expect={true}
  266. actual={false}/>)
  267. }
  268. xhr.onreadystatechange = function() {
  269. if(this.readyState == XMLHttpRequest.DONE) {
  270. count++
  271. report(
  272. <Assert key="Great! upload event not triggered"
  273. uid="ccc"
  274. expect={true}
  275. actual={true}/>,
  276. <Assert key="This should not triggered multiple times"
  277. uid="ddd"
  278. expect={1}
  279. actual={count}/>)
  280. done()
  281. }
  282. }
  283. xhr.open('GET', `${TEST_SERVER_URL}/public/github.png`)
  284. xhr.send()
  285. })