Просмотр исходного кода

Pull track changes backend into a module

James Allen 9 лет назад
Родитель
Сommit
2b36a443c9

+ 34 - 3
services/web/app/coffee/Features/Chat/ChatController.coffee

@@ -4,9 +4,9 @@ logger = require("logger-sharelatex")
 AuthenticationController = require('../Authentication/AuthenticationController')
 UserInfoManager = require('../User/UserInfoManager')
 UserInfoController = require('../User/UserInfoController')
-CommentsController = require('../Comments/CommentsController')
+async = require "async"
 
-module.exports =
+module.exports = ChatController =
 	sendMessage: (req, res, next)->
 		project_id = req.params.project_id
 		content = req.body.content
@@ -28,7 +28,38 @@ module.exports =
 		logger.log project_id:project_id, query:query, "getting messages"
 		ChatApiHandler.getGlobalMessages project_id, query.limit, query.before, (err, messages) ->
 			return next(err) if err?
-			CommentsController._injectUserInfoIntoThreads {global: { messages: messages }}, (err) ->
+			ChatController._injectUserInfoIntoThreads {global: { messages: messages }}, (err) ->
 				return next(err) if err?
 				logger.log length: messages?.length, "sending messages to client"
 				res.json messages
+
+	_injectUserInfoIntoThreads: (threads, callback = (error, threads) ->) ->
+		userCache = {}
+		getUserDetails = (user_id, callback = (error, user) ->) ->
+			return callback(null, userCache[user_id]) if userCache[user_id]?
+			UserInfoManager.getPersonalInfo user_id, (err, user) ->
+				return callback(error) if error?
+				user = UserInfoController.formatPersonalInfo user
+				userCache[user_id] = user
+				callback null, user
+		
+		jobs = []
+		for thread_id, thread of threads
+			do (thread) ->
+				if thread.resolved
+					jobs.push (cb) ->
+						getUserDetails thread.resolved_by_user_id, (error, user) ->
+							cb(error) if error?
+							thread.resolved_by_user = user
+							cb()
+				for message in thread.messages
+					do (message) ->
+						jobs.push (cb) ->
+							getUserDetails message.user_id, (error, user) ->
+								cb(error) if error?
+								message.user = user
+								cb()
+		
+		async.series jobs, (error) ->
+			return callback(error) if error?
+			return callback null, threads

+ 0 - 111
services/web/app/coffee/Features/Comments/CommentsController.coffee

