Skip to content

Commit 4b2103a

Browse files
authored
Merge pull request #11 from exo-do/features/testing-UserVotingPermissions
added tests and coverage for UserVotingPermissions
2 parents b3548c6 + 6902025 commit 4b2103a

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

0 commit comments

Comments
 (0)