'use strict'

var oauth = require('oauth-sign')
var qs = require('querystring')
var fs = require('fs')
var path = require('path')
var request = require('../index')
var tape = require('tape')
var http = require('http')

function getSignature (r) {
  var sign
  r.headers.Authorization.slice('OAuth '.length).replace(/, /g, ',').split(',').forEach(function (v) {
    if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') {
      sign = v.slice('oauth_signature="'.length, -1)
    }
  })
  return decodeURIComponent(sign)
}

// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth

var hmacsign = oauth.hmacsign
var hmacsign256 = oauth.hmacsign256
var rsasign = oauth.rsasign
var rsaPrivatePEM = fs.readFileSync(path.join(__dirname, 'ssl', 'test.key'))
var reqsign
var reqsign256
var reqsignRSA
var accsign
var accsign256
var accsignRSA
var upsign
var upsign256
var upsignRSA

tape('reqsign', function (t) {
  reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token',
    { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11',
      oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk',
      oauth_signature_method: 'HMAC-SHA1',
      oauth_timestamp: '1272323042',
      oauth_version: '1.0'
    }, 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98')

  t.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=')
  t.end()
})

tape('reqsign256', function (t) {
  reqsign256 = hmacsign256('POST', 'https://api.twitter.com/oauth/request_token',
    { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11',
      oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk',
      oauth_signature_method: 'HMAC-SHA256',
      oauth_timestamp: '1272323042',
      oauth_version: '1.0'
    }, 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98')

  t.equal(reqsign256, 'N0KBpiPbuPIMx2B77eIg7tNfGNF81iq3bcO9RO6lH+k=')
  t.end()
})

tape('reqsignRSA', function (t) {
  reqsignRSA = rsasign('POST', 'https://api.twitter.com/oauth/request_token',
    { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11',
      oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk',
      oauth_signature_method: 'RSA-SHA1',
      oauth_timestamp: '1272323042',
      oauth_version: '1.0'
    }, rsaPrivatePEM, 'this parameter is not used for RSA signing')

  t.equal(reqsignRSA, 'MXdzEnIrQco3ACPoVWxCwv5pxYrm5MFRXbsP3LfRV+zfcRr+WMp/dOPS/3r+Wcb+17Z2IK3uJ8dMHfzb5LiDNCTUIj7SWBrbxOpy3Y6SA6z3vcrtjSekkTHLek1j+mzxOi3r3fkbYaNwjHx3PyoFSazbEstnkQQotbITeFt5FBE=')
  t.end()
})

tape('accsign', function (t) {
  accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token',
    { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
      oauth_signature_method: 'HMAC-SHA1',
      oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
      oauth_timestamp: '1272323047',
      oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
      oauth_version: '1.0'
    }, 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98', 'x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA')

  t.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=')
  t.end()
})

tape('accsign256', function (t) {
  accsign256 = hmacsign256('POST', 'https://api.twitter.com/oauth/access_token',
    { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
      oauth_signature_method: 'HMAC-SHA256',
      oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
      oauth_timestamp: '1272323047',
      oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
      oauth_version: '1.0'
    }, 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98', 'x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA')

  t.equal(accsign256, 'y7S9eUhA0tC9/YfRzCPqkg3/bUdYRDpZ93Xi51AvhjQ=')
  t.end()
})

tape('accsignRSA', function (t) {
  accsignRSA = rsasign('POST', 'https://api.twitter.com/oauth/access_token',
    { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
      oauth_signature_method: 'RSA-SHA1',
      oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
      oauth_timestamp: '1272323047',
      oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
      oauth_version: '1.0'
    }, rsaPrivatePEM)

  t.equal(accsignRSA, 'gZrMPexdgGMVUl9H6RxK0MbR6Db8tzf2kIIj52kOrDFcMgh4BunMBgUZAO1msUwz6oqZIvkVqyfyDAOP2wIrpYem0mBg3vqwPIroSE1AlUWo+TtQxOTuqrU+3kDcXpdvJe7CAX5hUx9Np/iGRqaCcgByqb9DaCcQ9ViQ+0wJiXI=')
  t.end()
})

tape('upsign', function (t) {
  upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json',
    { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: 'oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y',
      oauth_signature_method: 'HMAC-SHA1',
      oauth_token: '819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw',
      oauth_timestamp: '1272325550',
      oauth_version: '1.0',
      status: 'setting up my twitter 私のさえずりを設定する'
    }, 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98', 'J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA')

  t.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=')
  t.end()
})

tape('upsign256', function (t) {
  upsign256 = hmacsign256('POST', 'http://api.twitter.com/1/statuses/update.json',
    { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: 'oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y',
      oauth_signature_method: 'HMAC-SHA256',
      oauth_token: '819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw',
      oauth_timestamp: '1272325550',
      oauth_version: '1.0',
      status: 'setting up my twitter 私のさえずりを設定する'
    }, 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98', 'J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA')

  t.equal(upsign256, 'xYhKjozxc3NYef7C26WU+gORdhEURdZRxSDzRttEKH0=')
  t.end()
})

tape('upsignRSA', function (t) {
  upsignRSA = rsasign('POST', 'http://api.twitter.com/1/statuses/update.json',
    { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
      oauth_nonce: 'oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y',
      oauth_signature_method: 'RSA-SHA1',
      oauth_token: '819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw',
      oauth_timestamp: '1272325550',
      oauth_version: '1.0',
      status: 'setting up my twitter 私のさえずりを設定する'
    }, rsaPrivatePEM)

  t.equal(upsignRSA, 'fF4G9BNzDxPu/htctzh9CWzGhtXo9DYYl+ZyRO1/QNOhOZPqnWVUOT+CGUKxmAeJSzLKMAH8y/MFSHI0lzihqwgfZr7nUhTx6kH7lUChcVasr+TZ4qPqvGGEhfJ8Av8D5dF5fytfCSzct62uONU0iHYVqainP+zefk1K7Ptb6hI=')
  t.end()
})

tape('rsign', function (t) {
  var rsign = request.post(
    { url: 'https://api.twitter.com/oauth/request_token',
      oauth: { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11',
        consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk',
        timestamp: '1272323042',
        version: '1.0',
        consumer_secret: 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98'
      }
    })

  process.nextTick(function () {
    t.equal(reqsign, getSignature(rsign))
    rsign.abort()
    t.end()
  })
})

tape('rsign_rsa', function (t) {
  var rsignRSA = request.post(
    { url: 'https://api.twitter.com/oauth/request_token',
      oauth: { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11',
        consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk',
        timestamp: '1272323042',
        version: '1.0',
        private_key: rsaPrivatePEM,
        signature_method: 'RSA-SHA1'
      }
    })

  process.nextTick(function () {
    t.equal(reqsignRSA, getSignature(rsignRSA))
    rsignRSA.abort()
    t.end()
  })
})

tape('raccsign', function (t) {
  var raccsign = request.post(
    { url: 'https://api.twitter.com/oauth/access_token',
      oauth: { consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
        signature_method: 'HMAC-SHA1',
        token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
        timestamp: '1272323047',
        verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
        version: '1.0',
        consumer_secret: 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98',
        token_secret: 'x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA'
      }
    })

  process.nextTick(function () {
    t.equal(accsign, getSignature(raccsign))
    raccsign.abort()
    t.end()
  })
})

tape('raccsignRSA', function (t) {
  var raccsignRSA = request.post(
    { url: 'https://api.twitter.com/oauth/access_token',
      oauth: { consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
        signature_method: 'RSA-SHA1',
        token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
        timestamp: '1272323047',
        verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
        version: '1.0',
        private_key: rsaPrivatePEM,
        token_secret: 'x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA'
      }
    })

  process.nextTick(function () {
    t.equal(accsignRSA, getSignature(raccsignRSA))
    raccsignRSA.abort()
    t.end()
  })
})

tape('rupsign', function (t) {
  var rupsign = request.post(
    { url: 'http://api.twitter.com/1/statuses/update.json',
      oauth: { consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: 'oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y',
        signature_method: 'HMAC-SHA1',
        token: '819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw',
        timestamp: '1272325550',
        version: '1.0',
        consumer_secret: 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98',
        token_secret: 'J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA'
      },
      form: {status: 'setting up my twitter 私のさえずりを設定する'}
    })
  process.nextTick(function () {
    t.equal(upsign, getSignature(rupsign))
    rupsign.abort()
    t.end()
  })
})

tape('rupsignRSA', function (t) {
  var rupsignRSA = request.post(
    { url: 'http://api.twitter.com/1/statuses/update.json',
      oauth: { consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: 'oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y',
        signature_method: 'RSA-SHA1',
        token: '819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw',
        timestamp: '1272325550',
        version: '1.0',
        private_key: rsaPrivatePEM,
        token_secret: 'J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA'
      },
      form: {status: 'setting up my twitter 私のさえずりを設定する'}
    })
  process.nextTick(function () {
    t.equal(upsignRSA, getSignature(rupsignRSA))
    rupsignRSA.abort()
    t.end()
  })
})

tape('rfc5849 example', function (t) {
  var rfc5849 = request.post(
    { url: 'http://example.com/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b',
      oauth: { consumer_key: '9djdj82h48djs9d2',
        nonce: '7d8f3e4a',
        signature_method: 'HMAC-SHA1',
        token: 'kkk9d7dh3k39sjv7',
        timestamp: '137131201',
        consumer_secret: 'j49sk3j29djd',
        token_secret: 'dh893hdasih9',
        realm: 'Example'
      },
      form: {
        c2: '',
        a3: '2 q'
      }
    })

  process.nextTick(function () {
    // different signature in rfc5849 because request sets oauth_version by default
    t.equal('OB33pYjWAnf+xtOHN4Gmbdil168=', getSignature(rfc5849))
    rfc5849.abort()
    t.end()
  })
})

tape('rfc5849 RSA example', function (t) {
  var rfc5849RSA = request.post(
    { url: 'http://example.com/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b',
      oauth: { consumer_key: '9djdj82h48djs9d2',
        nonce: '7d8f3e4a',
        signature_method: 'RSA-SHA1',
        token: 'kkk9d7dh3k39sjv7',
        timestamp: '137131201',
        private_key: rsaPrivatePEM,
        token_secret: 'dh893hdasih9',
        realm: 'Example'
      },
      form: {
        c2: '',
        a3: '2 q'
      }
    })

  process.nextTick(function () {
    // different signature in rfc5849 because request sets oauth_version by default
    t.equal('ThNYfZhYogcAU6rWgI3ZFlPEhoIXHMZcuMzl+jykJZW/ab+AxyefS03dyd64CclIZ0u8JEW64TQ5SHthoQS8aM8qir4t+t88lRF3LDkD2KtS1krgCZTUQxkDL5BO5pxsqAQ2Zfdcrzaxb6VMGD1Hf+Pno+fsHQo/UUKjq4V3RMo=', getSignature(rfc5849RSA))
    rfc5849RSA.abort()
    t.end()
  })
})

tape('plaintext signature method', function (t) {
  var plaintext = request.post(
    { url: 'https://dummy.com',
      oauth: { consumer_secret: 'consumer_secret',
        token_secret: 'token_secret',
        signature_method: 'PLAINTEXT'
      }
    })

  process.nextTick(function () {
    t.equal('consumer_secret&token_secret', getSignature(plaintext))
    plaintext.abort()
    t.end()
  })
})

tape('invalid transport_method', function (t) {
  t.throws(
    function () {
      request.post(
        { url: 'http://example.com/',
          oauth: { transport_method: 'headerquery'
          }
        })
    }, /transport_method invalid/)
  t.end()
})

tape("invalid method while using transport_method 'body'", function (t) {
  t.throws(
    function () {
      request.get(
        { url: 'http://example.com/',
          headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' },
          oauth: { transport_method: 'body'
          }
        })
    }, /requires POST/)
  t.end()
})

tape("invalid content-type while using transport_method 'body'", function (t) {
  t.throws(
    function () {
      request.post(
        { url: 'http://example.com/',
          headers: { 'content-type': 'application/json; charset=UTF-8' },
          oauth: { transport_method: 'body'
          }
        })
    }, /requires POST/)
  t.end()
})

tape('query transport_method', function (t) {
  var r = request.post(
    { url: 'https://api.twitter.com/oauth/access_token',
      oauth: { consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
        signature_method: 'HMAC-SHA1',
        token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
        timestamp: '1272323047',
        verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
        version: '1.0',
        consumer_secret: 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98',
        token_secret: 'x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA',
        transport_method: 'query'
      }
    })

  process.nextTick(function () {
    t.notOk(r.headers.Authorization, "oauth Authorization header should not be present with transport_method 'query'")
    t.equal(r.uri.path, r.path, 'r.uri.path should equal r.path')
    t.ok(r.path.match(/^\/oauth\/access_token\?/), 'path should contain path + query')
    t.deepEqual(qs.parse(r.uri.query),
      { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
        oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
        oauth_signature_method: 'HMAC-SHA1',
        oauth_timestamp: '1272323047',
        oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
        oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
        oauth_version: '1.0',
        oauth_signature: accsign })
    r.abort()
    t.end()
  })
})

tape('query transport_method + form option + url params', function (t) {
  var r = request.post(
    { url: 'http://example.com/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b',
      oauth: { consumer_key: '9djdj82h48djs9d2',
        nonce: '7d8f3e4a',
        signature_method: 'HMAC-SHA1',
        token: 'kkk9d7dh3k39sjv7',
        timestamp: '137131201',
        consumer_secret: 'j49sk3j29djd',
        token_secret: 'dh893hdasih9',
        realm: 'Example',
        transport_method: 'query'
      },
      form: {
        c2: '',
        a3: '2 q'
      }
    })

  process.nextTick(function () {
    t.notOk(r.headers.Authorization, "oauth Authorization header should not be present with transport_method 'query'")
    t.equal(r.uri.path, r.path, 'r.uri.path should equal r.path')
    t.ok(r.path.match(/^\/request\?/), 'path should contain path + query')
    t.deepEqual(qs.parse(r.uri.query),
      { b5: '=%3D',
        a3: 'a',
        'c@': '',
        a2: 'r b',
        realm: 'Example',
        oauth_consumer_key: '9djdj82h48djs9d2',
        oauth_nonce: '7d8f3e4a',
        oauth_signature_method: 'HMAC-SHA1',
        oauth_timestamp: '137131201',
        oauth_token: 'kkk9d7dh3k39sjv7',
        oauth_version: '1.0',
        oauth_signature: 'OB33pYjWAnf+xtOHN4Gmbdil168=' })
    r.abort()
    t.end()
  })
})

tape('query transport_method + qs option + url params', function (t) {
  var r = request.post(
    { url: 'http://example.com/request?a2=r%20b',
      oauth: { consumer_key: '9djdj82h48djs9d2',
        nonce: '7d8f3e4a',
        signature_method: 'HMAC-SHA1',
        token: 'kkk9d7dh3k39sjv7',
        timestamp: '137131201',
        consumer_secret: 'j49sk3j29djd',
        token_secret: 'dh893hdasih9',
        realm: 'Example',
        transport_method: 'query'
      },
      qs: {
        b5: '=%3D',
        a3: ['a', '2 q'],
        'c@': '',
        c2: ''
      }
    })

  process.nextTick(function () {
    t.notOk(r.headers.Authorization, "oauth Authorization header should not be present with transport_method 'query'")
    t.equal(r.uri.path, r.path, 'r.uri.path should equal r.path')
    t.ok(r.path.match(/^\/request\?/), 'path should contain path + query')
    t.deepEqual(qs.parse(r.uri.query),
      { a2: 'r b',
        b5: '=%3D',
        'a3[0]': 'a',
        'a3[1]': '2 q',
        'c@': '',
        c2: '',
        realm: 'Example',
        oauth_consumer_key: '9djdj82h48djs9d2',
        oauth_nonce: '7d8f3e4a',
        oauth_signature_method: 'HMAC-SHA1',
        oauth_timestamp: '137131201',
        oauth_token: 'kkk9d7dh3k39sjv7',
        oauth_version: '1.0',
        oauth_signature: 'OB33pYjWAnf+xtOHN4Gmbdil168=' })
    r.abort()
    t.end()
  })
})

tape('body transport_method', function (t) {
  var r = request.post(
    { url: 'https://api.twitter.com/oauth/access_token',
      headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' },
      oauth: { consumer_key: 'GDdmIQH6jhtmLUypg82g',
        nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
        signature_method: 'HMAC-SHA1',
        token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
        timestamp: '1272323047',
        verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
        version: '1.0',
        consumer_secret: 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98',
        token_secret: 'x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA',
        transport_method: 'body'
      }
    })

  process.nextTick(function () {
    t.notOk(r.headers.Authorization, "oauth Authorization header should not be present with transport_method 'body'")
    t.deepEqual(qs.parse(r.body),
      { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g',
        oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8',
        oauth_signature_method: 'HMAC-SHA1',
        oauth_timestamp: '1272323047',
        oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc',
        oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY',
        oauth_version: '1.0',
        oauth_signature: accsign })
    r.abort()
    t.end()
  })
})

tape('body transport_method + form option + url params', function (t) {
  var r = request.post(
    { url: 'http://example.com/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b',
      oauth: { consumer_key: '9djdj82h48djs9d2',
        nonce: '7d8f3e4a',
        signature_method: 'HMAC-SHA1',
        token: 'kkk9d7dh3k39sjv7',
        timestamp: '137131201',
        consumer_secret: 'j49sk3j29djd',
        token_secret: 'dh893hdasih9',
        realm: 'Example',
        transport_method: 'body'
      },
      form: {
        c2: '',
        a3: '2 q'
      }
    })

  process.nextTick(function () {
    t.notOk(r.headers.Authorization, "oauth Authorization header should not be present with transport_method 'body'")
    t.deepEqual(qs.parse(r.body),
      { c2: '',
        a3: '2 q',
        realm: 'Example',
        oauth_consumer_key: '9djdj82h48djs9d2',
        oauth_nonce: '7d8f3e4a',
        oauth_signature_method: 'HMAC-SHA1',
        oauth_timestamp: '137131201',
        oauth_token: 'kkk9d7dh3k39sjv7',
        oauth_version: '1.0',
        oauth_signature: 'OB33pYjWAnf+xtOHN4Gmbdil168=' })
    r.abort()
    t.end()
  })
})

tape('body_hash manually set', function (t) {
  var r = request.post(
    { url: 'http://example.com',
      oauth: { consumer_secret: 'consumer_secret',
        body_hash: 'ManuallySetHash'
      },
      json: {foo: 'bar'}
    })

  process.nextTick(function () {
    var hash = r.headers.Authorization.replace(/.*oauth_body_hash="([^"]+)".*/, '$1')
    t.equal('ManuallySetHash', hash)
    r.abort()
    t.end()
  })
})

tape('body_hash automatically built for string', function (t) {
  var r = request.post(
    { url: 'http://example.com',
      oauth: { consumer_secret: 'consumer_secret',
        body_hash: true
      },
      body: 'Hello World!'
    })

  process.nextTick(function () {
    var hash = r.headers.Authorization.replace(/.*oauth_body_hash="([^"]+)".*/, '$1')
    // from https://tools.ietf.org/id/draft-eaton-oauth-bodyhash-00.html#anchor15
    t.equal('Lve95gjOVATpfV8EL5X4nxwjKHE%3D', hash)
    r.abort()
    t.end()
  })
})

tape('body_hash automatically built for JSON', function (t) {
  var r = request.post(
    { url: 'http://example.com',
      oauth: { consumer_secret: 'consumer_secret',
        body_hash: true
      },
      json: {foo: 'bar'}
    })

  process.nextTick(function () {
    var hash = r.headers.Authorization.replace(/.*oauth_body_hash="([^"]+)".*/, '$1')
    t.equal('pedE0BZFQNM7HX6mFsKPL6l%2BdUo%3D', hash)
    r.abort()
    t.end()
  })
})

