EmailChangeHelpers.test.mjs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import { vi, expect } from 'vitest'
  2. import sinon from 'sinon'
  3. describe('EmailChangeHelper', function () {
  4. let AnalyticsManager
  5. let UserGetter
  6. let EmailChangeHelpers
  7. const email = 'test@example.com'
  8. const userId = '507f1f77bcf86cd799439011'
  9. beforeEach(async function () {
  10. UserGetter = {
  11. promises: {
  12. getUserFullEmails: sinon.stub().resolves([]),
  13. },
  14. }
  15. AnalyticsManager = {
  16. registerEmailChange: sinon.stub(),
  17. }
  18. vi.doMock('../../../../app/src/Features/User/UserGetter', () => ({
  19. default: UserGetter,
  20. }))
  21. vi.doMock(
  22. '../../../../app/src/Features/Analytics/AnalyticsManager',
  23. () => ({
  24. default: AnalyticsManager,
  25. })
  26. )
  27. EmailChangeHelpers = (
  28. await import('../../../../app/src/Features/Analytics/EmailChangeHelper.mjs')
  29. ).default
  30. })
  31. describe('registerEmailUpdate', function () {
  32. describe('when the email cannot be matched', function () {
  33. beforeEach(function () {
  34. UserGetter.promises.getUserFullEmails.resolves([
  35. {
  36. email: 'test2@example.com',
  37. reversedHostname: 'moc.elpmaxe',
  38. createdAt: new Date('2023-01-01T00:00:00'),
  39. confirmedAt: new Date('2023-02-01T00:00:00'),
  40. default: false,
  41. },
  42. ])
  43. })
  44. it('calls registerEmailChange with the passed event data', async function () {
  45. const eventData = {
  46. emailCreatedAt: new Date('2024-01-01T00:00:00'),
  47. isPrimary: true,
  48. }
  49. await EmailChangeHelpers.registerEmailUpdate(userId, email, eventData)
  50. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  51. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  52. expect(callArgs).to.include({
  53. userId,
  54. email,
  55. action: 'updated',
  56. isPrimary: true,
  57. })
  58. expect(callArgs.emailCreatedAt).to.eql('2024-01-01T00:00:00.000Z')
  59. expect(callArgs.emailConfirmedAt).to.be.null
  60. })
  61. })
  62. describe('when the email can be matched', function () {
  63. beforeEach(function () {
  64. UserGetter.promises.getUserFullEmails.resolves([
  65. {
  66. email,
  67. reversedHostname: 'moc.elpmaxe',
  68. createdAt: new Date('2023-01-01T00:00:00'),
  69. confirmedAt: new Date('2023-02-01T00:00:00'),
  70. default: false,
  71. },
  72. ])
  73. })
  74. it('calls registerEmailChange with the email data', async function () {
  75. await EmailChangeHelpers.registerEmailUpdate(userId, email)
  76. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  77. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  78. expect(callArgs).to.include({
  79. userId,
  80. email,
  81. action: 'updated',
  82. isPrimary: false,
  83. })
  84. expect(callArgs.emailCreatedAt).to.eql('2023-01-01T00:00:00.000Z')
  85. expect(callArgs.emailConfirmedAt).to.eql('2023-02-01T00:00:00.000Z')
  86. expect(callArgs.emailDeletedAt).to.be.null
  87. })
  88. it('prefers supplied event data over fetched email data', async function () {
  89. const eventData = {
  90. emailCreatedAt: new Date('2024-01-01T00:00:00'),
  91. emailConfirmedAt: new Date('2024-02-01T00:00:00'),
  92. isPrimary: true,
  93. }
  94. await EmailChangeHelpers.registerEmailUpdate(userId, email, eventData)
  95. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  96. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  97. expect(callArgs).to.include({
  98. userId,
  99. email,
  100. action: 'updated',
  101. isPrimary: true,
  102. })
  103. expect(callArgs.emailCreatedAt).to.eql('2024-01-01T00:00:00.000Z')
  104. expect(callArgs.emailConfirmedAt).to.eql('2024-02-01T00:00:00.000Z')
  105. expect(callArgs.emailDeletedAt).to.be.null
  106. })
  107. })
  108. describe('when the user is not found', function () {
  109. beforeEach(function () {
  110. UserGetter.promises.getUserFullEmails.rejects(
  111. new Error('User not found')
  112. )
  113. })
  114. it('throws the error', async function () {
  115. await expect(
  116. EmailChangeHelpers.registerEmailUpdate(userId, email)
  117. ).to.eventually.be.rejectedWith('User not found')
  118. })
  119. })
  120. })
  121. describe('registerEmailCreation', function () {
  122. describe('when the email cannot be matched', function () {
  123. beforeEach(function () {
  124. UserGetter.promises.getUserFullEmails.resolves([
  125. {
  126. email: 'test2@example.com',
  127. reversedHostname: 'moc.elpmaxe',
  128. createdAt: new Date('2023-01-01T00:00:00'),
  129. confirmedAt: new Date('2023-02-01T00:00:00'),
  130. default: false,
  131. },
  132. ])
  133. })
  134. it('calls registerEmailChange with the passed event data', async function () {
  135. const eventData = {
  136. emailCreatedAt: new Date('2024-01-01T00:00:00'),
  137. isPrimary: true,
  138. }
  139. await EmailChangeHelpers.registerEmailCreation(userId, email, eventData)
  140. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  141. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  142. expect(callArgs).to.include({
  143. userId,
  144. email,
  145. action: 'created',
  146. isPrimary: true,
  147. })
  148. expect(callArgs.emailCreatedAt).to.eql('2024-01-01T00:00:00.000Z')
  149. expect(callArgs.emailConfirmedAt).to.be.null
  150. expect(callArgs.emailDeletedAt).to.be.null
  151. })
  152. })
  153. describe('when the email can be matched', function () {
  154. beforeEach(function () {
  155. UserGetter.promises.getUserFullEmails.resolves([
  156. {
  157. email,
  158. reversedHostname: 'moc.elpmaxe',
  159. createdAt: new Date('2023-01-01T00:00:00'),
  160. confirmedAt: new Date('2023-02-01T00:00:00'),
  161. default: false,
  162. },
  163. ])
  164. })
  165. it('calls registerEmailChange with the email data', async function () {
  166. await EmailChangeHelpers.registerEmailCreation(userId, email)
  167. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  168. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  169. expect(callArgs).to.include({
  170. userId,
  171. email,
  172. action: 'created',
  173. isPrimary: false,
  174. })
  175. expect(callArgs.emailCreatedAt).to.eql('2023-01-01T00:00:00.000Z')
  176. expect(callArgs.emailConfirmedAt).to.eql('2023-02-01T00:00:00.000Z')
  177. expect(callArgs.emailDeletedAt).to.be.null
  178. })
  179. it('prefers supplied event data over fetched email data', async function () {
  180. const eventData = {
  181. emailCreatedAt: new Date('2024-01-01T00:00:00'),
  182. emailConfirmedAt: new Date('2024-02-01T00:00:00'),
  183. isPrimary: true,
  184. }
  185. await EmailChangeHelpers.registerEmailCreation(userId, email, eventData)
  186. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  187. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  188. expect(callArgs).to.include({
  189. userId,
  190. email,
  191. action: 'created',
  192. isPrimary: true,
  193. })
  194. expect(callArgs.emailCreatedAt).to.eql('2024-01-01T00:00:00.000Z')
  195. expect(callArgs.emailConfirmedAt).to.eql('2024-02-01T00:00:00.000Z')
  196. expect(callArgs.emailDeletedAt).to.be.null
  197. })
  198. })
  199. describe('when the user is not found', function () {
  200. beforeEach(function () {
  201. UserGetter.promises.getUserFullEmails.rejects(
  202. new Error('User not found')
  203. )
  204. })
  205. it('throws the error', async function () {
  206. await expect(
  207. EmailChangeHelpers.registerEmailCreation(userId, email)
  208. ).to.eventually.be.rejectedWith('User not found')
  209. })
  210. })
  211. })
  212. describe('registerEmailDeletion', function () {
  213. describe('when the email cannot be matched', function () {
  214. beforeEach(function () {
  215. UserGetter.promises.getUserFullEmails.resolves([
  216. {
  217. email: 'test2@example.com',
  218. reversedHostname: 'moc.elpmaxe',
  219. createdAt: new Date('2023-01-01T00:00:00'),
  220. confirmedAt: new Date('2023-02-01T00:00:00'),
  221. default: false,
  222. },
  223. ])
  224. })
  225. it('calls registerEmailChange with the passed event data', async function () {
  226. const eventData = {
  227. emailCreatedAt: new Date('2024-01-01T00:00:00'),
  228. emailDeletedAt: new Date('2025-02-01T00:00:00'),
  229. isPrimary: true,
  230. }
  231. await EmailChangeHelpers.registerEmailDeletion(userId, email, eventData)
  232. expect(AnalyticsManager.registerEmailChange).to.have.been.calledOnce
  233. const callArgs = AnalyticsManager.registerEmailChange.getCall(0).args[0]
  234. expect(callArgs).to.include({
  235. userId,
  236. email,
  237. action: 'deleted',
  238. isPrimary: true,
  239. })
  240. expect(callArgs.emailCreatedAt).to.eql('2024-01-01T00:00:00.000Z')
  241. expect(callArgs.emailDeletedAt).to.eql('2025-02-01T00:00:00.000Z')
  242. })
  243. })
  244. describe('when the user is not found', function () {
  245. beforeEach(function () {
  246. UserGetter.promises.getUserFullEmails.rejects(
  247. new Error('User not found')
  248. )
  249. })
  250. it('throws the error', async function () {
  251. await expect(
  252. EmailChangeHelpers.registerEmailDeletion(userId, email)
  253. ).to.eventually.be.rejectedWith('User not found')
  254. })
  255. })
  256. })
  257. })