test-basics.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /* globals atob, it */
  2. 'use strict'
  3. const bent = require('../')
  4. const assert = require('assert')
  5. const tsame = require('tsame')
  6. const { PassThrough } = require('stream')
  7. const http = require('http')
  8. const test = it
  9. const same = (x, y) => assert.ok(tsame(x, y))
  10. const baseurl = 'https://echo-server.mikeal.now.sh/src'
  11. const u = path => baseurl + path
  12. const enc = str => (new TextEncoder()).encode(str).buffer
  13. const dec = str => Uint8Array.from(atob(str), c => c.charCodeAt(0)).buffer
  14. const decode = arr => (new TextDecoder('utf-8')).decode(arr)
  15. test('basic 200 ok', async () => {
  16. const request = bent('string')
  17. const str = await request(u('/echo.js?body=ok'))
  18. same(str, 'ok')
  19. })
  20. test('basic 200 ok baseurl', async () => {
  21. const request = bent('string', baseurl)
  22. const str = await request('/echo.js?body=ok')
  23. same(str, 'ok')
  24. })
  25. test('basic 200', async () => {
  26. const request = bent()
  27. const res = await request(u('/echo.js?body=ok'))
  28. same(res.statusCode, 200)
  29. })
  30. test('basic buffer', async () => {
  31. const request = bent('buffer')
  32. const buff = await request(u('/echo.js?body=ok'))
  33. if (buff instanceof ArrayBuffer) {
  34. same(buff, enc('ok'))
  35. } else {
  36. same(buff, Buffer.from('ok'))
  37. }
  38. })
  39. test('double buffer decode', async () => {
  40. const request = bent()
  41. const resp = await request(u('/echo.js?body=ok'))
  42. const validate = buff => {
  43. if (buff instanceof ArrayBuffer) {
  44. same(buff, enc('ok'))
  45. } else {
  46. same(buff, Buffer.from('ok'))
  47. }
  48. }
  49. validate(await resp.arrayBuffer())
  50. let threw = true
  51. try {
  52. await resp.arrayBuffer()
  53. threw = false
  54. } catch (e) {
  55. if (!e.message.includes('body stream is locked')) throw e
  56. }
  57. assert.ok(threw)
  58. })
  59. test('basic json', async () => {
  60. const request = bent('json')
  61. const json = await request(u('/info.js'))
  62. same(json.method, 'GET')
  63. })
  64. test('json based media type', async () => {
  65. const request = bent('json', { accept: 'application/vnd.something.com' })
  66. const json = await request(u('/info.js'))
  67. same(json.headers.accept, 'application/vnd.something.com')
  68. })
  69. test('basic PUT', async () => {
  70. const request = bent('PUT', 'json')
  71. let body
  72. if (process.browser) {
  73. body = enc(Math.random().toString())
  74. } else {
  75. body = Buffer.from(Math.random().toString())
  76. }
  77. const json = await request(u('/info.js'), body)
  78. if (process.browser) {
  79. same(dec(json.base64), body)
  80. } else {
  81. same(Buffer.from(json.base64, 'base64'), body)
  82. }
  83. })
  84. test('base PUT string', async () => {
  85. const request = bent('PUT', 'json')
  86. const json = await request(u('/info.js'), 'teststring')
  87. if (process.browser) {
  88. same(atob(json.base64), 'teststring')
  89. } else {
  90. same(Buffer.from(json.base64, 'base64').toString(), 'teststring')
  91. }
  92. })
  93. test('status 201', async () => {
  94. const request = bent('string', 201)
  95. const str = await request(u('/echo.js?statusCode=201&body=ok'))
  96. same(str, 'ok')
  97. try {
  98. await request(u('/echo.js?body=ok'))
  99. throw new Error('Call should have thrown.')
  100. } catch (e) {
  101. same(e.message, process.browser ? null : 'OK')
  102. // basic header test
  103. same(e.headers['content-length'], '2')
  104. }
  105. })
  106. test('multiple status', async () => {
  107. const request = bent('string', [200, 201])
  108. const str200 = await request(u('/echo.js?body=ok'))
  109. same(str200, 'ok')
  110. const str201 = await request(u('/echo.js?statusCode=201&body=ok'))
  111. same(str201, 'ok')
  112. try {
  113. await request(u('/echo.js?statusCode=202&body=ok'))
  114. throw new Error('Call should have thrown.')
  115. } catch (e) {
  116. same(e.message, process.browser ? null : 'Accepted')
  117. // basic header test
  118. same(e.headers['content-length'], '2')
  119. }
  120. })
  121. test('PUT stream', async () => {
  122. const body = Buffer.from(Math.random().toString())
  123. const request = bent('PUT', 'json')
  124. const b = new PassThrough()
  125. const res = request(u('/info.js'), b)
  126. b.end(body)
  127. const info = await res
  128. same(info.method, 'PUT')
  129. // Unfortunately, we can't test this against lamda cause it doesn't support
  130. // transfer-encoding: chunked.
  131. // t.same(Buffer.from(info.base64, 'base64'), body)
  132. })
  133. test('PUT JSON', async () => {
  134. const request = bent('PUT', 'json')
  135. const info = await request(u('/info.js'), { ok: 200 })
  136. let res
  137. if (process.browser) {
  138. res = JSON.parse(atob(info.base64))
  139. } else {
  140. res = JSON.parse(Buffer.from(info.base64, 'base64').toString())
  141. }
  142. same(res, { ok: 200 })
  143. same(info.headers['content-type'], 'application/json')
  144. })
  145. if (process.browser) {
  146. test('500 Response body and message', async () => {
  147. const request = bent()
  148. let body
  149. let _e
  150. try {
  151. await request(u('/echo.js?statusCode=500&body=ok'))
  152. } catch (e) {
  153. _e = e
  154. body = e.responseBody
  155. }
  156. const validate = buffer => {
  157. if (process.browser) {
  158. same(decode(buffer), 'ok')
  159. } else {
  160. same(buffer.toString(), 'ok')
  161. }
  162. }
  163. validate(await body)
  164. // should be able to access again
  165. validate(await _e.responseBody)
  166. same(_e.message, null)
  167. })
  168. } else {
  169. test('500 Response body and message', async () => {
  170. const request = bent()
  171. let body
  172. let _e
  173. try {
  174. await request(u('/echo.js?statusCode=500&body=ok'))
  175. } catch (e) {
  176. _e = e
  177. body = e.responseBody
  178. }
  179. const validate = buffer => {
  180. if (process.browser) {
  181. same(decode(buffer), 'ok')
  182. } else {
  183. same(buffer.toString(), 'ok')
  184. }
  185. }
  186. validate(await body)
  187. // should be able to access again
  188. validate(await _e.responseBody)
  189. same(_e.message, 'Internal Server Error')
  190. })
  191. }
  192. test('auth', async () => {
  193. const request = bent('https://test:pass@httpbin.org/basic-auth/test/pass', 'json')
  194. const obj = await request()
  195. same(obj, { authenticated: true, user: 'test' })
  196. })
  197. if (process.browser) {
  198. test('override headers', async () => {
  199. const request = bent('string', { Accept: 'application/json' })
  200. let info = await request(u('/info.js'), null, { Accept: 'application/xml' })
  201. info = JSON.parse(info)
  202. same(info.headers.accept, 'application/xml')
  203. })
  204. } else {
  205. test('override headers', async () => {
  206. const request = bent('json', { 'X-Default': 'ok', 'X-Override-Me': 'not overriden' })
  207. const info = await request(u('/info.js'), null, { 'X-Override-Me': 'overriden', 'X-New': 'ok' })
  208. same(info.headers['x-default'], 'ok')
  209. same(info.headers['x-override-me'], 'overriden')
  210. same(info.headers['x-new'], 'ok')
  211. })
  212. test('manually-set content-type header when body is present', async () => {
  213. const server = http.createServer((request, response) => {
  214. response.statusCode = request.headers['content-type'] === 'application/jose+json' ? 200 : 400
  215. response.end()
  216. })
  217. await new Promise((resolve, reject) => {
  218. server.listen(9999, () => {
  219. resolve()
  220. })
  221. })
  222. const request = bent('POST')
  223. const response = request('http://localhost:9999', { ok: true }, { 'content-type': 'application/jose+json' })
  224. const info = await response
  225. same(info.statusCode, 200)
  226. server.close()
  227. })
  228. }