NewsletterManagerTests.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. const { expect } = require('chai')
  2. const sinon = require('sinon')
  3. const SandboxedModule = require('sandboxed-module')
  4. const MODULE_PATH = '../../../../app/src/Features/Newsletter/NewsletterManager'
  5. describe('NewsletterManager', function() {
  6. beforeEach('setup mocks', function() {
  7. this.Settings = {
  8. mailchimp: {
  9. api_key: 'api_key',
  10. list_id: 'list_id'
  11. }
  12. }
  13. this.mailchimp = {
  14. put: sinon.stub(),
  15. patch: sinon.stub(),
  16. delete: sinon.stub()
  17. }
  18. this.Mailchimp = sinon.stub().returns(this.mailchimp)
  19. this.mergeFields = {
  20. FNAME: 'Overleaf',
  21. LNAME: 'Duck',
  22. MONGO_ID: 'user_id'
  23. }
  24. this.NewsletterManager = SandboxedModule.require(MODULE_PATH, {
  25. requires: {
  26. 'mailchimp-api-v3': this.Mailchimp,
  27. 'settings-sharelatex': this.Settings
  28. },
  29. globals: { console: console }
  30. }).promises
  31. this.user = {
  32. _id: 'user_id',
  33. email: 'overleaf.duck@example.com',
  34. first_name: 'Overleaf',
  35. last_name: 'Duck'
  36. }
  37. // MD5 sum of the user email
  38. this.emailHash = 'c02f60ed0ef51818186274e406c9a48f'
  39. })
  40. describe('subscribe', function() {
  41. it('calls Mailchimp to subscribe the user', async function() {
  42. await this.NewsletterManager.subscribe(this.user)
  43. expect(this.mailchimp.put).to.have.been.calledWith(
  44. `/lists/list_id/members/${this.emailHash}`,
  45. {
  46. email_address: this.user.email,
  47. status: 'subscribed',
  48. status_if_new: 'subscribed',
  49. merge_fields: this.mergeFields
  50. }
  51. )
  52. })
  53. })
  54. describe('unsubscribe', function() {
  55. describe('when unsubscribing normally', function() {
  56. it('calls Mailchimp to unsubscribe the user', async function() {
  57. await this.NewsletterManager.unsubscribe(this.user)
  58. expect(this.mailchimp.patch).to.have.been.calledWith(
  59. `/lists/list_id/members/${this.emailHash}`,
  60. {
  61. status: 'unsubscribed',
  62. merge_fields: this.mergeFields
  63. }
  64. )
  65. })
  66. it('ignores a Mailchimp error about fake emails', async function() {
  67. this.mailchimp.patch.rejects(
  68. new Error(
  69. 'overleaf.duck@example.com looks fake or invalid, please enter a real email address'
  70. )
  71. )
  72. await expect(this.NewsletterManager.unsubscribe(this.user)).to.be
  73. .fulfilled
  74. })
  75. it('rejects on other errors', async function() {
  76. this.mailchimp.patch.rejects(
  77. new Error('something really wrong is happening')
  78. )
  79. await expect(this.NewsletterManager.unsubscribe(this.user)).to.be
  80. .rejected
  81. })
  82. })
  83. describe('when deleting', function() {
  84. it('calls Mailchimp to delete the user', async function() {
  85. await this.NewsletterManager.unsubscribe(this.user, { delete: true })
  86. expect(this.mailchimp.delete).to.have.been.calledWith(
  87. `/lists/list_id/members/${this.emailHash}`
  88. )
  89. })
  90. it('ignores a Mailchimp error about fake emails', async function() {
  91. this.mailchimp.delete.rejects(
  92. new Error(
  93. 'overleaf.duck@example.com looks fake or invalid, please enter a real email address'
  94. )
  95. )
  96. await expect(
  97. this.NewsletterManager.unsubscribe(this.user, { delete: true })
  98. ).to.be.fulfilled
  99. })
  100. it('rejects on other errors', async function() {
  101. this.mailchimp.delete.rejects(
  102. new Error('something really wrong is happening')
  103. )
  104. await expect(
  105. this.NewsletterManager.unsubscribe(this.user, { delete: true })
  106. ).to.be.rejected
  107. })
  108. })
  109. })
  110. describe('changeEmail', function() {
  111. it('calls Mailchimp to change the subscriber email', async function() {
  112. await this.NewsletterManager.changeEmail(
  113. this.user,
  114. 'overleaf.squirrel@example.com'
  115. )
  116. expect(this.mailchimp.patch).to.have.been.calledWith(
  117. `/lists/list_id/members/${this.emailHash}`,
  118. {
  119. email_address: 'overleaf.squirrel@example.com',
  120. merge_fields: this.mergeFields
  121. }
  122. )
  123. })
  124. it('deletes the old email if changing the address fails', async function() {
  125. this.mailchimp.patch
  126. .withArgs(`/lists/list_id/members/${this.emailHash}`, {
  127. email_address: 'overleaf.squirrel@example.com',
  128. merge_fields: this.mergeFields
  129. })
  130. .rejects(new Error('that did not work'))
  131. await expect(
  132. this.NewsletterManager.changeEmail(
  133. this.user,
  134. 'overleaf.squirrel@example.com'
  135. )
  136. ).to.be.rejected
  137. expect(this.mailchimp.delete).to.have.been.calledWith(
  138. `/lists/list_id/members/${this.emailHash}`
  139. )
  140. })
  141. })
  142. })