CommentsControllerTests.coffee 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. should = require('chai').should()
  2. SandboxedModule = require('sandboxed-module')
  3. assert = require('assert')
  4. path = require('path')
  5. sinon = require('sinon')
  6. modulePath = path.join __dirname, "../../../../app/js/Features/Comments/CommentsController"
  7. expect = require("chai").expect
  8. describe "CommentsController", ->
  9. beforeEach ->
  10. @user_id = 'mock-user-id'
  11. @settings = {}
  12. @ChatApiHandler = {}
  13. @EditorRealTimeController =
  14. emitToRoom:sinon.stub()
  15. @AuthenticationController =
  16. getLoggedInUserId: sinon.stub().returns(@user_id)
  17. @CommentsController = SandboxedModule.require modulePath, requires:
  18. "settings-sharelatex": @settings
  19. "logger-sharelatex": log: ->
  20. "../Chat/ChatApiHandler": @ChatApiHandler
  21. "../Editor/EditorRealTimeController": @EditorRealTimeController
  22. '../Authentication/AuthenticationController': @AuthenticationController
  23. '../User/UserInfoManager': @UserInfoManager = {}
  24. '../User/UserInfoController': @UserInfoController = {}
  25. "../DocumentUpdater/DocumentUpdaterHandler": @DocumentUpdaterHandler = {}
  26. @req = {}
  27. @res =
  28. json: sinon.stub()
  29. send: sinon.stub()
  30. describe "sendComment", ->
  31. beforeEach ->
  32. @req.params =
  33. project_id: @project_id = "mock-project-id"
  34. thread_id: @thread_id = "mock-thread-id"
  35. @req.body =
  36. content: @content = "message-content"
  37. @UserInfoManager.getPersonalInfo = sinon.stub().yields(null, @user = {"unformatted": "user"})
  38. @UserInfoController.formatPersonalInfo = sinon.stub().returns(@formatted_user = {"formatted": "user"})
  39. @ChatApiHandler.sendComment = sinon.stub().yields(null, @message = {"mock": "message", user_id: @user_id})
  40. @CommentsController.sendComment @req, @res
  41. it "should look up the user", ->
  42. @UserInfoManager.getPersonalInfo
  43. .calledWith(@user_id)
  44. .should.equal true
  45. it "should format and inject the user into the comment", ->
  46. @UserInfoController.formatPersonalInfo
  47. .calledWith(@user)
  48. .should.equal true
  49. @message.user.should.deep.equal @formatted_user
  50. it "should tell the chat handler about the message", ->
  51. @ChatApiHandler.sendComment
  52. .calledWith(@project_id, @thread_id, @user_id, @content)
  53. .should.equal true
  54. it "should tell the editor real time controller about the update with the data from the chat handler", ->
  55. @EditorRealTimeController.emitToRoom
  56. .calledWith(@project_id, "new-comment", @thread_id, @message)
  57. .should.equal true
  58. it "should return a 204 status code", ->
  59. @res.send.calledWith(204).should.equal true
  60. describe "getThreads", ->
  61. beforeEach ->
  62. @req.params =
  63. project_id: @project_id = "mock-project-id"
  64. @ChatApiHandler.getThreads = sinon.stub().yields(null, @threads = {"mock", "threads"})
  65. @CommentsController._injectUserInfoIntoThreads = sinon.stub().yields(null, @threads)
  66. @CommentsController.getThreads @req, @res
  67. it "should ask the chat handler about the request", ->
  68. @ChatApiHandler.getThreads
  69. .calledWith(@project_id)
  70. .should.equal true
  71. it "should inject the user details into the threads", ->
  72. @CommentsController._injectUserInfoIntoThreads
  73. .calledWith(@threads)
  74. .should.equal true
  75. it "should return the messages", ->
  76. @res.json.calledWith(@threads).should.equal true
  77. describe "resolveThread", ->
  78. beforeEach ->
  79. @req.params =
  80. project_id: @project_id = "mock-project-id"
  81. thread_id: @thread_id = "mock-thread-id"
  82. @ChatApiHandler.resolveThread = sinon.stub().yields()
  83. @UserInfoManager.getPersonalInfo = sinon.stub().yields(null, @user = {"unformatted": "user"})
  84. @UserInfoController.formatPersonalInfo = sinon.stub().returns(@formatted_user = {"formatted": "user"})
  85. @CommentsController.resolveThread @req, @res
  86. it "should ask the chat handler to resolve the thread", ->
  87. @ChatApiHandler.resolveThread
  88. .calledWith(@project_id, @thread_id)
  89. .should.equal true
  90. it "should look up the user", ->
  91. @UserInfoManager.getPersonalInfo
  92. .calledWith(@user_id)
  93. .should.equal true
  94. it "should tell the client the comment was resolved", ->
  95. @EditorRealTimeController.emitToRoom
  96. .calledWith(@project_id, "resolve-thread", @thread_id, @formatted_user)
  97. .should.equal true
  98. it "should return a success code", ->
  99. @res.send.calledWith(204).should.equal
  100. describe "reopenThread", ->
  101. beforeEach ->
  102. @req.params =
  103. project_id: @project_id = "mock-project-id"
  104. thread_id: @thread_id = "mock-thread-id"
  105. @ChatApiHandler.reopenThread = sinon.stub().yields()
  106. @CommentsController.reopenThread @req, @res
  107. it "should ask the chat handler to reopen the thread", ->
  108. @ChatApiHandler.reopenThread
  109. .calledWith(@project_id, @thread_id)
  110. .should.equal true
  111. it "should tell the client the comment was resolved", ->
  112. @EditorRealTimeController.emitToRoom
  113. .calledWith(@project_id, "reopen-thread", @thread_id)
  114. .should.equal true
  115. it "should return a success code", ->
  116. @res.send.calledWith(204).should.equal
  117. describe "deleteThread", ->
  118. beforeEach ->
  119. @req.params =
  120. project_id: @project_id = "mock-project-id"
  121. doc_id: @doc_id = "mock-doc-id"
  122. thread_id: @thread_id = "mock-thread-id"
  123. @DocumentUpdaterHandler.deleteThread = sinon.stub().yields()
  124. @ChatApiHandler.deleteThread = sinon.stub().yields()
  125. @CommentsController.deleteThread @req, @res
  126. it "should ask the doc udpater to delete the thread", ->
  127. @DocumentUpdaterHandler.deleteThread
  128. .calledWith(@project_id, @doc_id, @thread_id)
  129. .should.equal true
  130. it "should ask the chat handler to delete the thread", ->
  131. @ChatApiHandler.deleteThread
  132. .calledWith(@project_id, @thread_id)
  133. .should.equal true
  134. it "should tell the client the thread was deleted", ->
  135. @EditorRealTimeController.emitToRoom
  136. .calledWith(@project_id, "delete-thread", @thread_id)
  137. .should.equal true
  138. it "should return a success code", ->
  139. @res.send.calledWith(204).should.equal
  140. describe "editMessage", ->
  141. beforeEach ->
  142. @req.params =
  143. project_id: @project_id = "mock-project-id"
  144. thread_id: @thread_id = "mock-thread-id"
  145. message_id: @message_id = "mock-thread-id"
  146. @req.body =
  147. content: @content = "mock-content"
  148. @ChatApiHandler.editMessage = sinon.stub().yields()
  149. @CommentsController.editMessage @req, @res
  150. it "should ask the chat handler to edit the comment", ->
  151. @ChatApiHandler.editMessage
  152. .calledWith(@project_id, @thread_id, @message_id, @content)
  153. .should.equal true
  154. it "should tell the client the comment was edited", ->
  155. @EditorRealTimeController.emitToRoom
  156. .calledWith(@project_id, "edit-message", @thread_id, @message_id, @content)
  157. .should.equal true
  158. it "should return a success code", ->
  159. @res.send.calledWith(204).should.equal
  160. describe "deleteMessage", ->
  161. beforeEach ->
  162. @req.params =
  163. project_id: @project_id = "mock-project-id"
  164. thread_id: @thread_id = "mock-thread-id"
  165. message_id: @message_id = "mock-thread-id"
  166. @ChatApiHandler.deleteMessage = sinon.stub().yields()
  167. @CommentsController.deleteMessage @req, @res
  168. it "should ask the chat handler to deleted the message", ->
  169. @ChatApiHandler.deleteMessage
  170. .calledWith(@project_id, @thread_id, @message_id)
  171. .should.equal true
  172. it "should tell the client the message was deleted", ->
  173. @EditorRealTimeController.emitToRoom
  174. .calledWith(@project_id, "delete-message", @thread_id, @message_id)
  175. .should.equal true
  176. it "should return a success code", ->
  177. @res.send.calledWith(204).should.equal
  178. describe "_injectUserInfoIntoThreads", ->
  179. beforeEach ->
  180. @users = {
  181. "user_id_1": {
  182. "mock": "user_1"
  183. }
  184. "user_id_2": {
  185. "mock": "user_2"
  186. }
  187. }
  188. @UserInfoManager.getPersonalInfo = (user_id, callback) =>
  189. return callback(null, @users[user_id])
  190. sinon.spy @UserInfoManager, "getPersonalInfo"
  191. @UserInfoController.formatPersonalInfo = (user) ->
  192. return { "formatted": user["mock"] }
  193. it "should inject a user object into messaged and resolved data", (done) ->
  194. @CommentsController._injectUserInfoIntoThreads {
  195. thread1: {
  196. resolved: true
  197. resolved_by_user_id: "user_id_1"
  198. messages: [{
  199. user_id: "user_id_1"
  200. content: "foo"
  201. }, {
  202. user_id: "user_id_2"
  203. content: "bar"
  204. }]
  205. },
  206. thread2: {
  207. messages: [{
  208. user_id: "user_id_1"
  209. content: "baz"
  210. }]
  211. }
  212. }, (error, threads) ->
  213. expect(threads).to.deep.equal {
  214. thread1: {
  215. resolved: true
  216. resolved_by_user_id: "user_id_1"
  217. resolved_by_user: { "formatted": "user_1" }
  218. messages: [{
  219. user_id: "user_id_1"
  220. user: { "formatted": "user_1" }
  221. content: "foo"
  222. }, {
  223. user_id: "user_id_2"
  224. user: { "formatted": "user_2" }
  225. content: "bar"
  226. }]
  227. },
  228. thread2: {
  229. messages: [{
  230. user_id: "user_id_1"
  231. user: { "formatted": "user_1" }
  232. content: "baz"
  233. }]
  234. }
  235. }
  236. done()
  237. it "should only need to look up each user once", (done) ->
  238. @CommentsController._injectUserInfoIntoThreads [{
  239. messages: [{
  240. user_id: "user_id_1"
  241. content: "foo"
  242. }, {
  243. user_id: "user_id_1"
  244. content: "bar"
  245. }]
  246. }], (error, threads) =>
  247. @UserInfoManager.getPersonalInfo.calledOnce.should.equal true
  248. done()