NotificationsTests.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. no-dupe-keys,
  5. no-return-assign,
  6. no-unused-vars,
  7. */
  8. // TODO: This file was created by bulk-decaffeinate.
  9. // Fix any style issues and re-enable lint.
  10. /*
  11. * decaffeinate suggestions:
  12. * DS102: Remove unnecessary code created because of implicit returns
  13. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  14. */
  15. const sinon = require('sinon')
  16. const chai = require('chai')
  17. const expect = chai.should
  18. const should = chai.should()
  19. const modulePath = '../../../app/js/Notifications.js'
  20. const SandboxedModule = require('sandboxed-module')
  21. const assert = require('assert')
  22. const { ObjectId } = require('mongojs')
  23. const user_id = '51dc93e6fb625a261300003b'
  24. const notification_id = 'fb625a26f09d'
  25. const notification_key = 'notification-key'
  26. describe('Notifications Tests', function() {
  27. beforeEach(function() {
  28. const self = this
  29. this.findStub = sinon.stub()
  30. this.insertStub = sinon.stub()
  31. this.countStub = sinon.stub()
  32. this.updateStub = sinon.stub()
  33. this.removeStub = sinon.stub()
  34. this.mongojs = () => {
  35. return {
  36. notifications: {
  37. update: self.mongojsUpdate,
  38. find: this.findStub,
  39. insert: this.insertStub,
  40. count: this.countStub,
  41. update: this.updateStub,
  42. remove: this.removeStub
  43. }
  44. }
  45. }
  46. this.mongojs.ObjectId = ObjectId
  47. this.notifications = SandboxedModule.require(modulePath, {
  48. requires: {
  49. 'logger-sharelatex': {
  50. log() {},
  51. error() {}
  52. },
  53. 'settings-sharelatex': {},
  54. mongojs: this.mongojs,
  55. 'metrics-sharelatex': { timeAsyncMethod: sinon.stub() }
  56. },
  57. globals: {
  58. console
  59. }
  60. })
  61. this.stubbedNotification = {
  62. user_id: ObjectId(user_id),
  63. key: 'notification-key',
  64. messageOpts: 'some info',
  65. templateKey: 'template-key'
  66. }
  67. return (this.stubbedNotificationArray = [this.stubbedNotification])
  68. })
  69. describe('getUserNotifications', function() {
  70. return it('should find all notifications and return i', function(done) {
  71. this.findStub.callsArgWith(1, null, this.stubbedNotificationArray)
  72. return this.notifications.getUserNotifications(
  73. user_id,
  74. (err, notifications) => {
  75. notifications.should.equal(this.stubbedNotificationArray)
  76. assert.deepEqual(this.findStub.args[0][0], {
  77. user_id: ObjectId(user_id),
  78. templateKey: { $exists: true }
  79. })
  80. return done()
  81. }
  82. )
  83. })
  84. })
  85. describe('addNotification', function() {
  86. beforeEach(function() {
  87. this.stubbedNotification = {
  88. user_id: ObjectId(user_id),
  89. key: 'notification-key',
  90. messageOpts: 'some info',
  91. templateKey: 'template-key'
  92. }
  93. this.expectedDocument = {
  94. user_id: this.stubbedNotification.user_id,
  95. key: 'notification-key',
  96. messageOpts: 'some info',
  97. templateKey: 'template-key'
  98. }
  99. this.expectedQuery = {
  100. user_id: this.stubbedNotification.user_id,
  101. key: 'notification-key'
  102. }
  103. this.updateStub.yields()
  104. return this.countStub.yields(null, 0)
  105. })
  106. it('should insert the notification into the collection', function(done) {
  107. return this.notifications.addNotification(
  108. user_id,
  109. this.stubbedNotification,
  110. err => {
  111. expect(err).not.exists
  112. sinon.assert.calledWith(
  113. this.updateStub,
  114. this.expectedQuery,
  115. this.expectedDocument,
  116. { upsert: true }
  117. )
  118. return done()
  119. }
  120. )
  121. })
  122. describe('when there is an existing notification', function(done) {
  123. beforeEach(function() {
  124. return this.countStub.yields(null, 1)
  125. })
  126. it('should fail to insert', function(done) {
  127. return this.notifications.addNotification(
  128. user_id,
  129. this.stubbedNotification,
  130. err => {
  131. expect(err).not.exists
  132. sinon.assert.notCalled(this.updateStub)
  133. return done()
  134. }
  135. )
  136. })
  137. return it('should update the key if forceCreate is true', function(done) {
  138. this.stubbedNotification.forceCreate = true
  139. return this.notifications.addNotification(
  140. user_id,
  141. this.stubbedNotification,
  142. err => {
  143. expect(err).not.exists
  144. sinon.assert.calledWith(
  145. this.updateStub,
  146. this.expectedQuery,
  147. this.expectedDocument,
  148. { upsert: true }
  149. )
  150. return done()
  151. }
  152. )
  153. })
  154. })
  155. describe('when the notification is set to expire', function() {
  156. beforeEach(function() {
  157. this.stubbedNotification = {
  158. user_id: ObjectId(user_id),
  159. key: 'notification-key',
  160. messageOpts: 'some info',
  161. templateKey: 'template-key',
  162. expires: '2922-02-13T09:32:56.289Z'
  163. }
  164. this.expectedDocument = {
  165. user_id: this.stubbedNotification.user_id,
  166. key: 'notification-key',
  167. messageOpts: 'some info',
  168. templateKey: 'template-key',
  169. expires: new Date(this.stubbedNotification.expires)
  170. }
  171. return (this.expectedQuery = {
  172. user_id: this.stubbedNotification.user_id,
  173. key: 'notification-key'
  174. })
  175. })
  176. return it('should add an `expires` Date field to the document', function(done) {
  177. return this.notifications.addNotification(
  178. user_id,
  179. this.stubbedNotification,
  180. err => {
  181. expect(err).not.exists
  182. sinon.assert.calledWith(
  183. this.updateStub,
  184. this.expectedQuery,
  185. this.expectedDocument,
  186. { upsert: true }
  187. )
  188. return done()
  189. }
  190. )
  191. })
  192. })
  193. return describe('when the notification has a nonsensical expires field', function() {
  194. beforeEach(function() {
  195. this.stubbedNotification = {
  196. user_id: ObjectId(user_id),
  197. key: 'notification-key',
  198. messageOpts: 'some info',
  199. templateKey: 'template-key',
  200. expires: 'WAT'
  201. }
  202. return (this.expectedDocument = {
  203. user_id: this.stubbedNotification.user_id,
  204. key: 'notification-key',
  205. messageOpts: 'some info',
  206. templateKey: 'template-key',
  207. expires: new Date(this.stubbedNotification.expires)
  208. })
  209. })
  210. return it('should produce an error', function(done) {
  211. return this.notifications.addNotification(
  212. user_id,
  213. this.stubbedNotification,
  214. err => {
  215. ;(err instanceof Error).should.equal(true)
  216. sinon.assert.notCalled(this.updateStub)
  217. return done()
  218. }
  219. )
  220. })
  221. })
  222. })
  223. describe('removeNotificationId', function() {
  224. return it('should mark the notification id as read', function(done) {
  225. this.updateStub.callsArgWith(2, null)
  226. return this.notifications.removeNotificationId(
  227. user_id,
  228. notification_id,
  229. err => {
  230. const searchOps = {
  231. user_id: ObjectId(user_id),
  232. _id: ObjectId(notification_id)
  233. }
  234. const updateOperation = {
  235. $unset: { templateKey: true, messageOpts: true }
  236. }
  237. assert.deepEqual(this.updateStub.args[0][0], searchOps)
  238. assert.deepEqual(this.updateStub.args[0][1], updateOperation)
  239. return done()
  240. }
  241. )
  242. })
  243. })
  244. describe('removeNotificationKey', function() {
  245. return it('should mark the notification key as read', function(done) {
  246. this.updateStub.callsArgWith(2, null)
  247. return this.notifications.removeNotificationKey(
  248. user_id,
  249. notification_key,
  250. err => {
  251. const searchOps = {
  252. user_id: ObjectId(user_id),
  253. key: notification_key
  254. }
  255. const updateOperation = {
  256. $unset: { templateKey: true }
  257. }
  258. assert.deepEqual(this.updateStub.args[0][0], searchOps)
  259. assert.deepEqual(this.updateStub.args[0][1], updateOperation)
  260. return done()
  261. }
  262. )
  263. })
  264. })
  265. describe('removeNotificationByKeyOnly', function() {
  266. return it('should mark the notification key as read', function(done) {
  267. this.updateStub.callsArgWith(2, null)
  268. return this.notifications.removeNotificationByKeyOnly(
  269. notification_key,
  270. err => {
  271. const searchOps = { key: notification_key }
  272. const updateOperation = { $unset: { templateKey: true } }
  273. assert.deepEqual(this.updateStub.args[0][0], searchOps)
  274. assert.deepEqual(this.updateStub.args[0][1], updateOperation)
  275. return done()
  276. }
  277. )
  278. })
  279. })
  280. return describe('deleteNotificationByKeyOnly', function() {
  281. return it('should completely remove the notification', function(done) {
  282. this.removeStub.callsArgWith(2, null)
  283. return this.notifications.deleteNotificationByKeyOnly(
  284. notification_key,
  285. err => {
  286. const searchOps = { key: notification_key }
  287. const opts = { justOne: true }
  288. assert.deepEqual(this.removeStub.args[0][0], searchOps)
  289. assert.deepEqual(this.removeStub.args[0][1], opts)
  290. return done()
  291. }
  292. )
  293. })
  294. })
  295. })