diff --git a/src/topics/tags.js b/src/topics/tags.js index 192d5e8a26..88a8f3a69b 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -152,12 +152,15 @@ module.exports = function (Topics) { }; Topics.getTopicTags = async function (tid) { - return await db.getSetMembers('topic:' + tid + ':tags'); + const tags = await db.getSetMembers('topic:' + tid + ':tags'); + return tags.sort(); }; Topics.getTopicsTags = async function (tids) { const keys = tids.map(tid => 'topic:' + tid + ':tags'); - return await db.getSetsMembers(keys); + const tags = await db.getSetsMembers(keys); + tags.forEach(tags => tags.sort()); + return tags; }; Topics.getTopicTagsObjects = async function (tid) { @@ -192,6 +195,31 @@ module.exports = function (Topics) { return topicTags; }; + Topics.addTags = async function (tags, tids) { + const topicData = await Topics.getTopicsFields(tids, ['timestamp']); + const sets = tids.map(tid => 'topic:' + tid + ':tags'); + for (let i = 0; i < tags.length; i++) { + /* eslint-disable no-await-in-loop */ + await Promise.all([ + db.setsAdd(sets, tags[i]), + db.sortedSetAdd('tag:' + tags[i] + ':topics', topicData.map(t => t.timestamp), tids), + ]); + await updateTagCount(tags[i]); + } + }; + + Topics.removeTags = async function (tags, tids) { + const sets = tids.map(tid => 'topic:' + tid + ':tags'); + for (let i = 0; i < tags.length; i++) { + /* eslint-disable no-await-in-loop */ + await Promise.all([ + db.setsRemove(sets, tags[i]), + db.sortedSetRemove('tag:' + tags[i] + ':topics', tids), + ]); + await updateTagCount(tags[i]); + } + }; + Topics.updateTopicTags = async function (tid, tags) { await Topics.deleteTopicTags(tid); const timestamp = await Topics.getTopicField(tid, 'timestamp'); diff --git a/test/topics.js b/test/topics.js index 682ce72025..80380b5a3d 100644 --- a/test/topics.js +++ b/test/topics.js @@ -1753,6 +1753,19 @@ describe('Topic\'s', function () { }); }); }); + + it('should add and remove tags from topics properly', async () => { + const result = await topics.post({ uid: adminUid, tags: ['tag4', 'tag2', 'tag1', 'tag3'], title: 'tag topic', content: 'topic 1 content', cid: topic.categoryId }); + const tid = result.topicData.tid; + let tags = await topics.getTopicTags(tid); + assert.deepStrictEqual(tags, ['tag1', 'tag2', 'tag3', 'tag4']); + await topics.addTags(['tag7', 'tag6', 'tag5'], [tid]); + tags = await topics.getTopicTags(tid); + assert.deepStrictEqual(tags, ['tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6', 'tag7']); + await topics.removeTags(['tag1', 'tag3', 'tag5', 'tag7'], [tid]); + tags = await topics.getTopicTags(tid); + assert.deepStrictEqual(tags, ['tag2', 'tag4', 'tag6']); + }); }); describe('follow/unfollow', function () {