Skip to content

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.

Copy link

rtoal commented Dec 4, 2013

Very helpful! Thanks.

@sjevs

This comment has been minimized.

Copy link

sjevs commented Jan 1, 2014

+1

@mehdimehdi

This comment has been minimized.

Copy link

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.

Copy link

grawk commented Aug 22, 2014

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

@uliporeggia

This comment has been minimized.

Copy link

uliporeggia commented Oct 9, 2014

+1
and +1 for @mehdimehdi
Thanks

@roymath

This comment has been minimized.

Copy link

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.

Copy link

pagewang0 commented Mar 30, 2015

@mehdimehdi
Thanks +1

@vuonghichi

This comment has been minimized.

Copy link

vuonghichi commented Nov 7, 2015

dk

@stenio123

This comment has been minimized.

Copy link

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.

Copy link

stenio123 commented Nov 13, 2015

Found it!
var app = express();

module.exports = app;

Tx!

@JohnTian

This comment has been minimized.

Copy link

JohnTian commented Mar 15, 2016

Great job! Thx!

@LopatkinEvgeniy

This comment has been minimized.

Copy link

LopatkinEvgeniy commented Apr 8, 2016

Thanks, its very usefull!

@hillkim7

This comment has been minimized.

Copy link

hillkim7 commented Apr 8, 2016

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

@frisk

This comment has been minimized.

Copy link

frisk commented May 18, 2016

This is awesome! Thank you for sharing!

@rafaelgou

This comment has been minimized.

Copy link

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.

Copy link

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.

Copy link

Santiago-vdk commented Dec 3, 2016

This still works great!

@niteshpsit1

This comment has been minimized.

Copy link

niteshpsit1 commented Jan 4, 2017

Thanks it safe lot of time

@jontelm

This comment has been minimized.

Copy link

jontelm commented May 11, 2017

Thanks

@abhirathmahipal

This comment has been minimized.

Copy link

abhirathmahipal commented May 22, 2017

Just what I was looking for. Kudos!

@vishalbiradar

This comment has been minimized.

Copy link

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.

Copy link

ajay-justclean commented Mar 14, 2018

thanks

@ajay25487

This comment has been minimized.

Copy link

ajay25487 commented Mar 14, 2018

+1

@SalathielGenese

This comment has been minimized.

Copy link

SalathielGenese commented May 7, 2018

How can I thank you enough?

Tanks of Thanks !!!

@pc-vkaza

This comment has been minimized.

Copy link

pc-vkaza commented May 16, 2018

Thanks. Works great for Cookies persistence.

@rafaelcs

This comment has been minimized.

Copy link

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.

Copy link
Owner Author

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
You can’t perform that action at this time.