Skip to content

Commit d267984

Browse files
committed
added tests and coverage for UserVotingPermissions
1 parent b3548c6 commit d267984

3 files changed

Lines changed: 385 additions & 1 deletion

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ node_modules
3232
/.project
3333

3434
package-lock.json
35+
36+
.nyc_output/

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,12 @@
2424
"nbbpm": {
2525
"compatibility": "^1.18.0"
2626
},
27-
"dependencies": {}
27+
"dependencies": {},
28+
"devDependencies": {
29+
"nyc": "^15.1.0",
30+
"sinon": "^11.1.2"
31+
},
32+
"scripts": {
33+
"test": "nyc --reporter=lcov --reporter=text-summary mocha"
34+
}
2835
}

test/UserVotingPermissions.test.js

Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
const assert = require('assert');
2+
const sinon = require('sinon');
3+
const UserVotingPermissions = require('../UserVotingPermissions');
4+
5+
describe('UserVotingPermissions', function() {
6+
describe('#hasEnoughPostsToUpvote()', function() {
7+
it('should not throw an error when postcount is greater than the configured min posts to upvote', async function() {
8+
let user = { postcount: 15 };
9+
let config = {
10+
minPostToUpvote: sinon.fake.returns(10)
11+
};
12+
13+
let permissions = new UserVotingPermissions(config, null, user, null);
14+
await permissions.hasEnoughPostsToUpvote();
15+
});
16+
17+
it('should throw an error when postcount is less than the configured min posts to upvote', async function() {
18+
let user = { postcount: 15 };
19+
let config = {
20+
minPostToUpvote: sinon.fake.returns(20)
21+
};
22+
23+
let permissions = new UserVotingPermissions(config, null, user, null);
24+
try {
25+
await permissions.hasEnoughPostsToUpvote();
26+
assert.fail('expected an error');
27+
} catch (err) {
28+
assert.strictEqual(err.reason, 'notEnoughPosts');
29+
}
30+
});
31+
});
32+
33+
describe('#isOldEnoughToUpvote()', function() {
34+
it('should not throw an error when user is old enough to upvote', async function() {
35+
let user = { joindate: fiveDaysAgo() };
36+
let config = {
37+
minDaysToUpvote: sinon.fake.returns(2)
38+
};
39+
40+
let permissions = new UserVotingPermissions(config, null, user, null);
41+
await permissions.isOldEnoughToUpvote();
42+
});
43+
44+
it('should throw an error when user is not old enough to upvote', async function() {
45+
let user = { joindate: fiveDaysAgo() };
46+
let config = {
47+
minDaysToUpvote: sinon.fake.returns(6)
48+
};
49+
50+
let permissions = new UserVotingPermissions(config, null, user, null);
51+
try {
52+
await permissions.isOldEnoughToUpvote();
53+
assert.fail('expected an error');
54+
} catch (err) {
55+
assert.strictEqual(err.reason, 'notOldEnough');
56+
}
57+
});
58+
});
59+
60+
describe('#hasVotedTooManyPostsInThread()', function() {
61+
it('should not throw an error when user has not voted too many times in thread', async function() {
62+
let user = { uid: 1 };
63+
let post = { tid: 123 };
64+
let config = {
65+
maxVotesPerUserInThread: sinon.fake.returns(3),
66+
getPerThreadLogId: sinon.fake.returns('dummyVoteIdentifier')
67+
};
68+
let db = {
69+
getSetMembers: sinon.fake.returns(['vote1', 'vote2'])
70+
}
71+
72+
let permissions = new UserVotingPermissions(config, db, user, post);
73+
await permissions.hasVotedTooManyPostsInThread();
74+
});
75+
76+
it('should throw an error when user has voted too many times in thread', async function() {
77+
let user = { uid: 1 };
78+
let post = { tid: 123 };
79+
let config = {
80+
maxVotesPerUserInThread: sinon.fake.returns(3),
81+
getPerThreadLogId: sinon.fake.returns('dummyVoteIdentifier')
82+
};
83+
let db = {
84+
getSetMembers: sinon.fake.returns(['vote1', 'vote2', 'vote3'])
85+
}
86+
87+
let permissions = new UserVotingPermissions(config, db, user, post);
88+
try {
89+
await permissions.hasVotedTooManyPostsInThread();
90+
assert.fail('expected an error');
91+
} catch (err) {
92+
assert.strictEqual(err.reason, 'tooManyVotesInThread');
93+
}
94+
});
95+
});
96+
97+
describe('#hasVotedAuthorTooManyTimesThisMonth()', function() {
98+
it('should not throw an error when user has not voted too many times for this author this month', async function() {
99+
let user = { uid: 1 };
100+
let post = { tid: 123 };
101+
let config = {
102+
maxVotesToSameUserInMonth: sinon.fake.returns(10),
103+
getPerAuthorLogId: sinon.fake.returns('dummyVoteIdentifier')
104+
};
105+
let db = {
106+
getSetMembers: sinon.fake.returns(['vote1', 'vote2'])
107+
}
108+
109+
let permissions = new UserVotingPermissions(config, db, user, post);
110+
await permissions.hasVotedAuthorTooManyTimesThisMonth();
111+
});
112+
113+
it('should throw an error when user has voted too many times for this author this month', async function() {
114+
let user = { uid: 1 };
115+
let post = { tid: 123 };
116+
let config = {
117+
maxVotesToSameUserInMonth: sinon.fake.returns(10),
118+
getPerAuthorLogId: sinon.fake.returns('dummyVoteIdentifier')
119+
};
120+
let db = {
121+
getSetMembers: sinon.fake.returns(['vote1', 'vote2', 'vote3', 'vote4', 'vote5', 'vote6', 'vote7', 'vote8', 'vote9', 'vote10'])
122+
}
123+
124+
let permissions = new UserVotingPermissions(config, db, user, post);
125+
try {
126+
await permissions.hasVotedAuthorTooManyTimesThisMonth();
127+
assert.fail('expected an error');
128+
} catch (err) {
129+
assert.strictEqual(err.reason, 'tooManyVotesToSameUserThisMonth');
130+
}
131+
});
132+
});
133+
134+
describe('#hasVotedTooManyTimesToday()', function() {
135+
it('should not throw an error when user has not voted too many times today', async function() {
136+
let user = { uid: 1 };
137+
let config = {
138+
maxVotesPerUser: sinon.fake.returns(5),
139+
getPerUserLogId: sinon.fake.returns('dummyVoteIdentifier')
140+
};
141+
let db = {
142+
getSetMembers: sinon.fake.returns(['vote1', 'vote2'])
143+
}
144+
145+
let permissions = new UserVotingPermissions(config, db, user, null);
146+
await permissions.hasVotedTooManyTimesToday();
147+
});
148+
149+
it('should throw an error when user has voted too many times today', async function() {
150+
let user = { uid: 1 };
151+
let config = {
152+
maxVotesPerUser: sinon.fake.returns(5),
153+
getPerUserLogId: sinon.fake.returns('dummyVoteIdentifier')
154+
};
155+
let db = {
156+
getSetMembers: sinon.fake.returns(['vote1', 'vote2', 'vote3', 'vote4', 'vote5'])
157+
}
158+
159+
let permissions = new UserVotingPermissions(config, db, user, null);
160+
try {
161+
await permissions.hasVotedTooManyTimesToday();
162+
assert.fail('expected an error');
163+
} catch (err) {
164+
assert.strictEqual(err.reason, 'tooManyVotesToday');
165+
}
166+
});
167+
});
168+
169+
describe('#hasEnoughPostsToDownvote()', function() {
170+
it('should not throw an error when postcount is greater than the configured min posts to downvote', async function() {
171+
let user = { postcount: 15 };
172+
let config = {
173+
minPostToDownvote: sinon.fake.returns(10)
174+
};
175+
176+
let permissions = new UserVotingPermissions(config, null, user, null);
177+
await permissions.hasEnoughPostsToDownvote();
178+
});
179+
180+
it('should throw an error when postcount is less than the configured min posts to downvote', async function() {
181+
let user = { postcount: 15 };
182+
let config = {
183+
minPostToDownvote: sinon.fake.returns(20)
184+
};
185+
186+
let permissions = new UserVotingPermissions(config, null, user, null);
187+
try {
188+
await permissions.hasEnoughPostsToDownvote();
189+
assert.fail('expected an error');
190+
} catch (err) {
191+
assert.strictEqual(err.reason, 'notEnoughPosts');
192+
}
193+
});
194+
});
195+
196+
describe('#isOldEnoughToDownvote()', function() {
197+
it('should not throw an error when user is old enough to downvote', async function() {
198+
let user = { joindate: fiveDaysAgo() };
199+
let config = {
200+
minDaysToDownvote: sinon.fake.returns(2)
201+
};
202+
203+
let permissions = new UserVotingPermissions(config, null, user, null);
204+
await permissions.isOldEnoughToDownvote();
205+
});
206+
207+
it('should throw an error when user is not old enough to downvote', async function() {
208+
let user = { joindate: fiveDaysAgo() };
209+
let config = {
210+
minDaysToDownvote: sinon.fake.returns(6)
211+
};
212+
213+
let permissions = new UserVotingPermissions(config, null, user, null);
214+
try {
215+
await permissions.isOldEnoughToDownvote();
216+
assert.fail('expected an error');
217+
} catch (err) {
218+
assert.strictEqual(err.reason, 'notOldEnough');
219+
}
220+
});
221+
});
222+
223+
describe('#hasEnoughReputationToDownvote()', function() {
224+
it('should not throw an error when reputation is greater than the configured min to downvote', async function() {
225+
let user = { reputation: 15 };
226+
let config = {
227+
minReputationToDownvote: sinon.fake.returns(10)
228+
};
229+
230+
let permissions = new UserVotingPermissions(config, null, user, null);
231+
await permissions.hasEnoughReputationToDownvote();
232+
});
233+
234+
it('should throw an error when reputation is less than the configured min to downvote', async function() {
235+
let user = { reputation: 15 };
236+
let config = {
237+
minReputationToDownvote: sinon.fake.returns(20)
238+
};
239+
240+
let permissions = new UserVotingPermissions(config, null, user, null);
241+
try {
242+
await permissions.hasEnoughReputationToDownvote();
243+
assert.fail('expected an error');
244+
} catch (err) {
245+
assert.strictEqual(err.reason, 'notEnoughReputation');
246+
}
247+
});
248+
});
249+
250+
describe('#votingAllowedInCategory()', function() {
251+
it('should not throw an error when voting is allowed in category', async function() {
252+
let post = { cid: 456 };
253+
let config = {
254+
getDisabledCategories: sinon.fake.returns([])
255+
};
256+
257+
let permissions = new UserVotingPermissions(config, null, null, post);
258+
await permissions.votingAllowedInCategory();
259+
});
260+
261+
it('should throw an error when voting is disabled in category', async function() {
262+
let post = { cid: 456 };
263+
let config = {
264+
getDisabledCategories: sinon.fake.returns([123, 456])
265+
};
266+
267+
let permissions = new UserVotingPermissions(config, null, null, post);
268+
try {
269+
await permissions.votingAllowedInCategory();
270+
assert.fail('expected an error');
271+
} catch (err) {
272+
assert.strictEqual(err.reason, 'votingDisabledInCategory');
273+
}
274+
});
275+
});
276+
277+
describe('#postIsNotTooOld()', function() {
278+
it('should not throw an error when post is not too old', async function() {
279+
let post = { timestamp: fiveDaysAgo() };
280+
let config = {
281+
getMaxPostAgeDays: sinon.fake.returns(30)
282+
};
283+
284+
let permissions = new UserVotingPermissions(config, null, null, post);
285+
await permissions.postIsNotTooOld();
286+
});
287+
288+
it('should throw an error when post is too old', async function() {
289+
let post = { timestamp: sixtyDaysAgo() };
290+
let config = {
291+
getMaxPostAgeDays: sinon.fake.returns(30)
292+
};
293+
294+
let permissions = new UserVotingPermissions(config, null, null, post);
295+
try {
296+
await permissions.postIsNotTooOld();
297+
assert.fail('expected an error');
298+
} catch (err) {
299+
assert.strictEqual(err.reason, 'postTooOld');
300+
}
301+
});
302+
303+
it('should not throw an error when disabled (set to zero)', async function() {
304+
let post = { timestamp: sixtyDaysAgo() };
305+
let config = {
306+
getMaxPostAgeDays: sinon.fake.returns(0)
307+
};
308+
309+
let permissions = new UserVotingPermissions(config, null, null, post);
310+
await permissions.postIsNotTooOld();
311+
});
312+
});
313+
314+
describe('#hasDownvotedTooManyTimesToday()', function() {
315+
it('should not throw an error when user has not downvoted too many times today', async function() {
316+
let user = { reputation: 15 };
317+
let config = {
318+
maxDownvotesPerDay: sinon.fake.returns(5),
319+
getPerUserAndTypeLogId: sinon.fake.returns('dummyVoteIdentifier')
320+
};
321+
let db = {
322+
getSetMembers: sinon.fake.returns([])
323+
}
324+
325+
let permissions = new UserVotingPermissions(config, db, user, null);
326+
await permissions.hasDownvotedTooManyTimesToday();
327+
});
328+
329+
it('should throw an error when user has downvoted too many times today', async function() {
330+
let user = { reputation: 15 };
331+
let config = {
332+
maxDownvotesPerDay: sinon.fake.returns(5),
333+
getPerUserAndTypeLogId: sinon.fake.returns('dummyVoteIdentifier')
334+
};
335+
let db = {
336+
getSetMembers: sinon.fake.returns(['vote1', 'vote2', 'vote3', 'vote4', 'vote5'])
337+
}
338+
339+
let permissions = new UserVotingPermissions(config, db, user, null);
340+
try {
341+
await permissions.hasDownvotedTooManyTimesToday();
342+
assert.fail('expected an error');
343+
} catch (err) {
344+
assert.strictEqual(err.reason, 'tooManyDownvotesToday');
345+
}
346+
});
347+
348+
it('should not throw an error when disabled (set to zero)', async function() {
349+
let user = { reputation: 15 };
350+
let config = {
351+
maxDownvotesPerDay: sinon.fake.returns(0),
352+
getPerUserAndTypeLogId: sinon.fake.returns('dummyVoteIdentifier')
353+
};
354+
let db = {
355+
getSetMembers: sinon.fake.returns(['vote1', 'vote2', 'vote3', 'vote4', 'vote5'])
356+
}
357+
358+
let permissions = new UserVotingPermissions(config, db, user, null);
359+
await permissions.hasDownvotedTooManyTimesToday();
360+
});
361+
});
362+
});
363+
364+
function fiveDaysAgo() {
365+
return daysAgo(5);
366+
}
367+
368+
function sixtyDaysAgo() {
369+
return daysAgo(60);
370+
}
371+
372+
function daysAgo(days) {
373+
let now = new Date();
374+
return now.getTime() - days * 24 * 60 * 60 * 1000;
375+
}

0 commit comments

Comments
 (0)