diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index e091dd69c..674f690c0 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -31,6 +31,8 @@ define('forum/topic/events', [ 'event:topic_moved': onTopicMoved, + 'event:topic_resolved': onTopicResolved, + 'event:post_edited': onPostEdited, 'event:post_purged': onPostPurged, @@ -100,7 +102,16 @@ define('forum/topic/events', [ } } + function onTopicResolved(data) { + if (data.topic && data.topic.tags) { + require(['forum/topic/tag'], function (tag) { + tag.updateTopicTags([data.topic]); + }); + } + } + function onPostEdited(data) { + console.trace(); if (!data || !data.post || parseInt(data.post.tid, 10) !== parseInt(ajaxify.data.tid, 10)) { return; } diff --git a/src/topics/create.js b/src/topics/create.js index 9b0fd4453..e9b7098c1 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -14,6 +14,7 @@ const posts = require('../posts'); const privileges = require('../privileges'); const categories = require('../categories'); const translator = require('../translator'); +const websockets = require('../socket.io'); module.exports = function (Topics) { Topics.create = async function (data) { @@ -178,9 +179,10 @@ module.exports = function (Topics) { const { tid } = data; const { uid } = data; - const [topicData, isAdmin] = await Promise.all([ + const [topicData, isAdmin, isInstructor] = await Promise.all([ Topics.getTopicData(tid), privileges.users.isAdministrator(uid), + privileges.users.isInstructor(uid), ]); await canReply(data, topicData); @@ -203,6 +205,10 @@ module.exports = function (Topics) { data.timestamp = topicData.lastposttime + 1; } + if (isInstructor) { + await resolveTopic(topicData, topicData.tags); + } + data.ip = data.req ? data.req.ip : null; let postData = await posts.create(data); postData = await onNewPost(postData, data); @@ -233,6 +239,23 @@ module.exports = function (Topics) { return postData; }; + async function resolveTopic(data, tags) { + const { tid } = data; + // Remove unresolved tag and add resolved tag + const topicTags = tags.map(tagItem => tagItem.value); + if (!topicTags.includes('unresolved')) { + return; + } + topicTags.splice(topicTags.indexOf('unresolved'), 1); + topicTags.push('resolved'); + await Topics.updateTopicTags([tid], topicTags); + + // Refresh tags + tags = await Topics.getTopicTagsObjects(tid); + data.tags = tags; + websockets.in(`topic_${tid}`).emit('event:topic_resolved', { topic: data }); + } + async function onNewPost(postData, data) { const { tid, uid } = postData; await Topics.markAsRead([tid], uid); diff --git a/test/topics.js b/test/topics.js index 8a32e445f..db03afedd 100644 --- a/test/topics.js +++ b/test/topics.js @@ -29,6 +29,8 @@ describe('Topic\'s', () => { let topic; let categoryObj; let adminUid; + let instructorUid; + let studentUid; let adminJar; let csrf_token; let fooUid; @@ -41,6 +43,11 @@ describe('Topic\'s', () => { adminJar = adminLogin.jar; csrf_token = adminLogin.csrf_token; + instructorUid = await User.create({ username: 'prof' }); + await groups.join('Instructors', instructorUid); + studentUid = await User.create({ username: 'student' }); + await groups.join('Students', studentUid); + categoryObj = await categories.create({ name: 'Test Category', description: 'Test category created by testing script', @@ -1676,6 +1683,14 @@ describe('Topic\'s', () => { assert.deepStrictEqual(categoryTags.sort(), ['tag2', 'tag4', 'tag6']); }); + it('should resolve topic', async () => { + const t = await topics.post({ uid: studentUid, tags: [], title: 'topic title 1', content: 'topic 1 content', cid: topic.categoryId }); + const { tid } = t.topicData; + await topics.reply({ uid: instructorUid, content: 'reply 1 content', tid: tid }); + const tags = await topics.getTopicTags(tid); + assert.deepStrictEqual(tags.sort(), ['resolved']); + }); + it('should respect minTags', async () => { const oldValue = meta.config.minimumTagsPerTopic; meta.config.minimumTagsPerTopic = 2;