diff --git a/public/src/client/topic/fork.js b/public/src/client/topic/fork.js index a55b45220c..50888a9ca3 100644 --- a/public/src/client/topic/fork.js +++ b/public/src/client/topic/fork.js @@ -55,7 +55,8 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po forkCommit.attr('disabled', true); socket.emit('topics.createTopicFromPosts', { title: forkModal.find('#fork-title').val(), - pids: postSelect.pids + pids: postSelect.pids, + fromTid: ajaxify.data.tid }, function(err, newTopic) { function fadeOutAndRemove(pid) { components.get('post', 'pid', pid).fadeOut(500, function() { diff --git a/src/meta/configs.js b/src/meta/configs.js index 3ff42f66ae..69cc375b85 100644 --- a/src/meta/configs.js +++ b/src/meta/configs.js @@ -135,4 +135,4 @@ module.exports = function(Meta) { db.deleteObjectField('config', field); }; -}; \ No newline at end of file +}; diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index c96a77265e..6f5ab296d9 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -69,7 +69,7 @@ SocketTopics.createTopicFromPosts = function(socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - topics.createTopicFromPosts(socket.uid, data.title, data.pids, callback); + topics.createTopicFromPosts(socket.uid, data.title, data.pids, data.fromTid, callback); }; SocketTopics.toggleFollow = function(socket, tid, callback) { diff --git a/src/topics.js b/src/topics.js index 385d3ae558..fbdd507d9a 100644 --- a/src/topics.js +++ b/src/topics.js @@ -328,4 +328,88 @@ var social = require('./social'); } }; + Topics.getTopicBookmarks = function( tid, callback ){ + db.getSortedSetRangeWithScores(['tid:' + tid + ':bookmarks'], 0, -1, callback ); + }; + + Topics.updateTopicBookmarks = function( tid, pids, callback ){ + var maxIndex; + var Posts = posts; + async.waterfall([ + function(next){ + Topics.getPostCount( tid, next ); + }, + function(postcount, next){ + maxIndex = postcount; + Topics.getTopicBookmarks( tid, next ); + }, + function(bookmarks, next){ + var uids = bookmarks.map( function( bookmark ){return bookmark.value}); + var forkedPosts = pids.map( function( pid ){ return { pid: pid, tid: tid }; } ); + var uidBookmark = new Object(); + var uidData = bookmarks.map( + function( bookmark ){ + var u = new Object(); + u.uid = bookmark.value; + u.bookmark = bookmark.score; + return u; + } ); + async.map( + uidData, + function( data, mapCallback ){ + Posts.getPostIndices( + forkedPosts, + data.uid, + function( err, indices ){ + if( err ){ + callback( err ); + } + data.postIndices = indices; + mapCallback( null, data ); + } ) + }, + function( err, results ){ + if( err ){ + return callback(); + } + async.map( + results, + function( data, mapCallback ){ + var uid = data.uid; + var bookmark = data.bookmark; + bookmark = bookmark < maxIndex ? bookmark : maxIndex; + var postIndices = data.postIndices; + var i; + for( i = 0; i < postIndices.length && postIndices[i] < data.bookmark; ++i ){ + --bookmark; + } + + if( bookmark != data.bookmark ){ + mapCallback( null, { uid: uid, bookmark: bookmark } ); + } + else{ + mapCallback( null, null ); + } + }, + function( err, results ){ + async.map( results, + function(ui, cb ){ + if( ui && ui.bookmark){ + Topics.setUserBookmark( tid, ui.uid, ui.bookmark, cb ); + } + else{ + return cb( null, null ); + } + }, + function( err, results ){ + next(); + } + ); + } + ); + } + ); + }], + function( err, result ){ callback();} ); + }; }(exports)); diff --git a/src/topics/fork.js b/src/topics/fork.js index 80143e4d46..768b656d2a 100644 --- a/src/topics/fork.js +++ b/src/topics/fork.js @@ -13,7 +13,7 @@ var meta = require('../meta'); module.exports = function(Topics) { - Topics.createTopicFromPosts = function(uid, title, pids, callback) { + Topics.createTopicFromPosts = function(uid, title, pids, fromTid, callback) { if (title) { title = title.trim(); } @@ -55,6 +55,9 @@ module.exports = function(Topics) { } Topics.create({uid: results.postData.uid, title: title, cid: cid}, next); }, + function( results, next) { + Topics.updateTopicBookmarks(fromTid, pids, function(){ next( null, results );} ); + }, function(_tid, next) { function move(pid, next) { privileges.posts.canEdit(pid, uid, function(err, canEdit) { diff --git a/tests/topics.js b/tests/topics.js index fe00db7646..60c71960cd 100644 --- a/tests/topics.js +++ b/tests/topics.js @@ -7,6 +7,8 @@ var db = require('./mocks/databasemock'); var topics = require('../src/topics'); var categories = require('../src/categories'); var User = require('../src/user'); +var groups = require('../src/groups'); +var async = require('async'); describe('Topic\'s', function() { var topic, @@ -188,6 +190,100 @@ describe('Topic\'s', function() { }); + describe('.fork', function(){ + var newTopic; + var replies = new Array(); + var topicPids; + var originalBookmark = 5; + function postReply( next ){ + topics.reply({uid: topic.userId, content: 'test post ' + replies.length, tid: newTopic.tid}, + function(err, result) { + assert.equal(err, null, 'was created with error'); + assert.ok(result); + replies.push( result ); + next(); + } + ); + } + + before( function(done) { + async.waterfall( + [ + function(next){ + groups.join('administrators', topic.userId, next); + }, + function( next ){ + topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) { + assert.ifError( err ); + newTopic = result.topicData; + next(); + }); + }, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ postReply( next );}, + function( next ){ + topicPids = replies.map( function( reply ){ return reply.pid; } ); + topics.setUserBookmark( newTopic.tid, topic.userId, originalBookmark, next ); + }], + done ); + }); + + it('should have 12 replies', function(done) { + assert.equal( 12, replies.length ); + done(); + }); + + it('should not update the user\'s bookmark', function(done){ + async.waterfall([ + function(next){ + topics.createTopicFromPosts( + topic.userId, + 'Fork test, no bookmark update', + topicPids.slice( -2 ), + newTopic.tid, + next ); + }, + function( forkedTopicData, next){ + topics.getUserBookmark( newTopic.tid, topic.userId, next ); + }, + function( bookmark, next ){ + assert.equal( originalBookmark, bookmark ); + next(); + } + ],done); + }); + + it('should update the user\'s bookmark ', function(done){ + async.waterfall([ + function(next){ + topics.createTopicFromPosts( + topic.userId, + 'Fork test, no bookmark update', + topicPids.slice( 1, 3 ), + newTopic.tid, + next ); + }, + function( forkedTopicData, next){ + topics.getUserBookmark( newTopic.tid, topic.userId, next ); + }, + function( bookmark, next ){ + assert.equal( originalBookmark - 2, bookmark ); + next(); + } + ],done); + }); + }); + after(function() { db.flushdb(); });