BetaProgramHandler.test.mjs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { expect, vi } from 'vitest'
  2. import path from 'node:path'
  3. import sinon from 'sinon'
  4. import { fileURLToPath } from 'node:url'
  5. const __dirname = fileURLToPath(new URL('.', import.meta.url))
  6. const modulePath = path.join(
  7. __dirname,
  8. '../../../../app/src/Features/BetaProgram/BetaProgramHandler'
  9. )
  10. describe('BetaProgramHandler', function () {
  11. beforeEach(async function (ctx) {
  12. ctx.user_id = 'some_id'
  13. ctx.user = {
  14. _id: ctx.user_id,
  15. email: 'user@example.com',
  16. features: {},
  17. betaProgram: false,
  18. save: sinon.stub().callsArgWith(0, null),
  19. }
  20. vi.doMock('@overleaf/metrics', () => ({
  21. default: {
  22. inc: sinon.stub(),
  23. },
  24. }))
  25. vi.doMock('../../../../app/src/Features/User/UserUpdater', () => ({
  26. default: (ctx.UserUpdater = {
  27. promises: {
  28. updateUser: sinon.stub().resolves(),
  29. },
  30. }),
  31. }))
  32. vi.doMock(
  33. '../../../../app/src/Features/Analytics/AnalyticsManager',
  34. () => ({
  35. default: (ctx.AnalyticsManager = {
  36. setUserPropertyForUserInBackground: sinon.stub(),
  37. }),
  38. })
  39. )
  40. ctx.handler = (await import(modulePath)).default
  41. })
  42. describe('optIn', function () {
  43. beforeEach(function (ctx) {
  44. ctx.user.betaProgram = false
  45. ctx.call = callback => {
  46. ctx.handler.optIn(ctx.user_id, callback)
  47. }
  48. })
  49. it('should call userUpdater', async function (ctx) {
  50. await new Promise(resolve => {
  51. ctx.call(err => {
  52. expect(err).to.not.exist
  53. ctx.UserUpdater.promises.updateUser.callCount.should.equal(1)
  54. resolve()
  55. })
  56. })
  57. })
  58. it('should set beta-program user property to true', async function (ctx) {
  59. await new Promise(resolve => {
  60. ctx.call(err => {
  61. expect(err).to.not.exist
  62. sinon.assert.calledWith(
  63. ctx.AnalyticsManager.setUserPropertyForUserInBackground,
  64. ctx.user_id,
  65. 'beta-program',
  66. true
  67. )
  68. resolve()
  69. })
  70. })
  71. })
  72. it('should not produce an error', async function (ctx) {
  73. await new Promise(resolve => {
  74. ctx.call(err => {
  75. expect(err).to.not.exist
  76. resolve()
  77. })
  78. })
  79. })
  80. describe('when userUpdater produces an error', function () {
  81. beforeEach(function (ctx) {
  82. ctx.UserUpdater.promises.updateUser.rejects()
  83. })
  84. it('should produce an error', async function (ctx) {
  85. await new Promise(resolve => {
  86. ctx.call(err => {
  87. expect(err).to.exist
  88. expect(err).to.be.instanceof(Error)
  89. resolve()
  90. })
  91. })
  92. })
  93. })
  94. })
  95. describe('optOut', function () {
  96. beforeEach(function (ctx) {
  97. ctx.user.betaProgram = true
  98. ctx.call = callback => {
  99. ctx.handler.optOut(ctx.user_id, callback)
  100. }
  101. })
  102. it('should call userUpdater', async function (ctx) {
  103. await new Promise(resolve => {
  104. ctx.call(err => {
  105. expect(err).to.not.exist
  106. ctx.UserUpdater.promises.updateUser.callCount.should.equal(1)
  107. resolve()
  108. })
  109. })
  110. })
  111. it('should set beta-program user property to false', async function (ctx) {
  112. await new Promise(resolve => {
  113. ctx.call(err => {
  114. expect(err).to.not.exist
  115. sinon.assert.calledWith(
  116. ctx.AnalyticsManager.setUserPropertyForUserInBackground,
  117. ctx.user_id,
  118. 'beta-program',
  119. false
  120. )
  121. resolve()
  122. })
  123. })
  124. })
  125. it('should not produce an error', async function (ctx) {
  126. await new Promise(resolve => {
  127. ctx.call(err => {
  128. expect(err).to.not.exist
  129. resolve()
  130. })
  131. })
  132. })
  133. describe('when userUpdater produces an error', function () {
  134. beforeEach(function (ctx) {
  135. ctx.UserUpdater.promises.updateUser.rejects()
  136. })
  137. it('should produce an error', async function (ctx) {
  138. await new Promise(resolve => {
  139. ctx.call(err => {
  140. expect(err).to.exist
  141. expect(err).to.be.instanceof(Error)
  142. resolve()
  143. })
  144. })
  145. })
  146. })
  147. })
  148. })