From 0927d54c9877f8b024abd167121602b0e4aff2a5 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 14 Dec 2016 15:53:57 -0500 Subject: [PATCH] ability to filter flags by cid, #5232, more tests --- public/language/en-GB/flags.json | 2 ++ src/controllers/mods.js | 13 ++++++-- src/flags.js | 32 +++++++++++++++--- test/flags.js | 57 ++++++++++++++++++++++++++++---- 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/public/language/en-GB/flags.json b/public/language/en-GB/flags.json index f1fd71bf27..2a1bf919f8 100644 --- a/public/language/en-GB/flags.json +++ b/public/language/en-GB/flags.json @@ -19,7 +19,9 @@ "filter-type-post": "Post", "filter-state": "State", "filter-assignee": "Assignee UID", + "filter-cid": "Category", "filter-quick-mine": "Assigned to me", + "filter-cid-all": "All categories", "apply-filters": "Apply Filters", "quick-links": "Quick Links", diff --git a/src/controllers/mods.js b/src/controllers/mods.js index 666f449316..cae9ade1ed 100644 --- a/src/controllers/mods.js +++ b/src/controllers/mods.js @@ -3,6 +3,7 @@ var async = require('async'); var user = require('../user'); +var categories = require('../categories'); var flags = require('../flags'); var analytics = require('../analytics'); @@ -26,7 +27,7 @@ modsController.flags.list = function (req, res, next) { } // Parse query string params for filters - var valid = ['assignee', 'state', 'reporterId', 'type', 'targetUid', 'quick']; + var valid = ['assignee', 'state', 'reporterId', 'type', 'targetUid', 'cid', 'quick']; var filters = valid.reduce(function (memo, cur) { if (req.query.hasOwnProperty(cur)) { memo[cur] = req.query[cur]; @@ -37,15 +38,23 @@ modsController.flags.list = function (req, res, next) { async.parallel({ flags: async.apply(flags.list, filters, req.uid), - analytics: async.apply(analytics.getDailyStatsForSet, 'analytics:flags', Date.now(), 30) + analytics: async.apply(analytics.getDailyStatsForSet, 'analytics:flags', Date.now(), 30), + categories: async.apply(categories.buildForSelect, req.uid) }, function (err, data) { if (err) { return next(err); } + // Minimal returned set for templates.js + data.categories = data.categories.reduce(function (memo, cur) { + memo[cur.cid] = cur.name; + return memo; + }, {}); + res.render('flags/list', { flags: data.flags, analytics: data.analytics, + categories: data.categories, hasFilter: !!Object.keys(filters).length, filters: filters, title: '[[pages:flags]]' diff --git a/src/flags.js b/src/flags.js index 995e880801..81b97ee408 100644 --- a/src/flags.js +++ b/src/flags.js @@ -71,11 +71,15 @@ Flags.list = function (filters, uid, callback) { case 'assignee': sets.push('flags:byAssignee:' + filters[type]); break; - + case 'targetUid': sets.push('flags:byTargetUid:' + filters[type]); break; + case 'cid': + sets.push('flags:byCid:' + filters[type]); + break; + case 'quick': switch (filters.quick) { case 'mine': @@ -262,6 +266,7 @@ Flags.getNotes = function (flagId, callback) { Flags.create = function (type, id, uid, reason, timestamp, callback) { var targetUid; + var targetCid; var doHistoryAppend = false; // timestamp is optional @@ -273,17 +278,21 @@ Flags.create = function (type, id, uid, reason, timestamp, callback) { async.waterfall([ function (next) { - // Sanity checks async.parallel([ + // Sanity checks async.apply(Flags.exists, type, id, uid), async.apply(Flags.targetExists, type, id), - async.apply(Flags.getTargetUid, type, id) + + // Extra data for zset insertion + async.apply(Flags.getTargetUid, type, id), + async.apply(Flags.getTargetCid, type, id) ], function (err, checks) { if (err) { return next(err); } targetUid = checks[2] || null; + targetCid = checks[3] || null; if (checks[0]) { return next(new Error('[[error:already-flagged]]')); @@ -315,6 +324,9 @@ Flags.create = function (type, id, uid, reason, timestamp, callback) { if (targetUid) { tasks.push(async.apply(db.sortedSetAdd.bind(db), 'flags:byTargetUid:' + targetUid, timestamp, flagId)); // by target uid } + if (targetCid) { + tasks.push(async.apply(db.sortedSetAdd.bind(db), 'flags:byCid:' + targetCid, timestamp, flagId)); // by target uid + } async.parallel(tasks, function (err, data) { if (err) { @@ -358,12 +370,24 @@ Flags.getTargetUid = function (type, id, callback) { posts.getPostField(id, 'uid', callback); break; - case 'user': + default: setImmediate(callback, null, id); break; } }; +Flags.getTargetCid = function (type, id, callback) { + switch (type) { + case 'post': + posts.getCidByPid(id, callback); + break; + + default: + setImmediate(callback, null, id); + break; + } +}; + Flags.update = function (flagId, uid, changeset, callback) { // Retrieve existing flag data to compare for history-saving purposes var fields = ['state', 'assignee']; diff --git a/test/flags.js b/test/flags.js index 607b807db3..c46ac0bcef 100644 --- a/test/flags.js +++ b/test/flags.js @@ -72,6 +72,14 @@ describe('Flags', function () { done(); }); }); + + it('should add the flag to the byCid zset for category 1 if it is of type post', function (done) { + db.isSortedSetMember('flags:byCid:' + 1, 1, function (err, isMember) { + assert.ifError(err); + assert.ok(isMember); + done(); + }); + }); }); describe('.get()', function () { @@ -115,12 +123,49 @@ describe('Flags', function () { }); }); - it('should return a filtered list of flags if said filters are passed in', function (done) { - Flags.list({ - state: 'open' - }, 1, function (err, flags) { - assert.ifError(err); - done(); + describe('(with filters)', function () { + it('should return a filtered list of flags if said filters are passed in', function (done) { + Flags.list({ + state: 'open' + }, 1, function (err, flags) { + assert.ifError(err); + assert.ok(Array.isArray(flags)); + assert.strictEqual(1, flags[0].flagId); + done(); + }); + }); + + it('should return no flags if a filter with no matching flags is used', function (done) { + Flags.list({ + state: 'rejected' + }, 1, function (err, flags) { + assert.ifError(err); + assert.ok(Array.isArray(flags)); + assert.strictEqual(0, flags.length); + done(); + }); + }); + + it('should return a flag when filtered by cid 1', function (done) { + Flags.list({ + cid: 1 + }, 1, function (err, flags) { + assert.ifError(err); + assert.ok(Array.isArray(flags)); + assert.strictEqual(1, flags.length); + done(); + }); + }); + + it('shouldn\'t return a flag when filtered by cid 2', function (done) { + Flags.list({ + cid: 2 + }, 1, function (err, flags) { + assert.ifError(err); + assert.ok(Array.isArray(flags)); + assert.strictEqual(0, flags.length); + done(); + }); }); }); });