222 lines
7.2 KiB
JavaScript
222 lines
7.2 KiB
JavaScript
const PollModule = require('../../lib/channel/poll');
|
|
const assert = require('assert');
|
|
const Config = require('../../lib/config');
|
|
|
|
describe('PollModule', () => {
|
|
describe('#validatePollInput', () => {
|
|
let pollModule = new PollModule({ uniqueName: 'testChannel', modules: {} });
|
|
|
|
it('accepts valid input', () => {
|
|
let title = '';
|
|
for (let i = 0; i < 20; i++) {
|
|
title += 'x';
|
|
}
|
|
|
|
pollModule.validatePollInput(title, ['ab', 'cd']);
|
|
});
|
|
|
|
it('rejects non-string titles', () => {
|
|
assert.throws(() => {
|
|
pollModule.validatePollInput(null, []);
|
|
}, /title/);
|
|
});
|
|
|
|
it('rejects invalidly long titles', () => {
|
|
let title = '';
|
|
for (let i = 0; i < 256; i++) {
|
|
title += 'x';
|
|
}
|
|
|
|
assert.throws(() => {
|
|
pollModule.validatePollInput(title, []);
|
|
}, /title/);
|
|
});
|
|
|
|
it('rejects non-array option parameter', () => {
|
|
assert.throws(() => {
|
|
pollModule.validatePollInput('poll', 1234);
|
|
}, /options/);
|
|
});
|
|
|
|
it('rejects too many options', () => {
|
|
const limit = Config.get('poll.max-options');
|
|
Config.set('poll.max-options', 2);
|
|
try {
|
|
assert.throws(() => {
|
|
pollModule.validatePollInput('poll', ['1', '2', '3', '4']);
|
|
}, /maximum of 2 options/);
|
|
} finally {
|
|
Config.set('poll.max-options', limit);
|
|
}
|
|
});
|
|
|
|
it('rejects non-string options', () => {
|
|
assert.throws(() => {
|
|
pollModule.validatePollInput('poll', [null]);
|
|
}, /options must be strings/);
|
|
});
|
|
|
|
it('rejects invalidly long options', () => {
|
|
let option = '';
|
|
for (let i = 0; i < 256; i++) {
|
|
option += 'x';
|
|
}
|
|
|
|
assert.throws(() => {
|
|
pollModule.validatePollInput('poll', [option]);
|
|
}, /options must be 1-255 characters/);
|
|
});
|
|
});
|
|
|
|
describe('#handleNewPoll', () => {
|
|
let fakeChannel = {
|
|
uniqueName: 'testChannel',
|
|
logger: {
|
|
log() {
|
|
|
|
}
|
|
},
|
|
broadcastToRoom() {
|
|
},
|
|
broadcastAll() {
|
|
},
|
|
modules: {
|
|
permissions: {
|
|
canControlPoll() {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
let fakeUser = {
|
|
getName() {
|
|
return 'testUser';
|
|
},
|
|
socket: {
|
|
emit() {
|
|
}
|
|
}
|
|
};
|
|
let pollModule;
|
|
beforeEach(() => {
|
|
pollModule = new PollModule(fakeChannel);
|
|
});
|
|
|
|
it('creates a valid poll', () => {
|
|
let sentNewPoll = false;
|
|
let sentClosePoll = false;
|
|
fakeChannel.broadcastToRoom = (event, data, room) => {
|
|
if (room === 'testChannel:viewHidden' && event === 'newPoll') {
|
|
sentNewPoll = true;
|
|
}
|
|
};
|
|
fakeChannel.broadcastAll = (event) => {
|
|
if (event === 'closePoll') {
|
|
sentClosePoll = true;
|
|
}
|
|
};
|
|
pollModule.handleNewPoll(fakeUser, {
|
|
title: 'test poll',
|
|
opts: [
|
|
'option 1',
|
|
'option 2'
|
|
],
|
|
obscured: false
|
|
}, (ackResult) => {
|
|
assert(!ackResult.error, `Unexpected error: ${ackResult.error}`);
|
|
});
|
|
assert(!sentClosePoll, 'Unexpected broadcast of closePoll event');
|
|
assert(sentNewPoll, 'Expected broadcast of newPoll event');
|
|
});
|
|
|
|
it('closes an existing poll when a new one is created', () => {
|
|
let sentNewPoll = 0;
|
|
let sentClosePoll = 0;
|
|
let sentUpdatePoll = 0;
|
|
fakeChannel.broadcastToRoom = (event, data, room) => {
|
|
if (room === 'testChannel:viewHidden' && event === 'newPoll') {
|
|
sentNewPoll++;
|
|
}
|
|
};
|
|
fakeChannel.broadcastAll = (event, data) => {
|
|
if (event === 'closePoll') {
|
|
sentClosePoll++;
|
|
} else if (event === 'updatePoll') {
|
|
sentUpdatePoll++;
|
|
assert.deepStrictEqual(data.counts, [0, 0]);
|
|
}
|
|
};
|
|
pollModule.handleNewPoll(fakeUser, {
|
|
title: 'test poll',
|
|
opts: [
|
|
'option 1',
|
|
'option 2'
|
|
],
|
|
obscured: true
|
|
}, (ackResult) => {
|
|
assert(!ackResult.error, `Unexpected error: ${ackResult.error}`);
|
|
});
|
|
|
|
pollModule.handleNewPoll(fakeUser, {
|
|
title: 'poll 2',
|
|
opts: [
|
|
'option 3',
|
|
'option 4'
|
|
],
|
|
obscured: false
|
|
}, (ackResult) => {
|
|
assert(!ackResult.error, `Unexpected error: ${ackResult.error}`);
|
|
});
|
|
|
|
assert.strictEqual(sentClosePoll, 1, 'Expected 1 broadcast of closePoll event');
|
|
assert.strictEqual(sentUpdatePoll, 1, 'Expected 1 broadcast of updatePoll event');
|
|
assert.strictEqual(sentNewPoll, 2, 'Expected 2 broadcasts of newPoll event');
|
|
});
|
|
|
|
it('rejects an invalid poll', () => {
|
|
fakeChannel.broadcastToRoom = (event, data, room) => {
|
|
assert(false, 'Expected no events to be sent');
|
|
};
|
|
fakeChannel.broadcastAll = (event) => {
|
|
assert(false, 'Expected no events to be sent');
|
|
};
|
|
const options = [];
|
|
for (let i = 0; i < 200; i++) {
|
|
options.push('option ' + i);
|
|
}
|
|
pollModule.handleNewPoll(fakeUser, {
|
|
title: 'test poll',
|
|
opts: options,
|
|
obscured: false
|
|
}, (ackResult) => {
|
|
assert.equal(ackResult.error.message, 'Polls are limited to a maximum of 50 options.');
|
|
});
|
|
});
|
|
|
|
it('handles a rejection with no ack provided by socket.io', () => {
|
|
fakeChannel.broadcastToRoom = (event, data, room) => {
|
|
assert(false, 'Expected no events to be sent');
|
|
};
|
|
fakeChannel.broadcastAll = (event) => {
|
|
assert(false, 'Expected no events to be sent');
|
|
};
|
|
let sentErrorMsg = false;
|
|
fakeUser.socket.emit = (event, data) => {
|
|
if (event === 'errorMsg') {
|
|
sentErrorMsg = true;
|
|
}
|
|
};
|
|
const options = [];
|
|
for (let i = 0; i < 200; i++) {
|
|
options.push('option ' + i);
|
|
}
|
|
pollModule.handleNewPoll(fakeUser, {
|
|
title: 'test poll',
|
|
opts: options,
|
|
obscured: false
|
|
});
|
|
assert(sentErrorMsg, 'Expected to send errorMsg since ack was missing');
|
|
});
|
|
})
|
|
});
|