@sync-in/server 1.3.9 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +5 -3
  3. package/environment/environment.dist.yaml +2 -0
  4. package/package.json +6 -6
  5. package/server/app.bootstrap.js +9 -0
  6. package/server/app.bootstrap.js.map +1 -1
  7. package/server/app.service.spec.js +44 -19
  8. package/server/app.service.spec.js.map +1 -1
  9. package/server/applications/comments/comments.controller.spec.js +103 -4
  10. package/server/applications/comments/comments.controller.spec.js.map +1 -1
  11. package/server/applications/comments/services/comments-manager.service.spec.js +409 -9
  12. package/server/applications/comments/services/comments-manager.service.spec.js.map +1 -1
  13. package/server/applications/files/adapters/files-indexer-mysql.service.spec.js +333 -0
  14. package/server/applications/files/adapters/files-indexer-mysql.service.spec.js.map +1 -0
  15. package/server/applications/files/constants/files.js +0 -23
  16. package/server/applications/files/constants/files.js.map +1 -1
  17. package/server/applications/files/constants/only-office.js +8 -0
  18. package/server/applications/files/constants/only-office.js.map +1 -1
  19. package/server/applications/files/constants/routes.js +6 -1
  20. package/server/applications/files/constants/routes.js.map +1 -1
  21. package/server/applications/files/files-only-office.controller.js +11 -0
  22. package/server/applications/files/files-only-office.controller.js.map +1 -1
  23. package/server/applications/files/files-only-office.controller.spec.js +97 -3
  24. package/server/applications/files/files-only-office.controller.spec.js.map +1 -1
  25. package/server/applications/files/files-tasks.controller.spec.js +91 -1
  26. package/server/applications/files/files-tasks.controller.spec.js.map +1 -1
  27. package/server/applications/files/files.config.js +5 -0
  28. package/server/applications/files/files.config.js.map +1 -1
  29. package/server/applications/files/files.controller.spec.js +268 -46
  30. package/server/applications/files/files.controller.spec.js.map +1 -1
  31. package/server/applications/files/guards/files-only-office.guard.spec.js +77 -1
  32. package/server/applications/files/guards/files-only-office.guard.spec.js.map +1 -1
  33. package/server/applications/files/guards/files-only-office.strategy.js +0 -1
  34. package/server/applications/files/guards/files-only-office.strategy.js.map +1 -1
  35. package/server/applications/files/services/files-only-office-manager.service.js +5 -0
  36. package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
  37. package/server/applications/links/links.controller.spec.js +91 -58
  38. package/server/applications/links/links.controller.spec.js.map +1 -1
  39. package/server/applications/links/services/links-manager.service.js +4 -6
  40. package/server/applications/links/services/links-manager.service.js.map +1 -1
  41. package/server/applications/links/services/links-manager.service.spec.js +378 -14
  42. package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
  43. package/server/applications/links/services/links-queries.service.js +1 -1
  44. package/server/applications/links/services/links-queries.service.js.map +1 -1
  45. package/server/applications/notifications/notifications.controller.spec.js +56 -1
  46. package/server/applications/notifications/notifications.controller.spec.js.map +1 -1
  47. package/server/applications/notifications/services/notifications-manager.service.spec.js +461 -5
  48. package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
  49. package/server/applications/shares/services/shares-manager.service.spec.js +590 -14
  50. package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
  51. package/server/applications/spaces/guards/space.guard.spec.js +153 -18
  52. package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
  53. package/server/applications/spaces/services/spaces-browser.service.js +7 -7
  54. package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
  55. package/server/applications/spaces/services/spaces-manager.service.js +17 -17
  56. package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
  57. package/server/applications/sync/interceptors/sync-diff-gzip-body.interceptor.spec.js +120 -0
  58. package/server/applications/sync/interceptors/sync-diff-gzip-body.interceptor.spec.js.map +1 -0
  59. package/server/applications/sync/services/sync-clients-manager.service.spec.js +548 -8
  60. package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
  61. package/server/applications/sync/services/sync-manager.service.spec.js +837 -5
  62. package/server/applications/sync/services/sync-manager.service.spec.js.map +1 -1
  63. package/server/applications/sync/services/sync-paths-manager.service.spec.js +900 -7
  64. package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
  65. package/server/applications/sync/utils/routes.js +1 -1
  66. package/server/applications/sync/utils/routes.js.map +1 -1
  67. package/server/applications/users/guards/permissions.guard.js +4 -4
  68. package/server/applications/users/guards/permissions.guard.js.map +1 -1
  69. package/server/applications/users/guards/permissions.guard.spec.js +6 -6
  70. package/server/applications/users/guards/permissions.guard.spec.js.map +1 -1
  71. package/server/applications/users/guards/roles.guard.js +1 -1
  72. package/server/applications/users/guards/roles.guard.js.map +1 -1
  73. package/server/applications/users/models/user.model.js +1 -1
  74. package/server/applications/users/models/user.model.js.map +1 -1
  75. package/server/applications/users/services/admin-users-manager.service.js +22 -24
  76. package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
  77. package/server/applications/users/services/admin-users-manager.service.spec.js +763 -17
  78. package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
  79. package/server/applications/users/services/users-manager.service.js +1 -1
  80. package/server/applications/users/services/users-manager.service.js.map +1 -1
  81. package/server/applications/users/services/users-manager.service.spec.js +938 -49
  82. package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
  83. package/server/applications/webdav/decorators/if-header.decorator.js +4 -1
  84. package/server/applications/webdav/decorators/if-header.decorator.js.map +1 -1
  85. package/server/applications/webdav/filters/webdav.filter.spec.js +77 -0
  86. package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -0
  87. package/server/applications/webdav/guards/webdav-protocol.guard.js +3 -7
  88. package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
  89. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +580 -0
  90. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -0
  91. package/server/applications/webdav/services/webdav-methods.service.spec.js +1582 -3
  92. package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
  93. package/server/applications/webdav/services/webdav-spaces.service.spec.js +390 -2
  94. package/server/applications/webdav/services/webdav-spaces.service.spec.js.map +1 -1
  95. package/server/applications/webdav/webdav.controller.js +2 -2
  96. package/server/applications/webdav/webdav.controller.js.map +1 -1
  97. package/server/authentication/guards/auth-basic.guard.js.map +1 -1
  98. package/server/authentication/guards/auth-basic.guard.spec.js +38 -2
  99. package/server/authentication/guards/auth-basic.guard.spec.js.map +1 -1
  100. package/server/authentication/guards/auth-basic.strategy.js +0 -1
  101. package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
  102. package/server/authentication/guards/auth-digest.guard.js +1 -2
  103. package/server/authentication/guards/auth-digest.guard.js.map +1 -1
  104. package/server/authentication/guards/auth-local.guard.js.map +1 -1
  105. package/server/authentication/guards/auth-local.guard.spec.js +7 -5
  106. package/server/authentication/guards/auth-local.guard.spec.js.map +1 -1
  107. package/server/authentication/guards/auth-local.strategy.js +0 -1
  108. package/server/authentication/guards/auth-local.strategy.js.map +1 -1
  109. package/server/authentication/guards/auth-token-access.guard.spec.js +30 -0
  110. package/server/authentication/guards/auth-token-access.guard.spec.js.map +1 -1
  111. package/server/authentication/guards/auth-token-access.strategy.js +0 -1
  112. package/server/authentication/guards/auth-token-access.strategy.js.map +1 -1
  113. package/server/authentication/guards/auth-token-refresh.strategy.js +0 -1
  114. package/server/authentication/guards/auth-token-refresh.strategy.js.map +1 -1
  115. package/server/authentication/services/auth-methods/auth-method-database.service.js +1 -1
  116. package/server/authentication/services/auth-methods/auth-method-database.service.js.map +1 -1
  117. package/server/authentication/services/auth-methods/auth-method-database.service.spec.js +8 -6
  118. package/server/authentication/services/auth-methods/auth-method-database.service.spec.js.map +1 -1
  119. package/server/authentication/services/auth-methods/auth-method-ldap.service.js +2 -2
  120. package/server/authentication/services/auth-methods/auth-method-ldap.service.js.map +1 -1
  121. package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js +500 -5
  122. package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js.map +1 -1
  123. package/server/configuration/config.loader.js +0 -3
  124. package/server/configuration/config.loader.js.map +1 -1
  125. package/server/infrastructure/context/interceptors/context.interceptor.spec.js +135 -0
  126. package/server/infrastructure/context/interceptors/context.interceptor.spec.js.map +1 -0
  127. package/server/infrastructure/context/services/context-manager.service.spec.js +98 -0
  128. package/server/infrastructure/context/services/context-manager.service.spec.js.map +1 -0
  129. package/server/infrastructure/database/constants.js +0 -1
  130. package/server/infrastructure/database/constants.js.map +1 -1
  131. package/server/infrastructure/database/scripts/seed/usersgroups.js +3 -3
  132. package/server/infrastructure/database/scripts/seed/usersgroups.js.map +1 -1
  133. package/server/infrastructure/mailer/mailer.service.js +20 -19
  134. package/server/infrastructure/mailer/mailer.service.js.map +1 -1
  135. package/server/infrastructure/mailer/mailer.service.spec.js +176 -0
  136. package/server/infrastructure/mailer/mailer.service.spec.js.map +1 -0
  137. package/static/3rdpartylicenses.txt +26 -26
  138. package/static/assets/pdfjs/build/pdf.mjs +1177 -255
  139. package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
  140. package/static/assets/pdfjs/build/pdf.sandbox.mjs +25 -2
  141. package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
  142. package/static/assets/pdfjs/build/pdf.worker.mjs +140 -16
  143. package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
  144. package/static/assets/pdfjs/version +1 -1
  145. package/static/assets/pdfjs/web/debugger.css +31 -0
  146. package/static/assets/pdfjs/web/debugger.mjs +144 -2
  147. package/static/assets/pdfjs/web/images/comment-editButton.svg +6 -1
  148. package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -63
  149. package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -71
  150. package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -63
  151. package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -60
  152. package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -63
  153. package/static/assets/pdfjs/web/locale/be/viewer.ftl +38 -0
  154. package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -37
  155. package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -63
  156. package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -63
  157. package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -37
  158. package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -63
  159. package/static/assets/pdfjs/web/locale/bs/viewer.ftl +22 -0
  160. package/static/assets/pdfjs/web/locale/ca/viewer.ftl +0 -54
  161. package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -54
  162. package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -63
  163. package/static/assets/pdfjs/web/locale/cs/viewer.ftl +38 -0
  164. package/static/assets/pdfjs/web/locale/cy/viewer.ftl +38 -0
  165. package/static/assets/pdfjs/web/locale/da/viewer.ftl +38 -0
  166. package/static/assets/pdfjs/web/locale/de/viewer.ftl +38 -0
  167. package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +38 -0
  168. package/static/assets/pdfjs/web/locale/el/viewer.ftl +38 -0
  169. package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +38 -0
  170. package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +38 -0
  171. package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -0
  172. package/static/assets/pdfjs/web/locale/eo/viewer.ftl +38 -0
  173. package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +38 -0
  174. package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +38 -0
  175. package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -6
  176. package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -57
  177. package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -37
  178. package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -63
  179. package/static/assets/pdfjs/web/locale/fi/viewer.ftl +38 -0
  180. package/static/assets/pdfjs/web/locale/fr/viewer.ftl +38 -0
  181. package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +38 -0
  182. package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -71
  183. package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -54
  184. package/static/assets/pdfjs/web/locale/gl/viewer.ftl +8 -0
  185. package/static/assets/pdfjs/web/locale/gn/viewer.ftl +38 -0
  186. package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -63
  187. package/static/assets/pdfjs/web/locale/he/viewer.ftl +38 -0
  188. package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -60
  189. package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +38 -0
  190. package/static/assets/pdfjs/web/locale/hu/viewer.ftl +38 -0
  191. package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +0 -49
  192. package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -60
  193. package/static/assets/pdfjs/web/locale/ia/viewer.ftl +38 -0
  194. package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -3
  195. package/static/assets/pdfjs/web/locale/it/viewer.ftl +31 -0
  196. package/static/assets/pdfjs/web/locale/ja/viewer.ftl +8 -0
  197. package/static/assets/pdfjs/web/locale/ka/viewer.ftl +48 -10
  198. package/static/assets/pdfjs/web/locale/kab/viewer.ftl +5 -0
  199. package/static/assets/pdfjs/web/locale/kk/viewer.ftl +8 -0
  200. package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -63
  201. package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -71
  202. package/static/assets/pdfjs/web/locale/ko/viewer.ftl +38 -0
  203. package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -63
  204. package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -54
  205. package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -60
  206. package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -63
  207. package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -63
  208. package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -75
  209. package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -63
  210. package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -3
  211. package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -63
  212. package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -63
  213. package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -71
  214. package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +44 -6
  215. package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -71
  216. package/static/assets/pdfjs/web/locale/nl/viewer.ftl +38 -0
  217. package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +45 -1
  218. package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -31
  219. package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +38 -0
  220. package/static/assets/pdfjs/web/locale/pl/viewer.ftl +39 -1
  221. package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +38 -0
  222. package/static/assets/pdfjs/web/locale/ro/viewer.ftl +355 -1
  223. package/static/assets/pdfjs/web/locale/ru/viewer.ftl +38 -0
  224. package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -54
  225. package/static/assets/pdfjs/web/locale/sc/viewer.ftl +0 -38
  226. package/static/assets/pdfjs/web/locale/scn/viewer.ftl +0 -92
  227. package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -60
  228. package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -51
  229. package/static/assets/pdfjs/web/locale/sk/viewer.ftl +38 -0
  230. package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -27
  231. package/static/assets/pdfjs/web/locale/sl/viewer.ftl +8 -0
  232. package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -71
  233. package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -33
  234. package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +38 -0
  235. package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -63
  236. package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -63
  237. package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -60
  238. package/static/assets/pdfjs/web/locale/tg/viewer.ftl +38 -0
  239. package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -63
  240. package/static/assets/pdfjs/web/locale/tr/viewer.ftl +40 -2
  241. package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -72
  242. package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -60
  243. package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -71
  244. package/static/assets/pdfjs/web/locale/vi/viewer.ftl +38 -0
  245. package/static/assets/pdfjs/web/locale/wo/viewer.ftl +0 -77
  246. package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -71
  247. package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +38 -0
  248. package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +38 -0
  249. package/static/assets/pdfjs/web/viewer.css +649 -120
  250. package/static/assets/pdfjs/web/viewer.html +19 -0
  251. package/static/assets/pdfjs/web/viewer.mjs +489 -38
  252. package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
  253. package/static/chunk-22EANI6R.js +1 -0
  254. package/static/{chunk-KFM544CA.js → chunk-2UWN7IQF.js} +1 -1
  255. package/static/{chunk-N3T57OCA.js → chunk-2VSPDSJS.js} +1 -1
  256. package/static/{chunk-HUWQHCUX.js → chunk-34UZ7SYI.js} +1 -1
  257. package/static/{chunk-MWFRZBJD.js → chunk-45UQJGGY.js} +1 -1
  258. package/static/{chunk-LYTD6AJE.js → chunk-5TEXH3LJ.js} +1 -1
  259. package/static/{chunk-4KESSWTF.js → chunk-66FMKVJX.js} +1 -1
  260. package/static/{chunk-XE5YHU5J.js → chunk-BIUNUYZ5.js} +1 -1
  261. package/static/chunk-CK4BY2NX.js +27 -0
  262. package/static/{chunk-QTW62OKJ.js → chunk-CSBDAY77.js} +1 -1
  263. package/static/{chunk-XUZSYWRF.js → chunk-CXXPLBDZ.js} +1 -1
  264. package/static/{chunk-ZTXJC5IC.js → chunk-EILQG525.js} +1 -1
  265. package/static/{chunk-FJFNDK67.js → chunk-ENWABUR4.js} +1 -1
  266. package/static/{chunk-WL65GYD5.js → chunk-FR4AOLYL.js} +4 -4
  267. package/static/chunk-HW2H3ISM.js +559 -0
  268. package/static/{chunk-BW5PQAKK.js → chunk-HYMDGBZL.js} +1 -1
  269. package/static/{chunk-WLPYIJFI.js → chunk-IML5UYQG.js} +1 -1
  270. package/static/{chunk-Z5X7LVMZ.js → chunk-IPSMJHMQ.js} +1 -1
  271. package/static/{chunk-3S4WNZ2T.js → chunk-JVCWYSNP.js} +1 -1
  272. package/static/{chunk-CLSVDV7J.js → chunk-KGPCIUD2.js} +1 -1
  273. package/static/{chunk-O4AQBQBF.js → chunk-KQZJSEM3.js} +1 -1
  274. package/static/{chunk-MK7WZG3F.js → chunk-NPEMJJIU.js} +1 -1
  275. package/static/{chunk-4TEHM3AS.js → chunk-OEFBC4GG.js} +1 -1
  276. package/static/{chunk-O67RFAWU.js → chunk-P734A3XZ.js} +1 -1
  277. package/static/{chunk-SRLMFJ7C.js → chunk-RASR4CK6.js} +1 -1
  278. package/static/{chunk-S5WXHO6D.js → chunk-RFMOUC22.js} +1 -1
  279. package/static/{chunk-TTQ37MUV.js → chunk-RSS6GYNE.js} +1 -1
  280. package/static/{chunk-3FX6ISDY.js → chunk-SBOQGGZX.js} +1 -1
  281. package/static/{chunk-NV2MEIWP.js → chunk-SJAFPXQV.js} +1 -1
  282. package/static/{chunk-PYSFXLMV.js → chunk-XTYGMF2V.js} +1 -1
  283. package/static/{chunk-ZFKCGL6X.js → chunk-YCWMV2YR.js} +1 -1
  284. package/static/{chunk-LB7B5RIV.js → chunk-YGD22MWQ.js} +1 -1
  285. package/static/{chunk-MTRNPGS4.js → chunk-ZC5NIT55.js} +1 -1
  286. package/static/{chunk-SKDQM65G.js → chunk-ZVY37DKS.js} +1 -1
  287. package/static/index.html +2 -2
  288. package/static/main-N5CZRHAO.js +7 -0
  289. package/static/styles-FYUSO6OJ.css +1 -0
  290. package/static/chunk-AY2GOSJ2.js +0 -24
  291. package/static/chunk-RSNLYAN6.js +0 -560
  292. package/static/chunk-ZZ3LHYOY.js +0 -1
  293. package/static/main-RREKR34B.js +0 -10
  294. package/static/styles-3DONJ2Z4.css +0 -1
