fix tests
This commit is contained in:
parent
a528867a2f
commit
5f3774fe44
@ -10,7 +10,7 @@
|
|||||||
"author": "Michelle Bu, Eric Zhang",
|
"author": "Michelle Bu, Eric Zhang",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha test",
|
"test": "mocha test/**/*.js",
|
||||||
"start": "node ./src/index.js"
|
"start": "node ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -4,24 +4,10 @@ const config = require('../../../../config');
|
|||||||
|
|
||||||
const app = module.exports = express.Router();
|
const app = module.exports = express.Router();
|
||||||
|
|
||||||
const randomId = () => {
|
|
||||||
return (Math.random().toString(36) + '0000000000000000000').substr(2, 16);
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateClientId = () => {
|
|
||||||
let clientId = randomId();
|
|
||||||
|
|
||||||
while (realm.getClientById(clientId)) {
|
|
||||||
clientId = randomId();
|
|
||||||
}
|
|
||||||
|
|
||||||
return clientId;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve guaranteed random ID.
|
// Retrieve guaranteed random ID.
|
||||||
app.get('/id', (req, res, next) => {
|
app.get('/id', (req, res, next) => {
|
||||||
res.contentType = 'text/html';
|
res.contentType = 'text/html';
|
||||||
res.send(generateClientId());
|
res.send(realm.generateClientId());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get a list of all peers for a key, enabled by the `allowDiscovery` flag.
|
// Get a list of all peers for a key, enabled by the `allowDiscovery` flag.
|
||||||
|
56
src/models/realm.js
Normal file
56
src/models/realm.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
class Realm {
|
||||||
|
constructor () {
|
||||||
|
this.clients = new Map();
|
||||||
|
this.messageQueue = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
getClientsIds () {
|
||||||
|
return [...this.clients.keys()];
|
||||||
|
}
|
||||||
|
|
||||||
|
getClientById (clientId) {
|
||||||
|
return this.clients.get(clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
setClient (client, id) {
|
||||||
|
this.clients.set(id, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeClientById (id) {
|
||||||
|
const client = this.getClientById(id);
|
||||||
|
|
||||||
|
if (!client) return false;
|
||||||
|
|
||||||
|
this.clients.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMessageQueueById (id) {
|
||||||
|
return this.messageQueue.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
addMessageToQueue (id, message) {
|
||||||
|
if (!this.getMessageQueueById(id)) {
|
||||||
|
this.messageQueue.set(id, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getMessageQueueById(id).push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMessageQueue (id) {
|
||||||
|
this.messageQueue.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateClientId () {
|
||||||
|
const randomId = () => (Math.random().toString(36) + '0000000000000000000').substr(2, 16);
|
||||||
|
|
||||||
|
let clientId = randomId();
|
||||||
|
|
||||||
|
while (this.getClientById(clientId)) {
|
||||||
|
clientId = randomId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Realm;
|
@ -1,44 +1,3 @@
|
|||||||
class Realm {
|
const Realm = require('../../models/realm');
|
||||||
constructor () {
|
|
||||||
this.clients = new Map();
|
|
||||||
this.messageQueue = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
getClientsIds () {
|
|
||||||
return [...this.clients.keys()];
|
|
||||||
}
|
|
||||||
|
|
||||||
getClientById (clientId) {
|
|
||||||
return this.clients.get(clientId);
|
|
||||||
}
|
|
||||||
|
|
||||||
setClient (client, id) {
|
|
||||||
this.clients.set(id, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeClientById (id) {
|
|
||||||
const client = this.getClientById(id);
|
|
||||||
|
|
||||||
if (!client) return false;
|
|
||||||
|
|
||||||
this.clients.delete(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMessageQueueById (id) {
|
|
||||||
return this.messageQueue.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
addMessageToQueue (id, message) {
|
|
||||||
if (!this.getMessageQueueById(id)) {
|
|
||||||
this.messageQueue.set(id, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getMessageQueueById(id).push(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMessageQueue (id) {
|
|
||||||
this.messageQueue.delete(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Realm();
|
module.exports = new Realm();
|
||||||
|
49
test/models/realm.js
Normal file
49
test/models/realm.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
const { expect } = require('chai');
|
||||||
|
const Realm = require('../../src/models/realm');
|
||||||
|
const Client = require('../../src/models/client');
|
||||||
|
|
||||||
|
describe('Realm', () => {
|
||||||
|
describe('#generateClientId', () => {
|
||||||
|
it('should generate a 16-character ID', () => {
|
||||||
|
const realm = new Realm();
|
||||||
|
expect(realm.generateClientId().length).to.eq(16);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#setClient', () => {
|
||||||
|
it('should add client to realm', () => {
|
||||||
|
const realm = new Realm();
|
||||||
|
const client = new Client({ id: 'id', token: '' });
|
||||||
|
|
||||||
|
realm.setClient(client, 'id');
|
||||||
|
expect(realm.getClientsIds()).to.deep.eq(['id']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#removeClientById', () => {
|
||||||
|
it('should remove client from realm', () => {
|
||||||
|
const realm = new Realm();
|
||||||
|
const client = new Client({ id: 'id', token: '' });
|
||||||
|
|
||||||
|
realm.setClient(client, 'id');
|
||||||
|
realm.removeClientById('id');
|
||||||
|
|
||||||
|
expect(realm.getClientById('id')).to.be.undefined;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#getClientsIds', () => {
|
||||||
|
it('should reflects on add/remove childs', () => {
|
||||||
|
const realm = new Realm();
|
||||||
|
const client = new Client({ id: 'id', token: '' });
|
||||||
|
|
||||||
|
realm.setClient(client, 'id');
|
||||||
|
expect(realm.getClientsIds()).to.deep.eq(['id']);
|
||||||
|
|
||||||
|
expect(realm.getClientById('id')).to.eq(client);
|
||||||
|
|
||||||
|
realm.removeClientById('id');
|
||||||
|
expect(realm.getClientsIds()).to.deep.eq([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
152
test/server.js
152
test/server.js
@ -1,152 +0,0 @@
|
|||||||
const ExpressPeerServer = require('../').ExpressPeerServer;
|
|
||||||
const { expect } = require('chai');
|
|
||||||
const sinon = require('sinon');
|
|
||||||
|
|
||||||
describe('ExpressPeerServer', function () {
|
|
||||||
describe('method', function () {
|
|
||||||
var p;
|
|
||||||
|
|
||||||
before(function () {
|
|
||||||
p = ExpressPeerServer(undefined, { port: 8000 });
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#_checkKey', function () {
|
|
||||||
it('should reject keys that are not the default', function (done) {
|
|
||||||
p._checkKey('bad key', null, function (response) {
|
|
||||||
expect(response).to.be('Invalid key provided');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should accept valid key/ip pairs', function (done) {
|
|
||||||
p._checkKey('peerjs', 'myip', function (response) {
|
|
||||||
expect(response).to.be(null);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject ips that are at their limit', function (done) {
|
|
||||||
p._options.ip_limit = 0;
|
|
||||||
p._checkKey('peerjs', 'myip', function (response) {
|
|
||||||
expect(response).to.be('myip has reached its concurrent user limit');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject when the server is at its limit', function (done) {
|
|
||||||
p._options.concurrent_limit = 0;
|
|
||||||
p._checkKey('peerjs', 'myip', function (response) {
|
|
||||||
expect(response).to.be('Server has reached its concurrent user limit');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#_removePeer', function () {
|
|
||||||
before(function () {
|
|
||||||
var fake = { ip: '0.0.0.0' };
|
|
||||||
p._ips[fake.ip] = 1;
|
|
||||||
p._clients['peerjs'] = {};
|
|
||||||
p._clients['peerjs']['test'] = fake;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should decrement the number of ips being used and remove the connection', function () {
|
|
||||||
expect(p._ips['0.0.0.0']).to.be(1);
|
|
||||||
p._removePeer('peerjs', 'test');
|
|
||||||
expect(p._ips['0.0.0.0']).to.be(0);
|
|
||||||
expect(p._clients['peerjs']['test']).to.be(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#_handleTransmission', function () {
|
|
||||||
var KEY = 'peerjs';
|
|
||||||
var ID = 'test';
|
|
||||||
|
|
||||||
before(function () {
|
|
||||||
p._clients[KEY] = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should send to the socket when appropriate', function () {
|
|
||||||
var send = sinon.spy();
|
|
||||||
var write = sinon.spy();
|
|
||||||
var message = { dst: ID };
|
|
||||||
p._clients[KEY][ID] = {
|
|
||||||
socket: {
|
|
||||||
send: send
|
|
||||||
},
|
|
||||||
res: {
|
|
||||||
write: write
|
|
||||||
}
|
|
||||||
};
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(send.calledWith(JSON.stringify(message))).to.be(true);
|
|
||||||
expect(write.calledWith(JSON.stringify(message))).to.be(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should write to the response with a newline when appropriate', function () {
|
|
||||||
var write = sinon.spy();
|
|
||||||
var message = { dst: ID };
|
|
||||||
p._clients[KEY][ID] = {
|
|
||||||
res: {
|
|
||||||
write: write
|
|
||||||
}
|
|
||||||
};
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(write.calledWith(JSON.stringify(message) + '\n')).to.be(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
// no destination.
|
|
||||||
it('should push to outstanding messages if the destination is not found', function () {
|
|
||||||
var message = { dst: ID };
|
|
||||||
p._outstanding[KEY] = {};
|
|
||||||
p._clients[KEY] = {};
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(p._outstanding[KEY][ID][0]).to.be(message);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not push to outstanding messages if the message is a LEAVE or EXPIRE', function () {
|
|
||||||
var message = { dst: ID, type: 'LEAVE' };
|
|
||||||
p._outstanding[KEY] = {};
|
|
||||||
p._clients[KEY] = {};
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(p._outstanding[KEY][ID]).to.be(undefined);
|
|
||||||
|
|
||||||
message = { dst: ID, type: 'EXPIRE' };
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(p._outstanding[KEY][ID]).to.be(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the peer if there is no dst in the message', function () {
|
|
||||||
var message = { type: 'LEAVE' };
|
|
||||||
p._removePeer = sinon.spy();
|
|
||||||
p._outstanding[KEY] = {};
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(p._removePeer.calledWith(KEY, undefined)).to.be(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the peer and send a LEAVE message if the socket appears to be closed', function () {
|
|
||||||
var send = sinon.stub().throws();
|
|
||||||
var message = { dst: ID };
|
|
||||||
var leaveMessage = { type: 'LEAVE', dst: undefined, src: ID };
|
|
||||||
var oldHandleTransmission = p._handleTransmission;
|
|
||||||
p._removePeer = function () {
|
|
||||||
// Hacks!
|
|
||||||
p._handleTransmission = sinon.spy();
|
|
||||||
};
|
|
||||||
p._clients[KEY][ID] = {
|
|
||||||
socket: {
|
|
||||||
send: send
|
|
||||||
}
|
|
||||||
};
|
|
||||||
p._handleTransmission(KEY, message);
|
|
||||||
expect(p._handleTransmission.calledWith(KEY, leaveMessage)).to.be(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#_generateClientId', function () {
|
|
||||||
it('should generate a 16-character ID', function () {
|
|
||||||
expect(p._generateClientId('anykey').length).to.be(16);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
x
Reference in New Issue
Block a user