Skip to content

Instantly share code, notes, and snippets.

@joaoneto
Created March 13, 2013 13:49
  • Star 82 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save joaoneto/5152248 to your computer and use it in GitHub Desktop.
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();
});
});
});
@sergej-brazdeikis
Copy link

+1

@mehdimehdi
Copy link

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
Copy link

grawk commented Aug 22, 2014

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

@uliporeggia
Copy link

+1
and +1 for @mehdimehdi
Thanks

@roymath-zz
Copy link

@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
Copy link

@mehdimehdi
Thanks +1

@vuonghichi
Copy link

dk

@stenio123
Copy link

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
Copy link

Found it!
var app = express();

module.exports = app;

Tx!

@Digital2Slave
Copy link

Great job! Thx!

@LopatkinEvgeniy
Copy link

Thanks, its very usefull!

@hillkim7
Copy link

hillkim7 commented Apr 8, 2016

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

@frisk
Copy link

frisk commented May 18, 2016

This is awesome! Thank you for sharing!

@rafaelgou
Copy link

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
Copy link

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

@santiagovdk
Copy link

This still works great!

@niteshpsit1
Copy link

Thanks it safe lot of time

@jontelm
Copy link

jontelm commented May 11, 2017

Thanks

@abhirathmahipal
Copy link

Just what I was looking for. Kudos!

@vishalbiradar
Copy link

Please help me on the below issue too.

mochajs/mocha#3216

Thanks in advance.

@ajay-justclean
Copy link

thanks

@imashukla
Copy link

+1

@SalathielGenese
Copy link

How can I thank you enough?

Tanks of Thanks !!!

@pc-vkaza
Copy link

Thanks. Works great for Cookies persistence.

@rafaelcs
Copy link

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
Copy link
Author

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.

@gongdao
Copy link

gongdao commented Jan 30, 2022

Thank you.

@psoleckimoj
Copy link

Worked a treat 👍

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