tape('body_hash PLAINTEXT signature_method', function (t) {
  t.throws(function () {
    request.post(
      { url: 'http://example.com',
        oauth: { consumer_secret: 'consumer_secret',
          body_hash: true,
          signature_method: 'PLAINTEXT'
        },
        json: {foo: 'bar'}
      })
  }, /oauth: PLAINTEXT signature_method not supported with body_hash signing/)
  t.end()
})

tape('refresh oauth_nonce on redirect', function (t) {
  var oauthNonce1
  var oauthNonce2
  var url
  var s = http.createServer(function (req, res) {
    if (req.url === '/redirect') {
      oauthNonce1 = req.headers.authorization.replace(/.*oauth_nonce="([^"]+)".*/, '$1')
      res.writeHead(302, {location: url + '/response'})
      res.end()
    } else if (req.url === '/response') {
      oauthNonce2 = req.headers.authorization.replace(/.*oauth_nonce="([^"]+)".*/, '$1')
      res.writeHead(200, {'content-type': 'text/plain'})
      res.end()
    }
  })
  s.listen(0, function () {
    url = 'http://localhost:' + this.address().port
    request.get(
      { url: url + '/redirect',
        oauth: { consumer_key: 'consumer_key',
          consumer_secret: 'consumer_secret',
          token: 'token',
          token_secret: 'token_secret'
        }
      }, function (err, res, body) {
      t.equal(err, null)
      t.notEqual(oauthNonce1, oauthNonce2)
      s.close(function () {
        t.end()
      })
    })
  })
})

tape('no credentials on external redirect', function (t) {
  var s2 = http.createServer(function (req, res) {
    res.writeHead(200, {'content-type': 'text/plain'})
    res.end()
  })
  var s1 = http.createServer(function (req, res) {
    res.writeHead(302, {location: s2.url})
    res.end()
  })
  s1.listen(0, function () {
    s1.url = 'http://localhost:' + this.address().port
    s2.listen(0, function () {
      s2.url = 'http://127.0.0.1:' + this.address().port
      request.get(
        { url: s1.url,
          oauth: { consumer_key: 'consumer_key',
            consumer_secret: 'consumer_secret',
            token: 'token',
            token_secret: 'token_secret'
          }
        }, function (err, res, body) {
        t.equal(err, null)
        t.equal(res.request.headers.Authorization, undefined)
        s1.close(function () {
          s2.close(function () {
            t.end()
          })
        })
      })
    })
  })
})
