Merge pull request #3617 from overleaf/ae-fetch-json-data

Rename "responseBody" to "data" in fetchJSON error object

GitOrigin-RevId: 75c166b23cbef22e82232f334ef373c66d9612a7
This commit is contained in:
Alf Eaton 2021-02-05 14:01:37 +00:00 committed by Copybot
parent de1135d908
commit dfffc76562
3 changed files with 101 additions and 7 deletions

View file

@ -49,35 +49,35 @@ function fetchJSON(
return fetch(path, options)
.then(parseResponseBody)
.then(({ responseBody, response }) => {
.then(({ data, response }) => {
if (!response.ok) {
throw new OError(response.statusText, {
statusCode: response.status,
responseBody,
data,
response
})
}
return responseBody
return data
})
}
function parseResponseBody(response) {
const contentType = response.headers.get('Content-Type')
if (/application\/json/.test(contentType)) {
return response.json().then(json => {
return { responseBody: json, response }
return response.json().then(data => {
return { data, response }
})
} else if (
/text\/plain/.test(contentType) ||
/text\/html/.test(contentType)
) {
return response.text().then(text => {
return { responseBody: { message: text }, response }
return { data: { message: text }, response }
})
} else {
// response body ignored as content-type is either not set (e.g. 204
// responses) or unsupported
return Promise.resolve({ responseBody: {}, response })
return Promise.resolve({ data: {}, response })
}
}

View file

@ -8,6 +8,7 @@ require('jsdom-global/register')
// has a nicer failure messages
const chai = require('chai')
chai.use(require('sinon-chai'))
chai.use(require('chai-as-promised'))
window.i18n = { currentLangCode: 'en' }
require('../../frontend/js/i18n')

View file

@ -0,0 +1,93 @@
import { expect } from 'chai'
import fetchMock from 'fetch-mock'
import OError from '@overleaf/o-error'
import {
deleteJSON,
getJSON,
postJSON,
putJSON
} from '../../../frontend/js/infrastructure/fetch-json'
describe('fetchJSON', function() {
before(function() {
fetchMock.restore()
})
afterEach(function() {
fetchMock.restore()
})
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json'
}
it('handles GET requests', function() {
fetchMock.once(
{ method: 'GET', url: '/test', headers },
{ status: 200, body: { result: 'success' } }
)
return expect(getJSON('/test')).to.eventually.deep.equal({
result: 'success'
})
})
it('handles 4xx responses', function() {
fetchMock.get('/test', {
status: 400,
body: { message: 'The request was invalid' }
})
return expect(getJSON('/test'))
.to.eventually.be.rejectedWith('Bad Request')
.and.be.an.instanceOf(OError)
.to.nested.include({
'info.response.status': 400,
'info.data.message': 'The request was invalid'
})
})
it('handles 5xx responses', async function() {
fetchMock.get('/test', { status: 500 })
return expect(getJSON('/test'))
.to.eventually.be.rejectedWith('Internal Server Error')
.and.be.an.instanceOf(OError)
.to.nested.include({
'info.response.status': 500
})
})
it('handles POST requests', function() {
const body = { example: true }
fetchMock.once(
{ method: 'POST', url: '/test', headers, body },
{ status: 200, body: { result: 'success' } }
)
return expect(postJSON('/test', { body })).to.eventually.deep.equal({
result: 'success'
})
})
it('handles PUT requests', function() {
const body = { example: true }
fetchMock.once(
{ method: 'PUT', url: '/test', headers, body },
{ status: 200, body: { result: 'success' } }
)
return expect(putJSON('/test', { body })).to.eventually.deep.equal({
result: 'success'
})
})
it('handles DELETE requests', function() {
fetchMock.once({ method: 'DELETE', url: '/test', headers }, { status: 204 })
return expect(deleteJSON('/test')).to.eventually.deep.equal({})
})
})