Skip to content

Commit

Permalink
feat(body): automatic handling of different opts.body values
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Mar 15, 2018
1 parent 84b94ba commit f3b97db
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 5 deletions.
14 changes: 13 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,26 @@ function regFetch (uri, opts) {
// through that takes into account the scope, the prefix of `uri`, etc
const startTime = Date.now()
const conf = opts.config
const headers = getHeaders(registry, uri, opts)
let body = opts.body
const bodyIsStream = body &&
typeof body === 'object' &&
typeof body.pipe === 'function'
if (body && !bodyIsStream && typeof body !== 'string' && !Buffer.isBuffer(body)) {
headers['content-type'] = headers['content-type'] || 'application/json'
body = JSON.stringify(body)
} else if (body && !headers['content-type']) {
headers['content-type'] = 'application/octet-stream'
}
return fetch(uri, {
agent: opts.agent,
algorithms: opts.algorithms,
body,
cache: getCacheMode(conf),
cacheManager: conf.get('cache'),
ca: conf.get('ca'),
cert: conf.get('cert'),
headers: getHeaders(registry, uri, opts),
headers,
integrity: opts.integrity,
key: conf.get('key'),
localAddress: conf.get('local-address'),
Expand Down
109 changes: 105 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
'use strict'

const Buffer = require('safe-buffer').Buffer

const npmlog = require('npmlog')
const PassThrough = require('stream').PassThrough
const test = require('tap').test
const tnock = require('./util/tnock.js')

Expand Down Expand Up @@ -34,17 +37,115 @@ test('hello world', t => {
.get('/hello')
.reply(200, {hello: 'world'})
return fetch('/hello', OPTS)
.then(res => {
t.equal(res.status, 200, 'got successful response')
return res.json()
})
.then(json => t.deepEqual(json, {hello: 'world'}, 'got correct body'))
})

test('JSON body param', t => {
tnock(t, OPTS.config.get('registry'))
.matchHeader('content-type', ctype => {
t.equal(ctype[0], 'application/json', 'content-type automatically set')
return ctype[0] === 'application/json'
})
.post('/hello')
.reply(200, (uri, reqBody) => {
t.deepEqual(reqBody, {
hello: 'world'
}, 'got the JSON version of the body')
return reqBody
})
const opts = Object.assign({
method: 'POST',
body: {hello: 'world'}
}, OPTS)
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
return res.json()
})
.then(json => t.deepEqual(json, {hello: 'world'}))
})

test('json()')
test('method configurable')
test('npm-notice header logging')
test('optionally verifies request body integrity')
test('buffer body param', t => {
tnock(t, OPTS.config.get('registry'))
.matchHeader('content-type', ctype => {
t.equal(ctype[0], 'application/octet-stream', 'content-type automatically set')
return ctype[0] === 'application/octet-stream'
})
.post('/hello')
.reply(200, (uri, reqBody) => {
t.deepEqual(
Buffer.from(reqBody, 'utf8'),
Buffer.from('hello', 'utf8'),
'got the JSON version of the body'
)
return reqBody
})
const opts = Object.assign({
method: 'POST',
body: Buffer.from('hello', 'utf8')
}, OPTS)
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
return res.buffer()
})
.then(buf =>
t.deepEqual(buf, Buffer.from('hello', 'utf8'), 'got response')
)
})

test('stream body param', t => {
tnock(t, OPTS.config.get('registry'))
.matchHeader('content-type', ctype => {
t.equal(ctype[0], 'application/octet-stream', 'content-type automatically set')
return ctype[0] === 'application/octet-stream'
})
.post('/hello')
.reply(200, (uri, reqBody) => {
t.deepEqual(JSON.parse(reqBody), {
hello: 'world'
}, 'got the stringified version of the body')
return reqBody
})
const stream = new PassThrough()
setImmediate(() => stream.end(JSON.stringify({hello: 'world'})))
const opts = Object.assign({
method: 'POST',
body: stream
}, OPTS)
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
return res.json()
})
.then(json => t.deepEqual(json, {hello: 'world'}))
})

test('json()', t => {
tnock(t, OPTS.config.get('registry'))
.get('/hello')
.reply(200, {hello: 'world'})
return fetch.json('/hello', OPTS)
.then(json => t.deepEqual(json, {hello: 'world'}, 'got json body'))
})

test('method configurable', t => {
tnock(t, OPTS.config.get('registry'))
.delete('/hello')
.reply(200)
const opts = Object.assign({
method: 'DELETE'
}, OPTS)
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200, 'successfully used DELETE method')
})
})

test('pickRegistry() utility')

// TODO
Expand Down

0 comments on commit f3b97db

Please sign in to comment.