fetch-json.test.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import { expect } from 'chai'
  2. import fetchMock from 'fetch-mock'
  3. import {
  4. deleteJSON,
  5. FetchError,
  6. getJSON,
  7. postJSON,
  8. putJSON,
  9. } from '../../../frontend/js/infrastructure/fetch-json'
  10. describe('fetchJSON', function () {
  11. before(function () {
  12. fetchMock.restore()
  13. })
  14. afterEach(function () {
  15. fetchMock.restore()
  16. })
  17. const headers = {
  18. Accept: 'application/json',
  19. 'Content-Type': 'application/json',
  20. }
  21. it('handles GET requests', function () {
  22. fetchMock.once(
  23. { method: 'GET', url: '/test', headers },
  24. { status: 200, body: { result: 'success' } }
  25. )
  26. return expect(getJSON('/test')).to.eventually.deep.equal({
  27. result: 'success',
  28. })
  29. })
  30. it('handles 4xx responses', function () {
  31. fetchMock.get('/test', {
  32. status: 400,
  33. body: { message: 'The request was invalid' },
  34. })
  35. return expect(getJSON('/test'))
  36. .to.eventually.be.rejectedWith('Bad Request')
  37. .and.be.an.instanceOf(FetchError)
  38. .to.nested.include({
  39. message: 'Bad Request',
  40. 'data.message': 'The request was invalid',
  41. 'response.status': 400,
  42. 'info.statusCode': 400,
  43. })
  44. })
  45. it('handles 5xx responses', async function () {
  46. fetchMock.get('/test', { status: 500 })
  47. return expect(getJSON('/test'))
  48. .to.eventually.be.rejectedWith('Internal Server Error')
  49. .and.be.an.instanceOf(FetchError)
  50. .to.nested.include({
  51. 'response.status': 500,
  52. 'info.statusCode': 500,
  53. })
  54. })
  55. it('handles JSON error responses', async function () {
  56. fetchMock.get('/test', {
  57. status: 500,
  58. headers: {
  59. 'Content-Type': 'application/json',
  60. },
  61. body: { message: 'lorem ipsum' },
  62. })
  63. return expect(getJSON('/test'))
  64. .to.eventually.be.rejectedWith('Internal Server Error')
  65. .and.be.an.instanceOf(FetchError)
  66. .to.nested.include({
  67. 'data.message': 'lorem ipsum',
  68. })
  69. })
  70. it('handles text error responses', async function () {
  71. fetchMock.get('/test', {
  72. status: 500,
  73. headers: {
  74. 'Content-Type': 'text/plain',
  75. },
  76. body: 'lorem ipsum',
  77. })
  78. return expect(getJSON('/test'))
  79. .to.eventually.be.rejectedWith('Internal Server Error')
  80. .and.be.an.instanceOf(FetchError)
  81. .to.nested.include({
  82. 'data.message': 'lorem ipsum',
  83. })
  84. })
  85. it('handles text error responses sent as HTML', async function () {
  86. fetchMock.get('/test', {
  87. status: 500,
  88. headers: {
  89. 'Content-Type': 'text/html',
  90. },
  91. body: 'lorem ipsum',
  92. })
  93. return expect(getJSON('/test'))
  94. .to.eventually.be.rejectedWith('Internal Server Error')
  95. .and.be.an.instanceOf(FetchError)
  96. .to.nested.include({
  97. 'data.message': 'lorem ipsum',
  98. })
  99. })
  100. it('handles (ignores) HTML error responses sent as HTML', async function () {
  101. fetchMock.get('/test', {
  102. status: 500,
  103. headers: {
  104. 'Content-Type': 'text/html',
  105. },
  106. body:
  107. '<!doctype html><html lang="en"><body><p>lorem ipsum</p></body></html>',
  108. })
  109. const promise = getJSON('/test')
  110. expect(promise)
  111. .to.eventually.be.rejectedWith('Internal Server Error')
  112. .and.be.an.instanceOf(FetchError)
  113. try {
  114. await promise
  115. } catch (error) {
  116. expect(error.data).to.eql({})
  117. }
  118. })
  119. it('handles POST requests', function () {
  120. const body = { example: true }
  121. fetchMock.once(
  122. { method: 'POST', url: '/test', headers, body },
  123. { status: 200, body: { result: 'success' } }
  124. )
  125. return expect(postJSON('/test', { body })).to.eventually.deep.equal({
  126. result: 'success',
  127. })
  128. })
  129. it('handles PUT requests', function () {
  130. const body = { example: true }
  131. fetchMock.once(
  132. { method: 'PUT', url: '/test', headers, body },
  133. { status: 200, body: { result: 'success' } }
  134. )
  135. return expect(putJSON('/test', { body })).to.eventually.deep.equal({
  136. result: 'success',
  137. })
  138. })
  139. it('handles DELETE requests', function () {
  140. fetchMock.once({ method: 'DELETE', url: '/test', headers }, { status: 204 })
  141. return expect(deleteJSON('/test')).to.eventually.deep.equal({})
  142. })
  143. })