chaijs / chai-http

HTTP Response assertions for the Chai Assertion Library.
http://chaijs.com/plugins/chai-http
634 stars 113 forks source link

Cookies are not being properly set in requests #260

Closed notgull closed 5 years ago

notgull commented 5 years ago

My code that is being tested. This is express.js code.

  // process a login request
  app.post("/process-login", async function(req: express.Request, res: express.Response) {
      // user authentication happens here

      // add user to session table
      const id = sessionTable.addSession(user, false);
      res.cookie("sessionId", id, { maxAge: 8640000 * 8 });
      res.redirect("/");
  });

Here is a test that I am using:

getServer().then((serv) => {
  server = serv;
  done();
});

// later...
chai.request(server).post("/process-login").send(userData).end((err, res) => {
  expect(err).to.be.null;
  expect(res).to.redirect;
  expect(res).to.have.cookie("sessionId");
  done();
});

The third assertion (expect res to have cookie) fails, even though the cookie is set here.

austince commented 5 years ago

Hi @not-a-seagull, I think your problems should be solved by using the Agent. Please see: https://github.com/chaijs/chai-http/issues/98#issuecomment-223531629

Will reopen if this is not the case.

notgull commented 5 years ago

I tried using agents but I'm still having issues.

        const agent = chai.request.agent(server);
        agent.post("/process-login").send(userData).end((err, res) => {
          expect(err).to.be.null;
          expect(res).to.redirect;
          expect(res).to.have.cookie("sessionId");
          done();
        });

This results in:

Uncaught AssertionError: expected cookie 'sessionId' to exist

I should note that, when I use my web browser to access the server, the cookie is successfully set and used.

austince commented 5 years ago

Can you create a small reproducable code sample / repository? It will make it much easier for us to help

notgull commented 5 years ago

https://github.com/not-a-seagull/chai-http/tree/master/test

I forked and made a new test (cookie-w-express.js). It fails and is unable to access the cookie.

austince commented 5 years ago

I believe the issue is with your redirect - when the request is redirected after setting the cookie in /set-cookie, it is not forwarded along in the next response.

I've modified the test in your branch to show this, and show that you can assert the first cookie on the agent if you would like.

const cookieParser = require("cookie-parser");
const express = require("express");

// setting up an app to test with
var app = express();
app.use(cookieParser());

app.post("/set-cookie", function (req, res) {
  res.cookie("myCookie", "test_value", { maxAge: 8640000 });
  res.redirect("/");
});

app.get("/", function (req, res) {
  const text = `This is a test\nCookie is ${req.cookies.myCookie}`;
  res.cookie('myCookie2', req.cookies.myCookie);
  res.type("text/plain");
  res.send(text);
});

describe("Testing express w/ cookies and chai", function () {
  it("Run request", async () => {
    const agent = chai.request.agent(app);
    const res = await agent.post("/set-cookie").send({});
    expect(res).to.redirect;
    expect(res).to.have.cookie('myCookie2')
    expect(agent).to.have.cookie('myCookie');
  });
});