Giter Club home page Giter Club logo

chai-http's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chai-http's Issues

How to properly test for HTTP failure responses

I am trying to test a condition wherein the API returns 500 (internal server error). I am doing the expect assertion in the catch block like this:

  it ('Creation of user without email address, should fail', function(done) {
      chai.request(app).post('/users')
         .send(sampleUsers.userWithoutEmail)
         .then(function(res) {
            return done(new Error('should have failed with 400'));
      }).catch(function(e){
        console.log("error:", e.status);
        expect(e).to.have.status(400);  // shd fail with 'bad request'
        return done();
      });
    });

The problem with this is, it gets stuck at the expect line and doesn't come out until test framework times out. I can see that the console.log line gets printed correctly without consuming time, but expect invocation doesn't finish.

What am I doing wrong here?
Is this the correct way to test errors?

can't install chai-http

Hi, I'm trying to install chai-http in an ubuntu 16.04 machine, but once I execute
npm install chai-http --save-dev

I get the following error:

npm ERR! Linux 4.4.0-38-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install" "chai-http" "--save-dev"
npm ERR! node v4.5.0
npm ERR! npm  v2.15.9
npm ERR! file /home/ubuntu/.npm/methods/1.1.2/package/package.json
npm ERR! code EJSONPARSE

npm ERR! Failed to parse json
npm ERR! Unexpected token 'T' at 1:1
npm ERR! TJ Holowaychuk","email":"[email protected]","url":"http://tjholowaychuk.com"},
npm ERR! ^
npm ERR! File: /home/ubuntu/.npm/methods/1.1.2/package/package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
npm ERR!
npm ERR! This is not a bug in npm.
npm ERR! Tell the package author to fix their package.json file. JSON.parse

npm ERR! Please include the following file with any support request:
npm ERR!     /home/ubuntu/brewerly/api/npm-debug.log

Do I need some special package in order to install chai-http?
Thanks in advanced

redirectTo does not work for me

I use this as a route (express 4)

router.get('/', function(req, res) {
  res.redirect('/status');
});

When I expect(res).to.redirectTo('/status') the status code is 200 and not a 301, 302, or 303.
Express is actually working and I do get a redirect. Can it be that chai-http is following redirects and thus returns the final 200?

My old code works and looks like this:

expect(res.redirects).to.have.length(1);
expect(res.redirects[0]).to.contain('/status');

Related PR: #9
And maybe @hurrymaplelad can take a look?

Documentation on Promises is not clear enough OR a better Error message is required

It may seem obvious to others but I spent a while trying to figure out promises because they are not compatible with done

my original test looked like this:

it('it should be able to Create a new User', (done) => {
        chai.request(server)
            .post('/api/users')
            .send({email:'[email protected]', password:'abc123'})
            .then((err, res) => {
                console.log(res);
                res.should.have.status(200);
                res.text.should.be.eq('You must send the username and the password');
              done();
            })
            .catch(done);
      });

but I kept getting the error

Error: Bad Request
      at Test.Request.callback (node_modules/superagent/lib/node/index.js:626:17)
      at IncomingMessage.<anonymous> (node_modules/superagent/lib/node/index.js:795:18)
      at endReadableNT (_stream_readable.js:974:12)
      at _combinedTickCallback (internal/process/next_tick.js:74:11)
      at process._tickCallback (internal/process/next_tick.js:98:9)

When I removed the done, the test passed

it('it should be able to Create a new User', () => {
        chai.request(server)
            .post('/api/users')
            .send({email:'[email protected]', password:'abc123'})
            .then((err, res) => {
                console.log(res);
                res.should.have.status(200);
                res.text.should.be.eq('User Created');
            })
            .catch((err) => {
                throw err
          });
      });

Status codes different than 2xx shouldn't be trated as Promise rejections

Since Chai-Http is a testing utility, it shouldn't make the assumption that not 2xx responses are errors, because maybe (and probably) we're expecting status codes in the 4xx range (or in other ranges).

At this time, I have place a catch before the "then" call because the "then" method isn't triggered, and the last "catch" is triggered, making fail the test.

Example:

