diff --git a/public/language/en-GB/admin/manage/tags.json b/public/language/en-GB/admin/manage/tags.json index 3976ea97d7..01363dfda0 100644 --- a/public/language/en-GB/admin/manage/tags.json +++ b/public/language/en-GB/admin/manage/tags.json @@ -2,7 +2,6 @@ "none": "Your forum does not have any topics with tags yet.", "bg-color": "Background Colour", "text-color": "Text Colour", - "create-modify": "Create & Modify Tags", "description": "Select tags by clicking or dragging, use CTRL to select multiple tags.", "create": "Create Tag", "modify": "Modify Tags", diff --git a/public/src/admin/manage/tags.js b/public/src/admin/manage/tags.js index 512e0732d7..6cb4ad96f6 100644 --- a/public/src/admin/manage/tags.js +++ b/public/src/admin/manage/tags.js @@ -13,7 +13,6 @@ define('admin/manage/tags', [ handleCreate(); handleSearch(); - handleModify(); handleRename(); handleDeleteSelected(); }; @@ -82,54 +81,6 @@ define('admin/manage/tags', [ }); } - function handleModify() { - $('#modify').on('click', function () { - var tagsToModify = $('.tag-row.ui-selected'); - if (!tagsToModify.length) { - return; - } - - var firstTag = $(tagsToModify[0]); - bootbox.dialog({ - title: '[[admin/manage/tags:alerts.editing]]', - message: firstTag.find('.tag-modal').html(), - buttons: { - success: { - label: 'Save', - className: 'btn-primary save', - callback: function () { - var modal = $('.bootbox'); - var resetColors = modal.find('#reset-colors').is(':checked'); - var bgColor = resetColors ? '' : modal.find('[data-name="bgColor"]').val(); - var color = resetColors ? '' : modal.find('[data-name="color"]').val(); - - var data = []; - tagsToModify.each(function (idx, tag) { - tag = $(tag); - data.push({ - value: tag.attr('data-tag'), - color: color, - bgColor: bgColor, - }); - - tag.find('[data-name="bgColor"]').val(bgColor); - tag.find('[data-name="color"]').val(color); - tag.find('.tag-item').css('background-color', bgColor).css('color', color); - }); - - socket.emit('admin.tags.update', data, function (err) { - if (err) { - return app.alertError(err.message); - } - app.alertSuccess('[[admin/manage/tags:alerts.update-success]]'); - }); - }, - }, - }, - }); - }); - } - function handleRename() { $('#rename').on('click', function () { var tagsToModify = $('.tag-row.ui-selected'); diff --git a/src/controllers/write/topics.js b/src/controllers/write/topics.js index 4132b79b9e..19b3eb3172 100644 --- a/src/controllers/write/topics.js +++ b/src/controllers/write/topics.js @@ -89,8 +89,11 @@ Topics.addTags = async (req, res) => { if (!await privileges.topics.canEdit(req.params.tid, req.user.uid)) { return helpers.formatApiResponse(403, res); } + const cid = await topics.getTopicField(req.params.tid, 'cid'); + await topics.validateTags(req.body.tags, cid, req.user.uid, req.params.tid); + const tags = await topics.filterTags(req.body.tags); - await topics.createTags(req.body.tags, req.params.tid, Date.now()); + await topics.addTags(tags, [req.params.tid]); helpers.formatApiResponse(200, res); }; diff --git a/src/privileges/admin.js b/src/privileges/admin.js index 4a908e37bd..ead7f6fc5e 100644 --- a/src/privileges/admin.js +++ b/src/privileges/admin.js @@ -93,7 +93,6 @@ privsAdmin.socketMap = { 'admin.user.invite': 'admin:users', 'admin.tags.create': 'admin:tags', - 'admin.tags.update': 'admin:tags', 'admin.tags.rename': 'admin:tags', 'admin.tags.deleteTags': 'admin:tags', diff --git a/src/search.js b/src/search.js index 7ef8eb8062..99fae633e8 100644 --- a/src/search.js +++ b/src/search.js @@ -155,18 +155,15 @@ async function getUsers(uids, data) { async function getTopics(tids, data) { const topicsData = await topics.getTopicsData(tids); const cids = _.uniq(topicsData.map(topic => topic && topic.cid)); - const [categories, tags] = await Promise.all([ - getCategories(cids, data), - getTags(tids, data), - ]); + const categories = await getCategories(cids, data); const cidToCategory = _.zipObject(cids, categories); - topicsData.forEach((topic, index) => { + topicsData.forEach((topic) => { if (topic && categories && cidToCategory[topic.cid]) { topic.category = cidToCategory[topic.cid]; } - if (topic && tags && tags[index]) { - topic.tags = tags[index]; + if (topic && topic.tags) { + topic.tags = topic.tags.map(tag => tag.value); } }); @@ -186,13 +183,6 @@ async function getCategories(cids, data) { return await db.getObjectsFields(cids.map(cid => `category:${cid}`), categoryFields); } -async function getTags(tids, data) { - if (Array.isArray(data.hasTags) && data.hasTags.length) { - return await topics.getTopicsTags(tids); - } - return null; -} - function filterByPostcount(posts, postCount, repliesFilter) { postCount = parseInt(postCount, 10); if (postCount) { diff --git a/src/socket.io/admin/tags.js b/src/socket.io/admin/tags.js index 698c303224..cc67c017d1 100644 --- a/src/socket.io/admin/tags.js +++ b/src/socket.io/admin/tags.js @@ -12,14 +12,6 @@ Tags.create = async function (socket, data) { await topics.createEmptyTag(data.tag); }; -Tags.update = async function (socket, data) { - if (!Array.isArray(data)) { - throw new Error('[[error:invalid-data]]'); - } - - await topics.updateTags(data); -}; - Tags.rename = async function (socket, data) { if (!Array.isArray(data)) { throw new Error('[[error:invalid-data]]'); diff --git a/src/topics/create.js b/src/topics/create.js index a4b2c9ecac..666d203648 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -34,6 +34,11 @@ module.exports = function (Topics) { postcount: 0, viewcount: 0, }; + + if (Array.isArray(data.tags) && data.tags.length) { + topicData.tags = data.tags.join(','); + } + const result = await plugins.hooks.fire('filter:topic.create', { topic: topicData, data: data }); topicData = result.topic; await db.setObject(`topic:${topicData.tid}`, topicData); @@ -79,6 +84,7 @@ module.exports = function (Topics) { } Topics.checkTitle(data.title); await Topics.validateTags(data.tags, data.cid, uid); + data.tags = await Topics.filterTags(data.tags, data.cid); Topics.checkContent(data.content); const [categoryExists, canCreate, canTag] = await Promise.all([ diff --git a/src/topics/data.js b/src/topics/data.js index db13036176..50acd0615b 100644 --- a/src/topics/data.js +++ b/src/topics/data.js @@ -126,4 +126,12 @@ function modifyTopic(topic, fields) { if (fields.includes('teaserPid') || !fields.length) { topic.teaserPid = topic.teaserPid || null; } + + if (fields.includes('tags') || !fields.length) { + const tags = String(topic.tags || ''); + topic.tags = tags.split(',').filter(Boolean).map(tag => ({ + value: tag, + valueEscaped: validator.escape(String(tag)), + })); + } } diff --git a/src/topics/index.js b/src/topics/index.js index 92a74fa1bc..85f9aefb49 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -116,9 +116,8 @@ Topics.getTopicsByTids = async function (tids, options) { }; } - const [result, tags, hasRead, isIgnored, bookmarks, callerSettings] = await Promise.all([ + const [result, hasRead, isIgnored, bookmarks, callerSettings] = await Promise.all([ loadTopics(), - Topics.getTopicsTagsObjects(tids), Topics.hasReadTopics(tids, uid), Topics.isIgnoring(tids, uid), Topics.getUserBookmarks(tids, uid), @@ -136,8 +135,6 @@ Topics.getTopicsByTids = async function (tids, options) { topic.user.displayname = topic.user.username; } topic.teaser = result.teasers[i] || null; - topic.tags = tags[i]; - topic.isOwner = topic.uid === parseInt(uid, 10); topic.ignored = isIgnored[i]; topic.unread = parseInt(uid, 10) > 0 && !hasRead[i] && !isIgnored[i]; @@ -180,7 +177,7 @@ Topics.getTopicWithPosts = async function (topicData, set, uid, start, stop, rev social.getActivePostSharing(), getDeleter(topicData), getMerger(topicData), - getRelated(topicData, uid), + Topics.getRelatedTopics(topicData, uid), Topics.thumbs.load([topicData]), Topics.events.get(topicData.tid, uid), ]); @@ -268,12 +265,6 @@ async function getMerger(topicData) { return merger; } -async function getRelated(topicData, uid) { - const tags = await Topics.getTopicTagsObjects(topicData.tid); - topicData.tags = tags; - return await Topics.getRelatedTopics(topicData, uid); -} - Topics.getMainPost = async function (tid, uid) { const mainPosts = await Topics.getMainPosts([tid], uid); return Array.isArray(mainPosts) && mainPosts.length ? mainPosts[0] : null; diff --git a/src/topics/tags.js b/src/topics/tags.js index 5407ebdeb4..f47dc2aad5 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -19,23 +19,23 @@ module.exports = function (Topics) { if (!Array.isArray(tags) || !tags.length) { return; } - const result = await plugins.hooks.fire('filter:tags.filter', { tags: tags, tid: tid }); - tags = _.uniq(result.tags) - .map(tag => utils.cleanUpTag(tag, meta.config.maximumTagLength)) - .filter(tag => tag && tag.length >= (meta.config.minimumTagLength || 3)); - tags = await filterCategoryTags(tags, tid); const cid = await Topics.getTopicField(tid, 'cid'); const topicSets = tags.map(tag => `tag:${tag}:topics`).concat( tags.map(tag => `cid:${cid}:tag:${tag}:topics`) ); - await Promise.all([ - db.setAdd(`topic:${tid}:tags`, tags), - db.sortedSetsAdd(topicSets, timestamp, tid), - ]); - cache.del(`topic:${tid}:tags`); + await db.sortedSetsAdd(topicSets, timestamp, tid); await Topics.updateCategoryTagsCount([cid], tags); - await Promise.all(tags.map(tag => updateTagCount(tag))); + await Promise.all(tags.map(updateTagCount)); + }; + + Topics.filterTags = async function (tags, cid) { + const result = await plugins.hooks.fire('filter:tags.filter', { tags: tags, cid: cid }); + tags = _.uniq(result.tags) + .map(tag => utils.cleanUpTag(tag, meta.config.maximumTagLength)) + .filter(tag => tag && tag.length >= (meta.config.minimumTagLength || 3)); + + return await filterCategoryTags(tags, cid); }; Topics.updateCategoryTagsCount = async function (cids, tags) { @@ -92,8 +92,7 @@ module.exports = function (Topics) { } }; - async function filterCategoryTags(tags, tid) { - const cid = await Topics.getTopicField(tid, 'cid'); + async function filterCategoryTags(tags, cid) { const tagWhitelist = await categories.getTagWhitelist([cid]); if (!Array.isArray(tagWhitelist[0]) || !tagWhitelist[0].length) { return tags; @@ -116,15 +115,6 @@ module.exports = function (Topics) { } }; - Topics.updateTags = async function (data) { - await async.eachSeries(data, async (tagData) => { - await db.setObject(`tag:${tagData.value}`, { - color: tagData.color, - bgColor: tagData.bgColor, - }); - }); - }; - Topics.renameTags = async function (data) { await async.eachSeries(data, async (tagData) => { await renameTag(tagData.value, tagData.newName); @@ -136,19 +126,12 @@ module.exports = function (Topics) { return; } newTagName = utils.cleanUpTag(newTagName, meta.config.maximumTagLength); - const targetExists = await db.isSortedSetMember('tags:topic:count', newTagName); + await Topics.createEmptyTag(newTagName); const allCids = {}; - const tagData = await db.getObject(`tag:${tag}`); - if (tagData && !targetExists) { - await db.setObject(`tag:${newTagName}`, { - color: tagData.color, - bgColor: tagData.bgColor, - }); - } await batch.processSortedSet(`tag:${tag}:topics`, async (tids) => { - const topicData = await Topics.getTopicsFields(tids, ['tid', 'cid']); + const topicData = await Topics.getTopicsFields(tids, ['tid', 'cid', 'tags']); const cids = topicData.map(t => t.cid); topicData.forEach((t) => { allCids[t.cid] = true; }); const scores = await db.sortedSetScores(`tag:${tag}:topics`, tids); @@ -162,11 +145,18 @@ module.exports = function (Topics) { )); await db.sortedSetRemove(cids.map(cid => `cid:${cid}:tag:${tag}:topics`), tids); - // update topic::tags - const keys = tids.map(tid => `topic:${tid}:tags`); - await db.setsRemove(keys, tag); - await db.setsAdd(keys, newTagName); - cache.del(keys); + // update 'tags' field in topic hash + topicData.forEach((topic) => { + topic.tags = topic.tags.map(tagItem => tagItem.value); + const index = topic.tags.indexOf(tag); + if (index !== -1) { + topic.tags.splice(index, 1, newTagName); + } + }); + await db.setObjectBulk( + topicData.map(t => `topic:${t.tid}`), + topicData.map(t => ({ tags: t.tags.join(',') })) + ); }, {}); await Topics.deleteTag(tag); await updateTagCount(newTagName); @@ -235,9 +225,11 @@ module.exports = function (Topics) { if (!tids.length) { return; } - const keys = tids.map(tid => `topic:${tid}:tags`); - await db.setsRemove(keys, tag); - cache.del(keys); + + await db.deleteObjectFields( + tids.map(tid => `topic:${tid}`), + ['tags'], + ); }); } @@ -291,11 +283,8 @@ module.exports = function (Topics) { if (!tags.length) { return []; } - const tagData = await db.getObjects(tags.map(tag => `tag:${tag.value}`)); - tags.forEach((tag, index) => { + tags.forEach((tag) => { tag.valueEscaped = validator.escape(String(tag.value)); - tag.color = tagData[index] ? tagData[index].color : ''; - tag.bgColor = tagData[index] ? tagData[index].bgColor : ''; }); return tags; }; @@ -306,24 +295,8 @@ module.exports = function (Topics) { }; Topics.getTopicsTags = async function (tids) { - const cachedData = {}; - const uncachedKeys = cache.getUnCachedKeys( - tids.map(tid => `topic:${tid}:tags`), - cachedData - ); - - if (!uncachedKeys.length) { - return tids.map(tid => cachedData[`topic:${tid}:tags`].slice()); - } - - const tagData = await db.getSetsMembers( - uncachedKeys, - ); - uncachedKeys.forEach((uncachedKey, index) => { - cachedData[uncachedKey] = tagData[index]; - cache.set(uncachedKey, tagData[index]); - }); - return tids.map(tid => cachedData[`topic:${tid}:tags`].slice()); + const topicTagData = await Topics.getTopicsFields(tids, ['tags']); + return tids.map((tid, i) => topicTagData[i].tags.map(tagData => tagData.value)); }; Topics.getTopicTagsObjects = async function (tid) { @@ -349,65 +322,80 @@ module.exports = function (Topics) { }; Topics.addTags = async function (tags, tids) { - const topicData = await Topics.getTopicsFields(tids, ['tid', 'cid', 'timestamp']); - const sets = tids.map(tid => `topic:${tid}:tags`); - for (let i = 0; i < tags.length; i++) { - /* eslint-disable no-await-in-loop */ - const bulkAdd = []; - topicData.forEach((t) => { - bulkAdd.push([`tag:${tags[i]}:topics`, t.timestamp, t.tid]); - bulkAdd.push([`cid:${t.cid}:tag:${tags[i]}:topics`, t.timestamp, t.tid]); + const topicData = await Topics.getTopicsFields(tids, ['tid', 'cid', 'timestamp', 'tags']); + const bulkAdd = []; + const bulkSet = []; + topicData.forEach((t) => { + const topicTags = t.tags.map(tagItem => tagItem.value); + tags.forEach((tag) => { + bulkAdd.push([`tag:${tag}:topics`, t.timestamp, t.tid]); + bulkAdd.push([`cid:${t.cid}:tag:${tag}:topics`, t.timestamp, t.tid]); + if (!topicTags.includes(tag)) { + topicTags.push(tag); + } }); - await Promise.all([ - db.setsAdd(sets, tags[i]), - db.sortedSetAddBulk(bulkAdd), - ]); - await updateTagCount(tags[i]); - } + bulkSet.push({ tags: topicTags.join(',') }); + }); + await Promise.all([ + db.sortedSetAddBulk(bulkAdd), + db.setObjectBulk( + topicData.map(t => `topic:${t.tid}`), + bulkSet, + ), + ]); + + await Promise.all(tags.map(updateTagCount)); await Topics.updateCategoryTagsCount(_.uniq(topicData.map(t => t.cid)), tags); - cache.del(sets); }; Topics.removeTags = async function (tags, tids) { - const topicData = await Topics.getTopicsFields(tids, ['tid', 'cid']); - const sets = tids.map(tid => `topic:${tid}:tags`); - for (let i = 0; i < tags.length; i++) { - /* eslint-disable no-await-in-loop */ - const bulkRemove = []; - topicData.forEach((t) => { - bulkRemove.push([`tag:${tags[i]}:topics`, t.tid]); - bulkRemove.push([`cid:${t.cid}:tag:${tags[i]}:topics`, t.tid]); + const topicData = await Topics.getTopicsFields(tids, ['tid', 'cid', 'tags']); + const bulkRemove = []; + const bulkSet = []; + + topicData.forEach((t) => { + const topicTags = t.tags.map(tagItem => tagItem.value); + tags.forEach((tag) => { + bulkRemove.push([`tag:${tag}:topics`, t.tid]); + bulkRemove.push([`cid:${t.cid}:tag:${tag}:topics`, t.tid]); + if (topicTags.includes(tag)) { + topicTags.splice(topicTags.indexOf(tag), 1); + } }); - await Promise.all([ - db.setsRemove(sets, tags[i]), - db.sortedSetRemoveBulk(bulkRemove), - ]); - await updateTagCount(tags[i]); - } + bulkSet.push({ tags: topicTags.join(',') }); + }); + await Promise.all([ + db.sortedSetRemoveBulk(bulkRemove), + db.setObjectBulk( + topicData.map(t => `topic:${t.tid}`), + bulkSet, + ), + ]); + + await Promise.all(tags.map(updateTagCount)); await Topics.updateCategoryTagsCount(_.uniq(topicData.map(t => t.cid)), tags); - cache.del(sets); }; Topics.updateTopicTags = async function (tid, tags) { await Topics.deleteTopicTags(tid); - const timestamp = await Topics.getTopicField(tid, 'timestamp'); - await Topics.createTags(tags, tid, timestamp); + const cid = await Topics.getTopicField(tid, 'cid'); + + tags = await Topics.filterTags(tags, cid); + await Topics.addTags(tags, [tid]); }; Topics.deleteTopicTags = async function (tid) { - const [tags, cid] = await Promise.all([ - Topics.getTopicTags(tid), - Topics.getTopicField(tid, 'cid'), - ]); - await db.delete(`topic:${tid}:tags`); - cache.del(`topic:${tid}:tags`); + const topicData = await Topics.getTopicFields(tid, ['cid', 'tags']); + const { cid } = topicData; + const tags = topicData.tags.map(tagItem => tagItem.value); + await db.deleteObjectField(`topic:${tid}`, 'tags'); const sets = tags.map(tag => `tag:${tag}:topics`) .concat(tags.map(tag => `cid:${cid}:tag:${tag}:topics`)); await db.sortedSetsRemove(sets, tid); await Topics.updateCategoryTagsCount([cid], tags); - await Promise.all(tags.map(tag => updateTagCount(tag))); + await Promise.all(tags.map(updateTagCount)); }; Topics.searchTags = async function (data) { diff --git a/src/upgrades/1.16.0/category_tags.js b/src/upgrades/1.16.0/category_tags.js index 199185ab14..2dc7c40484 100644 --- a/src/upgrades/1.16.0/category_tags.js +++ b/src/upgrades/1.16.0/category_tags.js @@ -11,10 +11,16 @@ module.exports = { method: async function () { const { progress } = this; + async function getTopicsTags(tids) { + return await db.getSetsMembers( + tids.map(tid => `topic:${tid}:tags`), + ); + } + await batch.processSortedSet('topics:tid', async (tids) => { const [topicData, tags] = await Promise.all([ topics.getTopicsFields(tids, ['tid', 'cid', 'timestamp']), - topics.getTopicsTags(tids), + getTopicsTags(tids), ]); const topicsWithTags = topicData.map((t, i) => { t.tags = tags[i]; diff --git a/src/upgrades/1.18.0/topic_tags_refactor.js b/src/upgrades/1.18.0/topic_tags_refactor.js new file mode 100644 index 0000000000..c81e139bb3 --- /dev/null +++ b/src/upgrades/1.18.0/topic_tags_refactor.js @@ -0,0 +1,37 @@ +'use strict'; + +const db = require('../../database'); +const batch = require('../../batch'); + +module.exports = { + name: 'Store tags in topic hash', + timestamp: Date.UTC(2021, 8, 9), + method: async function () { + const { progress } = this; + + async function getTopicsTags(tids) { + return await db.getSetsMembers( + tids.map(tid => `topic:${tid}:tags`), + ); + } + + await batch.processSortedSet('topics:tid', async (tids) => { + const tags = await getTopicsTags(tids); + + const topicsWithTags = tids.map((tid, i) => { + const topic = { tid: tid }; + topic.tags = tags[i]; + return topic; + }).filter(t => t && t.tags.length); + + await db.setObjectBulk( + topicsWithTags.map(t => `topic:${t.tid}`), + topicsWithTags.map(t => ({ tags: t.tags.join(',') })) + ); + progress.incr(tids.length); + }, { + batch: 500, + progress: progress, + }); + }, +}; diff --git a/src/views/admin/manage/tags.tpl b/src/views/admin/manage/tags.tpl index 7492e05d41..0d3a0fa40d 100644 --- a/src/views/admin/manage/tags.tpl +++ b/src/views/admin/manage/tags.tpl @@ -3,7 +3,6 @@
- [[admin/manage/tags:create-modify]]

[[admin/manage/tags:description]]

@@ -22,21 +21,6 @@ {tags.valueEscaped}
-
@@ -48,7 +32,6 @@
-
diff --git a/test/topics.js b/test/topics.js index ec5c45182b..10a808f530 100644 --- a/test/topics.js +++ b/test/topics.js @@ -1824,9 +1824,9 @@ describe('Topic\'s', () => { assert.equal(data.matchCount, 3); assert.equal(data.pageCount, 1); const tagData = [ - { value: 'nodebb', valueEscaped: 'nodebb', color: '', bgColor: '', score: 3 }, - { value: 'nodejs', valueEscaped: 'nodejs', color: '', bgColor: '', score: 1 }, - { value: 'nosql', valueEscaped: 'nosql', color: '', bgColor: '', score: 1 }, + { value: 'nodebb', valueEscaped: 'nodebb', score: 3 }, + { value: 'nodejs', valueEscaped: 'nodejs', score: 1 }, + { value: 'nosql', valueEscaped: 'nosql', score: 1 }, ]; assert.deepEqual(data.tags, tagData); @@ -1893,66 +1893,24 @@ describe('Topic\'s', () => { }); }); - it('should error if data is invalid', (done) => { - socketAdmin.tags.update({ uid: adminUid }, null, (err) => { - assert.equal(err.message, '[[error:invalid-data]]'); - done(); - }); - }); - it('should error if data is not an array', (done) => { - socketAdmin.tags.update({ uid: adminUid }, { - bgColor: '#ff0000', - color: '#00ff00', - }, (err) => { - assert.equal(err.message, '[[error:invalid-data]]'); - done(); - }); - }); + it('should rename tags', async () => { + const result1 = await topics.post({ uid: adminUid, tags: ['plugins'], title: 'topic tagged with plugins', content: 'topic 1 content', cid: topic.categoryId }); + const result2 = await topics.post({ uid: adminUid, tags: ['plugin'], title: 'topic tagged with plugin', content: 'topic 2 content', cid: topic.categoryId }); + const data1 = await topics.getTopicData(result2.topicData.tid); - it('should update tag', (done) => { - socketAdmin.tags.update({ uid: adminUid }, [{ - value: 'emptytag', - bgColor: '#ff0000', - color: '#00ff00', - }], (err) => { - assert.ifError(err); - db.getObject('tag:emptytag', (err, data) => { - assert.ifError(err); - assert.equal(data.bgColor, '#ff0000'); - assert.equal(data.color, '#00ff00'); - done(); - }); - }); - }); + await socketAdmin.tags.rename({ uid: adminUid }, [{ + value: 'plugin', + newName: 'plugins', + }]); - it('should rename tags', (done) => { - async.series({ - topic1: function (next) { - topics.post({ uid: adminUid, tags: ['plugins'], title: 'topic tagged with plugins', content: 'topic 1 content', cid: topic.categoryId }, next); - }, - topic2: function (next) { - topics.post({ uid: adminUid, tags: ['plugin'], title: 'topic tagged with plugin', content: 'topic 2 content', cid: topic.categoryId }, next); - }, - }, (err, result) => { - assert.ifError(err); - socketAdmin.tags.rename({ uid: adminUid }, [{ - value: 'plugin', - newName: 'plugins', - }], (err) => { - assert.ifError(err); - topics.getTagTids('plugins', 0, -1, (err, tids) => { - assert.ifError(err); - assert.equal(tids.length, 2); - topics.getTopicTags(result.topic2.topicData.tid, (err, tags) => { - assert.ifError(err); - assert.equal(tags.length, 1); - assert.equal(tags[0], 'plugins'); - done(); - }); - }); - }); - }); + const tids = await topics.getTagTids('plugins', 0, -1); + assert.strictEqual(tids.length, 2); + const tags = await topics.getTopicTags(result2.topicData.tid); + + const data = await topics.getTopicData(result2.topicData.tid); + assert.strictEqual(tags.length, 1); + assert.strictEqual(tags[0], 'plugins'); }); it('should return related topics', (done) => { @@ -2108,18 +2066,17 @@ describe('Topic\'s', () => { await topics.post({ uid: adminUid, tags: ['cattag1'], title: title, content: 'topic 1 content', cid: cid }); let result = await topics.getCategoryTagsData(cid, 0, -1); assert.deepStrictEqual(result, [ - { value: 'cattag1', score: 3, bgColor: '', color: '', valueEscaped: 'cattag1' }, - { value: 'cattag2', score: 2, bgColor: '', color: '', valueEscaped: 'cattag2' }, - { value: 'cattag3', score: 1, bgColor: '', color: '', valueEscaped: 'cattag3' }, + { value: 'cattag1', score: 3, valueEscaped: 'cattag1' }, + { value: 'cattag2', score: 2, valueEscaped: 'cattag2' }, + { value: 'cattag3', score: 1, valueEscaped: 'cattag3' }, ]); // after purging values should update properly await topics.purge(postResult.topicData.tid, adminUid); result = await topics.getCategoryTagsData(cid, 0, -1); - assert.deepStrictEqual(result, [ - { value: 'cattag1', score: 2, bgColor: '', color: '', valueEscaped: 'cattag1' }, - { value: 'cattag2', score: 1, bgColor: '', color: '', valueEscaped: 'cattag2' }, + { value: 'cattag1', score: 2, valueEscaped: 'cattag1' }, + { value: 'cattag2', score: 1, valueEscaped: 'cattag2' }, ]); }); @@ -2138,11 +2095,11 @@ describe('Topic\'s', () => { let result1 = await topics.getCategoryTagsData(cid1, 0, -1); let result2 = await topics.getCategoryTagsData(cid2, 0, -1); assert.deepStrictEqual(result1, [ - { value: 'movedtag1', score: 2, bgColor: '', color: '', valueEscaped: 'movedtag1' }, - { value: 'movedtag2', score: 1, bgColor: '', color: '', valueEscaped: 'movedtag2' }, + { value: 'movedtag1', score: 2, valueEscaped: 'movedtag1' }, + { value: 'movedtag2', score: 1, valueEscaped: 'movedtag2' }, ]); assert.deepStrictEqual(result2, [ - { value: 'movedtag2', score: 1, bgColor: '', color: '', valueEscaped: 'movedtag2' }, + { value: 'movedtag2', score: 1, valueEscaped: 'movedtag2' }, ]); // after moving values should update properly @@ -2151,11 +2108,11 @@ describe('Topic\'s', () => { result1 = await topics.getCategoryTagsData(cid1, 0, -1); result2 = await topics.getCategoryTagsData(cid2, 0, -1); assert.deepStrictEqual(result1, [ - { value: 'movedtag1', score: 1, bgColor: '', color: '', valueEscaped: 'movedtag1' }, + { value: 'movedtag1', score: 1, valueEscaped: 'movedtag1' }, ]); assert.deepStrictEqual(result2, [ - { value: 'movedtag2', score: 2, bgColor: '', color: '', valueEscaped: 'movedtag2' }, - { value: 'movedtag1', score: 1, bgColor: '', color: '', valueEscaped: 'movedtag1' }, + { value: 'movedtag2', score: 2, valueEscaped: 'movedtag2' }, + { value: 'movedtag1', score: 1, valueEscaped: 'movedtag1' }, ]); });