1 const assert
= require('assert');
2 const { Poll
} = require('../lib/poll');
4 describe('Poll', () => {
5 describe('constructor', () => {
6 it('constructs a poll', () => {
7 let poll
= Poll
.create(
17 assert
.strictEqual(poll
.createdBy
, 'pollster');
18 assert
.strictEqual(poll
.title
, 'Which is better?');
19 assert
.deepStrictEqual(poll
.choices
, ['Coke', 'Pepsi']);
20 assert
.strictEqual(poll
.hideVotes
, false);
23 it('constructs a poll with hidden vote setting', () => {
24 let poll
= Poll
.create(
34 assert
.strictEqual(poll
.hideVotes
, true);
37 it('sanitizes title and choices', () => {
38 let poll
= Poll
.create(
40 'Which is better? <script></script>',
42 '<strong>Coke</strong>',
48 assert
.strictEqual(poll
.title
, 'Which is better? <script></script>');
49 assert
.deepStrictEqual(poll
.choices
, ['<strong>Coke</strong>', 'Pepsi']);
52 it('replaces URLs in title and choices', () => {
53 let poll
= Poll
.create(
55 'Which is better? https://example.com',
57 'Coke https://example.com',
65 'Which is better? <a href="https://example.com" target="_blank" rel="noopener noreferer">https://example.com</a>'
67 assert
.deepStrictEqual(
70 'Coke <a href="https://example.com" target="_blank" rel="noopener noreferer">https://example.com</a>',
77 describe('#countVote', () => {
91 it('counts a new vote', () => {
92 assert
.strictEqual(poll
.countVote('userA', 0), true);
93 assert
.strictEqual(poll
.countVote('userB', 1), true);
94 assert
.strictEqual(poll
.countVote('userC', 0), true);
96 let { counts
} = poll
.toUpdateFrame();
97 assert
.deepStrictEqual(counts
, [2, 1]);
100 it('does not count a revote for the same choice', () => {
101 assert
.strictEqual(poll
.countVote('userA', 0), true);
102 assert
.strictEqual(poll
.countVote('userA', 0), false);
104 let { counts
} = poll
.toUpdateFrame();
105 assert
.deepStrictEqual(counts
, [1, 0]);
108 it('changes a vote to a different choice', () => {
109 assert
.strictEqual(poll
.countVote('userA', 0), true);
110 assert
.strictEqual(poll
.countVote('userA', 1), true);
112 let { counts
} = poll
.toUpdateFrame();
113 assert
.deepStrictEqual(counts
, [0, 1]);
116 it('ignores out of range votes', () => {
117 assert
.strictEqual(poll
.countVote('userA', 1000), false);
118 assert
.strictEqual(poll
.countVote('userA', -10), false);
120 let { counts
} = poll
.toUpdateFrame();
121 assert
.deepStrictEqual(counts
, [0, 0]);
125 describe('#uncountVote', () => {
139 it('uncounts an existing vote', () => {
140 assert
.strictEqual(poll
.countVote('userA', 0), true);
141 assert
.strictEqual(poll
.uncountVote('userA', 0), true);
143 let { counts
} = poll
.toUpdateFrame();
144 assert
.deepStrictEqual(counts
, [0, 0]);
147 it('does not uncount if there is no existing vote', () => {
148 assert
.strictEqual(poll
.uncountVote('userA', 0), false);
150 let { counts
} = poll
.toUpdateFrame();
151 assert
.deepStrictEqual(counts
, [0, 0]);
155 describe('#toUpdateFrame', () => {
167 poll
.countVote('userA', 0);
168 poll
.countVote('userB', 1);
169 poll
.countVote('userC', 0);
172 it('generates an update frame', () => {
173 assert
.deepStrictEqual(
174 poll
.toUpdateFrame(),
176 title
: 'Which is better?',
177 options
: ['Coke', 'Pepsi'],
179 initiator
: 'pollster',
180 timestamp
: poll
.createdAt
.getTime()
185 it('hides votes when poll is hidden', () => {
186 poll
.hideVotes
= true;
188 assert
.deepStrictEqual(
189 poll
.toUpdateFrame(),
191 title
: 'Which is better?',
192 options
: ['Coke', 'Pepsi'],
194 initiator
: 'pollster',
195 timestamp
: poll
.createdAt
.getTime()
200 it('displays hidden votes when requested', () => {
201 poll
.hideVotes
= true;
203 assert
.deepStrictEqual(
204 poll
.toUpdateFrame(true),
206 title
: 'Which is better?',
207 options
: ['Coke', 'Pepsi'],
208 counts
: ['2?', '1?'],
209 initiator
: 'pollster',
210 timestamp
: poll
.createdAt
.getTime()
216 describe('#toChannelData/fromChannelData', () => {
217 it('round trips a poll', () => {
219 title
: '<strong>ready?</strong>',
221 options
: ['yes', 'no'],
224 '1.2.3.4': null, // Previous poll code would set removed votes to null
228 timestamp
: 1483414981110
231 let poll
= Poll
.fromChannelData(data
);
233 // New code does not store null votes
234 data
.votes
= { '5.6.7.8': 1 };
235 assert
.deepStrictEqual(poll
.toChannelData(), data
);
238 it('coerces a missing timestamp to the current time', () => {
240 title
: '<strong>ready?</strong>',
242 options
: ['yes', 'no'],
251 let now
= Date
.now();
252 let poll
= Poll
.fromChannelData(data
);
253 const { timestamp
} = poll
.toChannelData();
254 if (typeof timestamp
!== 'number' || isNaN(timestamp
))
255 assert
.fail(`Unexpected timestamp: ${timestamp}`);
257 if (Math
.abs(timestamp
- now
) > 1000)
258 assert
.fail(`Unexpected timestamp: ${timestamp}`);