current-plan-widget.test.tsx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. import { expect } from 'chai'
  2. import sinon from 'sinon'
  3. import { fireEvent, render, screen } from '@testing-library/react'
  4. import {
  5. CommonsPlanSubscription,
  6. GroupPlanSubscription,
  7. IndividualPlanSubscription,
  8. } from '../../../../../types/project/dashboard/subscription'
  9. import { DeepReadonly } from '../../../../../types/utils'
  10. import * as eventTracking from '@/infrastructure/event-tracking'
  11. import CurrentPlanWidget from '../../../../../frontend/js/features/project-list/components/current-plan-widget/current-plan-widget'
  12. describe('<CurrentPlanWidget />', function () {
  13. const freePlanTooltipMessage =
  14. /click to find out how you could benefit from overleaf premium features/i
  15. const paidPlanTooltipMessage =
  16. /click to find out how to make the most of your overleaf premium features/i
  17. const pausedTooltipMessage =
  18. /click to unpause and reactivate your overleaf premium features/i
  19. let sendMBSpy: sinon.SinonSpy
  20. beforeEach(function () {
  21. sendMBSpy = sinon.spy(eventTracking, 'sendMB')
  22. })
  23. afterEach(function () {
  24. sendMBSpy.restore()
  25. })
  26. describe('paused', function () {
  27. beforeEach(function () {
  28. window.metaAttributesCache.set('ol-usersBestSubscription', {
  29. type: 'individual',
  30. subscription: {
  31. recurlyStatus: {
  32. state: 'paused',
  33. },
  34. },
  35. })
  36. render(<CurrentPlanWidget />)
  37. })
  38. it('shows text and tooltip on mouseover', async function () {
  39. const link = screen.getByRole('link', {
  40. name: /plan is paused/i,
  41. })
  42. fireEvent.mouseOver(link)
  43. await screen.findByRole('tooltip', { name: pausedTooltipMessage })
  44. })
  45. })
  46. describe('free plan', function () {
  47. beforeEach(function () {
  48. window.metaAttributesCache.set('ol-usersBestSubscription', {
  49. type: 'free',
  50. })
  51. render(<CurrentPlanWidget />)
  52. })
  53. it('shows text and tooltip on mouseover', async function () {
  54. const link = screen.getByRole('link', {
  55. name: /you’re on the free plan/i,
  56. })
  57. fireEvent.mouseOver(link)
  58. await screen.findByRole('tooltip', { name: freePlanTooltipMessage })
  59. })
  60. it('clicks on upgrade button', function () {
  61. const upgradeLink = screen.getByRole('button', { name: /upgrade/i })
  62. fireEvent.click(upgradeLink)
  63. expect(sendMBSpy).to.be.calledOnce
  64. expect(sendMBSpy).calledWith('upgrade-button-click', {
  65. source: 'dashboard-top',
  66. page: '/',
  67. 'project-dashboard-react': 'enabled',
  68. 'is-dashboard-sidebar-hidden': false,
  69. 'is-screen-width-less-than-768px': false,
  70. })
  71. })
  72. })
  73. describe('paid plan', function () {
  74. describe('trial', function () {
  75. const subscription = {
  76. type: 'individual',
  77. plan: {
  78. name: 'Abc',
  79. },
  80. subscription: {
  81. name: 'Example Name',
  82. },
  83. remainingTrialDays: -1,
  84. } as DeepReadonly<IndividualPlanSubscription>
  85. beforeEach(function () {
  86. window.metaAttributesCache.set('ol-usersBestSubscription', {
  87. ...subscription,
  88. })
  89. })
  90. it('shows remaining days', function () {
  91. const newSubscription: IndividualPlanSubscription = {
  92. ...subscription,
  93. remainingTrialDays: 5,
  94. }
  95. window.metaAttributesCache.set(
  96. 'ol-usersBestSubscription',
  97. newSubscription
  98. )
  99. render(<CurrentPlanWidget />)
  100. screen.getByRole('link', {
  101. name: new RegExp(
  102. `${newSubscription.remainingTrialDays} more days on your overleaf premium trial`,
  103. 'i'
  104. ),
  105. })
  106. })
  107. it('shows last day message', function () {
  108. window.metaAttributesCache.set('ol-usersBestSubscription', {
  109. ...subscription,
  110. remainingTrialDays: 1,
  111. })
  112. render(<CurrentPlanWidget />)
  113. screen.getByRole('link', {
  114. name: /this is the last day of your overleaf premium trial/i,
  115. })
  116. })
  117. })
  118. describe('individual', function () {
  119. const subscription = {
  120. type: 'individual',
  121. plan: {
  122. name: 'Abc',
  123. },
  124. subscription: {
  125. teamName: 'Example Team',
  126. name: 'Example Name',
  127. },
  128. remainingTrialDays: -1,
  129. } as DeepReadonly<IndividualPlanSubscription>
  130. beforeEach(function () {
  131. window.metaAttributesCache.set('ol-usersBestSubscription', {
  132. ...subscription,
  133. })
  134. })
  135. it('shows text and tooltip on mouseover', async function () {
  136. render(<CurrentPlanWidget />)
  137. const link = screen.getByRole('link', {
  138. name: /you’re using overleaf premium/i,
  139. })
  140. fireEvent.mouseOver(link)
  141. await screen.findByRole('tooltip', {
  142. name: new RegExp(`on the ${subscription.plan.name}`, 'i'),
  143. })
  144. await screen.findByRole('tooltip', { name: paidPlanTooltipMessage })
  145. })
  146. })
  147. describe('group', function () {
  148. const subscription = {
  149. type: 'group',
  150. plan: {
  151. name: 'Abc',
  152. },
  153. subscription: {
  154. name: 'Example Name',
  155. },
  156. remainingTrialDays: -1,
  157. } as DeepReadonly<GroupPlanSubscription>
  158. beforeEach(function () {
  159. window.metaAttributesCache.set('ol-usersBestSubscription', {
  160. ...subscription,
  161. })
  162. })
  163. it('shows text and tooltip on mouseover (without subscription team name)', async function () {
  164. render(<CurrentPlanWidget />)
  165. const link = screen.getByRole('link', {
  166. name: /you’re using overleaf premium/i,
  167. })
  168. fireEvent.mouseOver(link)
  169. expect(subscription.subscription.teamName).to.be.undefined
  170. await screen.findByRole('tooltip', {
  171. name: new RegExp(
  172. `on the ${subscription.plan.name} plan as a member of a group subscription`,
  173. 'i'
  174. ),
  175. })
  176. await screen.findByRole('tooltip', { name: paidPlanTooltipMessage })
  177. })
  178. it('shows text and tooltip on mouseover (with subscription team name)', async function () {
  179. const newSubscription = {
  180. ...subscription,
  181. subscription: {
  182. teamName: 'Example Team',
  183. },
  184. }
  185. window.metaAttributesCache.set(
  186. 'ol-usersBestSubscription',
  187. newSubscription
  188. )
  189. render(<CurrentPlanWidget />)
  190. const link = screen.getByRole('link', {
  191. name: /you’re using overleaf premium/i,
  192. })
  193. fireEvent.mouseOver(link)
  194. await screen.findByRole('tooltip', {
  195. name: new RegExp(
  196. `on the ${newSubscription.plan.name} plan as a member of a group subscription, ${newSubscription.subscription.teamName}`,
  197. 'i'
  198. ),
  199. })
  200. await screen.findByRole('tooltip', { name: paidPlanTooltipMessage })
  201. })
  202. })
  203. describe('commons', function () {
  204. it('shows text and tooltip on mouseover', async function () {
  205. const subscription = {
  206. type: 'commons',
  207. plan: {
  208. name: 'Abc',
  209. },
  210. subscription: {
  211. name: 'Example Name',
  212. },
  213. } as DeepReadonly<CommonsPlanSubscription>
  214. window.metaAttributesCache.set('ol-usersBestSubscription', {
  215. ...subscription,
  216. })
  217. render(<CurrentPlanWidget />)
  218. const link = screen.getByRole('link', {
  219. name: /you’re using overleaf premium/i,
  220. })
  221. fireEvent.mouseOver(link)
  222. await screen.findByRole('tooltip', {
  223. name: new RegExp(
  224. `on the ${subscription.plan.name} plan because of your affiliation with ${subscription.subscription.name}`,
  225. 'i'
  226. ),
  227. })
  228. await screen.findByRole('tooltip', { name: paidPlanTooltipMessage })
  229. })
  230. })
  231. })
  232. describe('features page', function () {
  233. const plans = [
  234. { type: 'free' },
  235. {
  236. type: 'individual',
  237. plan: {
  238. name: 'Abc',
  239. },
  240. },
  241. {
  242. type: 'group',
  243. plan: {
  244. name: 'Abc',
  245. },
  246. subscription: {
  247. teamName: 'Example Team',
  248. name: 'Example Name',
  249. },
  250. },
  251. {
  252. type: 'commons',
  253. plan: {
  254. name: 'Abc',
  255. },
  256. subscription: {
  257. name: 'Example Name',
  258. },
  259. },
  260. ]
  261. for (const plan of plans) {
  262. it(`links to features page on ${plan.type} plan`, function () {
  263. window.metaAttributesCache.set('ol-usersBestSubscription', {
  264. ...plan,
  265. })
  266. render(<CurrentPlanWidget />)
  267. const links = screen.getAllByRole('link')
  268. expect(links[0].getAttribute('href')).to.equal(
  269. '/learn/how-to/Overleaf_premium_features'
  270. )
  271. fireEvent.click(links[0])
  272. window.metaAttributesCache.delete('ol-usersBestSubscription')
  273. })
  274. }
  275. })
  276. })