Created
October 28, 2012 08:30
-
-
Save pxsta/3968061 to your computer and use it in GitHub Desktop.
mochaとsuperagentを用いてexpressのアプリのセッション周りのテスト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var express = require('express') | |
, http = require('http') | |
, path = require('path') | |
, io = require('socket.io') | |
, connect = require("express/node_modules/connect") | |
, Session = express.session.Session | |
, app = module.exports = express(); | |
//メモリストアかRedisのどちらかでセッションを保存 | |
//var sessionStore = new express.session.MemoryStore() | |
var RedisStore = require('connect-redis')(express) | |
, sessionStore = new RedisStore(); | |
app.configure(function() { | |
app.set('port', process.env.PORT || 3000); | |
//セッションの署名に使われるキー | |
app.set('secretKey', 'mySecret'); | |
//cookieにexpressのsessionIDを保存する際のキー | |
app.set('cookieSessionKey', 'sid'); | |
//POSTの値を受け取れるようにする | |
app.use(express.bodyParser()); | |
//expressでセッション管理を行う | |
app.use(express.cookieParser(app.get('secretKey'))); | |
app.use(express.session({ | |
key : app.get('cookieSessionKey'), | |
store : sessionStore | |
})); | |
//テスト用 | |
app.set("sessionStore",sessionStore); | |
}); | |
app.get('/', function(req, res) { | |
res.sendfile(__dirname + '/index.html'); | |
}); | |
//ログイン処理 | |
app.post('/user/login', function(req, res) { | |
var postData = { | |
userID : req.body.userID, | |
password : req.body.password | |
}; | |
//passがtestならログイン成功させる | |
if ( typeof postData.userID !== 'undefined' && typeof postData.password !== 'undefined' && postData.password.toString() === 'test') { | |
//sessionにユーザーID保存 | |
req.session.userID = postData.userID.toString(); | |
res.redirect('/chat'); | |
} | |
else { | |
console.log('login failed'); | |
res.redirect('/'); | |
} | |
}); | |
//ログアウト処理 | |
app.get('/user/logout',function(req,res){ | |
req.session.destroy(function(err) { | |
if(err){ | |
console.log(err); | |
} | |
res.redirect('/'); | |
}); | |
}); | |
//チャットページ | |
app.get('/chat', function(req, res) { | |
//セッションにuserIDがあったらログイン済みとする | |
if ( typeof req.session.userID !== 'undefined' && req.session.userID) { | |
res.sendfile(__dirname + '/chat.html'); | |
} | |
else { | |
res.redirect('/'); | |
} | |
}); | |
io = io.listen(http.createServer(app).listen(app.get('port')), function() { | |
console.log("Express server & socket.io listening on port " + app.get('port')); | |
}); | |
//socket.ioのコネクション認証時にexpressのセッションIDを元にログイン済みか確認する | |
io.set('authorization', function(handshakeData, callback) { | |
if (handshakeData.headers.cookie) { | |
//cookieを取得 | |
var cookie = require('cookie').parse(decodeURIComponent(handshakeData.headers.cookie)); | |
cookie = connect.utils.parseSignedCookies(cookie, app.get('secretKey')); | |
var sessionID = cookie[app.get('cookieSessionKey')]; | |
// セッションをから取得 | |
sessionStore.get(sessionID, function(err, session) { | |
if (err) { | |
//セッションが取得できなかったら | |
console.dir(err); | |
callback(err.message, false); | |
} | |
else if (!session) { | |
console.log('session not found'); | |
callback('session not found', false); | |
} | |
else { | |
console.log("authorization success"); | |
// socket.ioからもセッションを参照できるようにする | |
handshakeData.cookie = cookie; | |
handshakeData.sessionID = sessionID; | |
handshakeData.sessionStore = sessionStore; | |
handshakeData.session = new Session(handshakeData, session); | |
callback(null, true); | |
} | |
}); | |
} | |
else { | |
//cookieが見つからなかった時 | |
return callback('cookie not found', false); | |
} | |
}); | |
io.sockets.on('connection', function(socket) { | |
// Expressのセッションをsocket.ioから参照する | |
console.log('session data', socket.handshake.session); | |
socket.on("chat", function(message) { | |
io.sockets.emit("message", socket.handshake.session.userID + " " + message); | |
}); | |
//Expressのセッションを定期的に更新する | |
var sessionReloadIntervalID = setInterval(function() { | |
socket.handshake.session.reload(function() { | |
socket.handshake.session.touch().save(); | |
}); | |
}, 60 * 2 * 1000); | |
socket.on("disconnect", function(message) { | |
clearInterval(sessionReloadIntervalID); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var url = require('url') | |
, connect = require("express/node_modules/connect") | |
, should = require('should') | |
, assert = require('assert') | |
, superagent = require('superagent') | |
, app = require('../app.js'); | |
describe('HTTP Server Test', function() { | |
//テストに使用するユーザーを作成 | |
var testUser = superagent.agent(); | |
//テスト前処理 | |
before(function(done) { | |
//セッションストアのデータをすべて消す | |
app.get("sessionStore").client.flushdb(done); | |
}); | |
it('ログインページにアクセスできるはず', function(done) { | |
testUser.get('http://localhost:3000/').end(function(err, res) { | |
should.not.exist(err); | |
should.equal(res.statusCode, 200); | |
done(); | |
}); | |
}); | |
it('ログイン前にチャットページにアクセスしたらログインページにリダイレクトされるはず', function(done) { | |
testUser.get('http://localhost:3000/chat').end(function(err, res) { | |
should.not.exist(err); | |
res.redirects.should.not.be.empty; | |
should.equal(url.parse(res.redirects[0], false, true).pathname, "/"); | |
done(); | |
}); | |
}); | |
it('ログインに失敗したらログインページにリダイレクトされるはず', function(done) { | |
//ログインページでのpost処理 | |
testUser.post('http://localhost:3000/user/login').send({ | |
userID : 'test', | |
password : 'bad_password' | |
}).end(function(err, res) { | |
should.not.exist(err); | |
res.redirects.should.not.be.empty; | |
should.equal(url.parse(res.redirects[0], false, true).pathname, "/"); | |
done(); | |
}); | |
}); | |
it('ログインに成功したらセッションストレージにユーザー名が保存されているはず', function(done) { | |
testUser.post('http://localhost:3000/user/login').send({ | |
userID : 'test', | |
password : 'test' | |
}).end(function(err, res) { | |
should.not.exist(err); | |
//sessionStoreにsessionデータが保存されているはず | |
var header_cookie = res.req._headers.cookie; | |
var cookie = require('cookie').parse(decodeURIComponent(header_cookie)); | |
cookie = connect.utils.parseSignedCookies(cookie, app.get('secretKey')); | |
var sessionID = cookie[app.get('cookieSessionKey')]; | |
app.get("sessionStore").get(sessionID,function(err,session){ | |
should.not.exist(err); | |
//userIDがログイン時のものと一致するはず | |
should.equal(session.userID,"test"); | |
done(); | |
}); | |
}); | |
}); | |
it('ログイン後はチャットページに直接アクセスしても表示されるはず', function(done) { | |
testUser.get('http://localhost:3000/chat').end(function(err, res) { | |
should.not.exist(err); | |
should.equal(res.statusCode, 200); | |
should.equal(res.req.path, "/chat"); | |
done(); | |
}); | |
}); | |
it('ログアウト後はログインページにリダイレクトされるはず', function(done) { | |
testUser.get('http://localhost:3000/user/logout').end(function(err, res) { | |
should.not.exist(err); | |
res.redirects.should.not.be.empty; | |
should.equal(url.parse(res.redirects[0], false, true).pathname, "/"); | |
done(); | |
}); | |
}); | |
it('ログアウト後はチャットページに直接アクセスしてもログインページにリダイレクトされるはず', function(done) { | |
testUser.get('http://localhost:3000/chat').end(function(err, res) { | |
should.not.exist(err); | |
res.redirects.should.not.be.empty; | |
should.equal(url.parse(res.redirects[0], false, true).pathname, "/"); | |
done(); | |
}); | |
}); | |
//テスト後処理 | |
after(function(done) { | |
app.get("sessionStore").client.flushdb(done); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<title>Socket.io-Express3.0.0rc3 session sample</title> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script> | |
<script src="/socket.io/socket.io.js"></script> | |
</head> | |
<body> | |
<h1>Socket.io-Express3.0.0rc3 session sample</h1> | |
<div id="nav"> | |
<a href="/user/logout">logout</a> | |
</div> | |
<div id="chat"> | |
<div id="board"></div> | |
<textarea id="textarea"></textarea> | |
<button id="btn-send">send</button> | |
</div> | |
</body> | |
<script type="text/javascript"> | |
var socket = io.connect(); | |
socket.on("message", function(message) { | |
$("#board").append("<p>" + message + "</p>"); | |
}); | |
var sendMessage = function() { | |
var message = $("#textarea").val(); | |
$("#textarea").val(""); | |
socket.emit("chat", message); | |
}; | |
$(document).ready(function() { | |
$('textarea#textarea').bind('keypress', function(e) { | |
if (e.keyCode == 13) { | |
sendMessage(); | |
} | |
}); | |
$("#btn-send").click(function() { | |
sendMessage(); | |
}); | |
}); | |
</script> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<title>Socket.io-Express3.0.0rc3 session sample</title> | |
</head> | |
<body> | |
<h1>Socket.io-Express3.0.0rc3 session sample</h1> | |
<div id="login"> | |
<form action="/user/login" method="post"> | |
ID: <input type="text" name="userID" value="test"/> <br/> | |
PASS: <input type="text" name="password" value ="test"/> | |
<input type="submit" value="login" /> | |
</form> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--reporter spec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "socketio-express3-chat", | |
"version": "0.0.1", | |
"private": true, | |
"scripts": { | |
"start": "node app" | |
}, | |
"engines": { | |
"node": "0.8.7", | |
"npm": "1.1.49" | |
}, | |
"dependencies": { | |
"express": "3.0.0rc3", | |
"socket.io": "0.9.10", | |
"cookie": "0.0.4", | |
"connect-redis": "~1.4.4", | |
"should": "~1.2.0", | |
"superagent": "~0.9.7" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment