How to Persist a request (with cookies, ie sessions) Like super-agent
Opened this issue Β· 15 comments
To access some urls in application, one must login first. I must go back to use super-agent to unit test these urls. Can supertest do thing like this?
server = require './testServer'
request = require 'superagent'
r = request.agent()
server.start 3002
fakeUser =
username:'tj',
password:'foobar'
describe 'after login', ->
beforeEach (done) ->
r
.post("http://localhost:3002/login")
.send(fakeUser)
.end (err, res) ->
assert res.statusCode is 200
done()
it 'can show restricted page', (done) ->
r
.get("http://localhost:3002/restricted")
.end (err, res) ->
assert.include res.text,'Wahoo!'
assert res.statusCode is 200
done()
@FZX As discussed in #26, it seems supertest
has no support for agent
yet.
Though not optimal at all, here's how I dealt with the case :[
describe "Login", ->
# Login first
beforeEach ( done )->
@agent = superagent.agent()
request( app ).post( '/login' )
.send( { username: 'myname', password: 'secur1ty' } )
.end ( err, res ) =>
@agent.saveCookies( res ) # Store cookies to `@agent`
done()
# Now you can test :)
describe 'GET /admin/articles', ->
beforeEach ( done )->
req = request( app ).get( '/admin/articles' )
@agent.attachCookies( req ) # Attach cookies (session info) to the request
req.end ( err, res )=>
@res = res
done()
it 'should render Hello', ->
@res.should.have.status( 200 )
@res.text.should.include( 'Hello' )
@mnmly,thank you very much, your code is very helpful!
@mnmly Best method I've seen so far to get the niceties of both supertest and superagent. Thx.
@mnmly Login session without the agent https://gist.github.com/joaoneto/5152248
Would be really great if this got resolved - such a common use case.
Using @mnmly approach you can then monkey patch supertest and chain on the agent.
supertest = require('supertest')
supertest.Test::agent = (agent) ->
agent.attachCookies @
return @
request.post('/api/collections').agent(@agent).send(...).expect(200).end ...
neither the agent nor cookies solution seems to work with express 3.2.6.
Ah, the cookies solution works fine if I set the Cookie header instead of the cookies property.
req.set( 'Cookie', cookies )
thanks @timmywil, it's weird, but really works!
Agent is exposed: https://github.com/visionmedia/supertest/blob/master/index.js#L46
var supertest = require('supertest');
var app = express();
var agent = supertest.agent(app);
// then you can persist cookie
For the records, full example for @alsotang suggest:
(this is a login form, not an API request)
var supertest = require('supertest');
var app = require('../path_to_my/app')
var agent = supertest.agent(app);
describe('Login', function () {
it('should login superadmin', 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();
});
};
});
In my case,
agent.saveCookie(res);
(version 1.x)
was smoothly replaced by
agent.jar.setCookie(res.headers['set-cookie'][0]);
(version 2.x)
For the records, full example for @alsotang suggest:
You don't need do anything more with the agent.
var supertest = require('supertest');
var agent = supertest.agent('localhost/api');
describe('Login', function () {
it('should login superadmin', 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); donβt need this line
return done();
});
};
it('get user info', function(done) {
// don't need do anything with cookies, agent will attached cookies automatically based on login above
agent
.get('/userinfo')
.expect(200)
.end(function(err, res) {
if (err) return done(err);
return done();
});
};
});