Skip to content

Commit

Permalink
testing and fixing json handling for errors of fetch api
Browse files Browse the repository at this point in the history
  • Loading branch information
felipesabino committed Aug 25, 2017
1 parent f822cb4 commit df42b80
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
90 changes: 90 additions & 0 deletions source/api/_tests/fetch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// import * as jest from 'jest';
import * as http from "http"

import { api } from "../fetch"

interface ResponseMock {
body?: any
statusCode?: number
contentType?: string
}

class TestServer {
private port = 30001
private hostname = "localhost"
private response: ResponseMock = null
private router = (req, res) => {
res.statusCode = this.response && this.response.statusCode ? this.response.statusCode : 200
res.setHeader(
"Content-Type",
this.response && this.response.contentType ? this.response.contentType : "application/json"
)
res.end(this.response ? this.response.body : null)
}
private server = http.createServer(this.router)

start = async (response: ResponseMock): Promise<void> => {
this.response = response
return new Promise<void>((resolve, reject) => {
this.server.listen(this.port, this.hostname, err => (err ? reject(err) : resolve()))
})
}
stop = async (): Promise<void> => {
this.response = null
return new Promise<void>((resolve, reject) => {
this.server.close(err => (err ? reject(err) : resolve()))
})
}
}

describe("fetch", () => {
let url: string
let server = new TestServer()

beforeEach(() => {
url = "http://localhost:30001/"
})

afterEach(async () => {
await server.stop()
})

it("handles json success", async () => {
let body = { key: "valid json" }
await server.start({
body: JSON.stringify(body),
})

let response = await api(url, {})
expect(response.ok).toBe(true)
expect(response.status).toBe(200)
expect(await response.json()).toMatchObject(body)
})

it("handles json error", async () => {
let body = { key: "valid json" }
await server.start({
body: JSON.stringify(body),
statusCode: 500,
})

let response = await api(url, {})
expect(response.ok).toBe(false)
expect(response.status).toBe(500)
expect(await response.json()).toMatchObject(body)
})

it("handles plain text error", async () => {
let body = "any plain text response"
await server.start({
body: body,
statusCode: 500,
contentType: "text/plain",
})

let response = await api(url, {})
expect(response.ok).toBe(false)
expect(response.status).toBe(500)
expect(await response.text()).toBe(body)
})
})
14 changes: 11 additions & 3 deletions source/api/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,17 @@ export function api(url: string | node_fetch.Request, init: node_fetch.RequestIn
return originalFetch(url, init).then(async (response: node_fetch.Response) => {
// Handle failing errors
if (!response.ok) {
const responseJSON = await response.json()
console.warn(`Request failed [${response.status}]: ${response.url}`)
console.warn(`Response: ${JSON.stringify(responseJSON, null, " ")}`)
// we should not modify the response when an error occur to allow body stream to be read again if needed
let clonedResponse = response.clone()
console.warn(`Request failed [${clonedResponse.status}]: ${clonedResponse.url}`)
let responseBody = await clonedResponse.text()
try {
// tries to pretty print the JSON response when possible
const responseJSON = await JSON.parse(responseBody.toString())
console.warn(`Response: ${JSON.stringify(responseJSON, null, " ")}`)
} catch (e) {
console.warn(`Response: ${responseBody}`)
}
}

return response
Expand Down

0 comments on commit df42b80

Please sign in to comment.