it('GET /agents/status with invalid appId returns 401 status and "Invalid app ID" message', function () {
        return serverPromise
            .then(function (server) {
                return chai.request(server).get('/agents/status?appId=');
            })
            .catch(function (err) {
                // not 2xx responses are treated as errors :( , it sucks.
                return err.hasOwnProperty('response') ? err.response : err;
            })
            .then(function (res) {
                res.should.have.status(401);
                res.body.should.have.property('error');
                res.body.error.should.have.property('message');
                res.body.error.message.should.equal('Invalid app ID');
            })
            .catch(registerError);
    });

without the first catch, which converts the error again to be a response, the last one is triggered... but this one is placed there to catch real errors, not the expected ones.

Unable to test response status codes with 3.0.0 version

This fix renamed property in http response object from "statusCode" to "status": 1c5194f.

It broke my tests which run with restify client and node version 4.4.0. And even the documentation for latest node version (6.x) says that the name of the property in response object should be "statusCode" (https://nodejs.org/api/http.html#http_response_statuscode). I don't understand to that fix. How can we just use a different property name for getting status code from response object and expect that everything will work as before?

POST

This is a bit of a wall of text, but please bear with me:

Here is a POST attempt formatted using an entirely different toolchain for testing:

Time: Mon, 27 Jun 16 13:40:54 -0700
Source ip: 204.191.154.66

Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING = 
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 19216
REMOTE_ADDR = 204.191.154.66
HTTP_CONNECTION = close
CONTENT_LENGTH = 64
HTTP_HOST = posttestserver.com
HTTP_TOKEN = text/plain
CONTENT_TYPE = application/x-www-form-urlencoded
UNIQUE_ID = V3GPVkBaMGUAAB1Uf04AAAAc
REQUEST_TIME_FLOAT = 1467060054.9575
REQUEST_TIME = 1467060054

Post Params:
key: 'grant_type' value: 'password'
key: 'username' value: '[email protected]'
key: 'password' value: 'password'
Empty post body.

Upload contains PUT data:
grant_type=password&username=hello%40world.com&password=password

And here is a POST attempt using Chai and Chai-HTTP:

Time: Mon, 27 Jun 16 13:47:29 -0700
Source ip: 204.191.154.66

Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING = 
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 19275
REMOTE_ADDR = 204.191.154.66
HTTP_CONNECTION = close
CONTENT_LENGTH = 410
CONTENT_TYPE = multipart/form-data; boundary=--------------------------112369991749419303041318
HTTP_TOKEN = text/plain
HTTP_USER_AGENT = node-superagent/2.0.0
HTTP_ACCEPT_ENCODING = gzip, deflate
HTTP_HOST = posttestserver.com
UNIQUE_ID = V3GQ4UBaMGUAACUNdbQAAAAN
REQUEST_TIME_FLOAT = 1467060449.4647
REQUEST_TIME = 1467060449

Post Params:
key: 'grant_type' value: 'password'
key: 'username' value: '[email protected]'
key: 'password' value: 'password'
Empty post body.

== Multipart File upload. ==
Received 0 file(s)

Notice the difference in CONTENT_TYPE in particular (I think this is the source of my problem) where my previous tools would submit the POST using the 'application/x-www-form-urlencoded' format, Chai-HTTP seems to be using this 'multipart/form-data; boundary=--------------------------112369991749419303041318' format (which I understand about as well as I can resolve this issue on my own).

Am I somehow misusing Chai-HTTP's POST cababilities? Or does Chai-HTTP not allow for 'application/x-www-form-urlencoded' POST requests? I do not seem to be able to resolve this and it is the final hurdle for me to jump to make the transition to using a Mocha/Chai toolchain for my testing.

Can't use promise libraries

According to the documentation I should be able to use the following code to use a custom promise library for older node environments:

var chai = require('chai');
chai.use(require('chai-http'));

// Add promise support if this does not exist natively.
if (!global.Promise) {
  var q = require('q');
  chai.request.addPromises(q.Promise);
} 

But when I try it I get the following error: "Object has no method 'addPromises'".

release new version to npm?

Latest npm published version is 1.0.0, since then you've committed a lot of changes - maybe it's time to release those to npm?

Pass error message?

If I use Supertest it passes the error message in this scenario however Chai-HTTP does not; yet both are using Superagent 1.2. Any ideas?

  describe('GET /error/500', function () {
    it('should return a 500 error', function (done) {
      chai.request(app)
        .get('/error/500')
        .end(function (err, res) {
          expect(err).to.not.be.ok;
          // expect(err.message).to.equal('Internal Server Error');  <- Doesn't Work with Chai-HTTP
          expect(res).to.have.status(500);
          expect(res.type).to.equal('text/html');
          expect(res.text).to.contain('<span class="red">Testing 1, 2, 3!</span>');
          done();
        });
    });
  });

Add easy testing for XML and Javascript content-types, and UTF-8 charset

I love the existing support for JSON, HTML and text:

expect(req).to.be.html;

I propose extending this:

expect(req).to.be.xml;
expect(req).to.be.javascript;

The proposed solution makes some assumptions:

  1. The expected content-type for XML is application/xml
  2. The expected content-type for Javascript is text/javascript - I suggest this is still the norm on servers despite application/javascript being more correct.

I'm also interested in testing the character encoding:

expect(res).to.be.utf8;   // Check for "charset=UTF-8" - case sensitive :(

My use-case is @nfreear/ou-media-player-test ../test/ou-podcast-test.js

Thoughts?

It's not working with response - Promises.

I have tried with q and es6-promise...in get method getting UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: res.send is not a function and i am able to console the response in express server just before res.json line.

Multiple parameter

Hi there,

I've been trying to send a request with a param list:

chai.request("myUrl").get("/v1/skus?id=123&id=456")...

this request got encoded and the server receives id[0]=123&id[1]=456 which is totally different than the expected format by the server.

Otherwise - using .query({id: "123", id: "456"}) or
.query({id: "123"})
.query({id: "456"})
override the initial value so only one param is getting sent.

Is there any reason the query param list get encoded ?
I might be doing it wrong - in this case could you please advice how to pass multiple param values ?

Cheers

Login using Passport not working occasionally

We use mocha, chai and chaiHttp to spin up a express server and make post and get calls.

When running the server and logging in inside of our test (on codeship) using ChaiHttp, We get req.user = undefined occasionally.

For the most of the logins we get successful deSerialization and all show that the users details are serialized into the session after logging in.

   "express": "4.10.7",
  "express-session": "^1.5",
   "passport": "^0.3.2",
    "passport-local": "^1.0.0",
    "passport-local-mongoose": "^4.0.0"

Express App is configured like so:

app.use(express.static(path.join(__dirname, '../client')));

    app.use(bodyParser ());

    app.use(bodyParser.urlencoded ({
        extended:true
    }));

    app.use(bodyParser.json ());


    app.use(morgan('dev'));


    //app.use(cookieParser('abs'));

    var mongoStore = new MongoStore ({
        mongooseConnection: mongoose.connection,
        db: db.connection
    });

    var sessionOpts = {
      saveUninitialized: true, // saved new sessions
      resave: false, // do not automatically write to the session store
      store: mongoStore,
      secret: 'abs',
      cookie : {secure:false, maxAge: 2419200000 } // configure when sessions expires
    }

    app.use(session(sessionOpts));

    app.use(flash());
    app.use(passport.initialize());
    app.use(passport.session());

Could this be an issue with express-session or with ChaiHttp? It seems to work properly when calling login/logout on the server directly.
Thanks.
-Deepak

No promise library set

Hello,

Just upgraded to the new chai-http and use the promises. I run my tests on Travis on node 0.10 and 0.11. Apparently 0.10 does not have native promises and i get this error Tried to use chai-http with promises, but no Promise library set.

Then i read the docs and now i understand this line:

If Promise is available, request() becomes a Promise capable library - and chaining of thens becomes possible:

How should i use this with node 0.10? Should i include https://github.com/kriskowal/q and set that on global.Promise?

Where is the lib-cov/http

Hi,

I was doing automatization tests with karma, phantom on gitlab and my tests didn't pass.
So I've received the message saying:

Module not found: Error: Cannot resolve 'file' or 'directory' ./lib-cov/http in D:\DEV\GIT\Interno\HoursBankAPI\node_modules\chai-http
@ ./~/chai-http/index.js 1:72-97

so, firstly I'm sorry, I'm new with chai-http but I I haven't found anything in the documentation about lib-cov, could you explain me what is it and how is it works?

README incomplete

The README cuts off in the middle of a sentence and also doesn't seem to describe the plugin accurately.

disable following redirects

I am testing a redirect with

return this.client.get('/')
    .then(res => {
        expect(res).to.redirect;
    });

Everything works however when I inspect res I see that it followed all the redirects (3 in all).
This is timing out the test sometimes. We need an option to disable following redirects.

Testing file download, res.files returns empty object

Originally asked here: http://stackoverflow.com/questions/40517088/using-mocha-chai-to-ensure-rest-api-serves-up-a-file/

I am wanting to download the response file in a test, but the req.files value is an empty object. Displays as {} when displayed with console. The superagent docs suggest that res.files should provide a file.

Note the endpoint works when testing with 'wget'.

The code I am using for my test

it('Should get a file', (done) => {
    chai.request(url)
        .get('/api/exercise/1?token=' + token)
        .end(function(err, res) {
            if (err) { done(err); }
            res.should.have.status(200);

            // Check the headers for type and size
            res.should.have.header('content-type');
            res.header['content-type'].should.be.equal('application/pdf');
            res.should.have.header('content-length');
            const size = fs.statSync(filepath).size.toString();
            res.header['content-length'].should.be.equal(size);

            // TODO get access to saved file and do tests on it
            //      tried 'res.files' but it returns {}                
        });
});

Is there something I am missing?

Wish: testing method check for empty bodies

In some cases, a server will return result.body as a null value, in other cases it will return an empty response. Practically, the difference often doesn't matter. It would be nice if a method checked that either of these were met:

expect(res.body).to.be.null or expect(res.body).to.be.empty

Some responses doesn't contain text

Test case: https://gist.github.com/vslinko/5244480
Execution output:

$ make
node test.js
chai-http text.txt
supertest text.js
chai-http text.js

/Users/vyacheslav/q/test/node_modules/chai/lib/chai/assertion.js:107
    throw new AssertionError({
          ^
expected undefined to match /Hooray/
make: *** [test] Error 1

Tested with original chai-http and my PR #3

Update to superagent 1.0

Hi, I wanted to know if there are any plans to update to Superagent 1.0. It has been released only few days ago, but I'm very interested in this fix: ladjs/superagent@8c3858a as I need to test if my API returns a null value or not.

cookie() doesnt assert on Agent cookies

Hi, I'm trying to use the cookie method and I'm getting the following error:

TypeError: Cannot call method 'split' of undefined at [object Object].<anonymous>
(http.js:307:48)

Here is my code:

var agent = chai.request.agent(app)

describe('POST /logout', function() {
  it('Should logout the user', function() {
    return agent.get('/api/v1/users/me')
                .then( function(res) {
                  expect(res).to.have.cookie('connect.sid')
                });
  });
});

I'm using v1.0.0

Help with cookies

I'm using the following code to test my passport js api:

var agent = chai.request.agent(app);
agent
    .post("/accounts/signin")
    .send({ username: "admin", password: Config.admin_password })
    .then((res) => {
      let user = res.body;
      (user.username === "admin").should.be.ok;
      res.should.have.cookie("connect.sid");
      console.log(res);
      return agent.get("/accounts/me")
        .then((res2) => res2.should.have.status(200));
    })
    .catch((err) => {
      throw err;
    });

Doing it manually via the command line gives me:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 170
Content-Type: application/json; charset=utf-8
Date: Sun, 18 Dec 2016 10:50:39 GMT
ETag: W/"aa-qQek/aYvw28iu282Y2x1Hw"
X-Powered-By: Express
set-cookie: connect.sid=s%3A5lQUj03Bf2DZwmMLJ7inb7PI5nzmMcTb.QXuh6xmxohZyG810dd5TrBcLFTDZrfuJ%2BsMo7oxEKYs; Domain=backend; Path=/; Expires=Sun, 18 Dec 2016 13:38:39 GMT; HttpOnly

{
    "__v": 0,
    "_id": "585669ff37c1ec29963be286",
    "password": "$2a$08$1TgBcXq66BtwqlndAxWqheRCr9J7/ilqXWhgqYv4a2.hSb9q4mmDm",
    "username": "admin"
}

The username === admin test passes but the cookie one does not... and when I comment out the cookie one, the the subsequent get request also fails (I think because of cookies not being maintained).

Can anyone tell me what I'm doing wrong?

JSON request with file upload?

Is it possible to upload json data and and attach a file at the same time?

The code I am looking at is:

it('Should upload a content file', (done) => {
    var data = {
        name: 'Test content',
        description: 'lorem ipsum'
    }
    chai.request(url)
        .post(`/api/content?token=${token}`)
        .attach('file', fs.readFileSync(filepath), filename)
        .send(data)
        .end(function(err, res) {
            console.log(res.body, res.err)
            if (err) { done(err); }
            res.should.have.status(200);
            res.should.be.json;
            //res.body.should.be.a('array');
            //res.body.length.should.be.equal(0);
            done();
        });
});

When I do this I only get the file. Commenting out the 'attach' line gets be the name and description, but then I don't have the file.

The server side is being handled by express and express-fileupload:

createContent(req, res, next) {
     var name = req.body.name;
     var description = req.body.description;

    if (!req.files || !req.files.file) {
        res.json({
            message: 'no file uploaded'
        });
        return;
    }

   winston.debug('name', name);
   winston.debug('description', description);
   winston.debug('filename', req.files.file.name);

}

reading response's data / response data event

Is there a way to read response's data? Or am I missing something?

I have a proxy server functionality that i need to test and I would like to compare two json files. I tried res.on('data' but it seams that mocha finishes run before hand.

Question: adding express-session user property to chai-http request?

Is there a way to add or manipulate properties of the req object in chai-http requests?

I want to test my API which uses express-session and authenticates any request based on the presence of the req.session.user object, as shown below:

app.use(function(req, res, next) {
  if (req.session.user) {
  console.log('Authenticated request\n');
  next();
  } else {
    console.log('Request not authenticated, request rejected\n');    
    res.status(403).json({'message': 'Request rejected'});;
  }
});

I'm writing tests for my API with chai-http as shown below:

describe('test', function(){
 it('/test', function(done){
   chai.request(server)
   .get('/test')
   .end(function(err, res){
     res.body.should.be.a('object');
   });
 });
});

Can I add the .session.user object to my chai-http requests so that they will pass the authentication?

Thanks!

header regex not working

I'm having trouble with the regex functionality of the header expectations. It seems to fail no matter what.

expect(res).to.have.header('content-type', /json/);
and even
expect(res).to.have.header('content-type', /.*/);

Uncaught AssertionError: expected header 'content-type' to have value /.*/ but got 'application/api-problem+json; charset=utf-8'

Am I missing something?

App errors are swallowed

I'm trying to test an error condition in my app. First I'm adding middleware that throws and expect this test to pass because there is no error handler in the app. However, it just hangs because the end handler and done are never called.

 it('throws', function(done) {
      var app = express();
      app.use(function(req, res, next) {
        throw new Error('Test failed request.');
      });

      chai.request(app)
        .get('/foo')
        .end(function(err, res) {
          expect(err).to.be.ok;
          done();
        });
});

Is this the right setup? Seems odd that things can just hang.

Attach file gives 400 bad request

var file_path = '../data/invalid.csv';

chai.request(config.baseUrl)
.put(url)
.set('Accept', 'application/json')
.set('Content-Type', 'customHeader')
.attach('file', fs.readFileSync(file_path))
.end(function (err, res) {
res.should.have.status(500);
done();
});

I am expecting a 500 response (not here to argue, that's a good way to do things or not, it's a requirement, that I have to test) but I am getting 400

Testing the same manually (using POSTMAN) works just fine.

Any resolution will be highly appreciated. I am kinda blocked on this one..

Unable to Authenticate with Basic authentication

The following example doesn't work and doesn't appear to be tested.

// Authenticate with Basic authentication
chai.request(app)
  .auth('user', 'pass')
  .get('/protected')

The auth method doesn't even appear to exist:

> Object.keys(chai.request(app));
[ 'get',
  'post',
  'put',
  'head',
  'delete',
  'options',
  'trace',
  'copy',
  'lock',
  'mkcol',
  'move',
  'propfind',
  'proppatch',
  'unlock',
  'report',
  'mkactivity',
  'checkout',
  'merge',
  'm-search',
  'notify',
  'subscribe',
  'unsubscribe',
  'patch',
  'del' ]

Browser support

Chai and Superagent can both be run in Node or in web browsers. It would be great if your plugin worked in browsers too. This would allow people to write universal tests that can run in Node (great for CI) and in browsers (great for real-world testing). Mocha also supports both Node and web browsers, so it's dead-simple to accomplish truly universal tests.

I don't think it would even require many changes to the code, since most of your dependencies are already universal. And some dependencies (like cookie jar) wouldn't be needed when running in a browser. You could probably just bundle your existing code via Browserify or WebPack.

How do I post with this thing?!

   chai.request(url_params)
        .post(get_params)
        .send(post_data)
        .res((response)->
          console.warn response
          res = response
          done()
      )

no luck

Can't test expected error responses because superagent throws

Consider the following Mocha test (written in ES7 async/await style which is syntactic sugar for Promises):

describe('Querying a nonexistent table', function() {
  it('causes a 404', async function() {
    const res = await chai.request(app).get('/faketable');
    res.should.have.status(404);
  });
});

If the endpoint returns a 404, the response promise gets rejected with an Error originating in superagent's response handler, and the test fails before reaching the status assertion. Other 4xx/5xx status codes similarly cannot be tested for in this way. I think this is surprising behavior that makes testing error responses much harder than it should be.

Settings headers and delete requests

It seems like there's some sort of weird thing going on with the del method paired with the setting of any headers. Example:

chai.request(app)
  .del("/any_url")
  .set('Any-Header', 'xxx')
  .res(function(res){ console.log(res); })

What's strage about this is that the test passes fully, hitting the right method with the right headers, but it does not hit the console.log and fails with the following error message:

TypeError: Object #<Test> has no method 'set'

If you want me to take a look into this and can push me in the right direction, would be happy to take a stab at it! It's really messing up my test suite ๐Ÿ˜ข

EDIT: Same thing happens with get

Calling .then() multiple times on the same promise has weird side effects

I just spent an hour tracking down this problem... Calling .then() on a promise should cause a new promise to be returned. But chai-http modifies the original promise. This causes all sorts of problems when I actually try to use chai-http with a test runner which attaches its own handlers to a promises.

From chai-http/lib/request.js:

Test.prototype.then = function (onResolve, onReject) {
  if (!Test.Promise) {
    throw new Error('Tried to use chai-http with promises, but no Promise library set');
  }
  if (!this._promise) {
    var self = this;
    this._promise = new Test.Promise(function (resolve, reject) {
      self.end(function (err, res) {
        console.log('resolve on Request.end', !! err, !! res, onResolve, onReject)
        if (err) {
          reject(err);
        } else {
          resolve(res);
        }
      });
    });
  }
  this._promise = this._promise.then(onResolve, onReject);
  return this;
};

Sorry I don't have a unit test to demonstrate this problem, I just wanted to jot down this note quickly while it's fresh in my head, hopefully this will save someone else an hour of debugging...

does the request store the cookie?

Hi, I'm just wondering if the cookie is stored in some way if the header is set-cookie.

I'm writing some tests and after the login I want to do the rest on websockets where I would like to get the cookie on the upgradeReq, but I can't seem to find it.

'npm run posttest' fails when COVERALLS_REPO_TOKEN is unset

NP-1B45EDC80F2C:chai-http farmisen$ unset COVERALLS_REPO_TOKEN
NP-1B45EDC80F2C:chai-http farmisen$ npm run posttest

> [email protected] posttest /Users/farmisen/dev/occamz/chai-http
> if [ -z $COVERALLS_REPO_TOKEN ]; then cat coverage/lcov.info | coveralls; fi


/Users/farmisen/dev/occamz/chai-http/node_modules/coveralls/bin/coveralls.js:18
        throw err;
        ^
Bad response: 422 {"message":"Couldn't find a repository matching this job.","error":true}

seems like the bash test for COVERALLS_REPO_TOKEN presence is backward.

expect cookie fails with a proper set-cookie header

In a test I'm making some expectations on the response. One of the expectations verifies the existence of a cookie in the form:

expect(res).to.have.cookie('cookieName');

The expectation fails while the response object contains the set-cookie header with the cookie.

Using v1.0.0

HTTP POST with form fields not working

see http://stackoverflow.com/a/36938187/6113110

It seems that simply the chai-http documentation is wrong. It sais:

// Send some Form Data
chai.request(app)
 .post('/user/me')
 .field('_method', 'put')
 .field('password', '123')
 .field('confirmPassword', '123')

Which does NOT work. This worked for me:

chai.request(app)
  .post('/create')
  .send({ 
      title: 'Dummy title',
      description: 'Dummy description'
  })
  .end(function(err, res) { ... }

redirects(0) causes then() does not work

if using redirects(5), .then() works well for a POST. But if using redirect(0), which I only want to get the first http req's response, .then() never run. The workaround is using .end(err, res) instead.

Can you help to fix this?

My original code:

agent.post('/login')
    .field("pwd", pwd)
    .field("user", uid)
    .then( function( res ) { 
        debug(res, 'POST login');
        expect(res).to.have.status(200);

    agent.get( res.body.location )   // get the location field from the json response body
        .redirects(0)
        .then( function( res ) { 
            console.log('==================');    // this is never printed out
        });
 });

chai http post not working

http post to both internal and external service is failing .. with mocha, chai, chai-http

NOTE : successfully able to get the response with curl.
curl -H "Content-Type: application/json" -X POST -d '{"y":"heartbeat"}' http://localhost:3500/hb

http server code :

var server = http.createServer(function (req, res) {

 if(req.method=="POST" && req.url=="/hb"){
            var body = '';
            req.on('data', function (data) {
                body += data;
                console.log("Partial body: " + body);
            });
            req.on('end', function () {
                console.log("Body: " + body);

                var reqBody
                try {
                    reqBody= JSON.parse(body);
                } catch (e) {
                    console.log("Parse Exception : " + e);
                    reqBody=" Req Parse Exception ";
                }

                var r= {"a":1,"req":reqBody};
                res.setHeader('Content-type', 'application/json; charset=utf-8');
                res.statusCode = 200 ;
                res.end(JSON.stringify(r));
            });
        }

test code

var chai = require('chai');
var chaiHttp = require('chai-http');
var app = require('../lib/server');
var should = chai.should();
var expect = chai.expect();
chai.use(chaiHttp);


describe(' Server :', function() {
    /*describe('test heartbeat :', function () {
        it('check test:', function () {
            assert.equal(-1, [1,2,3].indexOf(5));
            assert.equal(-1, [1,2,3].indexOf(0));
        });
    });*/
    describe('Logic : ', function () {
        it('/hb  then: ', function (done) {
            chai.request('http://localhost:3500/')
                .post('hb')
                .send({"y":"heartbeat"})
                .then(function (res) {
                    //res.should.have.status(200);
                    expect(res).to.have.status(200);
                 //  expect(err).to.be.null;
                //    expect(res).to.have.status(200);
                //    console.log("CAlling DOne ........... ");
                    //done();
                }, function (err) {
                    console.log(err);
                    throw err;
                })/*.catch(function (err) {
                    throw err;
                    console.log("HB THEN ERR :");
                    console.log(err);
                });*/

        });
        it('/hb  end: ', function (done) {
            chai.request('http://localhost:3500/')
                .post('hb')
                .send({"y":"heartbeat"})
                .end(function (err, res) {
                    expect(res).to.have.status(200);
                    //res.should.have.status(200);
                    /*if(err){
                        console.log(err);
                    }else {
                        res.should.have.status(200);
                    }*/
                    done();
                }).catch(function (err) {
                    throw err;
                    console.log("HB END ERR :");
                    console.log(err);
                });
        });

        it('/cot GET : ', function (done) {
            chai.request("http://localhost:3500")
                .get('/cot')
                .end(function (err, res) {
                    res.should.have.status(200);
                    done();
                });
        });
    });

    describe('Web Requests : ', function () {
        it('/hb  : ', function (done) {
            chai.request(app)
                .post('POST /hb')
                .send({"n":"heartbeat"})
                .end(function (err, res) {
                    res.should.have.status(200);
                    //res.should.have.status(200);
                    done();
                });
               /* .then(function (res) {
                    expect(err).to.be.null;
                    expect(res).to.have.status(200);
                    console.log("CAlling DOne ........... ");
                    done();
                }, function (err) {
                    console.log(err);
                    throw err;
                });*/

            /*chai.request("http://localhost:3500")
             .post('/hb')
             .send({"n":"heartbeat"})
             .end(function (err, res) {
             expect(err).to.be.null;
             expect(res).to.have.status(200);
             //res.should.have.status(200);
             //done();
             });*/
        });
        it('/cot GET : ', function (done) {
            chai.request(app).get('/cot').then(function (res) {
                    expect(err).to.be.null;
                    expect(res).to.have.status(200);
                    console.log("CAlling DOne ........... ");
                   // done();
                }, function (err) {
                    console.log(err);
                    throw err;
                });
        });
    });

});

mocha output

 Logic : 
      1) /hb  then: 
double callback!
double callback!
double callback!
      2) /hb  end: 
      โœ“ /cot GET : 
    Web Requests : 
      3) /hb  : 
      4) /cot GET : 


  1 passing (2s)
  4 failing

  1)  Server : Logic :  /hb  then: :
     Uncaught Error: Max retries reached, transport in silent mode, OFFLINE
      at Socket.<anonymous> (node_modules/joplog/node_modules/winston-logstash/lib/winston-logstash.js:197:26)
      at TCP.close (net.js:485:12)

  2)  Server : Logic :  /hb  end: :
     Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.


  3)  Server : Web Requests :  /hb  : :
     TypeError: undefined is not a function
      at serverAddress (/usr/lib/node_modules/chai-http/lib/request.js:293:18)
      at new Test (/usr/lib/node_modules/chai-http/lib/request.js:214:53)
      at Object.obj.(anonymous function) [as post] (/usr/lib/node_modules/chai-http/lib/request.js:183:14)
      at Context.<anonymous> (test/test.js:94:18)

  4)  Server : Web Requests :  /cot GET : :
     TypeError: undefined is not a function
      at serverAddress (/usr/lib/node_modules/chai-http/lib/request.js:293:18)
      at new Test (/usr/lib/node_modules/chai-http/lib/request.js:214:53)
      at Object.obj.(anonymous function) [as get] (/usr/lib/node_modules/chai-http/lib/request.js:183:14)
      at Context.<anonymous> (test/test.js:122:31)

