MySQLUserSubscriptionRepository.spec.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import 'reflect-metadata'
  2. import { SubscriptionName } from '@standardnotes/common'
  3. import { Repository, SelectQueryBuilder, UpdateQueryBuilder } from 'typeorm'
  4. import { UserSubscription } from '../../Domain/Subscription/UserSubscription'
  5. import { MySQLUserSubscriptionRepository } from './MySQLUserSubscriptionRepository'
  6. import { UserSubscriptionType } from '../../Domain/Subscription/UserSubscriptionType'
  7. import { TimerInterface } from '@standardnotes/time'
  8. describe('MySQLUserSubscriptionRepository', () => {
  9. let ormRepository: Repository<UserSubscription>
  10. let selectQueryBuilder: SelectQueryBuilder<UserSubscription>
  11. let updateQueryBuilder: UpdateQueryBuilder<UserSubscription>
  12. let subscription: UserSubscription
  13. let timer: TimerInterface
  14. const createRepository = () => new MySQLUserSubscriptionRepository(ormRepository, timer)
  15. beforeEach(() => {
  16. selectQueryBuilder = {} as jest.Mocked<SelectQueryBuilder<UserSubscription>>
  17. updateQueryBuilder = {} as jest.Mocked<UpdateQueryBuilder<UserSubscription>>
  18. subscription = {
  19. planName: SubscriptionName.ProPlan,
  20. cancelled: false,
  21. } as jest.Mocked<UserSubscription>
  22. ormRepository = {} as jest.Mocked<Repository<UserSubscription>>
  23. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  24. ormRepository.save = jest.fn()
  25. timer = {} as jest.Mocked<TimerInterface>
  26. timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123)
  27. })
  28. it('should save', async () => {
  29. await createRepository().save(subscription)
  30. expect(ormRepository.save).toHaveBeenCalledWith(subscription)
  31. })
  32. it('should find all subscriptions by user uuid', async () => {
  33. const canceledSubscription = {
  34. planName: SubscriptionName.ProPlan,
  35. cancelled: true,
  36. } as jest.Mocked<UserSubscription>
  37. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  38. selectQueryBuilder.where = jest.fn().mockReturnThis()
  39. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  40. selectQueryBuilder.getMany = jest.fn().mockReturnValue([canceledSubscription, subscription])
  41. const result = await createRepository().findByUserUuid('123')
  42. expect(selectQueryBuilder.where).toHaveBeenCalledWith('user_uuid = :user_uuid', {
  43. user_uuid: '123',
  44. })
  45. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('ends_at', 'DESC')
  46. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  47. expect(result).toEqual([canceledSubscription, subscription])
  48. })
  49. it('should count all active subscriptions', async () => {
  50. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  51. selectQueryBuilder.groupBy = jest.fn().mockReturnThis()
  52. selectQueryBuilder.where = jest.fn().mockReturnThis()
  53. selectQueryBuilder.getCount = jest.fn().mockReturnValue(2)
  54. const result = await createRepository().countActiveSubscriptions()
  55. expect(selectQueryBuilder.where).toHaveBeenCalledWith('ends_at > :timestamp', {
  56. timestamp: 123,
  57. })
  58. expect(selectQueryBuilder.groupBy).toHaveBeenCalledWith('user_uuid')
  59. expect(selectQueryBuilder.getCount).toHaveBeenCalled()
  60. expect(result).toEqual(2)
  61. })
  62. it('should find one longest lasting uncanceled subscription by user uuid if there are canceled ones', async () => {
  63. const canceledSubscription = {
  64. planName: SubscriptionName.ProPlan,
  65. cancelled: true,
  66. } as jest.Mocked<UserSubscription>
  67. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  68. selectQueryBuilder.where = jest.fn().mockReturnThis()
  69. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  70. selectQueryBuilder.getMany = jest.fn().mockReturnValue([canceledSubscription, subscription])
  71. const result = await createRepository().findOneByUserUuid('123')
  72. expect(selectQueryBuilder.where).toHaveBeenCalledWith('user_uuid = :user_uuid', {
  73. user_uuid: '123',
  74. })
  75. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('ends_at', 'DESC')
  76. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  77. expect(result).toEqual(subscription)
  78. })
  79. it('should find one, longest lasting subscription by user uuid if there are no canceled ones', async () => {
  80. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  81. selectQueryBuilder.where = jest.fn().mockReturnThis()
  82. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  83. selectQueryBuilder.getMany = jest.fn().mockReturnValue([subscription])
  84. const result = await createRepository().findOneByUserUuid('123')
  85. expect(selectQueryBuilder.where).toHaveBeenCalledWith('user_uuid = :user_uuid', {
  86. user_uuid: '123',
  87. })
  88. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('ends_at', 'DESC')
  89. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  90. expect(result).toEqual(subscription)
  91. })
  92. it('should count by user uuid', async () => {
  93. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  94. selectQueryBuilder.where = jest.fn().mockReturnThis()
  95. selectQueryBuilder.getCount = jest.fn().mockReturnValue(2)
  96. const result = await createRepository().countByUserUuid('123')
  97. expect(selectQueryBuilder.where).toHaveBeenCalledWith('user_uuid = :user_uuid', {
  98. user_uuid: '123',
  99. })
  100. expect(selectQueryBuilder.getCount).toHaveBeenCalled()
  101. expect(result).toEqual(2)
  102. })
  103. it('should find one, longest lasting subscription by user uuid if there are no ucanceled ones', async () => {
  104. subscription.cancelled = true
  105. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  106. selectQueryBuilder.where = jest.fn().mockReturnThis()
  107. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  108. selectQueryBuilder.getMany = jest.fn().mockReturnValue([subscription])
  109. const result = await createRepository().findOneByUserUuid('123')
  110. expect(selectQueryBuilder.where).toHaveBeenCalledWith('user_uuid = :user_uuid', {
  111. user_uuid: '123',
  112. })
  113. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('ends_at', 'DESC')
  114. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  115. expect(result).toEqual(subscription)
  116. })
  117. it('should find none if there are no subscriptions for the user', async () => {
  118. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  119. selectQueryBuilder.where = jest.fn().mockReturnThis()
  120. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  121. selectQueryBuilder.getMany = jest.fn().mockReturnValue([])
  122. const result = await createRepository().findOneByUserUuid('123')
  123. expect(selectQueryBuilder.where).toHaveBeenCalledWith('user_uuid = :user_uuid', {
  124. user_uuid: '123',
  125. })
  126. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('ends_at', 'DESC')
  127. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  128. expect(result).toBeNull()
  129. })
  130. it('should update ends at by subscription id', async () => {
  131. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => updateQueryBuilder)
  132. updateQueryBuilder.update = jest.fn().mockReturnThis()
  133. updateQueryBuilder.set = jest.fn().mockReturnThis()
  134. updateQueryBuilder.where = jest.fn().mockReturnThis()
  135. updateQueryBuilder.execute = jest.fn()
  136. await createRepository().updateEndsAt(1, 1000, 1000)
  137. expect(updateQueryBuilder.update).toHaveBeenCalled()
  138. expect(updateQueryBuilder.set).toHaveBeenCalledWith({
  139. updatedAt: 1000,
  140. renewedAt: 1000,
  141. endsAt: 1000,
  142. })
  143. expect(updateQueryBuilder.where).toHaveBeenCalledWith('subscription_id = :subscriptionId', {
  144. subscriptionId: 1,
  145. })
  146. expect(updateQueryBuilder.execute).toHaveBeenCalled()
  147. })
  148. it('should update cancelled by subscription id', async () => {
  149. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => updateQueryBuilder)
  150. updateQueryBuilder.update = jest.fn().mockReturnThis()
  151. updateQueryBuilder.set = jest.fn().mockReturnThis()
  152. updateQueryBuilder.where = jest.fn().mockReturnThis()
  153. updateQueryBuilder.execute = jest.fn()
  154. await createRepository().updateCancelled(1, true, 1000)
  155. expect(updateQueryBuilder.update).toHaveBeenCalled()
  156. expect(updateQueryBuilder.set).toHaveBeenCalledWith({
  157. updatedAt: expect.any(Number),
  158. cancelled: true,
  159. })
  160. expect(updateQueryBuilder.where).toHaveBeenCalledWith('subscription_id = :subscriptionId', {
  161. subscriptionId: 1,
  162. })
  163. expect(updateQueryBuilder.execute).toHaveBeenCalled()
  164. })
  165. it('should find subscriptions by id', async () => {
  166. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  167. selectQueryBuilder.where = jest.fn().mockReturnThis()
  168. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  169. selectQueryBuilder.getMany = jest.fn().mockReturnValue([subscription])
  170. const result = await createRepository().findBySubscriptionId(123)
  171. expect(selectQueryBuilder.where).toHaveBeenCalledWith('subscription_id = :subscriptionId', {
  172. subscriptionId: 123,
  173. })
  174. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('created_at', 'DESC')
  175. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  176. expect(result).toEqual([subscription])
  177. })
  178. it('should find subscriptions by id and type', async () => {
  179. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  180. selectQueryBuilder.where = jest.fn().mockReturnThis()
  181. selectQueryBuilder.orderBy = jest.fn().mockReturnThis()
  182. selectQueryBuilder.getMany = jest.fn().mockReturnValue([subscription])
  183. const result = await createRepository().findBySubscriptionIdAndType(123, UserSubscriptionType.Regular)
  184. expect(selectQueryBuilder.where).toHaveBeenCalledWith(
  185. 'subscription_id = :subscriptionId AND subscription_type = :type',
  186. {
  187. subscriptionId: 123,
  188. type: 'regular',
  189. },
  190. )
  191. expect(selectQueryBuilder.orderBy).toHaveBeenCalledWith('created_at', 'DESC')
  192. expect(selectQueryBuilder.getMany).toHaveBeenCalled()
  193. expect(result).toEqual([subscription])
  194. })
  195. it('should find one subscription by id and user uuid', async () => {
  196. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  197. selectQueryBuilder.where = jest.fn().mockReturnThis()
  198. selectQueryBuilder.getOne = jest.fn().mockReturnValue(subscription)
  199. const result = await createRepository().findOneByUserUuidAndSubscriptionId('1-2-3', 5)
  200. expect(selectQueryBuilder.where).toHaveBeenCalledWith(
  201. 'user_uuid = :userUuid AND subscription_id = :subscriptionId',
  202. {
  203. subscriptionId: 5,
  204. userUuid: '1-2-3',
  205. },
  206. )
  207. expect(selectQueryBuilder.getOne).toHaveBeenCalled()
  208. expect(result).toEqual(subscription)
  209. })
  210. it('should find one subscription by uuid', async () => {
  211. ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => selectQueryBuilder)
  212. selectQueryBuilder.where = jest.fn().mockReturnThis()
  213. selectQueryBuilder.getOne = jest.fn().mockReturnValue(subscription)
  214. const result = await createRepository().findOneByUuid('1-2-3')
  215. expect(selectQueryBuilder.where).toHaveBeenCalledWith('uuid = :uuid', {
  216. uuid: '1-2-3',
  217. })
  218. expect(selectQueryBuilder.getOne).toHaveBeenCalled()
  219. expect(result).toEqual(subscription)
  220. })
  221. })