chai      = require 'chai'
sinon     = require 'sinon'
sinonChai = require 'sinon-chai'
expect    = chai.expect




chai.use sinonChai
chai.should()




ClientToken = require '../../../models/ClientToken'
verifyClientToken = require('../../../oidc').verifyClientToken




describe 'Verify Client Token', ->


  {req,res,next,err} = {}


  describe 'with missing bearer token', ->

    before (done) ->
      req  = headers: {}
      res  = {}
      next = sinon.spy()

      verifyClientToken req, res, (error) ->
        err = error
        done()

    it 'should provide an UnauthorizedError', ->
      err.name.should.equal 'UnauthorizedError'

    it 'should provide a realm', ->
      err.realm.should.equal 'client'

    it 'should provide an error code', ->
      err.error.should.equal 'unauthorized_client'

    it 'should provide an error description', ->
      err.error_description.should.equal 'Missing authorization header'

    it 'should provide a status code', ->
      err.statusCode.should.equal 403




  describe 'with valid token', ->

    token = null

    before (done) ->
      token =
        header: {}
        payload: {}

      sinon.stub(ClientToken, 'decode').returns token

      req  = headers: { authorization: 'Bearer valid.signed.jwt' }
      res  = {}
      next = sinon.spy (error) ->
        err = error
        done()

      verifyClientToken req, res, next

    after ->
      ClientToken.decode.restore()

    it 'should reference the retrieved token object', ->
      req.token.should.equal token

    it 'should continue', ->
      next.should.have.been.called




  describe 'with invalid token', ->

    before (done) ->
      req  = headers: { authorization: 'Bearer invalid' }
      res  = {}
      next = sinon.spy()

      verifyClientToken req, res, (error) ->
        err = error
        done()

    it 'should provide an UnauthorizedError', ->
      err.name.should.equal 'UnauthorizedError'

    it 'should provide a realm', ->
      err.realm.should.equal 'client'

    it 'should provide an error code', ->
      err.error.should.equal 'unauthorized_client'

    it 'should provide an error description', ->
      err.error_description.should.equal 'Invalid access token'

    it 'should provide a status code', ->
      err.statusCode.should.equal 403