@@ -1,111 +0,0 @@
-ChatApiHandler = require("../Chat/ChatApiHandler")
-EditorRealTimeController = require("../Editor/EditorRealTimeController")
-logger = require("logger-sharelatex")
-AuthenticationController = require('../Authentication/AuthenticationController')
-UserInfoManager = require('../User/UserInfoManager')
-UserInfoController = require('../User/UserInfoController')
-DocumentUpdaterHandler = require "../DocumentUpdater/DocumentUpdaterHandler"
-async = require "async"
-
-module.exports = CommentsController =
-	sendComment: (req, res, next) ->
-		{project_id, thread_id} = req.params
-		content = req.body.content
-		user_id = AuthenticationController.getLoggedInUserId(req)
-		if !user_id?
-			err = new Error('no logged-in user')
-			return next(err)
-		logger.log {project_id, thread_id, user_id, content}, "sending comment"
-		ChatApiHandler.sendComment project_id, thread_id, user_id, content, (err, comment) ->
-			return next(err) if err?
-			UserInfoManager.getPersonalInfo comment.user_id, (err, user) ->
-				return next(err) if err?
-				comment.user = UserInfoController.formatPersonalInfo(user)
-				EditorRealTimeController.emitToRoom project_id, "new-comment", thread_id, comment, (err) ->
-				res.send 204
-
-	getThreads: (req, res, next) ->
-		{project_id} = req.params
-		logger.log {project_id}, "getting comment threads for project"
-		ChatApiHandler.getThreads project_id, (err, threads) ->
-			return next(err) if err?
-			CommentsController._injectUserInfoIntoThreads threads, (error, threads) ->
-				return next(err) if err?
-				res.json threads
-
-	resolveThread: (req, res, next) ->
-		{project_id, thread_id} = req.params
-		user_id = AuthenticationController.getLoggedInUserId(req)
-		logger.log {project_id, thread_id, user_id}, "resolving comment thread"
-		ChatApiHandler.resolveThread project_id, thread_id, user_id, (err) ->
-			return next(err) if err?
-			UserInfoManager.getPersonalInfo user_id, (err, user) ->
-				return next(err) if err?
-				EditorRealTimeController.emitToRoom project_id, "resolve-thread", thread_id, UserInfoController.formatPersonalInfo(user), (err)->
-				res.send 204
-
-	reopenThread: (req, res, next) ->
-		{project_id, thread_id} = req.params
-		logger.log {project_id, thread_id}, "reopening comment thread"
-		ChatApiHandler.reopenThread project_id, thread_id, (err, threads) ->
-			return next(err) if err?
-			EditorRealTimeController.emitToRoom project_id, "reopen-thread", thread_id, (err)->
-			res.send 204
-	
-	deleteThread: (req, res, next) ->
-		{project_id, doc_id, thread_id} = req.params
-		logger.log {project_id, doc_id, thread_id}, "deleting comment thread"
-		DocumentUpdaterHandler.deleteThread project_id, doc_id, thread_id, (err) ->
-			return next(err) if err?
-			ChatApiHandler.deleteThread project_id, thread_id, (err, threads) ->
-				return next(err) if err?
-				EditorRealTimeController.emitToRoom project_id, "delete-thread", thread_id, (err)->
-				res.send 204
-	
-	editMessage: (req, res, next) ->
-		{project_id, thread_id, message_id} = req.params
-		{content} = req.body
-		logger.log {project_id, thread_id, message_id}, "editing message thread"
-		ChatApiHandler.editMessage project_id, thread_id, message_id, content, (err) ->
-			return next(err) if err?
-			EditorRealTimeController.emitToRoom project_id, "edit-message", thread_id, message_id, content, (err)->
-			res.send 204
-	
-	deleteMessage: (req, res, next) ->
-		{project_id, thread_id, message_id} = req.params
-		logger.log {project_id, thread_id, message_id}, "deleting message"
-		ChatApiHandler.deleteMessage project_id, thread_id, message_id, (err, threads) ->
-			return next(err) if err?
-			EditorRealTimeController.emitToRoom project_id, "delete-message", thread_id, message_id, (err)->
-			res.send 204
-
-	_injectUserInfoIntoThreads: (threads, callback = (error, threads) ->) ->
-		userCache = {}
-		getUserDetails = (user_id, callback = (error, user) ->) ->
-			return callback(null, userCache[user_id]) if userCache[user_id]?
-			UserInfoManager.getPersonalInfo user_id, (err, user) ->
-				return callback(error) if error?
-				user = UserInfoController.formatPersonalInfo user
-				userCache[user_id] = user
-				callback null, user
-		
-		jobs = []
-		for thread_id, thread of threads
-			do (thread) ->
-				if thread.resolved
-					jobs.push (cb) ->
-						getUserDetails thread.resolved_by_user_id, (error, user) ->
-							cb(error) if error?
-							thread.resolved_by_user = user
-							cb()
-				for message in thread.messages
-					do (message) ->
-						jobs.push (cb) ->
-							getUserDetails message.user_id, (error, user) ->
-								cb(error) if error?
-								message.user = user
-								cb()
-		
-		async.series jobs, (error) ->
-			return callback(error) if error?
-			return callback null, threads

+ 3 - 1
services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee

@@ -1,6 +1,8 @@
 _ = require("underscore")
 
 module.exports = ProjectEditorHandler =
+	trackChangesAvailable: false
+
 	buildProjectModelView: (project, members, invites) ->
 		result =
 			_id        : project._id
@@ -38,7 +40,7 @@ module.exports = ProjectEditorHandler =
 			templates: false
 			references: false
 			trackChanges: false
-			trackChangesVisible: trackChangesVisible
+			trackChangesVisible: ProjectEditorHandler.trackChangesAvailable and trackChangesVisible
 		})
 
 		return result

+ 0 - 23
services/web/app/coffee/Features/TrackChanges/RangesManager.coffee