@@ -11,6 +11,15 @@ const _notificationscontroller = require("./notifications.controller");
11
11
  const _notificationsmanagerservice = require("./services/notifications-manager.service");
12
12
  describe(_notificationscontroller.NotificationsController.name, ()=>{
13
13
  let controller;
14
+ const notificationsManagerMock = {
15
+ list: jest.fn(),
16
+ wasRead: jest.fn(),
17
+ delete: jest.fn()
18
+ };
19
+ const user = {
20
+ id: 1,
21
+ login: 'john.doe'
22
+ };
14
23
  beforeAll(async ()=>{
15
24
  const module = await _testing.Test.createTestingModule({
16
25
  controllers: [
@@ -19,15 +28,61 @@ describe(_notificationscontroller.NotificationsController.name, ()=>{
19
28
  providers: [
20
29
  {
21
30
  provide: _notificationsmanagerservice.NotificationsManager,
22
- useValue: {}
31
+ useValue: notificationsManagerMock
23
32
  }
24
33
  ]
25
34
  }).compile();
26
35
  controller = module.get(_notificationscontroller.NotificationsController);
27
36
  });
37
+ beforeEach(()=>{
38
+ jest.clearAllMocks();
39
+ });
28
40
  it('should be defined', ()=>{
29
41
  expect(controller).toBeDefined();
30
42
  });
43
+ it('list() should return notifications and call manager.list with user', async ()=>{
44
+ const notifications = [
45
+ {
46
+ id: 10
47
+ },
48
+ {
49
+ id: 11
50
+ }
51
+ ];
52
+ notificationsManagerMock.list.mockResolvedValueOnce(notifications);
53
+ await expect(controller.list(user)).resolves.toBe(notifications);
54
+ expect(notificationsManagerMock.list).toHaveBeenCalledTimes(1);
55
+ expect(notificationsManagerMock.list).toHaveBeenCalledWith(user);
56
+ });
57
+ it('listUnread() should return unread notifications and call manager.list with unread=true', async ()=>{
58
+ const notifications = [
59
+ {
60
+ id: 12
61
+ }
62
+ ];
63
+ notificationsManagerMock.list.mockResolvedValueOnce(notifications);
64
+ await expect(controller.listUnread(user)).resolves.toBe(notifications);
65
+ expect(notificationsManagerMock.list).toHaveBeenCalledTimes(1);
66
+ expect(notificationsManagerMock.list).toHaveBeenCalledWith(user, true);
67
+ });
68
+ it('wasRead() should delegate to manager.wasRead with user and id', ()=>{
69
+ notificationsManagerMock.wasRead.mockReturnValueOnce(undefined);
70
+ controller.wasRead(user, 42);
71
+ expect(notificationsManagerMock.wasRead).toHaveBeenCalledTimes(1);
72
+ expect(notificationsManagerMock.wasRead).toHaveBeenCalledWith(user, 42);
73
+ });
74
+ it('deleteAll() should call manager.delete with user only', async ()=>{
75
+ notificationsManagerMock.delete.mockResolvedValueOnce(undefined);
76
+ await expect(controller.deleteAll(user)).resolves.toBeUndefined();
77
+ expect(notificationsManagerMock.delete).toHaveBeenCalledTimes(1);
78
+ expect(notificationsManagerMock.delete).toHaveBeenCalledWith(user);
79
+ });
80
+ it('delete(:id) should call manager.delete with user and id', async ()=>{
81
+ notificationsManagerMock.delete.mockResolvedValueOnce(undefined);
82
+ await expect(controller.delete(user, 7)).resolves.toBeUndefined();
83
+ expect(notificationsManagerMock.delete).toHaveBeenCalledTimes(1);
84
+ expect(notificationsManagerMock.delete).toHaveBeenCalledWith(user, 7);
85
+ });
31
86
  });
32
87
 
33
88
  //# sourceMappingURL=notifications.controller.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../backend/src/applications/notifications/notifications.controller.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { NotificationsController } from './notifications.controller'\nimport { NotificationsManager } from './services/notifications-manager.service'\n\ndescribe(NotificationsController.name, () => {\n let controller: NotificationsController\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n controllers: [NotificationsController],\n providers: [{ provide: NotificationsManager, useValue: {} }]\n }).compile()\n\n controller = module.get<NotificationsController>(NotificationsController)\n })\n\n it('should be defined', () => {\n expect(controller).toBeDefined()\n })\n})\n"],"names":["describe","NotificationsController","name","controller","beforeAll","module","Test","createTestingModule","controllers","providers","provide","NotificationsManager","useValue","compile","get","it","expect","toBeDefined"],"mappings":"AAAA;;;;CAIC;;;;yBAEmC;yCACI;6CACH;AAErCA,SAASC,gDAAuB,CAACC,IAAI,EAAE;IACrC,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,aAAa;gBAACP,gDAAuB;aAAC;YACtCQ,WAAW;gBAAC;oBAAEC,SAASC,iDAAoB;oBAAEC,UAAU,CAAC;gBAAE;aAAE;QAC9D,GAAGC,OAAO;QAEVV,aAAaE,OAAOS,GAAG,CAA0Bb,gDAAuB;IAC1E;IAEAc,GAAG,qBAAqB;QACtBC,OAAOb,YAAYc,WAAW;IAChC;AACF"}
1
+ {"version":3,"sources":["../../../../backend/src/applications/notifications/notifications.controller.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { NotificationsController } from './notifications.controller'\nimport { NotificationsManager } from './services/notifications-manager.service'\n\ndescribe(NotificationsController.name, () => {\n let controller: NotificationsController\n const notificationsManagerMock: jest.Mocked<NotificationsManager> = {\n list: jest.fn(),\n wasRead: jest.fn(),\n delete: jest.fn()\n } as unknown as jest.Mocked<NotificationsManager>\n\n const user = { id: 1, login: 'john.doe' } as any\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n controllers: [NotificationsController],\n providers: [{ provide: NotificationsManager, useValue: notificationsManagerMock }]\n }).compile()\n\n controller = module.get<NotificationsController>(NotificationsController)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(controller).toBeDefined()\n })\n\n it('list() should return notifications and call manager.list with user', async () => {\n const notifications = [{ id: 10 }, { id: 11 }] as any\n notificationsManagerMock.list.mockResolvedValueOnce(notifications)\n\n await expect(controller.list(user)).resolves.toBe(notifications)\n expect(notificationsManagerMock.list).toHaveBeenCalledTimes(1)\n expect(notificationsManagerMock.list).toHaveBeenCalledWith(user)\n })\n\n it('listUnread() should return unread notifications and call manager.list with unread=true', async () => {\n const notifications = [{ id: 12 }] as any\n notificationsManagerMock.list.mockResolvedValueOnce(notifications)\n\n await expect(controller.listUnread(user)).resolves.toBe(notifications)\n expect(notificationsManagerMock.list).toHaveBeenCalledTimes(1)\n expect(notificationsManagerMock.list).toHaveBeenCalledWith(user, true)\n })\n\n it('wasRead() should delegate to manager.wasRead with user and id', () => {\n notificationsManagerMock.wasRead.mockReturnValueOnce(undefined as unknown as void)\n\n controller.wasRead(user, 42)\n expect(notificationsManagerMock.wasRead).toHaveBeenCalledTimes(1)\n expect(notificationsManagerMock.wasRead).toHaveBeenCalledWith(user, 42)\n })\n\n it('deleteAll() should call manager.delete with user only', async () => {\n notificationsManagerMock.delete.mockResolvedValueOnce(undefined)\n\n await expect(controller.deleteAll(user)).resolves.toBeUndefined()\n expect(notificationsManagerMock.delete).toHaveBeenCalledTimes(1)\n expect(notificationsManagerMock.delete).toHaveBeenCalledWith(user)\n })\n\n it('delete(:id) should call manager.delete with user and id', async () => {\n notificationsManagerMock.delete.mockResolvedValueOnce(undefined)\n\n await expect(controller.delete(user, 7)).resolves.toBeUndefined()\n expect(notificationsManagerMock.delete).toHaveBeenCalledTimes(1)\n expect(notificationsManagerMock.delete).toHaveBeenCalledWith(user, 7)\n })\n})\n"],"names":["describe","NotificationsController","name","controller","notificationsManagerMock","list","jest","fn","wasRead","delete","user","id","login","beforeAll","module","Test","createTestingModule","controllers","providers","provide","NotificationsManager","useValue","compile","get","beforeEach","clearAllMocks","it","expect","toBeDefined","notifications","mockResolvedValueOnce","resolves","toBe","toHaveBeenCalledTimes","toHaveBeenCalledWith","listUnread","mockReturnValueOnce","undefined","deleteAll","toBeUndefined"],"mappings":"AAAA;;;;CAIC;;;;yBAEmC;yCACI;6CACH;AAErCA,SAASC,gDAAuB,CAACC,IAAI,EAAE;IACrC,IAAIC;IACJ,MAAMC,2BAA8D;QAClEC,MAAMC,KAAKC,EAAE;QACbC,SAASF,KAAKC,EAAE;QAChBE,QAAQH,KAAKC,EAAE;IACjB;IAEA,MAAMG,OAAO;QAAEC,IAAI;QAAGC,OAAO;IAAW;IAExCC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,aAAa;gBAAChB,gDAAuB;aAAC;YACtCiB,WAAW;gBAAC;oBAAEC,SAASC,iDAAoB;oBAAEC,UAAUjB;gBAAyB;aAAE;QACpF,GAAGkB,OAAO;QAEVnB,aAAaW,OAAOS,GAAG,CAA0BtB,gDAAuB;IAC1E;IAEAuB,WAAW;QACTlB,KAAKmB,aAAa;IACpB;IAEAC,GAAG,qBAAqB;QACtBC,OAAOxB,YAAYyB,WAAW;IAChC;IAEAF,GAAG,sEAAsE;QACvE,MAAMG,gBAAgB;YAAC;gBAAElB,IAAI;YAAG;YAAG;gBAAEA,IAAI;YAAG;SAAE;QAC9CP,yBAAyBC,IAAI,CAACyB,qBAAqB,CAACD;QAEpD,MAAMF,OAAOxB,WAAWE,IAAI,CAACK,OAAOqB,QAAQ,CAACC,IAAI,CAACH;QAClDF,OAAOvB,yBAAyBC,IAAI,EAAE4B,qBAAqB,CAAC;QAC5DN,OAAOvB,yBAAyBC,IAAI,EAAE6B,oBAAoB,CAACxB;IAC7D;IAEAgB,GAAG,0FAA0F;QAC3F,MAAMG,gBAAgB;YAAC;gBAAElB,IAAI;YAAG;SAAE;QAClCP,yBAAyBC,IAAI,CAACyB,qBAAqB,CAACD;QAEpD,MAAMF,OAAOxB,WAAWgC,UAAU,CAACzB,OAAOqB,QAAQ,CAACC,IAAI,CAACH;QACxDF,OAAOvB,yBAAyBC,IAAI,EAAE4B,qBAAqB,CAAC;QAC5DN,OAAOvB,yBAAyBC,IAAI,EAAE6B,oBAAoB,CAACxB,MAAM;IACnE;IAEAgB,GAAG,iEAAiE;QAClEtB,yBAAyBI,OAAO,CAAC4B,mBAAmB,CAACC;QAErDlC,WAAWK,OAAO,CAACE,MAAM;QACzBiB,OAAOvB,yBAAyBI,OAAO,EAAEyB,qBAAqB,CAAC;QAC/DN,OAAOvB,yBAAyBI,OAAO,EAAE0B,oBAAoB,CAACxB,MAAM;IACtE;IAEAgB,GAAG,yDAAyD;QAC1DtB,yBAAyBK,MAAM,CAACqB,qBAAqB,CAACO;QAEtD,MAAMV,OAAOxB,WAAWmC,SAAS,CAAC5B,OAAOqB,QAAQ,CAACQ,aAAa;QAC/DZ,OAAOvB,yBAAyBK,MAAM,EAAEwB,qBAAqB,CAAC;QAC9DN,OAAOvB,yBAAyBK,MAAM,EAAEyB,oBAAoB,CAACxB;IAC/D;IAEAgB,GAAG,2DAA2D;QAC5DtB,yBAAyBK,MAAM,CAACqB,qBAAqB,CAACO;QAEtD,MAAMV,OAAOxB,WAAWM,MAAM,CAACC,MAAM,IAAIqB,QAAQ,CAACQ,aAAa;QAC/DZ,OAAOvB,yBAAyBK,MAAM,EAAEwB,qBAAqB,CAAC;QAC9DN,OAAOvB,yBAAyBK,MAAM,EAAEyB,oBAAoB,CAACxB,MAAM;IACrE;AACF"}
@@ -8,31 +8,131 @@ Object.defineProperty(exports, "__esModule", {
8
8
  });
9
9
  const _testing = require("@nestjs/testing");
10
10
  const _mailerservice = require("../../../infrastructure/mailer/mailer.service");
11
+ const _user = require("../../users/constants/user");
11
12
  const _usersmanagerservice = require("../../users/services/users-manager.service");
13
+ const _notifications = require("../constants/notifications");
14
+ const _websocket = require("../constants/websocket");
15
+ const _models = /*#__PURE__*/ _interop_require_wildcard(require("../mails/models"));
12
16
  const _notificationsgateway = require("../notifications.gateway");
13
17
  const _notificationsmanagerservice = require("./notifications-manager.service");
14
18
  const _notificationsqueriesservice = require("./notifications-queries.service");
19
+ function _getRequireWildcardCache(nodeInterop) {
20
+ if (typeof WeakMap !== "function") return null;
21
+ var cacheBabelInterop = new WeakMap();
22
+ var cacheNodeInterop = new WeakMap();
23
+ return (_getRequireWildcardCache = function(nodeInterop) {
24
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
25
+ })(nodeInterop);
26
+ }
27
+ function _interop_require_wildcard(obj, nodeInterop) {
28
+ if (!nodeInterop && obj && obj.__esModule) {
29
+ return obj;
30
+ }
31
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
32
+ return {
33
+ default: obj
34
+ };
35
+ }
36
+ var cache = _getRequireWildcardCache(nodeInterop);
37
+ if (cache && cache.has(obj)) {
38
+ return cache.get(obj);
39
+ }
40
+ var newObj = {
41
+ __proto__: null
42
+ };
43
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
44
+ for(var key in obj){
45
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
46
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
47
+ if (desc && (desc.get || desc.set)) {
48
+ Object.defineProperty(newObj, key, desc);
49
+ } else {
50
+ newObj[key] = obj[key];
51
+ }
52
+ }
53
+ }
54
+ newObj.default = obj;
55
+ if (cache) {
56
+ cache.set(obj, newObj);
57
+ }
58
+ return newObj;
59
+ }
60
+ // Compact mock for mail generators
61
+ jest.mock('../mails/models', ()=>({
62
+ commentMail: jest.fn(()=>[
63
+ 'comment title',
64
+ 'comment html'
65
+ ]),
66
+ spaceMail: jest.fn(()=>[
67
+ 'space title',
68
+ 'space html'
69
+ ]),
70
+ spaceRootMail: jest.fn(()=>[
71
+ 'spaceRoot title',
72
+ 'spaceRoot html'
73
+ ]),
74
+ shareMail: jest.fn(()=>[
75
+ 'share title',
76
+ 'share html'
77
+ ]),
78
+ linkMail: jest.fn(()=>[
79
+ 'link title',
80
+ 'link html'
81
+ ]),
82
+ syncMail: jest.fn(()=>[
83
+ 'sync title',
84
+ 'sync html'
85
+ ])
86
+ }));
15
87
  describe(_notificationsmanagerservice.NotificationsManager.name, ()=>{
16
88
  let service;
17
- beforeAll(async ()=>{
89
+ const usersManagerMock = {
90
+ getAvatarBase64: jest.fn()
91
+ };
92
+ const mailerMock = {
93
+ available: true,
94
+ sendMails: jest.fn()
95
+ };
96
+ const notificationsQueriesMock = {
97
+ list: jest.fn(),
98
+ usersNotifiedByEmail: jest.fn(),
99
+ create: jest.fn(),
100
+ wasRead: jest.fn(),
101
+ delete: jest.fn()
102
+ };
103
+ const webSocketNotificationsMock = {
104
+ sendMessageToUsers: jest.fn()
105
+ };
106
+ const flushPromises = ()=>new Promise((r)=>setImmediate(r));
107
+ const spyLogger = ()=>jest.spyOn(service.logger, 'error').mockImplementation(()=>undefined);
108
+ beforeEach(async ()=>{
109
+ jest.clearAllMocks();
110
+ mailerMock.available = true;
111
+ mailerMock.sendMails.mockResolvedValue(undefined);
112
+ notificationsQueriesMock.create.mockResolvedValue(undefined);
113
+ notificationsQueriesMock.wasRead.mockResolvedValue(undefined);
114
+ notificationsQueriesMock.delete.mockResolvedValue(undefined);
115
+ notificationsQueriesMock.list.mockResolvedValue([]);
116
+ notificationsQueriesMock.usersNotifiedByEmail.mockResolvedValue([]);
117
+ usersManagerMock.getAvatarBase64.mockResolvedValue('avatar-base64');
18
118
  const module = await _testing.Test.createTestingModule({
19
119
  providers: [
20
120
  _notificationsmanagerservice.NotificationsManager,
21
121
  {
22
122
  provide: _usersmanagerservice.UsersManager,
23
- useValue: {}
123
+ useValue: usersManagerMock
24
124
  },
25
125
  {
26
126
  provide: _mailerservice.Mailer,
27
- useValue: {}
127
+ useValue: mailerMock
28
128
  },
29
129
  {
30
130
  provide: _notificationsgateway.WebSocketNotifications,
31
- useValue: {}
131
+ useValue: webSocketNotificationsMock
32
132
  },
33
133
  {
34
134
  provide: _notificationsqueriesservice.NotificationsQueries,
35
- useValue: {}
135
+ useValue: notificationsQueriesMock
36
136
  }
37
137
  ]
38
138
  }).compile();
@@ -41,6 +141,362 @@ describe(_notificationsmanagerservice.NotificationsManager.name, ()=>{
41
141
  it('should be defined', ()=>{
42
142
  expect(service).toBeDefined();
43
143
  });
144
+ describe('list', ()=>{
145
+ it.each`
146
+ userId | onlyUnread | expected
147
+ ${42} | ${true} | ${true}
148
+ ${1} | ${undefined} | ${false}
149
+ `('should list notifications (userId=$userId, onlyUnread=$onlyUnread)', async ({ userId, onlyUnread, expected })=>{
150
+ const expectedRes = [
151
+ {
152
+ id: userId
153
+ }
154
+ ];
155
+ notificationsQueriesMock.list.mockResolvedValueOnce(expectedRes);
156
+ const res = await service.list({
157
+ id: userId
158
+ }, onlyUnread);
159
+ expect(notificationsQueriesMock.list).toHaveBeenCalledWith(userId, expected);
160
+ expect(res).toBe(expectedRes);
161
+ });
162
+ });
163
+ describe('create', ()=>{
164
+ it('stores, sends WS and no email when filtered list empty (object input)', async ()=>{
165
+ const sendEmailSpy = jest.spyOn(service, 'sendEmailNotification').mockResolvedValue(undefined);
166
+ const toUsers = [
167
+ {
168
+ id: 10,
169
+ email: 'u1@test.tld',
170
+ language: 'en',
171
+ notification: _user.USER_NOTIFICATION.APPLICATION
172
+ },
173
+ {
174
+ id: 11,
175
+ email: 'u2@test.tld',
176
+ language: 'fr',
177
+ notification: _user.USER_NOTIFICATION.APPLICATION
178
+ }
179
+ ];
180
+ await service.create(toUsers, {
181
+ app: _notifications.NOTIFICATION_APP.COMMENTS
182
+ }, {
183
+ author: {
184
+ id: 99,
185
+ login: 'john'
186
+ }
187
+ });
188
+ expect(notificationsQueriesMock.create).toHaveBeenCalledWith(99, [
189
+ 10,
190
+ 11
191
+ ], {
192
+ app: _notifications.NOTIFICATION_APP.COMMENTS
193
+ });
194
+ expect(webSocketNotificationsMock.sendMessageToUsers).toHaveBeenCalledWith([
195
+ 10,
196
+ 11
197
+ ], _websocket.NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check');
198
+ expect(sendEmailSpy).not.toHaveBeenCalled();
199
+ expect(notificationsQueriesMock.usersNotifiedByEmail).not.toHaveBeenCalled();
200
+ });
201
+ it('stores, sends WS and email for ids input', async ()=>{
202
+ const sendEmailSpy = jest.spyOn(service, 'sendEmailNotification').mockResolvedValue(undefined);
203
+ const toUserIds = [
204
+ 1,
205
+ 2,
206
+ 3
207
+ ];
208
+ const content = {
209
+ app: _notifications.NOTIFICATION_APP.SHARES
210
+ };
211
+ const emailUsers = [
212
+ {
213
+ id: 1,
214
+ email: 'a@test',
215
+ language: 'en'
216
+ },
217
+ {
218
+ id: 3,
219
+ email: 'c@test',
220
+ language: 'fr'
221
+ }
222
+ ];
223
+ notificationsQueriesMock.usersNotifiedByEmail.mockResolvedValueOnce(emailUsers);
224
+ await service.create(toUserIds, content);
225
+ expect(notificationsQueriesMock.create).toHaveBeenCalledWith(null, toUserIds, content);
226
+ expect(webSocketNotificationsMock.sendMessageToUsers).toHaveBeenCalledWith(toUserIds, _websocket.NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check');
227
+ expect(notificationsQueriesMock.usersNotifiedByEmail).toHaveBeenCalledWith(toUserIds);
228
+ expect(sendEmailSpy).toHaveBeenCalledWith(emailUsers, content, undefined);
229
+ });
230
+ it('does not try email when mailer is unavailable', async ()=>{
231
+ mailerMock.available = false;
232
+ const sendEmailSpy = jest.spyOn(service, 'sendEmailNotification').mockResolvedValue(undefined);
233
+ await service.create([
234
+ 7
235
+ ], {
236
+ app: _notifications.NOTIFICATION_APP.SYNC
237
+ }, {
238
+ author: {
239
+ id: 12,
240
+ login: 'jane'
241
+ }
242
+ });
243
+ expect(notificationsQueriesMock.create).toHaveBeenCalledWith(12, [
244
+ 7
245
+ ], {
246
+ app: _notifications.NOTIFICATION_APP.SYNC
247
+ });
248
+ expect(webSocketNotificationsMock.sendMessageToUsers).toHaveBeenCalledWith([
249
+ 7
250
+ ], _websocket.NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check');
251
+ expect(notificationsQueriesMock.usersNotifiedByEmail).not.toHaveBeenCalled();
252
+ expect(sendEmailSpy).not.toHaveBeenCalled();
253
+ });
254
+ it('logs error when storeNotification internal try/catch catches create error', async ()=>{
255
+ const loggerSpy = spyLogger();
256
+ notificationsQueriesMock.create.mockRejectedValueOnce(new Error('DB fail'));
257
+ await service.create([
258
+ 1
259
+ ], {
260
+ app: _notifications.NOTIFICATION_APP.LINKS
261
+ });
262
+ await flushPromises();
263
+ expect(loggerSpy).toHaveBeenCalled();
264
+ expect(loggerSpy.mock.calls[0]?.[0]).toMatch(/create/i);
265
+ });
266
+ it('logs error when storeNotification promise rejects (create catch)', async ()=>{
267
+ const loggerSpy = spyLogger();
268
+ jest.spyOn(service, 'storeNotification').mockRejectedValueOnce(new Error('store reject'));
269
+ await service.create([
270
+ 1,
271
+ 2
272
+ ], {
273
+ app: _notifications.NOTIFICATION_APP.SYNC
274
+ }, {
275
+ author: {
276
+ id: 5,
277
+ login: 'xx'
278
+ }
279
+ });
280
+ await flushPromises();
281
+ expect(loggerSpy).toHaveBeenCalled();
282
+ expect(loggerSpy.mock.calls[0]?.[0]).toMatch(/create/i);
283
+ });
284
+ it('logs error when sendEmailNotification rejects (create catch)', async ()=>{
285
+ const loggerSpy = spyLogger();
286
+ notificationsQueriesMock.usersNotifiedByEmail.mockResolvedValueOnce([
287
+ {
288
+ id: 1,
289
+ email: 'a@test',
290
+ language: 'en'
291
+ }
292
+ ]);
293
+ jest.spyOn(service, 'sendEmailNotification').mockRejectedValueOnce(new Error('email reject'));
294
+ await service.create([
295
+ 1
296
+ ], {
297
+ app: _notifications.NOTIFICATION_APP.COMMENTS
298
+ });
299
+ await flushPromises();
300
+ expect(loggerSpy).toHaveBeenCalled();
301
+ expect(loggerSpy.mock.calls[0]?.[0]).toMatch(/create/i);
302
+ });
303
+ });
304
+ describe('wasRead', ()=>{
305
+ it('calls queries.wasRead and logs on error', async ()=>{
306
+ service.wasRead({
307
+ id: 5
308
+ }, 123);
309
+ expect(notificationsQueriesMock.wasRead).toHaveBeenCalledWith(5, 123);
310
+ const loggerSpy = spyLogger();
311
+ notificationsQueriesMock.wasRead.mockRejectedValueOnce(new Error('fail'));
312
+ service.wasRead({
313
+ id: 8
314
+ }, undefined);
315
+ await flushPromises();
316
+ expect(loggerSpy).toHaveBeenCalled();
317
+ expect(loggerSpy.mock.calls[0]?.[0]).toMatch(/wasRead/i);
318
+ });
319
+ });
320
+ describe('delete', ()=>{
321
+ it('forwards to queries.delete', async ()=>{
322
+ await service.delete({
323
+ id: 77
324
+ }, 456);
325
+ expect(notificationsQueriesMock.delete).toHaveBeenCalledWith(77, 456);
326
+ });
327
+ });
328
+ describe('sendEmailNotification', ()=>{
329
+ it('returns early when mailer is not available', async ()=>{
330
+ mailerMock.available = false;
331
+ await service.sendEmailNotification([
332
+ {
333
+ id: 1,
334
+ email: 'a@test',
335
+ language: 'en'
336
+ }
337
+ ], {
338
+ app: _notifications.NOTIFICATION_APP.COMMENTS
339
+ }, {
340
+ author: {
341
+ id: 1,
342
+ login: 'john'
343
+ }
344
+ });
345
+ expect(usersManagerMock.getAvatarBase64).not.toHaveBeenCalled();
346
+ expect(mailerMock.sendMails).not.toHaveBeenCalled();
347
+ });
348
+ it('enriches author avatar and sends mapped mails', async ()=>{
349
+ usersManagerMock.getAvatarBase64.mockResolvedValueOnce('base64-xxx');
350
+ const toUsers = [
351
+ {
352
+ id: 1,
353
+ email: 'a@test',
354
+ language: 'en'
355
+ },
356
+ {
357
+ id: 2,
358
+ email: 'b@test',
359
+ language: 'fr'
360
+ }
361
+ ];
362
+ const options = {
363
+ author: {
364
+ id: 9,
365
+ login: 'jdoe'
366
+ },
367
+ content: 'hello',
368
+ currentUrl: 'https://app.test/path'
369
+ };
370
+ const content = {
371
+ app: _notifications.NOTIFICATION_APP.COMMENTS
372
+ };
373
+ await service.sendEmailNotification(toUsers, content, options);
374
+ expect(usersManagerMock.getAvatarBase64).toHaveBeenCalledWith('jdoe');
375
+ expect(options.author.avatarBase64).toBe('base64-xxx');
376
+ expect(mailerMock.sendMails).toHaveBeenCalledTimes(1);
377
+ expect(mailerMock.sendMails.mock.calls[0][0]).toEqual([
378
+ {
379
+ to: 'a@test',
380
+ subject: 'comment title',
381
+ html: 'comment html'
382
+ },
383
+ {
384
+ to: 'b@test',
385
+ subject: 'comment title',
386
+ html: 'comment html'
387
+ }
388
+ ]);
389
+ });
390
+ it('logs error when sendMails rejects', async ()=>{
391
+ mailerMock.sendMails.mockRejectedValueOnce(new Error('smtp down'));
392
+ const loggerSpy = spyLogger();
393
+ await service.sendEmailNotification([
394
+ {
395
+ id: 1,
396
+ email: 'a@test',
397
+ language: 'en'
398
+ }
399
+ ], {
400
+ app: _notifications.NOTIFICATION_APP.SYNC
401
+ }, {});
402
+ expect(loggerSpy).toHaveBeenCalled();
403
+ expect(loggerSpy.mock.calls[0]?.[0]).toMatch(/sendEmailNotification/i);
404
+ });
405
+ });
406
+ describe('genMail (private) - switch coverage', ()=>{
407
+ const cases = [
408
+ {
409
+ name: 'COMMENTS',
410
+ app: _notifications.NOTIFICATION_APP.COMMENTS,
411
+ fn: 'commentMail',
412
+ options: {
413
+ content: 'c',
414
+ currentUrl: 'u',
415
+ author: {
416
+ id: 1,
417
+ login: 'x'
418
+ }
419
+ }
420
+ },
421
+ {
422
+ name: 'SPACES',
423
+ app: _notifications.NOTIFICATION_APP.SPACES,
424
+ fn: 'spaceMail',
425
+ options: {
426
+ currentUrl: 'u',
427
+ action: 'A'
428
+ }
429
+ },
430
+ {
431
+ name: 'SPACE_ROOTS',
432
+ app: _notifications.NOTIFICATION_APP.SPACE_ROOTS,
433
+ fn: 'spaceRootMail',
434
+ options: {
435
+ currentUrl: 'u',
436
+ author: {
437
+ id: 2,
438
+ login: 'y'
439
+ },
440
+ action: 'B'
441
+ }
442
+ },
443
+ {
444
+ name: 'SHARES',
445
+ app: _notifications.NOTIFICATION_APP.SHARES,
446
+ fn: 'shareMail',
447
+ options: {
448
+ currentUrl: 'u',
449
+ author: {
450
+ id: 3,
451
+ login: 'z'
452
+ },
453
+ action: 'C'
454
+ }
455
+ },
456
+ {
457
+ name: 'LINKS',
458
+ app: _notifications.NOTIFICATION_APP.LINKS,
459
+ fn: 'linkMail',
460
+ options: {
461
+ currentUrl: 'u',
462
+ author: {
463
+ id: 4,
464
+ login: 'w'
465
+ },
466
+ linkUUID: 'uuid',
467
+ action: 'D'
468
+ }
469
+ },
470
+ {
471
+ name: 'SYNC',
472
+ app: _notifications.NOTIFICATION_APP.SYNC,
473
+ fn: 'syncMail',
474
+ options: {
475
+ currentUrl: 'u',
476
+ action: 'E'
477
+ }
478
+ }
479
+ ];
480
+ it.each(cases)('uses $fn for $name', ({ app, fn, options })=>{
481
+ const res = service.genMail('en', {
482
+ app
483
+ }, options);
484
+ expect(res).toEqual([
485
+ `${fn.replace('Mail', '')} title`.replace('spaceRoot', 'spaceRoot'),
486
+ `${fn.replace('Mail', '')} html`.replace('spaceRoot', 'spaceRoot')
487
+ ]);
488
+ expect(_models[fn]).toHaveBeenCalled();
489
+ });
490
+ it('logs error for unhandled app', ()=>{
491
+ const loggerSpy = spyLogger();
492
+ const result = service.genMail('en', {
493
+ app: 99999
494
+ }, {});
495
+ expect(result).toBeUndefined();
496
+ expect(loggerSpy).toHaveBeenCalled();
497
+ expect(loggerSpy.mock.calls[0]?.[0]).toMatch(/case not handled/i);
498
+ });
499
+ });
44
500
  });
45
501
 
46
502
  //# sourceMappingURL=notifications-manager.service.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/notifications/services/notifications-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { Mailer } from '../../../infrastructure/mailer/mailer.service'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { WebSocketNotifications } from '../notifications.gateway'\nimport { NotificationsManager } from './notifications-manager.service'\nimport { NotificationsQueries } from './notifications-queries.service'\n\ndescribe(NotificationsManager.name, () => {\n let service: NotificationsManager\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n NotificationsManager,\n { provide: UsersManager, useValue: {} },\n {\n provide: Mailer,\n useValue: {}\n },\n { provide: WebSocketNotifications, useValue: {} },\n { provide: NotificationsQueries, useValue: {} }\n ]\n }).compile()\n\n service = module.get<NotificationsManager>(NotificationsManager)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n})\n"],"names":["describe","NotificationsManager","name","service","beforeAll","module","Test","createTestingModule","providers","provide","UsersManager","useValue","Mailer","WebSocketNotifications","NotificationsQueries","compile","get","it","expect","toBeDefined"],"mappings":"AAAA;;;;CAIC;;;;yBAEmC;+BACb;qCACM;sCACU;6CACF;6CACA;AAErCA,SAASC,iDAAoB,CAACC,IAAI,EAAE;IAClC,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,WAAW;gBACTP,iDAAoB;gBACpB;oBAAEQ,SAASC,iCAAY;oBAAEC,UAAU,CAAC;gBAAE;gBACtC;oBACEF,SAASG,qBAAM;oBACfD,UAAU,CAAC;gBACb;gBACA;oBAAEF,SAASI,4CAAsB;oBAAEF,UAAU,CAAC;gBAAE;gBAChD;oBAAEF,SAASK,iDAAoB;oBAAEH,UAAU,CAAC;gBAAE;aAC/C;QACH,GAAGI,OAAO;QAEVZ,UAAUE,OAAOW,GAAG,CAAuBf,iDAAoB;IACjE;IAEAgB,GAAG,qBAAqB;QACtBC,OAAOf,SAASgB,WAAW;IAC7B;AACF"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/notifications/services/notifications-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { Mailer } from '../../../infrastructure/mailer/mailer.service'\nimport { USER_NOTIFICATION } from '../../users/constants/user'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { NOTIFICATION_APP } from '../constants/notifications'\nimport { NOTIFICATIONS_WS } from '../constants/websocket'\nimport * as mailModels from '../mails/models'\nimport { WebSocketNotifications } from '../notifications.gateway'\nimport { NotificationsManager } from './notifications-manager.service'\nimport { NotificationsQueries } from './notifications-queries.service'\n\n// Compact mock for mail generators\njest.mock('../mails/models', () => ({\n commentMail: jest.fn(() => ['comment title', 'comment html']),\n spaceMail: jest.fn(() => ['space title', 'space html']),\n spaceRootMail: jest.fn(() => ['spaceRoot title', 'spaceRoot html']),\n shareMail: jest.fn(() => ['share title', 'share html']),\n linkMail: jest.fn(() => ['link title', 'link html']),\n syncMail: jest.fn(() => ['sync title', 'sync html'])\n}))\n\ndescribe(NotificationsManager.name, () => {\n let service: NotificationsManager\n\n const usersManagerMock = { getAvatarBase64: jest.fn() }\n const mailerMock = { available: true, sendMails: jest.fn() }\n const notificationsQueriesMock = {\n list: jest.fn(),\n usersNotifiedByEmail: jest.fn(),\n create: jest.fn(),\n wasRead: jest.fn(),\n delete: jest.fn()\n }\n const webSocketNotificationsMock = { sendMessageToUsers: jest.fn() }\n\n const flushPromises = () => new Promise<void>((r) => setImmediate(r))\n const spyLogger = () => jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n\n beforeEach(async () => {\n jest.clearAllMocks()\n mailerMock.available = true\n mailerMock.sendMails.mockResolvedValue(undefined)\n notificationsQueriesMock.create.mockResolvedValue(undefined)\n notificationsQueriesMock.wasRead.mockResolvedValue(undefined)\n notificationsQueriesMock.delete.mockResolvedValue(undefined)\n notificationsQueriesMock.list.mockResolvedValue([])\n notificationsQueriesMock.usersNotifiedByEmail.mockResolvedValue([])\n usersManagerMock.getAvatarBase64.mockResolvedValue('avatar-base64')\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n NotificationsManager,\n { provide: UsersManager, useValue: usersManagerMock },\n { provide: Mailer, useValue: mailerMock },\n { provide: WebSocketNotifications, useValue: webSocketNotificationsMock },\n { provide: NotificationsQueries, useValue: notificationsQueriesMock }\n ]\n }).compile()\n service = module.get<NotificationsManager>(NotificationsManager)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('list', () => {\n it.each`\n userId | onlyUnread | expected\n ${42} | ${true} | ${true}\n ${1} | ${undefined} | ${false}\n `('should list notifications (userId=$userId, onlyUnread=$onlyUnread)', async ({ userId, onlyUnread, expected }) => {\n const expectedRes = [{ id: userId }] as any\n notificationsQueriesMock.list.mockResolvedValueOnce(expectedRes)\n const res = await service.list({ id: userId } as any, onlyUnread as any)\n expect(notificationsQueriesMock.list).toHaveBeenCalledWith(userId, expected)\n expect(res).toBe(expectedRes)\n })\n })\n\n describe('create', () => {\n it('stores, sends WS and no email when filtered list empty (object input)', async () => {\n const sendEmailSpy = jest.spyOn(service, 'sendEmailNotification').mockResolvedValue(undefined)\n const toUsers = [\n { id: 10, email: 'u1@test.tld', language: 'en', notification: USER_NOTIFICATION.APPLICATION },\n { id: 11, email: 'u2@test.tld', language: 'fr', notification: USER_NOTIFICATION.APPLICATION }\n ]\n await service.create(toUsers as any, { app: NOTIFICATION_APP.COMMENTS } as any, { author: { id: 99, login: 'john' } } as any)\n expect(notificationsQueriesMock.create).toHaveBeenCalledWith(99, [10, 11], { app: NOTIFICATION_APP.COMMENTS })\n expect(webSocketNotificationsMock.sendMessageToUsers).toHaveBeenCalledWith([10, 11], NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check')\n expect(sendEmailSpy).not.toHaveBeenCalled()\n expect(notificationsQueriesMock.usersNotifiedByEmail).not.toHaveBeenCalled()\n })\n\n it('stores, sends WS and email for ids input', async () => {\n const sendEmailSpy = jest.spyOn(service, 'sendEmailNotification').mockResolvedValue(undefined)\n const toUserIds = [1, 2, 3]\n const content = { app: NOTIFICATION_APP.SHARES } as any\n const emailUsers = [\n { id: 1, email: 'a@test', language: 'en' },\n { id: 3, email: 'c@test', language: 'fr' }\n ]\n notificationsQueriesMock.usersNotifiedByEmail.mockResolvedValueOnce(emailUsers as any)\n await service.create(toUserIds, content)\n expect(notificationsQueriesMock.create).toHaveBeenCalledWith(null, toUserIds, content)\n expect(webSocketNotificationsMock.sendMessageToUsers).toHaveBeenCalledWith(toUserIds, NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check')\n expect(notificationsQueriesMock.usersNotifiedByEmail).toHaveBeenCalledWith(toUserIds)\n expect(sendEmailSpy).toHaveBeenCalledWith(emailUsers as any, content, undefined)\n })\n\n it('does not try email when mailer is unavailable', async () => {\n mailerMock.available = false\n const sendEmailSpy = jest.spyOn(service, 'sendEmailNotification').mockResolvedValue(undefined)\n await service.create([7], { app: NOTIFICATION_APP.SYNC } as any, { author: { id: 12, login: 'jane' } } as any)\n expect(notificationsQueriesMock.create).toHaveBeenCalledWith(12, [7], { app: NOTIFICATION_APP.SYNC })\n expect(webSocketNotificationsMock.sendMessageToUsers).toHaveBeenCalledWith([7], NOTIFICATIONS_WS.EVENTS.NOTIFICATION, 'check')\n expect(notificationsQueriesMock.usersNotifiedByEmail).not.toHaveBeenCalled()\n expect(sendEmailSpy).not.toHaveBeenCalled()\n })\n\n it('logs error when storeNotification internal try/catch catches create error', async () => {\n const loggerSpy = spyLogger()\n notificationsQueriesMock.create.mockRejectedValueOnce(new Error('DB fail'))\n await service.create([1], { app: NOTIFICATION_APP.LINKS } as any)\n await flushPromises()\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls[0]?.[0] as string).toMatch(/create/i)\n })\n\n it('logs error when storeNotification promise rejects (create catch)', async () => {\n const loggerSpy = spyLogger()\n jest.spyOn<any, any>(service as any, 'storeNotification').mockRejectedValueOnce(new Error('store reject'))\n await service.create([1, 2], { app: NOTIFICATION_APP.SYNC } as any, { author: { id: 5, login: 'xx' } } as any)\n await flushPromises()\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls[0]?.[0] as string).toMatch(/create/i)\n })\n\n it('logs error when sendEmailNotification rejects (create catch)', async () => {\n const loggerSpy = spyLogger()\n notificationsQueriesMock.usersNotifiedByEmail.mockResolvedValueOnce([{ id: 1, email: 'a@test', language: 'en' }] as any)\n jest.spyOn(service, 'sendEmailNotification').mockRejectedValueOnce(new Error('email reject'))\n await service.create([1], { app: NOTIFICATION_APP.COMMENTS } as any)\n await flushPromises()\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls[0]?.[0] as string).toMatch(/create/i)\n })\n })\n\n describe('wasRead', () => {\n it('calls queries.wasRead and logs on error', async () => {\n service.wasRead({ id: 5 } as any, 123)\n expect(notificationsQueriesMock.wasRead).toHaveBeenCalledWith(5, 123)\n const loggerSpy = spyLogger()\n notificationsQueriesMock.wasRead.mockRejectedValueOnce(new Error('fail'))\n service.wasRead({ id: 8 } as any, undefined)\n await flushPromises()\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls[0]?.[0] as string).toMatch(/wasRead/i)\n })\n })\n\n describe('delete', () => {\n it('forwards to queries.delete', async () => {\n await service.delete({ id: 77 } as any, 456)\n expect(notificationsQueriesMock.delete).toHaveBeenCalledWith(77, 456)\n })\n })\n\n describe('sendEmailNotification', () => {\n it('returns early when mailer is not available', async () => {\n mailerMock.available = false\n await service.sendEmailNotification(\n [{ id: 1, email: 'a@test', language: 'en' }] as any,\n { app: NOTIFICATION_APP.COMMENTS } as any,\n {\n author: { id: 1, login: 'john' }\n } as any\n )\n expect(usersManagerMock.getAvatarBase64).not.toHaveBeenCalled()\n expect(mailerMock.sendMails).not.toHaveBeenCalled()\n })\n\n it('enriches author avatar and sends mapped mails', async () => {\n usersManagerMock.getAvatarBase64.mockResolvedValueOnce('base64-xxx')\n const toUsers = [\n { id: 1, email: 'a@test', language: 'en' },\n { id: 2, email: 'b@test', language: 'fr' }\n ]\n const options: any = { author: { id: 9, login: 'jdoe' }, content: 'hello', currentUrl: 'https://app.test/path' }\n const content = { app: NOTIFICATION_APP.COMMENTS } as any\n await service.sendEmailNotification(toUsers as any, content, options)\n expect(usersManagerMock.getAvatarBase64).toHaveBeenCalledWith('jdoe')\n expect(options.author.avatarBase64).toBe('base64-xxx')\n expect(mailerMock.sendMails).toHaveBeenCalledTimes(1)\n expect((mailerMock.sendMails as jest.Mock).mock.calls[0][0]).toEqual([\n { to: 'a@test', subject: 'comment title', html: 'comment html' },\n { to: 'b@test', subject: 'comment title', html: 'comment html' }\n ])\n })\n\n it('logs error when sendMails rejects', async () => {\n mailerMock.sendMails.mockRejectedValueOnce(new Error('smtp down'))\n const loggerSpy = spyLogger()\n await service.sendEmailNotification([{ id: 1, email: 'a@test', language: 'en' }] as any, { app: NOTIFICATION_APP.SYNC } as any, {} as any)\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls[0]?.[0] as string).toMatch(/sendEmailNotification/i)\n })\n })\n\n describe('genMail (private) - switch coverage', () => {\n const cases = [\n {\n name: 'COMMENTS',\n app: NOTIFICATION_APP.COMMENTS,\n fn: 'commentMail',\n options: { content: 'c', currentUrl: 'u', author: { id: 1, login: 'x' } }\n },\n { name: 'SPACES', app: NOTIFICATION_APP.SPACES, fn: 'spaceMail', options: { currentUrl: 'u', action: 'A' } },\n {\n name: 'SPACE_ROOTS',\n app: NOTIFICATION_APP.SPACE_ROOTS,\n fn: 'spaceRootMail',\n options: { currentUrl: 'u', author: { id: 2, login: 'y' }, action: 'B' }\n },\n { name: 'SHARES', app: NOTIFICATION_APP.SHARES, fn: 'shareMail', options: { currentUrl: 'u', author: { id: 3, login: 'z' }, action: 'C' } },\n {\n name: 'LINKS',\n app: NOTIFICATION_APP.LINKS,\n fn: 'linkMail',\n options: { currentUrl: 'u', author: { id: 4, login: 'w' }, linkUUID: 'uuid', action: 'D' }\n },\n { name: 'SYNC', app: NOTIFICATION_APP.SYNC, fn: 'syncMail', options: { currentUrl: 'u', action: 'E' } }\n ] as const\n\n it.each(cases)('uses $fn for $name', ({ app, fn, options }) => {\n const res = (service as any).genMail('en', { app } as any, options as any)\n expect(res).toEqual([\n `${fn.replace('Mail', '')} title`.replace('spaceRoot', 'spaceRoot'),\n `${fn.replace('Mail', '')} html`.replace('spaceRoot', 'spaceRoot')\n ])\n expect((mailModels as any)[fn]).toHaveBeenCalled()\n })\n\n it('logs error for unhandled app', () => {\n const loggerSpy = spyLogger()\n const result = (service as any).genMail('en', { app: 99999 } as any, {} as any)\n expect(result).toBeUndefined()\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls[0]?.[0] as string).toMatch(/case not handled/i)\n })\n })\n})\n"],"names":["jest","mock","commentMail","fn","spaceMail","spaceRootMail","shareMail","linkMail","syncMail","describe","NotificationsManager","name","service","usersManagerMock","getAvatarBase64","mailerMock","available","sendMails","notificationsQueriesMock","list","usersNotifiedByEmail","create","wasRead","delete","webSocketNotificationsMock","sendMessageToUsers","flushPromises","Promise","r","setImmediate","spyLogger","spyOn","logger","mockImplementation","undefined","beforeEach","clearAllMocks","mockResolvedValue","module","Test","createTestingModule","providers","provide","UsersManager","useValue","Mailer","WebSocketNotifications","NotificationsQueries","compile","get","it","expect","toBeDefined","each","userId","onlyUnread","expected","expectedRes","id","mockResolvedValueOnce","res","toHaveBeenCalledWith","toBe","sendEmailSpy","toUsers","email","language","notification","USER_NOTIFICATION","APPLICATION","app","NOTIFICATION_APP","COMMENTS","author","login","NOTIFICATIONS_WS","EVENTS","NOTIFICATION","not","toHaveBeenCalled","toUserIds","content","SHARES","emailUsers","SYNC","loggerSpy","mockRejectedValueOnce","Error","LINKS","calls","toMatch","sendEmailNotification","options","currentUrl","avatarBase64","toHaveBeenCalledTimes","toEqual","to","subject","html","cases","SPACES","action","SPACE_ROOTS","linkUUID","genMail","replace","mailModels","result","toBeUndefined"],"mappings":"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"}