Add `done` to documentation

TL;DR:

Documentation doesn't mention the required use of done:

// Fails, as expected.
it('should fail', function(done) {   // <= done parameter not mentioned in docs
  chai.request('https://github.com')
  .get('/')
  .end(function(err, res) {
    res.should.have.status(123) ;    // <= fails, as expected
    done() ;                         // <= done call not mentioned in docs
  }) ;
}) ;

// Silently passes!
it('silently passes', function() {   // <= missing done parameter
  chai.request('https://github.com')
  .get('/')
  .end(function(err, res) {
    res.should.have.status(123) ;    // <= passes silently (never fails)
                                     // <= missing call to done()
  }) ;
}) ;

Details

Nowhere in the documentation or examples do you mention the use of done when writing tests. In retrospect, it is obvious that it should be called in asynchronous test, but as a new user, not knowing this (and not seeing it in the documentation) was a huge pain. Tests using chai-http without done pass silently, which was difficult to debug not knowing where to look. The documentation should mention done at least once, and why it is required.

Issues sending certain mimeTypes with formdata

Maybe a superagent issue, but I have a test that attaches a csv/xls/xlsx (all in separate tests) to send to a busboy route. Busboy interprets the csv as a file, but the xls/xlsx as a field (form field). I have also seen the same behavior with png files, but works with jpg. Sending from the browser works fine.

// Works and interprets as file so I can pipe the data into a writeStream
chai.request(app)
  .post('/my-busboy-endpoint')
  .attach(fs.readFileSync('mycsvfile.csv'), 'mycsvfile.csv');

// Does not work and busboy interprets as a field
chai.request(app)
  .post('/my-busboy-endpoint')
  .attach(fs.readFileSync('myexcelfile.xls'), 'myexcelfile.xls');

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.