@@ -1,23 +0,0 @@
-DocumentUpdaterHandler = require "../DocumentUpdater/DocumentUpdaterHandler"
-DocstoreManager = require "../Docstore/DocstoreManager"
-UserInfoManager = require "../User/UserInfoManager"
-async = require "async"
-
-module.exports = RangesManager =
-	getAllRanges: (project_id, callback = (error, docs) ->) ->
-		DocumentUpdaterHandler.flushProjectToMongo project_id, (error) ->
-			return callback(error) if error?
-			DocstoreManager.getAllRanges project_id, callback
-	
-	getAllChangesUsers: (project_id, callback = (error, users) ->) ->
-		user_ids = {}
-		RangesManager.getAllRanges project_id, (error, docs) ->
-			return callback(error) if error?
-			jobs = []
-			for doc in docs
-				for change in doc.ranges?.changes or []
-					user_ids[change.metadata.user_id] = true
-			
-			async.mapSeries Object.keys(user_ids), (user_id, cb) ->
-				UserInfoManager.getPersonalInfo user_id, cb
-			, callback

+ 0 - 42
services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee

@@ -1,42 +0,0 @@
-RangesManager = require "./RangesManager"
-logger = require "logger-sharelatex"
-UserInfoController = require "../User/UserInfoController"
-DocumentUpdaterHandler = require "../DocumentUpdater/DocumentUpdaterHandler"
-EditorRealTimeController = require("../Editor/EditorRealTimeController")
-TrackChangesManager = require "./TrackChangesManager"
-
-module.exports = TrackChangesController =
-	getAllRanges: (req, res, next) ->
-		project_id = req.params.project_id
-		logger.log {project_id}, "request for project ranges"
-		RangesManager.getAllRanges project_id, (error, docs = []) ->
-			return next(error) if error?
-			docs = ({id: d._id, ranges: d.ranges} for d in docs)
-			res.json docs
-	
-	getAllChangesUsers: (req, res, next) ->
-		project_id = req.params.project_id
-		logger.log {project_id}, "request for project range users"
-		RangesManager.getAllChangesUsers project_id, (error, users) ->
-			return next(error) if error?
-			users = (UserInfoController.formatPersonalInfo(user) for user in users)
-			# Get rid of any anonymous/deleted user objects
-			users = users.filter (u) -> u?.id?
-			res.json users
-	
-	acceptChange: (req, res, next) ->
-		{project_id, doc_id, change_id} = req.params
-		logger.log {project_id, doc_id, change_id}, "request to accept change"
-		DocumentUpdaterHandler.acceptChange project_id, doc_id, change_id, (error) ->
-			return next(error) if error?
-			EditorRealTimeController.emitToRoom project_id, "accept-change", doc_id, change_id, (err)->
-			res.send 204
-
-	toggleTrackChanges: (req, res, next) ->
-		{project_id} = req.params
-		track_changes_on = !!req.body.on
-		logger.log {project_id, track_changes_on}, "request to toggle track changes"
-		TrackChangesManager.toggleTrackChanges project_id, track_changes_on, (error) ->
-			return next(error) if error?
-			EditorRealTimeController.emitToRoom project_id, "toggle-track-changes", track_changes_on, (err)->
-			res.send 204

+ 0 - 5
services/web/app/coffee/Features/TrackChanges/TrackChangesManager.coffee

@@ -1,5 +0,0 @@
-Project = require("../../models/Project").Project
-
-module.exports = TrackChangesManager =
-	toggleTrackChanges: (project_id, track_changes_on, callback = (error) ->) ->
-		Project.update {_id: project_id}, {track_changes: track_changes_on}, callback

+ 0 - 16
services/web/app/coffee/router.coffee

