-
Notifications
You must be signed in to change notification settings - Fork 127
Expand file tree
/
Copy path_server_test.js
More file actions
230 lines (188 loc) · 6.47 KB
/
_server_test.js
File metadata and controls
230 lines (188 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright (c) 2012 Titanium I.T. LLC. All rights reserved. See LICENSE.txt for details.
(function() {
"use strict";
var Server = require("./server.js");
var http = require("http");
var fs = require("fs");
var async = require("async");
var assert = require("../shared/_assert.js");
var io = require("socket.io-client");
var CONTENT_DIR = "generated/test";
var INDEX_PAGE = "index.html";
var OTHER_PAGE = "other.html";
var NOT_FOUND_PAGE = "test404.html";
var INDEX_PAGE_DATA = "This is index page file";
var OTHER_PAGE_DATA = "This is another page";
var NOT_FOUND_DATA = "This is 404 page file";
var PORT = 5020;
var BASE_URL = "http://localhost:" + PORT;
var TEST_FILES = [
[ CONTENT_DIR + "/" + INDEX_PAGE, INDEX_PAGE_DATA],
[ CONTENT_DIR + "/" + OTHER_PAGE, OTHER_PAGE_DATA],
[ CONTENT_DIR + "/" + NOT_FOUND_PAGE, NOT_FOUND_DATA]
];
describe("HTTP Server", function() {
var server;
beforeEach(function(done) {
server = new Server();
async.each(TEST_FILES, createTestFile, done);
});
afterEach(function(done) {
async.each(TEST_FILES, deleteTestFile, done);
});
it("serves files from directory", function(done) {
httpGet(BASE_URL + "/" + INDEX_PAGE, function(response, responseData) {
assert.equal(response.statusCode, 200, "status code");
assert.equal(responseData, INDEX_PAGE_DATA, "response text");
done();
});
});
it("sets content-type and charset for HTML files", function(done) {
httpGet(BASE_URL + "/" + INDEX_PAGE, function(response, responseData) {
assert.equal(response.headers["content-type"], "text/html; charset=UTF-8", "content-type header");
done();
});
});
it("supports multiple files", function(done) {
httpGet(BASE_URL + "/" + OTHER_PAGE, function(response, responseData) {
assert.equal(response.statusCode, 200, "status code");
assert.equal(responseData, OTHER_PAGE_DATA, "response text");
done();
});
});
it("serves index.html when asked for home page", function(done) {
httpGet(BASE_URL, function(response, responseData) {
assert.equal(response.statusCode, 200, "status code");
assert.equal(responseData, INDEX_PAGE_DATA, "response text");
done();
});
});
it("returns 404 when file doesn't exist", function(done) {
httpGet(BASE_URL + "/bargle", function(response, responseData) {
assert.equal(response.statusCode, 404, "status code");
assert.equal(responseData, NOT_FOUND_DATA, "404 text");
done();
});
});
it("sets content-type and charset for 404 page", function(done) {
httpGet(BASE_URL + "/bargle", function(response, responseData) {
assert.equal(response.headers["content-type"], "text/html; charset=UTF-8", "content-type header");
done();
});
});
it("requires home page parameter", function() {
assert.throws(function() {
server.start();
});
});
it("requires 404 page parameter", function() {
assert.throws(function() {
server.start(CONTENT_DIR);
});
});
it("requires port parameter", function() {
assert.throws(function() {
server.start(CONTENT_DIR, NOT_FOUND_PAGE);
});
});
it("runs callback when stop completes", function(done) {
server.start(CONTENT_DIR, NOT_FOUND_PAGE, PORT);
server.stop(function() {
done();
});
});
it("stop() provides error parameter if the server isn't running", function(done) {
server.stop(function(err) {
assert.defined(err);
done();
});
});
function httpGet(url, callback) {
server.start(CONTENT_DIR, NOT_FOUND_PAGE, PORT, function() {
http.get(url, function(response) {
var receivedData = "";
response.setEncoding("utf8");
response.on("data", function(chunk) {
receivedData += chunk;
});
response.on("error", function(err) {
console.log("ERROR", err);
});
response.on("end", function() {
server.stop(function() {
callback(response, receivedData);
});
});
});
});
}
});
describe("Socket.io Server", function() {
var server;
beforeEach(function(done) {
server = new Server();
server.start(CONTENT_DIR, NOT_FOUND_PAGE, PORT, done);
});
afterEach(function(done) {
server.stop(done);
});
it("broadcasts mouse message from one client to all others", function(done) {
var EXPECTED_DATA = "mouse data";
var clients = createSockets(3);
var emitter = clients[0];
var receivers = clients.slice().splice(1);
emitter.on("mouse", function() {
assert.fail("emitter should not receive its own events");
});
async.each(receivers, function(client, next) {
client.on("mouse", function(data) {
assert.equal(data, EXPECTED_DATA);
next();
});
}, end);
emitter.emit("mouse", EXPECTED_DATA);
function end() {
async.each(clients, closeSocket, done);
}
});
function createSockets(count){
return Array.from({length: count}, createSocket);
//Or without ES6: return Array.apply(null, Array(count)).map(createSocket);
}
function createSocket() {
return io("http://localhost:" + PORT);
}
function closeSocket(socket, callback) {
// timeout is necessary due to apparent race condition in socket.io-client
// see https://github.com/socketio/socket.io-client/issues/935
setTimeout(function() {
socket.disconnect();
callback();
}, 50);
}
});
function createTestFile(fileAndData, done) {
// Note: writeFile() MUST be called asynchronously in order for this code to work on Windows 7.
// If it's called synchronously, it fails with an EPERM error when the second test starts. This
// may be related to this Node.js issue: https://github.com/joyent/node/issues/6599
// This issue appeared after upgrading send 0.2.0 to 0.9.3. Prior to that, writeFileSync()
// worked fine.
fs.writeFile(fileAndData[0], fileAndData[1], function(err) {
if (err) console.log("could not create test file: [" + fileAndData[0] + "]. Error: " + err);
done();
});
}
function deleteTestFile(fileAndData, done) {
// Note: unlink() MUST be called asynchronously here in order for this code to work on Windows 7.
// If it's called synchronously, then it will run before the file is closed, and that is not allowed
// on Windows 7. It's possible that this is the result of a Node.js bug; see this issue for details:
// https://github.com/joyent/node/issues/6599
var file = fileAndData[0];
if (fs.existsSync(file)) {
fs.unlink(file, function(err) {
if (err || fs.existsSync(file)) console.log("could not delete test file: [" + file + "]. Error: " + err);
done();
});
}
}
}());