Instantly share code, notes, and snippets.

Embed
What would you like to do?
Login session test with mocha
var request = require('supertest'),
should = require('should'),
app = require('../server');
var Cookies;
describe('Functional Test <Sessions>:', function () {
it('should create user session for valid user', function (done) {
request(app)
.post('/v1/sessions')
.set('Accept','application/json')
.send({"email": "user_test@example.com", "password": "123"})
.expect('Content-Type', /json/)
.expect(200)
.end(function (err, res) {
res.body.id.should.equal('1');
res.body.short_name.should.equal('Test user');
res.body.email.should.equal('user_test@example.com');
// Save the cookie to use it later to retrieve the session
Cookies = res.headers['set-cookie'].pop().split(';')[0];
done();
});
});
it('should get user session for current user', function (done) {
var req = request(app).get('/v1/sessions');
// Set cookie to get saved user session
req.cookies = Cookies;
req.set('Accept','application/json')
.expect('Content-Type', /json/)
.expect(200)
.end(function (err, res) {
res.body.id.should.equal('1');
res.body.short_name.should.equal('Test user');
res.body.email.should.equal('user_test@example.com');
done();
});
});
});
@rtoal

This comment has been minimized.

rtoal commented Dec 4, 2013

Very helpful! Thanks.

@sjevs

This comment has been minimized.

sjevs commented Jan 1, 2014

+1

@mehdimehdi

This comment has been minimized.

mehdimehdi commented Jan 5, 2014

If you want all the cookies that have been set, you will need something like this:

  Cookies = res.headers['set-cookie']
            .map(function(r){
              return r.replace("; path=/; httponly","") 
            }).join("; ");
@grawk

This comment has been minimized.

grawk commented Aug 22, 2014

@mehdimehdi thanks for that snippet. You saved me a lot of trouble!!

@uliporeggia

This comment has been minimized.

uliporeggia commented Oct 9, 2014

+1
and +1 for @mehdimehdi
Thanks

@roymath

This comment has been minimized.

roymath commented Feb 16, 2015

@mehdimehdi - it's safer to do a case-insensitve replacement.

var re = new RegExp('; path=/; httponly', 'gi');
Cookies = res.headers['set-cookie']
    .map(function(r){
        return r.replace(re, '');
    }).join("; ");
@pagewang0

This comment has been minimized.

pagewang0 commented Mar 30, 2015

@mehdimehdi
Thanks +1

@vuonghichi

This comment has been minimized.

vuonghichi commented Nov 7, 2015

dk

@stenio123

This comment has been minimized.

stenio123 commented Nov 13, 2015

can you share the content of ../server.js ?

I am trying a similar setup, with a traditional Express server that starts listening for connections as my server.js. However when I run a similar test I get the message

Object # has no method 'address'. This error doesnt happen if I just use a URL instead of the server.js. Just wondering if you are exporting something in your server.js or made any other specific adjustment to have it run within the test. Thanks!

@stenio123

This comment has been minimized.

stenio123 commented Nov 13, 2015

Found it!
var app = express();

module.exports = app;

Tx!

@JohnTian

This comment has been minimized.

JohnTian commented Mar 15, 2016

Great job! Thx!

@LopatkinEvgeniy

This comment has been minimized.

LopatkinEvgeniy commented Apr 8, 2016

Thanks, its very usefull!

@hillkim7

This comment has been minimized.

hillkim7 commented Apr 8, 2016

Very good!!
req.cookies = Cookies;
can be changed.
req.set('Cookie', Cookies);

@frisk

This comment has been minimized.

frisk commented May 18, 2016

This is awesome! Thank you for sharing!

@rafaelgou

This comment has been minimized.

rafaelgou commented May 19, 2016

My suggest (after researching):

(this is a login form, not an API, or when API is on the same domain of APP)

var supertest = require('supertest');
var app       = require('../path_to_my/app')
var agent     = supertest.agent(app);

