text: "use strict";
  
  const request = require("../../");
  const setup = require("../support/setup");
  const base = setup.uri;
  const assert = require("assert");
  const fs = require("fs");
  const EventEmitter = require("events").EventEmitter;
  const StringDecoder = require("string_decoder").StringDecoder;
  const url = require("url");
  
  describe("[node] request", () => {
    describe("with an url", () => {
      it("should preserve the encoding of the url", done => {
        request.get(`${base}/url?a=(b%29`).end((err, res) => {
          assert.equal("/url?a=(b%29", res.text);
          done();
        });
      });
    });
  
    describe("with an object", () => {
      it("should format the url", () =>
        request.get(url.parse(`${base}/login`)).then(res => {
          assert(res.ok);
        }));
    });
  
    describe("without a schema", () => {
      it("should default to http", () =>
        request.get("localhost:5000/login").then(res => {
          assert.equal(res.status, 200);
        }));
    });
  
    describe("res.toJSON()", () => {
      it("should describe the response", () =>
        request
          .post(`${base}/echo`)
          .send({ foo: "baz" })
          .then(res => {
            const obj = res.toJSON();
            assert.equal("object", typeof obj.header);
            assert.equal("object", typeof obj.req);
            assert.equal(200, obj.status);
            assert.equal('{"foo":"baz"}', obj.text);
          }));
    });
  
    describe("res.links", () => {
      it("should default to an empty object", () =>
        request.get(`${base}/login`).then(res => {
          res.links.should.eql({});
        }));
  
      it("should parse the Link header field", done => {
        request.get(`${base}/links`).end((err, res) => {
          res.links.next.should.equal(
            "https://api.github.com/repos/visionmedia/mocha/issues?page=2"
          );
          done();
        });
      });
    });
  
    describe("req.unset(field)", () => {
      it("should remove the header field", done => {
        request
          .post(`${base}/echo`)
          .unset("User-Agent")
          .end((err, res) => {
            assert.equal(void 0, res.header["user-agent"]);
            done();
          });
      });
    });
  
    describe("case-insensitive", () => {
      it("should set/get header fields case-insensitively", () => {
        const r = request.post(`${base}/echo`);
        r.set("MiXeD", "helloes");
        assert.strictEqual(r.get("mixed"), "helloes");
      });
  
      it("should unset header fields case-insensitively", () => {
        const r = request.post(`${base}/echo`);
        r.set("MiXeD", "helloes");
        r.unset("MIXED");
        assert.strictEqual(r.get("mixed"), undefined);
      });
    });
  
    describe("req.write(str)", () => {
      it("should write the given data", done => {
        const req = request.post(`${base}/echo`);
        req.set("Content-Type", "application/json");
        assert.equal("boolean", typeof req.write('{"name"'));
        assert.equal("boolean", typeof req.write(':"tobi"}'));
        req.end((err, res) => {
          res.text.should.equal('{"name":"tobi"}');
          done();
        });
      });
    });
  
    describe("req.pipe(stream)", () => {
      it("should pipe the response to the given stream", done => {
        const stream = new EventEmitter();
  
        stream.buf = "";
        stream.writable = true;
  
        stream.write = function(chunk) {
          this.buf += chunk;
        };
  
        stream.end = function() {
          this.buf.should.equal('{"name":"tobi"}');
          done();
        };
  
        request
          .post(`${base}/echo`)
          .send('{"name":"tobi"}')
          .pipe(stream);
      });
    });
  
    describe(".buffer()", () => {
      it("should enable buffering", done => {
        request
          .get(`${base}/custom`)
          .buffer()
          .end((err, res) => {
            assert.equal(null, err);
            assert.equal("custom stuff", res.text);
            assert(res.buffered);
            done();
          });
      });
    });
  
    describe(".buffer(false)", () => {
      it("should disable buffering", done => {
        request
          .post(`${base}/echo`)
          .type("application/x-dog")
          .send("hello this is dog")
          .buffer(false)
          .end((err, res) => {
            assert.equal(null, err);
            assert.equal(null, res.text);
            res.body.should.eql({});
            let buf = "";
            res.setEncoding("utf8");
            res.on("data", chunk => {
              buf += chunk;
            });
            res.on("end", () => {
              buf.should.equal("hello this is dog");
              done();
            });
          });
      });
    });
  
    describe(".withCredentials()", () => {
      it('should not throw an error when using the client-side "withCredentials" method', done => {
        request
          .get(`${base}/custom`)
          .withCredentials()
          .end((err, res) => {
            assert.equal(null, err);
            done();
          });
      });
    });
  
    describe(".agent()", () => {
      it("should return the defaut agent", done => {
        const req = request.post(`${base}/echo`);
        req.agent().should.equal(false);
        done();
      });
    });
  
    describe(".agent(undefined)", () => {
      it("should set an agent to undefined and ensure it is chainable", done => {
        const req = request.get(`${base}/echo`);
        const ret = req.agent(undefined);
        ret.should.equal(req);
        assert.strictEqual(req.agent(), undefined);
        done();
      });
    });
  
    describe(".agent(new http.Agent())", () => {
      it("should set passed agent", done => {
        const http = require("http");
        const req = request.get(`${base}/echo`);
        const agent = new http.Agent();
        const ret = req.agent(agent);
        ret.should.equal(req);
        req.agent().should.equal(agent);
        done();
      });
    });
  
    describe("with a content type other than application/json or text/*", () => {
      it("should disable buffering", done => {
        request
          .post(`${base}/echo`)
          .type("application/x-dog")
          .send("hello this is dog")
          .end((err, res) => {
            assert.equal(null, err);
            assert.equal(null, res.text);
            res.body.should.eql({});
            let buf = "";
            res.setEncoding("utf8");
            res.buffered.should.be.false;
            res.on("data", chunk => {
              buf += chunk;
            });
            res.on("end", () => {
              buf.should.equal("hello this is dog");
              done();
            });
          });
      });
    });
  
    describe("content-length", () => {
      it("should be set to the byte length of a non-buffer object", done => {
        const decoder = new StringDecoder("utf8");
        let img = fs.readFileSync(`${__dirname}/fixtures/test.png`);
        img = decoder.write(img);
        request
          .post(`${base}/echo`)
          .type("application/x-image")
          .send(img)
          .buffer(false)
          .end((err, res) => {
            assert.equal(null, err);
            assert(!res.buffered);
            assert.equal(res.header["content-length"], Buffer.byteLength(img));
            done();
          });
      });
  
      it("should be set to the length of a buffer object", done => {
        const img = fs.readFileSync(`${__dirname}/fixtures/test.png`);
        request
          .post(`${base}/echo`)
          .type("application/x-image")
          .send(img)
          .buffer(true)
          .end((err, res) => {
            assert.equal(null, err);
            assert(res.buffered);
            assert.equal(res.header["content-length"], img.length);
            done();
          });
      });
    });
  
    it("should send body with .get().send()", next => {
      request
        .get(`${base}/echo`)
        .set("Content-Type", "text/plain")
        .send("wahoo")
        .end((err, res) => {
          try {
            assert.equal("wahoo", res.text);
            next();
          } catch (e) {
            next(e);
          }
        });
    });
  });
  