@@ -40,8 +40,6 @@ AuthorizationMiddlewear = require('./Features/Authorization/AuthorizationMiddlew
 BetaProgramController = require('./Features/BetaProgram/BetaProgramController')
 AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
 AnnouncementsController = require("./Features/Announcements/AnnouncementsController")
-TrackChangesController = require("./Features/TrackChanges/TrackChangesController")
-CommentsController = require "./Features/Comments/CommentsController"
 
 logger = require("logger-sharelatex")
 _ = require("underscore")
@@ -177,11 +175,6 @@ module.exports = class Router
 		webRouter.get  "/project/:Project_id/doc/:doc_id/diff", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.proxyToHistoryApi
 		webRouter.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.proxyToHistoryApi
 
-		webRouter.get "/project/:project_id/ranges", AuthorizationMiddlewear.ensureUserCanReadProject, TrackChangesController.getAllRanges
-		webRouter.get "/project/:project_id/changes/users", AuthorizationMiddlewear.ensureUserCanReadProject, TrackChangesController.getAllChangesUsers
-		webRouter.post "/project/:project_id/doc/:doc_id/changes/:change_id/accept", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, TrackChangesController.acceptChange
-		webRouter.post "/project/:project_id/track_changes", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, TrackChangesController.toggleTrackChanges
-
 		webRouter.get  '/Project/:Project_id/download/zip', AuthorizationMiddlewear.ensureUserCanReadProject, ProjectDownloadsController.downloadProject
 		webRouter.get  '/project/download/zip', AuthorizationMiddlewear.ensureUserCanReadMultipleProjects, ProjectDownloadsController.downloadMultipleProjects
 
@@ -232,15 +225,6 @@ module.exports = class Router
 
 		webRouter.get  "/project/:project_id/messages", AuthorizationMiddlewear.ensureUserCanReadProject, ChatController.getMessages
 		webRouter.post "/project/:project_id/messages", AuthorizationMiddlewear.ensureUserCanReadProject, ChatController.sendMessage
-		
-		# Note: Read only users can still comment
-		webRouter.post "/project/:project_id/thread/:thread_id/messages", AuthorizationMiddlewear.ensureUserCanReadProject, CommentsController.sendComment
-		webRouter.get  "/project/:project_id/threads", AuthorizationMiddlewear.ensureUserCanReadProject, CommentsController.getThreads
-		webRouter.post "/project/:project_id/thread/:thread_id/resolve", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, CommentsController.resolveThread
-		webRouter.post "/project/:project_id/thread/:thread_id/reopen", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, CommentsController.reopenThread
-		webRouter.delete "/project/:project_id/doc/:doc_id/thread/:thread_id", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, CommentsController.deleteThread
-		webRouter.post "/project/:project_id/thread/:thread_id/messages/:message_id/edit", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, CommentsController.editMessage
-		webRouter.delete  "/project/:project_id/thread/:thread_id/messages/:message_id", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, CommentsController.deleteMessage
 
 		webRouter.post "/project/:Project_id/references/index", AuthorizationMiddlewear.ensureUserCanReadProject, ReferencesController.index
 		webRouter.post "/project/:Project_id/references/indexAll", AuthorizationMiddlewear.ensureUserCanReadProject, ReferencesController.indexAll

+ 76 - 2
services/web/test/UnitTests/coffee/Chat/ChatControllerTests.coffee

@@ -69,7 +69,7 @@ describe "ChatController", ->
 			@req.query =
 				limit: @limit = "30"
 				before: @before = "12345"
-			@CommentsController._injectUserInfoIntoThreads = sinon.stub().yields()
+			@ChatController._injectUserInfoIntoThreads = sinon.stub().yields()
 			@ChatApiHandler.getGlobalMessages = sinon.stub().yields(null, @messages = ["mock", "messages"])
 			@ChatController.getMessages @req, @res
 
@@ -79,4 +79,78 @@ describe "ChatController", ->
 				.should.equal true
 
 		it "should return the messages", ->
-			@res.json.calledWith(@messages).should.equal true
+			@res.json.calledWith(@messages).should.equal true
+
+	describe "_injectUserInfoIntoThreads", ->
+		beforeEach ->
+			@users = {
+				"user_id_1": {
+					"mock": "user_1"
+				}
+				"user_id_2": {
+					"mock": "user_2"
+				}
+			}
+			@UserInfoManager.getPersonalInfo = (user_id, callback) =>
+				return callback(null, @users[user_id])
+			sinon.spy @UserInfoManager, "getPersonalInfo"
+			@UserInfoController.formatPersonalInfo = (user) ->
+				return { "formatted": user["mock"] }
+			
+		it "should inject a user object into messaged and resolved data", (done) ->
+			@ChatController._injectUserInfoIntoThreads {
+				thread1: {
+					resolved: true
+					resolved_by_user_id: "user_id_1"
+					messages: [{
+						user_id: "user_id_1"
+						content: "foo"
+					}, {
+						user_id: "user_id_2"
+						content: "bar"
+					}]
+				},
+				thread2: {
+					messages: [{
+						user_id: "user_id_1"
+						content: "baz"
+					}]
+				}
+			}, (error, threads) ->
+				expect(threads).to.deep.equal {
+					thread1: {
+						resolved: true
+						resolved_by_user_id: "user_id_1"
+						resolved_by_user: { "formatted": "user_1" }
+						messages: [{
+							user_id: "user_id_1"
+							user: { "formatted": "user_1" }
+							content: "foo"
+						}, {
+							user_id: "user_id_2"
+							user: { "formatted": "user_2" }
+							content: "bar"
+						}]
+					},
+					thread2: {
+						messages: [{
+							user_id: "user_id_1"
+							user: { "formatted": "user_1" }
+							content: "baz"
+						}]
+					}
+				}
+				done()
+
+		it "should only need to look up each user once", (done) ->
+			@ChatController._injectUserInfoIntoThreads [{
+				messages: [{
+					user_id: "user_id_1"
+					content: "foo"
+				}, {
+					user_id: "user_id_1"
+					content: "bar"
+				}]
+			}], (error, threads) =>
+				@UserInfoManager.getPersonalInfo.calledOnce.should.equal true
+				done()

+ 0 - 284
services/web/test/UnitTests/coffee/Comments/CommentsControllerTests.coffee

@@ -1,284 +0,0 @@
-should = require('chai').should()
-SandboxedModule = require('sandboxed-module')
-assert = require('assert')
-path = require('path')
-sinon = require('sinon')
-modulePath = path.join __dirname, "../../../../app/js/Features/Comments/CommentsController"
-expect = require("chai").expect
-
-describe "CommentsController", ->
-	beforeEach ->
-		@user_id = 'mock-user-id'
-		@settings = {}
-		@ChatApiHandler = {}
-		@EditorRealTimeController =
-			emitToRoom:sinon.stub()
-		@AuthenticationController =
-			getLoggedInUserId: sinon.stub().returns(@user_id)
-		@CommentsController = SandboxedModule.require modulePath, requires:
-			"settings-sharelatex": @settings
-			"logger-sharelatex": log: ->
-			"../Chat/ChatApiHandler": @ChatApiHandler
-			"../Editor/EditorRealTimeController": @EditorRealTimeController
-			'../Authentication/AuthenticationController': @AuthenticationController
-			'../User/UserInfoManager': @UserInfoManager = {}
-			'../User/UserInfoController': @UserInfoController = {}
-			"../DocumentUpdater/DocumentUpdaterHandler": @DocumentUpdaterHandler = {}
-		@req = {}
-		@res =
-			json: sinon.stub()
-			send: sinon.stub()
-
-	describe "sendComment", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-				thread_id: @thread_id = "mock-thread-id"
-			@req.body =
-				content: @content = "message-content"
-			@UserInfoManager.getPersonalInfo = sinon.stub().yields(null, @user = {"unformatted": "user"})
-			@UserInfoController.formatPersonalInfo = sinon.stub().returns(@formatted_user = {"formatted": "user"})
-			@ChatApiHandler.sendComment = sinon.stub().yields(null, @message = {"mock": "message", user_id: @user_id})
-			@CommentsController.sendComment @req, @res
-		
-		it "should look up the user", ->
-			@UserInfoManager.getPersonalInfo
-				.calledWith(@user_id)
-				.should.equal true
-
-		it "should format and inject the user into the comment", ->
-			@UserInfoController.formatPersonalInfo
-				.calledWith(@user)
-				.should.equal true
-			@message.user.should.deep.equal @formatted_user
-
-		it "should tell the chat handler about the message", ->
-			@ChatApiHandler.sendComment
-				.calledWith(@project_id, @thread_id, @user_id, @content)
-				.should.equal true
-
-		it "should tell the editor real time controller about the update with the data from the chat handler", ->
-			@EditorRealTimeController.emitToRoom
-				.calledWith(@project_id, "new-comment", @thread_id, @message)
-				.should.equal true
-				
-		it "should return a 204 status code", ->
-			@res.send.calledWith(204).should.equal true
-
-	describe "getThreads", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-			@ChatApiHandler.getThreads = sinon.stub().yields(null, @threads = {"mock", "threads"})
-			@CommentsController._injectUserInfoIntoThreads = sinon.stub().yields(null, @threads)
-			@CommentsController.getThreads @req, @res
-
-		it "should ask the chat handler about the request", ->
-			@ChatApiHandler.getThreads
-				.calledWith(@project_id)
-				.should.equal true
-			
-		it "should inject the user details into the threads", ->
-			@CommentsController._injectUserInfoIntoThreads
-				.calledWith(@threads)
-				.should.equal true
-
-		it "should return the messages", ->
-			@res.json.calledWith(@threads).should.equal true
-
-	describe "resolveThread", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-				thread_id: @thread_id = "mock-thread-id"
-			@ChatApiHandler.resolveThread = sinon.stub().yields()
-			@UserInfoManager.getPersonalInfo = sinon.stub().yields(null, @user = {"unformatted": "user"})
-			@UserInfoController.formatPersonalInfo = sinon.stub().returns(@formatted_user = {"formatted": "user"})
-			@CommentsController.resolveThread @req, @res
-
-		it "should ask the chat handler to resolve the thread", ->
-			@ChatApiHandler.resolveThread
-				.calledWith(@project_id, @thread_id)
-				.should.equal true
-			
-		it "should look up the user", ->
-			@UserInfoManager.getPersonalInfo
-				.calledWith(@user_id)
-				.should.equal true
-
-		it "should tell the client the comment was resolved", ->
-			@EditorRealTimeController.emitToRoom
-				.calledWith(@project_id, "resolve-thread", @thread_id, @formatted_user)
-				.should.equal true
-
-		it "should return a success code", ->
-			@res.send.calledWith(204).should.equal
-
-	describe "reopenThread", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-				thread_id: @thread_id = "mock-thread-id"
-			@ChatApiHandler.reopenThread = sinon.stub().yields()
-			@CommentsController.reopenThread @req, @res
-
-		it "should ask the chat handler to reopen the thread", ->
-			@ChatApiHandler.reopenThread
-				.calledWith(@project_id, @thread_id)
-				.should.equal true
-
-		it "should tell the client the comment was resolved", ->
-			@EditorRealTimeController.emitToRoom
-				.calledWith(@project_id, "reopen-thread", @thread_id)
-				.should.equal true
-
-		it "should return a success code", ->
-			@res.send.calledWith(204).should.equal
-
-	describe "deleteThread", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-				doc_id: @doc_id = "mock-doc-id"
-				thread_id: @thread_id = "mock-thread-id"
-			@DocumentUpdaterHandler.deleteThread = sinon.stub().yields()
-			@ChatApiHandler.deleteThread = sinon.stub().yields()
-			@CommentsController.deleteThread @req, @res
-		
-		it "should ask the doc udpater to delete the thread", ->
-			@DocumentUpdaterHandler.deleteThread
-				.calledWith(@project_id, @doc_id, @thread_id)
-				.should.equal true
-
-		it "should ask the chat handler to delete the thread", ->
-			@ChatApiHandler.deleteThread
-				.calledWith(@project_id, @thread_id)
-				.should.equal true
-
-		it "should tell the client the thread was deleted", ->
-			@EditorRealTimeController.emitToRoom
-				.calledWith(@project_id, "delete-thread", @thread_id)
-				.should.equal true
-
-		it "should return a success code", ->
-			@res.send.calledWith(204).should.equal
-
-	describe "editMessage", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-				thread_id: @thread_id = "mock-thread-id"
-				message_id: @message_id = "mock-thread-id"
-			@req.body =
-				content: @content = "mock-content"
-			@ChatApiHandler.editMessage = sinon.stub().yields()
-			@CommentsController.editMessage @req, @res
-
-		it "should ask the chat handler to edit the comment", ->
-			@ChatApiHandler.editMessage
-				.calledWith(@project_id, @thread_id, @message_id, @content)
-				.should.equal true
-
-		it "should tell the client the comment was edited", ->
-			@EditorRealTimeController.emitToRoom
-				.calledWith(@project_id, "edit-message", @thread_id, @message_id, @content)
-				.should.equal true
-
-		it "should return a success code", ->
-			@res.send.calledWith(204).should.equal
-
-	describe "deleteMessage", ->
-		beforeEach ->
-			@req.params =
-				project_id: @project_id = "mock-project-id"
-				thread_id: @thread_id = "mock-thread-id"
-				message_id: @message_id = "mock-thread-id"
-			@ChatApiHandler.deleteMessage = sinon.stub().yields()
-			@CommentsController.deleteMessage @req, @res
-
-		it "should ask the chat handler to deleted the message", ->
-			@ChatApiHandler.deleteMessage
-				.calledWith(@project_id, @thread_id, @message_id)
-				.should.equal true
-
-		it "should tell the client the message was deleted", ->
-			@EditorRealTimeController.emitToRoom
-				.calledWith(@project_id, "delete-message", @thread_id, @message_id)
-				.should.equal true
-
-		it "should return a success code", ->
-			@res.send.calledWith(204).should.equal
-
-	describe "_injectUserInfoIntoThreads", ->
-		beforeEach ->
-			@users = {
-				"user_id_1": {
-					"mock": "user_1"
-				}
-				"user_id_2": {
-					"mock": "user_2"
-				}
-			}
-			@UserInfoManager.getPersonalInfo = (user_id, callback) =>
-				return callback(null, @users[user_id])
-			sinon.spy @UserInfoManager, "getPersonalInfo"
-			@UserInfoController.formatPersonalInfo = (user) ->
-				return { "formatted": user["mock"] }
-			
-		it "should inject a user object into messaged and resolved data", (done) ->
-			@CommentsController._injectUserInfoIntoThreads {
-				thread1: {
-					resolved: true
-					resolved_by_user_id: "user_id_1"
-					messages: [{
-						user_id: "user_id_1"
-						content: "foo"
-					}, {
-						user_id: "user_id_2"
-						content: "bar"
-					}]
-				},
-				thread2: {
-					messages: [{
-						user_id: "user_id_1"
-						content: "baz"
-					}]
-				}
-			}, (error, threads) ->
-				expect(threads).to.deep.equal {
-					thread1: {
-						resolved: true
-						resolved_by_user_id: "user_id_1"
-						resolved_by_user: { "formatted": "user_1" }
-						messages: [{
-							user_id: "user_id_1"
-							user: { "formatted": "user_1" }
-							content: "foo"
-						}, {
-							user_id: "user_id_2"
-							user: { "formatted": "user_2" }
-							content: "bar"
-						}]
-					},
-					thread2: {
-						messages: [{
-							user_id: "user_id_1"
-							user: { "formatted": "user_1" }
-							content: "baz"
-						}]
-					}
-				}
-				done()
-
-		it "should only need to look up each user once", (done) ->
-			@CommentsController._injectUserInfoIntoThreads [{
-				messages: [{
-					user_id: "user_id_1"
-					content: "foo"
-				}, {
-					user_id: "user_id_1"
-					content: "bar"
-				}]
-			}], (error, threads) =>
-				@UserInfoManager.getPersonalInfo.calledOnce.should.equal true
-				done()

+ 0 - 55
services/web/test/UnitTests/coffee/TrackChanges/RangesManagerTests.coffee

@@ -1,55 +0,0 @@
-should = require('chai').should()
-SandboxedModule = require('sandboxed-module')
-assert = require('assert')
-sinon = require('sinon')
-path = require "path"
-modulePath = path.join __dirname, "../../../../app/js/Features/TrackChanges/RangesManager"
-expect = require("chai").expect
-
-describe "RangesManager", ->
-	beforeEach ->
-		@RangesManager = SandboxedModule.require modulePath, requires:
-			"../DocumentUpdater/DocumentUpdaterHandler": @DocumentUpdaterHandler = {}
-			"../Docstore/DocstoreManager": @DocstoreManager = {}
-			"../User/UserInfoManager": @UserInfoManager = {}
-
-	describe "getAllChangesUsers", ->
-		beforeEach ->
-			@project_id = "mock-project-id"
-			@user_id1 = "mock-user-id-1"
-			@user_id1 = "mock-user-id-2"
-			@docs = [{
-				ranges:
-					changes: [{
-						op: { i: "foo", p: 42 }
-						metadata:
-							user_id: @user_id1
-					}, {
-						op: { i: "bar", p: 102 }
-						metadata:
-							user_id: @user_id2
-					}]
-			}, {
-				ranges:
-					changes: [{
-						op: { i: "baz", p: 3 }
-						metadata:
-							user_id: @user_id1
-					}]
-			}]
-			@users = {}
-			@users[@user_id1] = {"mock": "user-1"}
-			@users[@user_id2] = {"mock": "user-2"}
-			@UserInfoManager.getPersonalInfo = (user_id, callback) => callback null, @users[user_id]
-			sinon.spy @UserInfoManager, "getPersonalInfo"
-			@RangesManager.getAllRanges = sinon.stub().yields(null, @docs)
-
-		it "should return an array of unique users", (done) ->
-			@RangesManager.getAllChangesUsers @project_id, (error, users) =>
-				users.should.deep.equal [{"mock": "user-1"}, {"mock": "user-2"}]
-				done()
-
-		it "should only call getPersonalInfo once for each user", (done) ->
-			@RangesManager.getAllChangesUsers @project_id, (error, users) =>
-				@UserInfoManager.getPersonalInfo.calledTwice.should.equal true
-				done()