LimitationsManagerTests.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. const SandboxedModule = require('sandboxed-module')
  2. const assert = require('assert')
  3. const sinon = require('sinon')
  4. const modulePath = require('path').join(
  5. __dirname,
  6. '../../../../app/src/Features/Subscription/LimitationsManager'
  7. )
  8. describe('LimitationsManager', function () {
  9. beforeEach(function () {
  10. this.user = {
  11. _id: (this.userId = 'user-id'),
  12. features: { collaborators: 1 },
  13. }
  14. this.project = {
  15. _id: (this.projectId = 'project-id'),
  16. owner_ref: this.userId,
  17. }
  18. this.ProjectGetter = {
  19. promises: {
  20. getProject: sinon.stub().callsFake(async (projectId, fields) => {
  21. if (projectId === this.projectId) {
  22. return this.project
  23. } else {
  24. return null
  25. }
  26. }),
  27. },
  28. }
  29. this.UserGetter = {
  30. promises: {
  31. getUser: sinon.stub().callsFake(async (userId, filter) => {
  32. if (userId === this.userId) {
  33. return this.user
  34. } else {
  35. return null
  36. }
  37. }),
  38. },
  39. }
  40. this.SubscriptionLocator = {
  41. promises: {
  42. getUsersSubscription: sinon.stub().resolves(),
  43. getSubscription: sinon.stub().resolves(),
  44. getMemberSubscriptions: sinon.stub().resolves(),
  45. },
  46. }
  47. this.V1SubscriptionManager = {
  48. promises: {
  49. getSubscriptionsFromV1: sinon.stub().resolves(),
  50. },
  51. }
  52. this.CollaboratorsGetter = {
  53. promises: {
  54. getInvitedCollaboratorCount: sinon.stub().resolves(),
  55. getInvitedEditCollaboratorCount: sinon.stub().resolves(),
  56. },
  57. }
  58. this.CollaboratorsInviteHandler = {
  59. promises: {
  60. getInviteCount: sinon.stub().resolves(),
  61. getEditInviteCount: sinon.stub().resolves(),
  62. },
  63. }
  64. this.LimitationsManager = SandboxedModule.require(modulePath, {
  65. requires: {
  66. '../Project/ProjectGetter': this.ProjectGetter,
  67. '../User/UserGetter': this.UserGetter,
  68. './SubscriptionLocator': this.SubscriptionLocator,
  69. '@overleaf/settings': (this.Settings = {}),
  70. '../Collaborators/CollaboratorsGetter': this.CollaboratorsGetter,
  71. '../Collaborators/CollaboratorsInviteHandler':
  72. this.CollaboratorsInviteHandler,
  73. './V1SubscriptionManager': this.V1SubscriptionManager,
  74. },
  75. })
  76. })
  77. describe('allowedNumberOfCollaboratorsInProject', function () {
  78. describe('when the project is owned by a user without a subscription', function () {
  79. beforeEach(function (done) {
  80. this.Settings.defaultFeatures = { collaborators: 23 }
  81. this.project.owner_ref = this.userId
  82. delete this.user.features
  83. this.callback = sinon.stub().callsFake(() => done())
  84. this.LimitationsManager.allowedNumberOfCollaboratorsInProject(
  85. this.projectId,
  86. this.callback
  87. )
  88. })
  89. it('should return the default number', function () {
  90. this.callback
  91. .calledWith(null, this.Settings.defaultFeatures.collaborators)
  92. .should.equal(true)
  93. })
  94. })
  95. describe('when the project is owned by a user with a subscription', function () {
  96. beforeEach(function (done) {
  97. this.project.owner_ref = this.userId
  98. this.user.features = { collaborators: 21 }
  99. this.callback = sinon.stub().callsFake(() => done())
  100. this.LimitationsManager.allowedNumberOfCollaboratorsInProject(
  101. this.projectId,
  102. this.callback
  103. )
  104. })
  105. it('should return the number of collaborators the user is allowed', function () {
  106. this.callback
  107. .calledWith(null, this.user.features.collaborators)
  108. .should.equal(true)
  109. })
  110. })
  111. })
  112. describe('allowedNumberOfCollaboratorsForUser', function () {
  113. describe('when the user has no features', function () {
  114. beforeEach(function (done) {
  115. this.Settings.defaultFeatures = { collaborators: 23 }
  116. delete this.user.features
  117. this.callback = sinon.stub().callsFake(() => done())
  118. this.LimitationsManager.allowedNumberOfCollaboratorsForUser(
  119. this.userId,
  120. this.callback
  121. )
  122. })
  123. it('should return the default number', function () {
  124. this.callback
  125. .calledWith(null, this.Settings.defaultFeatures.collaborators)
  126. .should.equal(true)
  127. })
  128. })
  129. describe('when the user has features', function () {
  130. beforeEach(function (done) {
  131. this.user.features = { collaborators: 21 }
  132. this.callback = sinon.stub().callsFake(() => done())
  133. this.LimitationsManager.allowedNumberOfCollaboratorsForUser(
  134. this.userId,
  135. this.callback
  136. )
  137. })
  138. it('should return the number of collaborators the user is allowed', function () {
  139. this.callback
  140. .calledWith(null, this.user.features.collaborators)
  141. .should.equal(true)
  142. })
  143. })
  144. })
  145. describe('canAddXCollaborators', function () {
  146. describe('when the project has fewer collaborators than allowed', function () {
  147. beforeEach(function (done) {
  148. this.current_number = 1
  149. this.user.features.collaborators = 2
  150. this.invite_count = 0
  151. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  152. .stub()
  153. .resolves(this.current_number)
  154. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  155. .stub()
  156. .resolves(this.invite_count)
  157. this.callback = sinon.stub().callsFake(() => done())
  158. this.LimitationsManager.canAddXCollaborators(
  159. this.projectId,
  160. 1,
  161. this.callback
  162. )
  163. })
  164. it('should return true', function () {
  165. this.callback.calledWith(null, true).should.equal(true)
  166. })
  167. })
  168. describe('when the project has fewer collaborators and invites than allowed', function () {
  169. beforeEach(function (done) {
  170. this.current_number = 1
  171. this.user.features.collaborators = 4
  172. this.invite_count = 1
  173. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  174. .stub()
  175. .resolves(this.current_number)
  176. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  177. .stub()
  178. .resolves(this.invite_count)
  179. this.callback = sinon.stub().callsFake(() => done())
  180. this.LimitationsManager.canAddXCollaborators(
  181. this.projectId,
  182. 1,
  183. this.callback
  184. )
  185. })
  186. it('should return true', function () {
  187. this.callback.calledWith(null, true).should.equal(true)
  188. })
  189. })
  190. describe('when the project has fewer collaborators than allowed but I want to add more than allowed', function () {
  191. beforeEach(function (done) {
  192. this.current_number = 1
  193. this.user.features.collaborators = 2
  194. this.invite_count = 0
  195. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  196. .stub()
  197. .resolves(this.current_number)
  198. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  199. .stub()
  200. .resolves(this.invite_count)
  201. this.callback = sinon.stub().callsFake(() => done())
  202. this.LimitationsManager.canAddXCollaborators(
  203. this.projectId,
  204. 2,
  205. this.callback
  206. )
  207. })
  208. it('should return false', function () {
  209. this.callback.calledWith(null, false).should.equal(true)
  210. })
  211. })
  212. describe('when the project has more collaborators than allowed', function () {
  213. beforeEach(function (done) {
  214. this.current_number = 3
  215. this.user.features.collaborators = 2
  216. this.invite_count = 0
  217. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  218. .stub()
  219. .resolves(this.current_number)
  220. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  221. .stub()
  222. .resolves(this.invite_count)
  223. this.callback = sinon.stub().callsFake(() => done())
  224. this.LimitationsManager.canAddXCollaborators(
  225. this.projectId,
  226. 1,
  227. this.callback
  228. )
  229. })
  230. it('should return false', function () {
  231. this.callback.calledWith(null, false).should.equal(true)
  232. })
  233. })
  234. describe('when the project has infinite collaborators', function () {
  235. beforeEach(function (done) {
  236. this.current_number = 100
  237. this.user.features.collaborators = -1
  238. this.invite_count = 0
  239. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  240. .stub()
  241. .resolves(this.current_number)
  242. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  243. .stub()
  244. .resolves(this.invite_count)
  245. this.callback = sinon.stub().callsFake(() => done())
  246. this.LimitationsManager.canAddXCollaborators(
  247. this.projectId,
  248. 1,
  249. this.callback
  250. )
  251. })
  252. it('should return true', function () {
  253. this.callback.calledWith(null, true).should.equal(true)
  254. })
  255. })
  256. describe('when the project has more invites than allowed', function () {
  257. beforeEach(function (done) {
  258. this.current_number = 0
  259. this.user.features.collaborators = 2
  260. this.invite_count = 2
  261. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  262. .stub()
  263. .resolves(this.current_number)
  264. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  265. .stub()
  266. .resolves(this.invite_count)
  267. this.callback = sinon.stub().callsFake(() => done())
  268. this.LimitationsManager.canAddXCollaborators(
  269. this.projectId,
  270. 1,
  271. this.callback
  272. )
  273. })
  274. it('should return false', function () {
  275. this.callback.calledWith(null, false).should.equal(true)
  276. })
  277. })
  278. describe('when the project has more invites and collaborators than allowed', function () {
  279. beforeEach(function (done) {
  280. this.current_number = 1
  281. this.user.features.collaborators = 2
  282. this.invite_count = 1
  283. this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
  284. .stub()
  285. .resolves(this.current_number)
  286. this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
  287. .stub()
  288. .resolves(this.invite_count)
  289. this.callback = sinon.stub().callsFake(() => done())
  290. this.LimitationsManager.canAddXCollaborators(
  291. this.projectId,
  292. 1,
  293. this.callback
  294. )
  295. })
  296. it('should return false', function () {
  297. this.callback.calledWith(null, false).should.equal(true)
  298. })
  299. })
  300. })
  301. describe('canAddXEditCollaborators', function () {
  302. describe('when the project has fewer collaborators than allowed', function () {
  303. beforeEach(function (done) {
  304. this.current_number = 1
  305. this.user.features.collaborators = 2
  306. this.invite_count = 0
  307. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  308. sinon.stub().resolves(this.current_number)
  309. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  310. .stub()
  311. .resolves(this.invite_count)
  312. this.callback = sinon.stub().callsFake(() => done())
  313. this.LimitationsManager.canAddXEditCollaborators(
  314. this.projectId,
  315. 1,
  316. this.callback
  317. )
  318. })
  319. it('should return true', function () {
  320. this.callback.calledWith(null, true).should.equal(true)
  321. })
  322. })
  323. describe('when the project has fewer collaborators and invites than allowed', function () {
  324. beforeEach(function (done) {
  325. this.current_number = 1
  326. this.user.features.collaborators = 4
  327. this.invite_count = 1
  328. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  329. sinon.stub().resolves(this.current_number)
  330. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  331. .stub()
  332. .resolves(this.invite_count)
  333. this.callback = sinon.stub().callsFake(() => done())
  334. this.LimitationsManager.canAddXEditCollaborators(
  335. this.projectId,
  336. 1,
  337. this.callback
  338. )
  339. })
  340. it('should return true', function () {
  341. this.callback.calledWith(null, true).should.equal(true)
  342. })
  343. })
  344. describe('when the project has fewer collaborators than allowed but I want to add more than allowed', function () {
  345. beforeEach(function (done) {
  346. this.current_number = 1
  347. this.user.features.collaborators = 2
  348. this.invite_count = 0
  349. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  350. sinon.stub().resolves(this.current_number)
  351. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  352. .stub()
  353. .resolves(this.invite_count)
  354. this.callback = sinon.stub().callsFake(() => done())
  355. this.LimitationsManager.canAddXEditCollaborators(
  356. this.projectId,
  357. 2,
  358. this.callback
  359. )
  360. })
  361. it('should return false', function () {
  362. this.callback.calledWith(null, false).should.equal(true)
  363. })
  364. })
  365. describe('when the project has more collaborators than allowed', function () {
  366. beforeEach(function (done) {
  367. this.current_number = 3
  368. this.user.features.collaborators = 2
  369. this.invite_count = 0
  370. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  371. sinon.stub().resolves(this.current_number)
  372. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  373. .stub()
  374. .resolves(this.invite_count)
  375. this.callback = sinon.stub().callsFake(() => done())
  376. this.LimitationsManager.canAddXEditCollaborators(
  377. this.projectId,
  378. 1,
  379. this.callback
  380. )
  381. })
  382. it('should return false', function () {
  383. this.callback.calledWith(null, false).should.equal(true)
  384. })
  385. })
  386. describe('when the project has infinite collaborators', function () {
  387. beforeEach(function (done) {
  388. this.current_number = 100
  389. this.user.features.collaborators = -1
  390. this.invite_count = 0
  391. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  392. sinon.stub().resolves(this.current_number)
  393. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  394. .stub()
  395. .resolves(this.invite_count)
  396. this.callback = sinon.stub().callsFake(() => done())
  397. this.LimitationsManager.canAddXEditCollaborators(
  398. this.projectId,
  399. 1,
  400. this.callback
  401. )
  402. })
  403. it('should return true', function () {
  404. this.callback.calledWith(null, true).should.equal(true)
  405. })
  406. })
  407. describe('when the project has more invites than allowed', function () {
  408. beforeEach(function (done) {
  409. this.current_number = 0
  410. this.user.features.collaborators = 2
  411. this.invite_count = 2
  412. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  413. sinon.stub().resolves(this.current_number)
  414. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  415. .stub()
  416. .resolves(this.invite_count)
  417. this.callback = sinon.stub().callsFake(() => done())
  418. this.LimitationsManager.canAddXEditCollaborators(
  419. this.projectId,
  420. 1,
  421. this.callback
  422. )
  423. })
  424. it('should return false', function () {
  425. this.callback.calledWith(null, false).should.equal(true)
  426. })
  427. })
  428. describe('when the project has more invites and collaborators than allowed', function () {
  429. beforeEach(function (done) {
  430. this.current_number = 1
  431. this.user.features.collaborators = 2
  432. this.invite_count = 1
  433. this.CollaboratorsGetter.promises.getInvitedEditCollaboratorCount =
  434. sinon.stub().resolves(this.current_number)
  435. this.CollaboratorsInviteHandler.promises.getEditInviteCount = sinon
  436. .stub()
  437. .resolves(this.invite_count)
  438. this.callback = sinon.stub().callsFake(() => done())
  439. this.LimitationsManager.canAddXEditCollaborators(
  440. this.projectId,
  441. 1,
  442. this.callback
  443. )
  444. })
  445. it('should return false', function () {
  446. this.callback.calledWith(null, false).should.equal(true)
  447. })
  448. })
  449. })
  450. describe('userHasV2Subscription', function () {
  451. beforeEach(function () {
  452. this.SubscriptionLocator.promises.getUsersSubscription = sinon
  453. .stub()
  454. .resolves()
  455. })
  456. it('should return true if the recurly token is set', function (done) {
  457. this.SubscriptionLocator.promises.getUsersSubscription = sinon
  458. .stub()
  459. .resolves({
  460. recurlySubscription_id: '1234',
  461. })
  462. this.LimitationsManager.userHasV2Subscription(
  463. this.user,
  464. (err, hasSubscription) => {
  465. assert.equal(err, null)
  466. hasSubscription.should.equal(true)
  467. done()
  468. }
  469. )
  470. })
  471. it('should return false if the recurly token is not set', function (done) {
  472. this.SubscriptionLocator.promises.getUsersSubscription.resolves({})
  473. this.subscription = {}
  474. this.LimitationsManager.userHasV2Subscription(
  475. this.user,
  476. (err, hasSubscription) => {
  477. assert.equal(err, null)
  478. hasSubscription.should.equal(false)
  479. done()
  480. }
  481. )
  482. })
  483. it('should return false if the subscription is undefined', function (done) {
  484. this.SubscriptionLocator.promises.getUsersSubscription.resolves()
  485. this.LimitationsManager.userHasV2Subscription(
  486. this.user,
  487. (err, hasSubscription) => {
  488. assert.equal(err, null)
  489. hasSubscription.should.equal(false)
  490. done()
  491. }
  492. )
  493. })
  494. it('should return the subscription', function (done) {
  495. const stubbedSubscription = { freeTrial: {}, token: '' }
  496. this.SubscriptionLocator.promises.getUsersSubscription.resolves(
  497. stubbedSubscription
  498. )
  499. this.LimitationsManager.userHasV2Subscription(
  500. this.user,
  501. (err, hasSubOrIsGroupMember, subscription) => {
  502. assert.equal(err, null)
  503. subscription.should.deep.equal(stubbedSubscription)
  504. done()
  505. }
  506. )
  507. })
  508. describe('when user has a custom account', function () {
  509. beforeEach(function () {
  510. this.fakeSubscription = { customAccount: true }
  511. this.SubscriptionLocator.promises.getUsersSubscription.resolves(
  512. this.fakeSubscription
  513. )
  514. })
  515. it('should return true', function (done) {
  516. this.LimitationsManager.userHasV2Subscription(
  517. this.user,
  518. (err, hasSubscription, subscription) => {
  519. assert.equal(err, null)
  520. hasSubscription.should.equal(true)
  521. done()
  522. }
  523. )
  524. })
  525. it('should return the subscription', function (done) {
  526. this.LimitationsManager.userHasV2Subscription(
  527. this.user,
  528. (err, hasSubscription, subscription) => {
  529. assert.equal(err, null)
  530. subscription.should.deep.equal(this.fakeSubscription)
  531. done()
  532. }
  533. )
  534. })
  535. })
  536. })
  537. describe('userIsMemberOfGroupSubscription', function () {
  538. beforeEach(function () {
  539. this.SubscriptionLocator.promises.getMemberSubscriptions = sinon
  540. .stub()
  541. .resolves()
  542. })
  543. it('should return false if there are no groups subcriptions', function (done) {
  544. this.SubscriptionLocator.promises.getMemberSubscriptions.resolves([])
  545. this.LimitationsManager.userIsMemberOfGroupSubscription(
  546. this.user,
  547. (err, isMember) => {
  548. assert.equal(err, null)
  549. isMember.should.equal(false)
  550. done()
  551. }
  552. )
  553. })
  554. it('should return true if there are no groups subcriptions', function (done) {
  555. let subscriptions
  556. this.SubscriptionLocator.promises.getMemberSubscriptions.resolves(
  557. (subscriptions = ['mock-subscription'])
  558. )
  559. this.LimitationsManager.userIsMemberOfGroupSubscription(
  560. this.user,
  561. (err, isMember, retSubscriptions) => {
  562. assert.equal(err, null)
  563. isMember.should.equal(true)
  564. retSubscriptions.should.equal(subscriptions)
  565. done()
  566. }
  567. )
  568. })
  569. })
  570. describe('hasPaidSubscription', function () {
  571. beforeEach(function () {
  572. this.SubscriptionLocator.promises.getMemberSubscriptions = sinon
  573. .stub()
  574. .resolves([])
  575. this.SubscriptionLocator.promises.getUsersSubscription = sinon
  576. .stub()
  577. .resolves(null)
  578. this.V1SubscriptionManager.promises.userHasV1Subscription = sinon
  579. .stub()
  580. .yields(null, null)
  581. })
  582. it('should return true if userIsMemberOfGroupSubscription', function (done) {
  583. this.SubscriptionLocator.promises.getMemberSubscriptions = sinon
  584. .stub()
  585. .resolves([{ _id: '123' }])
  586. this.LimitationsManager.hasPaidSubscription(
  587. this.user,
  588. (err, hasSubOrIsGroupMember) => {
  589. assert.equal(err, null)
  590. hasSubOrIsGroupMember.should.equal(true)
  591. done()
  592. }
  593. )
  594. })
  595. it('should return true if userHasV2Subscription', function (done) {
  596. this.SubscriptionLocator.promises.getUsersSubscription = sinon
  597. .stub()
  598. .resolves({ recurlySubscription_id: '123' })
  599. this.LimitationsManager.hasPaidSubscription(
  600. this.user,
  601. (err, hasSubOrIsGroupMember) => {
  602. assert.equal(err, null)
  603. hasSubOrIsGroupMember.should.equal(true)
  604. done()
  605. }
  606. )
  607. })
  608. it('should return true if userHasV1Subscription', function (done) {
  609. this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
  610. .stub()
  611. .resolves({ has_subscription: true })
  612. this.LimitationsManager.hasPaidSubscription(
  613. this.user,
  614. (err, hasSubOrIsGroupMember) => {
  615. assert.equal(err, null)
  616. hasSubOrIsGroupMember.should.equal(true)
  617. done()
  618. }
  619. )
  620. })
  621. it('should return false if none are true', function (done) {
  622. this.LimitationsManager.hasPaidSubscription(
  623. this.user,
  624. (err, hasSubOrIsGroupMember) => {
  625. assert.equal(err, null)
  626. hasSubOrIsGroupMember.should.equal(false)
  627. done()
  628. }
  629. )
  630. })
  631. it('should have userHasSubscriptionOrIsGroupMember alias', function (done) {
  632. this.LimitationsManager.userHasSubscriptionOrIsGroupMember(
  633. this.user,
  634. (err, hasSubOrIsGroupMember) => {
  635. assert.equal(err, null)
  636. hasSubOrIsGroupMember.should.equal(false)
  637. done()
  638. }
  639. )
  640. })
  641. })
  642. describe('userHasV1OrV2Subscription', function () {
  643. beforeEach(function () {
  644. this.SubscriptionLocator.promises.getUsersSubscription = sinon
  645. .stub()
  646. .resolves()
  647. this.V1SubscriptionManager.promises.userHasV1Subscription = sinon
  648. .stub()
  649. .resolves()
  650. })
  651. it('should return true if userHasV2Subscription', function (done) {
  652. this.SubscriptionLocator.promises.getUsersSubscription = sinon
  653. .stub()
  654. .resolves({ recurlySubscription_id: '123' })
  655. this.LimitationsManager.userHasV1OrV2Subscription(
  656. this.user,
  657. (err, hasSub) => {
  658. assert.equal(err, null)
  659. hasSub.should.equal(true)
  660. done()
  661. }
  662. )
  663. })
  664. it('should return true if userHasV1Subscription', function (done) {
  665. this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
  666. .stub()
  667. .resolves({ has_subscription: true })
  668. this.LimitationsManager.userHasV1OrV2Subscription(
  669. this.user,
  670. (err, hasSub) => {
  671. assert.equal(err, null)
  672. hasSub.should.equal(true)
  673. done()
  674. }
  675. )
  676. })
  677. it('should return false if none are true', function (done) {
  678. this.LimitationsManager.userHasV1OrV2Subscription(
  679. this.user,
  680. (err, hasSub) => {
  681. assert.equal(err, null)
  682. hasSub.should.equal(false)
  683. done()
  684. }
  685. )
  686. })
  687. })
  688. describe('hasGroupMembersLimitReached', function () {
  689. beforeEach(function () {
  690. this.subscriptionId = '12312'
  691. this.subscription = {
  692. membersLimit: 3,
  693. member_ids: ['', ''],
  694. teamInvites: [
  695. { email: 'bob@example.com', sentAt: new Date(), token: 'hey' },
  696. ],
  697. }
  698. })
  699. it('should return true if the limit is hit (including members and invites)', function (done) {
  700. this.SubscriptionLocator.promises.getSubscription.resolves(
  701. this.subscription
  702. )
  703. this.LimitationsManager.hasGroupMembersLimitReached(
  704. this.subscriptionId,
  705. (err, limitReached) => {
  706. assert.equal(err, null)
  707. limitReached.should.equal(true)
  708. done()
  709. }
  710. )
  711. })
  712. it('should return false if the limit is not hit (including members and invites)', function (done) {
  713. this.subscription.membersLimit = 4
  714. this.SubscriptionLocator.promises.getSubscription.resolves(
  715. this.subscription
  716. )
  717. this.LimitationsManager.hasGroupMembersLimitReached(
  718. this.subscriptionId,
  719. (err, limitReached) => {
  720. assert.equal(err, null)
  721. limitReached.should.equal(false)
  722. done()
  723. }
  724. )
  725. })
  726. it('should return true if the limit has been exceded (including members and invites)', function (done) {
  727. this.subscription.membersLimit = 2
  728. this.SubscriptionLocator.promises.getSubscription.resolves(
  729. this.subscription
  730. )
  731. this.LimitationsManager.hasGroupMembersLimitReached(
  732. this.subscriptionId,
  733. (err, limitReached) => {
  734. assert.equal(err, null)
  735. limitReached.should.equal(true)
  736. done()
  737. }
  738. )
  739. })
  740. })
  741. describe('userHasV1Subscription', function () {
  742. it('should return true if v1 returns has_subscription = true', function (done) {
  743. this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
  744. .stub()
  745. .resolves({ has_subscription: true })
  746. this.LimitationsManager.userHasV1Subscription(
  747. this.user,
  748. (error, result) => {
  749. assert.equal(error, null)
  750. this.V1SubscriptionManager.promises.getSubscriptionsFromV1
  751. .calledWith(this.userId)
  752. .should.equal(true)
  753. result.should.equal(true)
  754. done()
  755. }
  756. )
  757. })
  758. it('should return false if v1 returns has_subscription = false', function (done) {
  759. this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
  760. .stub()
  761. .resolves({ has_subscription: false })
  762. this.LimitationsManager.userHasV1Subscription(
  763. this.user,
  764. (error, result) => {
  765. assert.equal(error, null)
  766. this.V1SubscriptionManager.promises.getSubscriptionsFromV1
  767. .calledWith(this.userId)
  768. .should.equal(true)
  769. result.should.equal(false)
  770. done()
  771. }
  772. )
  773. })
  774. it('should return false if v1 returns nothing', function (done) {
  775. this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
  776. .stub()
  777. .resolves({ has_subscription: false })
  778. this.LimitationsManager.userHasV1Subscription(
  779. this.user,
  780. (error, result) => {
  781. assert.equal(error, null)
  782. this.V1SubscriptionManager.promises.getSubscriptionsFromV1
  783. .calledWith(this.userId)
  784. .should.equal(true)
  785. result.should.equal(false)
  786. done()
  787. }
  788. )
  789. })
  790. })
  791. })