describe "HAPINode", ->
    HAPINode = require "../../../../../src/com/huzutech/hapi/rest/HAPINode"
    restler = require "restler"
    nock = require "nock"
    hapiNode = null
    host = "http://www.huzutech.com"
    nockScope = null

    beforeEach ->
        hapiNode = new HAPINode
        hapiNode.setBaseUrl host
        nock.cleanAll()
        nockScope = nock(host)

    it "can be instantiated", ->
        expect(hapiNode).toBeDefined()

    it "includes a X-Requested-With header in each request", ->
        spyOn(restler, "request")
        hapiNode.get("/assets", ->)
        args = restler.request.mostRecentCall.args
        options = args[1]
        expect(options.headers["X-Requested-With"]).toBeDefined()

    it "calls the callback function if restler call successful", ->
        assets = [
            "asset1",
            "asset2"
        ]
            
        nockScope.get("/assets").reply(200, assets)
        done = false
        obj =
            callback: (err, data) ->
                done = true
        spyOn(obj, "callback").andCallThrough()
        runs ->
            hapiNode.get("/assets", obj.callback)
        waitsFor ->
            done
        runs ->
            expect(obj.callback).toHaveBeenCalledWith(undefined, JSON.stringify(assets))
        
    it "calls the callback function with an error if restler call receives an error", ->
        nockScope.get("/assets").reply(400)
        done = false
        obj =
            callback: (err, data) ->
                done = true
        spyOn(obj, "callback").andCallThrough()
        runs ->
            hapiNode.get("/assets", obj.callback)
        waitsFor ->
            done
        runs ->
            expect(obj.callback).toHaveBeenCalledWith(jasmine.any(Error))

    it "calls the callback function with errors detail if restler call receives an error with reasons in the body", ->
        response =
            errors: [
                "first error",
                "second error"
            ]
        nockScope.get("/assets").reply(400, response)
        done = false
        error = undefined
        obj =
            callback: (err, data) ->
                error = err
                done = true
        spyOn(obj, "callback").andCallThrough()
        runs ->
            hapiNode.get("/assets", obj.callback)
        waitsFor ->
            done
        runs ->
            expect(obj.callback).toHaveBeenCalledWith(jasmine.any(Error))
            for message in response.errors
                expect(error.message).toMatch(message)

    it "calls the callback function with an error if connection is down", ->
        done = false
        obj =
            callback: (err, data) ->
                done = true
        spyOn(obj, "callback").andCallThrough()
        runs ->
            hapiNode.get("/assets", obj.callback)
        waitsFor ->
            done
        runs ->
            expect(obj.callback).toHaveBeenCalledWith(jasmine.any(Error))

    it "calls the global error callback if restler call receives an error", ->
        nockScope.get("/assets").reply(500)
        done = false
        error = null
        obj =
            callback: (err) ->
                error = err
                done = true
        spyOn(obj, "callback").andCallThrough()
        runs ->
            hapiNode.onError obj.callback
            hapiNode.get("/assets", -> )
        waitsFor ->
            done
        runs ->
            expect(error).toBeDefined()
            expect(error.statusCode).toEqual(500)

    it "doesn't call the global error callback if restler call receives an error and onError callback has been removed", ->
        nockScope.get("/assets").reply(500)
        done = false
        error = null
        obj =
            callback: (err) ->
        spyOn(obj, "callback")
        runs ->
            hapiNode.onError obj.callback
            hapiNode.removeOnError obj.callback
            hapiNode.get "/assets", ->
                done = true
        waitsFor ->
            done
        runs ->
            expect(obj.callback).not.toHaveBeenCalled()

    it "aborts all the current and queued requests if abortAll is called", ->
        count = 2
        abortCallback = ->
            count--
        runs ->
            assetsReq = hapiNode.get("/assets", ->)
            assetsReq?.on "abort", abortCallback
            categoriesReq = hapiNode.get("/categories", ->)
            categoriesReq?.on "abort", abortCallback
            process.nextTick ->
                hapiNode.abortAll()
        waitsFor ->
            count is 0
        runs ->
            expect(hapiNode.requestCount()).toEqual(0)

