mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 20:16:04 +01:00
additional tests and proper handling for purged flag targets, #5232
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
"assignee": "Assignee",
|
"assignee": "Assignee",
|
||||||
"update": "Update",
|
"update": "Update",
|
||||||
"updated": "Updated",
|
"updated": "Updated",
|
||||||
|
"target-purged": "The content this flag referred to has been purged and is no longer available.",
|
||||||
|
|
||||||
"quick-filters": "Quick Filters",
|
"quick-filters": "Quick Filters",
|
||||||
"filter-active": "There are one or more filters active in this list of flags",
|
"filter-active": "There are one or more filters active in this list of flags",
|
||||||
|
|||||||
@@ -78,8 +78,13 @@ modsController.flags.detail = function (req, res, next) {
|
|||||||
|
|
||||||
res.render('flags/detail', Object.assign(results.flagData, {
|
res.render('flags/detail', Object.assign(results.flagData, {
|
||||||
assignees: results.assignees,
|
assignees: results.assignees,
|
||||||
type_bool: ['post', 'user'].reduce(function (memo, cur) {
|
type_bool: ['post', 'user', 'empty'].reduce(function (memo, cur) {
|
||||||
memo[cur] = results.flagData.type === cur;
|
if (cur !== 'empty') {
|
||||||
|
memo[cur] = results.flagData.type === cur && !!Object.keys(results.flagData.target).length;
|
||||||
|
} else {
|
||||||
|
memo[cur] = !Object.keys(results.flagData.target).length;
|
||||||
|
}
|
||||||
|
|
||||||
return memo;
|
return memo;
|
||||||
}, {}),
|
}, {}),
|
||||||
title: '[[pages:flag-details, ' + req.params.flagId + ']]'
|
title: '[[pages:flag-details, ' + req.params.flagId + ']]'
|
||||||
|
|||||||
60
src/flags.js
60
src/flags.js
@@ -202,31 +202,6 @@ Flags.validate = function (payload, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Flags.getTarget = function (type, id, uid, callback) {
|
|
||||||
switch (type) {
|
|
||||||
case 'post':
|
|
||||||
async.waterfall([
|
|
||||||
async.apply(posts.getPostsByPids, [id], uid),
|
|
||||||
function (posts, next) {
|
|
||||||
topics.addPostData(posts, uid, next);
|
|
||||||
}
|
|
||||||
], function (err, posts) {
|
|
||||||
callback(err, posts[0]);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'user':
|
|
||||||
user.getUsersData([id], function (err, users) {
|
|
||||||
callback(err, users ? users[0] : undefined);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
callback(new Error('[[error:invalid-data]]'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Flags.getNotes = function (flagId, callback) {
|
Flags.getNotes = function (flagId, callback) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
async.apply(db.getSortedSetRevRangeWithScores.bind(db), 'flag:' + flagId + ':notes', 0, -1),
|
async.apply(db.getSortedSetRevRangeWithScores.bind(db), 'flag:' + flagId + ':notes', 0, -1),
|
||||||
@@ -348,6 +323,41 @@ Flags.exists = function (type, id, uid, callback) {
|
|||||||
db.isSortedSetMember('flags:hash', [type, id, uid].join(':'), callback);
|
db.isSortedSetMember('flags:hash', [type, id, uid].join(':'), callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Flags.getTarget = function (type, id, uid, callback) {
|
||||||
|
async.waterfall([
|
||||||
|
async.apply(Flags.targetExists, type, id),
|
||||||
|
function (exists, next) {
|
||||||
|
if (exists) {
|
||||||
|
switch (type) {
|
||||||
|
case 'post':
|
||||||
|
async.waterfall([
|
||||||
|
async.apply(posts.getPostsByPids, [id], uid),
|
||||||
|
function (posts, next) {
|
||||||
|
topics.addPostData(posts, uid, next);
|
||||||
|
}
|
||||||
|
], function (err, posts) {
|
||||||
|
next(err, posts[0]);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'user':
|
||||||
|
user.getUsersData([id], function (err, users) {
|
||||||
|
next(err, users ? users[0] : undefined);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
next(new Error('[[error:invalid-data]]'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Target used to exist (otherwise flag creation'd fail), but no longer
|
||||||
|
next(null, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
Flags.targetExists = function (type, id, callback) {
|
Flags.targetExists = function (type, id, callback) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'post':
|
case 'post':
|
||||||
|
|||||||
@@ -144,9 +144,6 @@ module.exports = function (Posts) {
|
|||||||
},
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
db.sortedSetsRemove(['posts:pid', 'posts:flagged'], pid, next);
|
db.sortedSetsRemove(['posts:pid', 'posts:flagged'], pid, next);
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
flags.dismiss(pid, next);
|
|
||||||
}
|
}
|
||||||
], function (err) {
|
], function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -455,53 +455,6 @@ Upgrade.upgrade = function (callback) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function (next) {
|
|
||||||
thisSchemaDate = Date.UTC(2016, 3, 29);
|
|
||||||
|
|
||||||
if (schemaDate < thisSchemaDate) {
|
|
||||||
updatesMade = true;
|
|
||||||
winston.info('[2016/04/29] Dismiss flags from deleted topics');
|
|
||||||
|
|
||||||
var posts = require('./posts');
|
|
||||||
var topics = require('./topics');
|
|
||||||
var flags = require('./flags');
|
|
||||||
|
|
||||||
var pids, tids;
|
|
||||||
|
|
||||||
async.waterfall([
|
|
||||||
async.apply(db.getSortedSetRange, 'posts:flagged', 0, -1),
|
|
||||||
function (_pids, next) {
|
|
||||||
pids = _pids;
|
|
||||||
posts.getPostsFields(pids, ['tid'], next);
|
|
||||||
},
|
|
||||||
function (_tids, next) {
|
|
||||||
tids = _tids.map(function (a) {
|
|
||||||
return a.tid;
|
|
||||||
});
|
|
||||||
|
|
||||||
topics.getTopicsFields(tids, ['deleted'], next);
|
|
||||||
},
|
|
||||||
function (state, next) {
|
|
||||||
var toDismiss = state.map(function (a, idx) {
|
|
||||||
return parseInt(a.deleted, 10) === 1 ? pids[idx] : null;
|
|
||||||
}).filter(Boolean);
|
|
||||||
|
|
||||||
winston.info('[2016/04/29] ' + toDismiss.length + ' dismissable flags found');
|
|
||||||
async.each(toDismiss, flags.dismiss, next);
|
|
||||||
}
|
|
||||||
], function (err) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
winston.info('[2016/04/29] Dismiss flags from deleted topics done');
|
|
||||||
Upgrade.update(thisSchemaDate, next);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
winston.info('[2016/04/29] Dismiss flags from deleted topics skipped!');
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function (next) {
|
function (next) {
|
||||||
thisSchemaDate = Date.UTC(2016, 4, 28);
|
thisSchemaDate = Date.UTC(2016, 4, 28);
|
||||||
|
|
||||||
|
|||||||
@@ -56,14 +56,4 @@ module.exports = function (User) {
|
|||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
User.resetFlags = function (uids, callback) {
|
|
||||||
if (!Array.isArray(uids) || !uids.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
async.eachSeries(uids, function (uid, next) {
|
|
||||||
flags.dismissByUid(uid, next);
|
|
||||||
}, callback);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -82,6 +82,42 @@ describe('Flags', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('.exists()', function () {
|
||||||
|
it('should return Boolean True if a flag matching the flag hash already exists', function (done) {
|
||||||
|
Flags.exists('post', 1, 1, function (err, exists) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(true, exists);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return Boolean False if a flag matching the flag hash does not already exists', function (done) {
|
||||||
|
Flags.exists('post', 1, 2, function (err, exists) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(false, exists);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.targetExists()', function () {
|
||||||
|
it('should return Boolean True if the targeted element exists', function (done) {
|
||||||
|
Flags.targetExists('post', 1, function (err, exists) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(true, exists);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return Boolean False if the targeted element does not exist', function (done) {
|
||||||
|
Flags.targetExists('post', 15, function (err, exists) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(false, exists);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('.get()', function () {
|
describe('.get()', function () {
|
||||||
it('should retrieve and display a flag\'s data', function (done) {
|
it('should retrieve and display a flag\'s data', function (done) {
|
||||||
Flags.get(1, function (err, flagData) {
|
Flags.get(1, function (err, flagData) {
|
||||||
@@ -252,6 +288,14 @@ describe('Flags', function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return a plain object with no properties if the target no longer exists', function (done) {
|
||||||
|
Flags.getTarget('user', 15, 1, function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(0, Object.keys(data).length);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('.validate()', function () {
|
describe('.validate()', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user