describe('Login', function () {
  it('should login form', function(done) {
    agent
      .post('/login')
      .type('form')
      .send({ email: 'email' })
      .send({ password: 'password' })
      .expect(302)
      .expect('Location', '/')
      .expect('set-cookie', /connect.sid/)
      .end(function(err, res) {
        if (err) return done(err);
        agent.saveCookies(res);
        return done();
      });
  };
});
@SickAssApp

This comment has been minimized.

SickAssApp commented Nov 4, 2016

@rafaelgou
agent.saveCookies(res);
This won't work in later version of supertest

@Santiago-vdk

This comment has been minimized.

Santiago-vdk commented Dec 3, 2016

This still works great!

@niteshpsit1

This comment has been minimized.

niteshpsit1 commented Jan 4, 2017

Thanks it safe lot of time

@jontelm

This comment has been minimized.

jontelm commented May 11, 2017

Thanks

@abhirathmahipal

This comment has been minimized.

abhirathmahipal commented May 22, 2017

Just what I was looking for. Kudos!

@vishalbiradar

This comment has been minimized.

vishalbiradar commented Jan 22, 2018

Please help me on the below issue too.

mochajs/mocha#3216

Thanks in advance.

@ajay-justclean

This comment has been minimized.

ajay-justclean commented Mar 14, 2018

thanks

@ajay25487

This comment has been minimized.

ajay25487 commented Mar 14, 2018

+1

@SalathielGenese

This comment has been minimized.

SalathielGenese commented May 7, 2018

How can I thank you enough?

Tanks of Thanks !!!

@pc-vkaza

This comment has been minimized.

pc-vkaza commented May 16, 2018

Thanks. Works great for Cookies persistence.

@rafaelcs

This comment has been minimized.

rafaelcs commented Aug 10, 2018

It's not working for me. Actually, the login is working but when I use the session in the second block it() the application still require the login

const assert = require('chai').assert,
	  expect = require('chai').expect,
          request = require('supertest'),
	  envData = require('../../data/envData'),
	  tokenAuthData = require('../../data/tokenAuthData');
	  
var Cookies;

describe ('POST /Authenticate', function() {

	const authenticate = '/TokenAuth/Authenticate';

	it ('Should create a session', function(done) {
		request(envData.upstreamUrl)
		.post(authenticate)
		.set('Content-type', 'application/json')
		.send(tokenAuthData.masterUser)
		.end(function(err, res) {
			if (err) return done(err);
			assert.equal(res.status, 200)
			Cookies = res.header['set-cookie'];
			done();
		});
    });
    
	it ('Should return status 200', function(done) {
		var req = request(envData.upstreamUrl).get('/v1/StudyDashboard/DataConfirmation');
		req.cookies = Cookies;
		req.set('Accept', 'application/json')
		.end(function(err, res) {
			if (err) return done(err);
			assert.equal(res.status, 200)
			done();
		});
    });
});
@joaoneto

This comment has been minimized.

Owner

joaoneto commented Aug 11, 2018

Hello @rafaelcs,
I did a working test here, with a simple app and changed a few parameters in your test. Take a look in your test, the envData and tokenAuthData may have some missing parameter.
The supertest request should receive your express app and the tokenAuthData login payload
I changed some things in your test, commenting on the lines that may be causing the behavior you mentioned

const assert = require('chai').assert;
const expect = require('chai').expect;
const request = require('supertest');
// const envData = require('../../data/envData');
// const tokenAuthData = require('../../data/tokenAuthData');

const app = require('./app');

var Cookies;

describe ('POST /Authenticate', function() {

  const authenticate = '/TokenAuth/Authenticate';

  it ('Should create a session', function(done) {
    // request(envData.upstreamUrl)
    request(app)
      .post(authenticate)
      .set('Content-type', 'application/json')
      // .send(tokenAuthData.masterUser)
      .send({ username: 'myself', password: 'mypass' })
      .end(function(err, res) {
        if (err) return done(err);
        assert.equal(res.status, 200)
        Cookies = res.header['set-cookie'];
        done();
      });
  });

  it ('Should return status 200', function(done) {
    // var req = request(envData.upstreamUrl).get('/v1/StudyDashboard/DataConfirmation');
    var req = request(app).get('/v1/StudyDashboard/DataConfirmation');
    req.cookies = Cookies;
    req.set('Accept', 'application/json')
      .end(function(err, res) {
        if (err) return done(err);
        assert.equal(res.body.message, 'Restricted resource')
        assert.equal(res.status, 200)
        done();
      });
  });

  it ('Should return status 401', function(done) {
    var req = request(app).get('/v1/StudyDashboard/DataConfirmation');
    // req.cookies = Cookies;
    req.set('Accept', 'application/json')
      .end(function(err, res) {
        if (err) return done(err);
        assert.equal(res.status, 401)
        done();
      });
  });
});
const express = require('express');
const app = express();
const session = require('express-session');

const isLoggedIn = (req, res, next) => {
  if (!req.session.authenticated) {
    return res.status(401).send({ message: 'Unauthorized' });
  }
  next();
}

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true
}));

app.post('/TokenAuth/Authenticate', (req, res) => {
  req.session.authenticated = true;
  res.send({ message: 'Login success' });
});

app.get('/v1/StudyDashboard/DataConfirmation', isLoggedIn, (req, res) => {
  res.send({ message: 'Restricted resource' });
});

module.exports = app;

I hope it helps you to solve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment