SubscriptionHelperTests.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. const SandboxedModule = require('sandboxed-module')
  2. const { expect } = require('chai')
  3. const { formatCurrencyLocalized } = require('../../../../app/src/util/currency')
  4. const modulePath =
  5. '../../../../app/src/Features/Subscription/SubscriptionHelper'
  6. const plans = {
  7. expensive: {
  8. planCode: 'expensive',
  9. price_in_cents: 1500,
  10. },
  11. cheaper: {
  12. planCode: 'cheaper',
  13. price_in_cents: 500,
  14. },
  15. alsoCheap: {
  16. plancode: 'also-cheap',
  17. price_in_cents: 500,
  18. },
  19. expensiveGroup: {
  20. plancode: 'group_expensive',
  21. price_in_cents: 49500,
  22. groupPlan: true,
  23. },
  24. cheapGroup: {
  25. plancode: 'group_cheap',
  26. price_in_cents: 1000,
  27. groupPlan: true,
  28. },
  29. bad: {},
  30. }
  31. describe('SubscriptionHelper', function () {
  32. beforeEach(function () {
  33. this.INITIAL_LICENSE_SIZE = 2
  34. this.settings = {
  35. groupPlanModalOptions: {
  36. currencySymbols: {
  37. USD: '$',
  38. CHF: 'Fr',
  39. DKK: 'kr',
  40. NOK: 'kr',
  41. SEK: 'kr',
  42. },
  43. },
  44. }
  45. this.GroupPlansData = {
  46. enterprise: {
  47. collaborator: {
  48. CHF: {
  49. [this.INITIAL_LICENSE_SIZE]: {
  50. price_in_cents: 1000,
  51. },
  52. },
  53. DKK: {
  54. [this.INITIAL_LICENSE_SIZE]: {
  55. price_in_cents: 2000,
  56. },
  57. },
  58. SEK: {
  59. [this.INITIAL_LICENSE_SIZE]: {
  60. price_in_cents: 3000,
  61. },
  62. },
  63. NOK: {
  64. [this.INITIAL_LICENSE_SIZE]: {
  65. price_in_cents: 4000,
  66. },
  67. },
  68. USD: {
  69. [this.INITIAL_LICENSE_SIZE]: {
  70. price_in_cents: 5000,
  71. },
  72. },
  73. },
  74. professional: {
  75. CHF: {
  76. [this.INITIAL_LICENSE_SIZE]: {
  77. price_in_cents: 10000,
  78. },
  79. },
  80. DKK: {
  81. [this.INITIAL_LICENSE_SIZE]: {
  82. price_in_cents: 20000,
  83. },
  84. },
  85. SEK: {
  86. [this.INITIAL_LICENSE_SIZE]: {
  87. price_in_cents: 30000,
  88. },
  89. },
  90. NOK: {
  91. [this.INITIAL_LICENSE_SIZE]: {
  92. price_in_cents: 40000,
  93. },
  94. },
  95. USD: {
  96. [this.INITIAL_LICENSE_SIZE]: {
  97. price_in_cents: 50000,
  98. },
  99. },
  100. },
  101. },
  102. }
  103. this.SubscriptionHelper = SandboxedModule.require(modulePath, {
  104. requires: {
  105. '@overleaf/settings': this.settings,
  106. './GroupPlansData': this.GroupPlansData,
  107. },
  108. })
  109. })
  110. describe('shouldPlanChangeAtTermEnd', function () {
  111. it('should return true if the new plan is less expensive', function () {
  112. const changeAtTermEnd = this.SubscriptionHelper.shouldPlanChangeAtTermEnd(
  113. plans.expensive,
  114. plans.cheaper
  115. )
  116. expect(changeAtTermEnd).to.be.true
  117. })
  118. it('should return false if the new plan is more exepensive', function () {
  119. const changeAtTermEnd = this.SubscriptionHelper.shouldPlanChangeAtTermEnd(
  120. plans.cheaper,
  121. plans.expensive
  122. )
  123. expect(changeAtTermEnd).to.be.false
  124. })
  125. it('should return false if the new plan is the same price', function () {
  126. const changeAtTermEnd = this.SubscriptionHelper.shouldPlanChangeAtTermEnd(
  127. plans.cheaper,
  128. plans.alsoCheap
  129. )
  130. expect(changeAtTermEnd).to.be.false
  131. })
  132. it('should return false if the change is from an individual plan to a more expensive group plan', function () {
  133. const changeAtTermEnd = this.SubscriptionHelper.shouldPlanChangeAtTermEnd(
  134. plans.expensive,
  135. plans.expensiveGroup
  136. )
  137. expect(changeAtTermEnd).to.be.false
  138. })
  139. it('should return true if the change is from an individual plan to a cheaper group plan', function () {
  140. const changeAtTermEnd = this.SubscriptionHelper.shouldPlanChangeAtTermEnd(
  141. plans.expensive,
  142. plans.cheapGroup
  143. )
  144. expect(changeAtTermEnd).to.be.true
  145. })
  146. })
  147. describe('generateInitialLocalizedGroupPrice', function () {
  148. describe('CHF currency', function () {
  149. it('should return the correct localized price for every plan', function () {
  150. const localizedPrice =
  151. this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
  152. 'CHF',
  153. 'fr',
  154. formatCurrencyLocalized
  155. )
  156. expect(localizedPrice).to.deep.equal({
  157. price: {
  158. collaborator: '10 CHF',
  159. professional: '100 CHF',
  160. },
  161. pricePerUser: {
  162. collaborator: '5 CHF',
  163. professional: '50 CHF',
  164. },
  165. })
  166. })
  167. })
  168. describe('DKK currency', function () {
  169. it('should return the correct localized price for every plan', function () {
  170. const localizedPrice =
  171. this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
  172. 'DKK',
  173. 'da',
  174. formatCurrencyLocalized
  175. )
  176. expect(localizedPrice).to.deep.equal({
  177. price: {
  178. collaborator: '20 kr.',
  179. professional: '200 kr.',
  180. },
  181. pricePerUser: {
  182. collaborator: '10 kr.',
  183. professional: '100 kr.',
  184. },
  185. })
  186. })
  187. })
  188. describe('SEK currency', function () {
  189. it('should return the correct localized price for every plan', function () {
  190. const localizedPrice =
  191. this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
  192. 'SEK',
  193. 'sv',
  194. formatCurrencyLocalized
  195. )
  196. expect(localizedPrice).to.deep.equal({
  197. price: {
  198. collaborator: '30 kr',
  199. professional: '300 kr',
  200. },
  201. pricePerUser: {
  202. collaborator: '15 kr',
  203. professional: '150 kr',
  204. },
  205. })
  206. })
  207. })
  208. describe('NOK currency', function () {
  209. it('should return the correct localized price for every plan', function () {
  210. const localizedPrice =
  211. this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
  212. 'NOK',
  213. // there seem to be possible inconsistencies with the CI
  214. // maybe it depends on what languages are installed on the server?
  215. 'en',
  216. formatCurrencyLocalized
  217. )
  218. expect(localizedPrice).to.deep.equal({
  219. price: {
  220. collaborator: 'kr 40',
  221. professional: 'kr 400',
  222. },
  223. pricePerUser: {
  224. collaborator: 'kr 20',
  225. professional: 'kr 200',
  226. },
  227. })
  228. })
  229. })
  230. describe('other supported currencies', function () {
  231. it('should return the correct localized price for every plan', function () {
  232. const localizedPrice =
  233. this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
  234. 'USD',
  235. 'en',
  236. formatCurrencyLocalized
  237. )
  238. expect(localizedPrice).to.deep.equal({
  239. price: {
  240. collaborator: '$50',
  241. professional: '$500',
  242. },
  243. pricePerUser: {
  244. collaborator: '$25',
  245. professional: '$250',
  246. },
  247. })
  248. })
  249. })
  250. })
  251. })