diff --git a/services/web/app/src/Features/Subscription/LimitationsManager.js b/services/web/app/src/Features/Subscription/LimitationsManager.js index 97e47986c3..c42289f7fd 100644 --- a/services/web/app/src/Features/Subscription/LimitationsManager.js +++ b/services/web/app/src/Features/Subscription/LimitationsManager.js @@ -1,4 +1,3 @@ -const OError = require('@overleaf/o-error') const logger = require('@overleaf/logger') const ProjectGetter = require('../Project/ProjectGetter') const UserGetter = require('../User/UserGetter') @@ -8,208 +7,166 @@ const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter') const CollaboratorsInvitesHandler = require('../Collaborators/CollaboratorsInviteHandler') const V1SubscriptionManager = require('./V1SubscriptionManager') const { V1ConnectionError } = require('../Errors/Errors') -const { promisifyAll } = require('@overleaf/promise-utils') +const { + callbackify, + callbackifyMultiResult, +} = require('@overleaf/promise-utils') + +async function allowedNumberOfCollaboratorsInProject(projectId) { + const project = await ProjectGetter.promises.getProject(projectId, { + owner_ref: true, + }) + return await allowedNumberOfCollaboratorsForUser(project.owner_ref) +} + +async function allowedNumberOfCollaboratorsForUser(userId) { + const user = await UserGetter.promises.getUser(userId, { features: 1 }) + if (user.features && user.features.collaborators) { + return user.features.collaborators + } else { + return Settings.defaultFeatures.collaborators + } +} + +async function canAddXCollaborators(projectId, numberOfNewCollaborators) { + const allowedNumber = await allowedNumberOfCollaboratorsInProject(projectId) + const currentNumber = + await CollaboratorsGetter.promises.getInvitedCollaboratorCount(projectId) + const inviteCount = + await CollaboratorsInvitesHandler.promises.getInviteCount(projectId) + return ( + currentNumber + inviteCount + numberOfNewCollaborators <= allowedNumber || + allowedNumber < 0 + ) +} + +async function hasPaidSubscription(user) { + const { hasSubscription, subscription } = await userHasV2Subscription(user) + const { isMember } = await userIsMemberOfGroupSubscription(user) + try { + const hasV1Subscription = await userHasV1Subscription(user) + return { + hasPaidSubscription: hasSubscription || isMember || hasV1Subscription, + subscription, + } + } catch (err) { + throw new V1ConnectionError('error getting subscription from v1').withCause( + err + ) + } +} + +// alias for backward-compatibility with modules. Use `haspaidsubscription` instead +async function userHasSubscriptionOrIsGroupMember(user) { + return await hasPaidSubscription(user) +} + +async function userHasV2Subscription(user) { + const subscription = await SubscriptionLocator.promises.getUsersSubscription( + user._id + ) + let hasValidSubscription = false + if (subscription) { + if (subscription.recurlySubscription_id || subscription.customAccount) { + hasValidSubscription = true + } + } + return { + hasSubscription: hasValidSubscription, + subscription, + } +} + +async function userHasV1OrV2Subscription(user) { + const { hasSubscription: hasV2Subscription } = + await userHasV2Subscription(user) + if (hasV2Subscription) { + return true + } + const hasV1Subscription = await userHasV1Subscription(user) + if (hasV1Subscription) { + return true + } + return false +} + +async function userIsMemberOfGroupSubscription(user) { + const subscriptions = + (await SubscriptionLocator.promises.getMemberSubscriptions(user._id)) || [] + return { isMember: subscriptions.length > 0, subscriptions } +} + +async function userHasV1Subscription(user, callback) { + const v1Subscription = + await V1SubscriptionManager.promises.getSubscriptionsFromV1(user._id) + return !!(v1Subscription ? v1Subscription.has_subscription : undefined) +} + +function teamHasReachedMemberLimit(subscription) { + const currentTotal = + (subscription.member_ids || []).length + + (subscription.teamInvites || []).length + + (subscription.invited_emails || []).length + + return currentTotal >= subscription.membersLimit +} + +async function hasGroupMembersLimitReached(subscriptionId, callback) { + const subscription = + await SubscriptionLocator.promises.getSubscription(subscriptionId) + if (!subscription) { + logger.warn({ subscriptionId }, 'no subscription found') + throw new Error('no subscription found') + } + const limitReached = teamHasReachedMemberLimit(subscription) + return { limitReached, subscription } +} const LimitationsManager = { - allowedNumberOfCollaboratorsInProject(projectId, callback) { - ProjectGetter.getProject( - projectId, - { owner_ref: true }, - (error, project) => { - if (error) { - return callback(error) - } - this.allowedNumberOfCollaboratorsForUser(project.owner_ref, callback) - } - ) - }, + allowedNumberOfCollaboratorsInProject: callbackify( + allowedNumberOfCollaboratorsInProject + ), + allowedNumberOfCollaboratorsForUser: callbackify( + allowedNumberOfCollaboratorsForUser + ), + canAddXCollaborators: callbackify(canAddXCollaborators), + hasPaidSubscription: callbackifyMultiResult(hasPaidSubscription, [ + 'hasPaidSubscription', + 'subscription', + ]), + userHasSubscriptionOrIsGroupMember: callbackifyMultiResult( + userHasSubscriptionOrIsGroupMember, + ['hasPaidSubscription', 'subscription'] + ), + userHasV2Subscription: callbackifyMultiResult(userHasV2Subscription, [ + 'hasSubscription', + 'subscription', + ]), + userHasV1OrV2Subscription: callbackify(userHasV1OrV2Subscription), + userIsMemberOfGroupSubscription: callbackifyMultiResult( + userIsMemberOfGroupSubscription, + ['isMember', 'subscriptions'] + ), + userHasV1Subscription: callbackify(userHasV1Subscription), + hasGroupMembersLimitReached: callbackifyMultiResult( + hasGroupMembersLimitReached, + ['limitReached', 'subscription'] + ), - allowedNumberOfCollaboratorsForUser(userId, callback) { - UserGetter.getUser(userId, { features: 1 }, function (error, user) { - if (error) { - return callback(error) - } - if (user.features && user.features.collaborators) { - callback(null, user.features.collaborators) - } else { - callback(null, Settings.defaultFeatures.collaborators) - } - }) - }, + teamHasReachedMemberLimit, - canAddXCollaborators(projectId, numberOfNewCollaborators, callback) { - this.allowedNumberOfCollaboratorsInProject( - projectId, - (error, allowedNumber) => { - if (error) { - return callback(error) - } - CollaboratorsGetter.getInvitedCollaboratorCount( - projectId, - (error, currentNumber) => { - if (error) { - return callback(error) - } - CollaboratorsInvitesHandler.getInviteCount( - projectId, - (error, inviteCount) => { - if (error) { - return callback(error) - } - if ( - currentNumber + inviteCount + numberOfNewCollaborators <= - allowedNumber || - allowedNumber < 0 - ) { - callback(null, true) - } else { - callback(null, false) - } - } - ) - } - ) - } - ) - }, - - hasPaidSubscription(user, callback) { - this.userHasV2Subscription(user, (err, hasSubscription, subscription) => { - if (err) { - return callback(err) - } - this.userIsMemberOfGroupSubscription(user, (err, isMember) => { - if (err) { - return callback(err) - } - this.userHasV1Subscription(user, (err, hasV1Subscription) => { - if (err) { - return callback( - new V1ConnectionError( - 'error getting subscription from v1' - ).withCause(err) - ) - } - callback( - err, - isMember || hasSubscription || hasV1Subscription, - subscription - ) - }) - }) - }) - }, - - // alias for backward-compatibility with modules. Use `haspaidsubscription` instead - userHasSubscriptionOrIsGroupMember(user, callback) { - this.hasPaidSubscription(user, callback) - }, - - userHasV2Subscription(user, callback) { - SubscriptionLocator.getUsersSubscription( - user._id, - function (err, subscription) { - if (err) { - return callback(err) - } - let hasValidSubscription = false - if (subscription) { - if ( - subscription.recurlySubscription_id || - subscription.customAccount - ) { - hasValidSubscription = true - } - } - callback(err, hasValidSubscription, subscription) - } - ) - }, - - userHasV1OrV2Subscription(user, callback) { - this.userHasV2Subscription(user, (err, hasV2Subscription) => { - if (err) { - return callback(err) - } - if (hasV2Subscription) { - return callback(null, true) - } - this.userHasV1Subscription(user, (err, hasV1Subscription) => { - if (err) { - return callback(err) - } - if (hasV1Subscription) { - return callback(null, true) - } - callback(null, false) - }) - }) - }, - - userIsMemberOfGroupSubscription(user, callback) { - SubscriptionLocator.getMemberSubscriptions( - user._id, - function (err, subscriptions) { - if (!subscriptions) { - subscriptions = [] - } - if (err) { - return callback(err) - } - callback(err, subscriptions.length > 0, subscriptions) - } - ) - }, - - userHasV1Subscription(user, callback) { - V1SubscriptionManager.getSubscriptionsFromV1( - user._id, - function (err, v1Subscription) { - callback( - err, - !!(v1Subscription ? v1Subscription.has_subscription : undefined) - ) - } - ) - }, - - teamHasReachedMemberLimit(subscription) { - const currentTotal = - (subscription.member_ids || []).length + - (subscription.teamInvites || []).length + - (subscription.invited_emails || []).length - - return currentTotal >= subscription.membersLimit - }, - - hasGroupMembersLimitReached(subscriptionId, callback) { - SubscriptionLocator.getSubscription( - subscriptionId, - function (err, subscription) { - if (err) { - OError.tag(err, 'error getting subscription', { - subscriptionId, - }) - return callback(err) - } - if (!subscription) { - logger.warn({ subscriptionId }, 'no subscription found') - return callback(new Error('no subscription found')) - } - - const limitReached = - LimitationsManager.teamHasReachedMemberLimit(subscription) - callback(err, limitReached, subscription) - } - ) + promises: { + allowedNumberOfCollaboratorsInProject, + allowedNumberOfCollaboratorsForUser, + canAddXCollaborators, + hasPaidSubscription, + userHasSubscriptionOrIsGroupMember, + userHasV2Subscription, + userHasV1OrV2Subscription, + userIsMemberOfGroupSubscription, + userHasV1Subscription, + hasGroupMembersLimitReached, }, } -LimitationsManager.promises = promisifyAll(LimitationsManager, { - multiResult: { - userHasV2Subscription: ['hasSubscription', 'subscription'], - userIsMemberOfGroupSubscription: ['isMember', 'subscriptions'], - hasGroupMembersLimitReached: ['limitReached', 'subscription'], - }, -}) module.exports = LimitationsManager diff --git a/services/web/test/unit/src/Subscription/LimitationsManagerTests.js b/services/web/test/unit/src/Subscription/LimitationsManagerTests.js index a8934e6899..6a78249229 100644 --- a/services/web/test/unit/src/Subscription/LimitationsManagerTests.js +++ b/services/web/test/unit/src/Subscription/LimitationsManagerTests.js @@ -8,30 +8,57 @@ const modulePath = require('path').join( describe('LimitationsManager', function () { beforeEach(function () { - this.project = { _id: (this.projectId = 'project-id') } - this.user = { _id: (this.userId = 'user-id'), features: {} } + this.user = { + _id: (this.userId = 'user-id'), + features: { collaborators: 1 }, + } + this.project = { + _id: (this.projectId = 'project-id'), + owner_ref: this.userId, + } this.ProjectGetter = { - getProject: (projectId, fields, callback) => { - if (projectId === this.projectId) { - callback(null, this.project) - } else { - callback(null, null) - } + promises: { + getProject: sinon.stub().callsFake(async (projectId, fields) => { + if (projectId === this.projectId) { + return this.project + } else { + return null + } + }), }, } this.UserGetter = { - getUser: (userId, filter, callback) => { - if (userId === this.userId) { - callback(null, this.user) - } else { - callback(null, null) - } + promises: { + getUser: sinon.stub().callsFake(async (userId, filter) => { + if (userId === this.userId) { + return this.user + } else { + return null + } + }), }, } this.SubscriptionLocator = { - getUsersSubscription: sinon.stub(), - getSubscription: sinon.stub(), + promises: { + getUsersSubscription: sinon.stub().resolves(), + getSubscription: sinon.stub().resolves(), + getMemberSubscriptions: sinon.stub().resolves(), + }, + } + + this.V1SubscriptionManager = { + promises: { + getSubscriptionsFromV1: sinon.stub().resolves(), + }, + } + + this.CollaboratorsGetter = { + promises: { getInvitedCollaboratorCount: sinon.stub().resolves() }, + } + + this.CollaboratorsInviteHandler = { + promises: { getInviteCount: sinon.stub().resolves() }, } this.LimitationsManager = SandboxedModule.require(modulePath, { @@ -40,21 +67,21 @@ describe('LimitationsManager', function () { '../User/UserGetter': this.UserGetter, './SubscriptionLocator': this.SubscriptionLocator, '@overleaf/settings': (this.Settings = {}), - '../Collaborators/CollaboratorsGetter': (this.CollaboratorsGetter = {}), + '../Collaborators/CollaboratorsGetter': this.CollaboratorsGetter, '../Collaborators/CollaboratorsInviteHandler': - (this.CollaboratorsInviteHandler = {}), - './V1SubscriptionManager': (this.V1SubscriptionManager = {}), + this.CollaboratorsInviteHandler, + './V1SubscriptionManager': this.V1SubscriptionManager, }, }) }) describe('allowedNumberOfCollaboratorsInProject', function () { describe('when the project is owned by a user without a subscription', function () { - beforeEach(function () { + beforeEach(function (done) { this.Settings.defaultFeatures = { collaborators: 23 } this.project.owner_ref = this.userId delete this.user.features - this.callback = sinon.stub() + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.allowedNumberOfCollaboratorsInProject( this.projectId, this.callback @@ -69,10 +96,10 @@ describe('LimitationsManager', function () { }) describe('when the project is owned by a user with a subscription', function () { - beforeEach(function () { + beforeEach(function (done) { this.project.owner_ref = this.userId this.user.features = { collaborators: 21 } - this.callback = sinon.stub() + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.allowedNumberOfCollaboratorsInProject( this.projectId, this.callback @@ -89,10 +116,10 @@ describe('LimitationsManager', function () { describe('allowedNumberOfCollaboratorsForUser', function () { describe('when the user has no features', function () { - beforeEach(function () { + beforeEach(function (done) { this.Settings.defaultFeatures = { collaborators: 23 } delete this.user.features - this.callback = sinon.stub() + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.allowedNumberOfCollaboratorsForUser( this.userId, this.callback @@ -107,9 +134,9 @@ describe('LimitationsManager', function () { }) describe('when the user has features', function () { - beforeEach(function () { + beforeEach(function (done) { this.user.features = { collaborators: 21 } - this.callback = sinon.stub() + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.allowedNumberOfCollaboratorsForUser( this.userId, this.callback @@ -126,27 +153,17 @@ describe('LimitationsManager', function () { describe('canAddXCollaborators', function () { describe('when the project has fewer collaborators than allowed', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 1 - this.allowed_number = 2 + this.user.features.collaborators = 2 this.invite_count = 0 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 1, @@ -160,27 +177,17 @@ describe('LimitationsManager', function () { }) describe('when the project has fewer collaborators and invites than allowed', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 1 - this.allowed_number = 4 + this.user.features.collaborators = 4 this.invite_count = 1 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 1, @@ -194,27 +201,17 @@ describe('LimitationsManager', function () { }) describe('when the project has fewer collaborators than allowed but I want to add more than allowed', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 1 - this.allowed_number = 2 + this.user.features.collaborators = 2 this.invite_count = 0 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 2, @@ -228,27 +225,17 @@ describe('LimitationsManager', function () { }) describe('when the project has more collaborators than allowed', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 3 - this.allowed_number = 2 + this.user.features.collaborators = 2 this.invite_count = 0 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 1, @@ -262,27 +249,17 @@ describe('LimitationsManager', function () { }) describe('when the project has infinite collaborators', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 100 - this.allowed_number = -1 + this.user.features.collaborators = -1 this.invite_count = 0 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 1, @@ -296,27 +273,17 @@ describe('LimitationsManager', function () { }) describe('when the project has more invites than allowed', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 0 - this.allowed_number = 2 + this.user.features.collaborators = 2 this.invite_count = 2 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 1, @@ -330,27 +297,17 @@ describe('LimitationsManager', function () { }) describe('when the project has more invites and collaborators than allowed', function () { - beforeEach(function () { + beforeEach(function (done) { this.current_number = 1 - this.allowed_number = 2 + this.user.features.collaborators = 2 this.invite_count = 1 - this.CollaboratorsGetter.getInvitedCollaboratorCount = ( - projectId, - callback - ) => callback(null, this.current_number) - this.CollaboratorsInviteHandler.getInviteCount = ( - projectId, - callback - ) => callback(null, this.invite_count) - sinon - .stub( - this.LimitationsManager, - 'allowedNumberOfCollaboratorsInProject' - ) - .callsFake((projectId, callback) => { - callback(null, this.allowed_number) - }) - this.callback = sinon.stub() + this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon + .stub() + .resolves(this.current_number) + this.CollaboratorsInviteHandler.promises.getInviteCount = sinon + .stub() + .resolves(this.invite_count) + this.callback = sinon.stub().callsFake(() => done()) this.LimitationsManager.canAddXCollaborators( this.projectId, 1, @@ -366,13 +323,17 @@ describe('LimitationsManager', function () { describe('userHasV2Subscription', function () { beforeEach(function () { - this.SubscriptionLocator.getUsersSubscription = sinon.stub() + this.SubscriptionLocator.promises.getUsersSubscription = sinon + .stub() + .resolves() }) it('should return true if the recurly token is set', function (done) { - this.SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, { - recurlySubscription_id: '1234', - }) + this.SubscriptionLocator.promises.getUsersSubscription = sinon + .stub() + .resolves({ + recurlySubscription_id: '1234', + }) this.LimitationsManager.userHasV2Subscription( this.user, (err, hasSubscription) => { @@ -384,7 +345,7 @@ describe('LimitationsManager', function () { }) it('should return false if the recurly token is not set', function (done) { - this.SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, {}) + this.SubscriptionLocator.promises.getUsersSubscription.resolves({}) this.subscription = {} this.LimitationsManager.userHasV2Subscription( this.user, @@ -397,7 +358,7 @@ describe('LimitationsManager', function () { }) it('should return false if the subscription is undefined', function (done) { - this.SubscriptionLocator.getUsersSubscription.callsArgWith(1) + this.SubscriptionLocator.promises.getUsersSubscription.resolves() this.LimitationsManager.userHasV2Subscription( this.user, (err, hasSubscription) => { @@ -410,9 +371,7 @@ describe('LimitationsManager', function () { it('should return the subscription', function (done) { const stubbedSubscription = { freeTrial: {}, token: '' } - this.SubscriptionLocator.getUsersSubscription.callsArgWith( - 1, - null, + this.SubscriptionLocator.promises.getUsersSubscription.resolves( stubbedSubscription ) this.LimitationsManager.userHasV2Subscription( @@ -428,9 +387,7 @@ describe('LimitationsManager', function () { describe('when user has a custom account', function () { beforeEach(function () { this.fakeSubscription = { customAccount: true } - this.SubscriptionLocator.getUsersSubscription.callsArgWith( - 1, - null, + this.SubscriptionLocator.promises.getUsersSubscription.resolves( this.fakeSubscription ) }) @@ -461,11 +418,13 @@ describe('LimitationsManager', function () { describe('userIsMemberOfGroupSubscription', function () { beforeEach(function () { - this.SubscriptionLocator.getMemberSubscriptions = sinon.stub() + this.SubscriptionLocator.promises.getMemberSubscriptions = sinon + .stub() + .resolves() }) it('should return false if there are no groups subcriptions', function (done) { - this.SubscriptionLocator.getMemberSubscriptions.callsArgWith(1, null, []) + this.SubscriptionLocator.promises.getMemberSubscriptions.resolves([]) this.LimitationsManager.userIsMemberOfGroupSubscription( this.user, (err, isMember) => { @@ -478,9 +437,7 @@ describe('LimitationsManager', function () { it('should return true if there are no groups subcriptions', function (done) { let subscriptions - this.SubscriptionLocator.getMemberSubscriptions.callsArgWith( - 1, - null, + this.SubscriptionLocator.promises.getMemberSubscriptions.resolves( (subscriptions = ['mock-subscription']) ) this.LimitationsManager.userIsMemberOfGroupSubscription( @@ -497,21 +454,21 @@ describe('LimitationsManager', function () { describe('hasPaidSubscription', function () { beforeEach(function () { - this.LimitationsManager.userIsMemberOfGroupSubscription = sinon + this.SubscriptionLocator.promises.getMemberSubscriptions = sinon .stub() - .yields(null, false) - this.LimitationsManager.userHasV2Subscription = sinon + .resolves([]) + this.SubscriptionLocator.promises.getUsersSubscription = sinon .stub() - .yields(null, false) - this.LimitationsManager.userHasV1Subscription = sinon + .resolves(null) + this.V1SubscriptionManager.promises.userHasV1Subscription = sinon .stub() - .yields(null, false) + .yields(null, null) }) it('should return true if userIsMemberOfGroupSubscription', function (done) { - this.LimitationsManager.userIsMemberOfGroupSubscription = sinon + this.SubscriptionLocator.promises.getMemberSubscriptions = sinon .stub() - .yields(null, true) + .resolves([{ _id: '123' }]) this.LimitationsManager.hasPaidSubscription( this.user, (err, hasSubOrIsGroupMember) => { @@ -523,9 +480,9 @@ describe('LimitationsManager', function () { }) it('should return true if userHasV2Subscription', function (done) { - this.LimitationsManager.userHasV2Subscription = sinon + this.SubscriptionLocator.promises.getUsersSubscription = sinon .stub() - .yields(null, true) + .resolves({ recurlySubscription_id: '123' }) this.LimitationsManager.hasPaidSubscription( this.user, (err, hasSubOrIsGroupMember) => { @@ -537,9 +494,9 @@ describe('LimitationsManager', function () { }) it('should return true if userHasV1Subscription', function (done) { - this.LimitationsManager.userHasV1Subscription = sinon + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon .stub() - .yields(null, true) + .resolves({ has_subscription: true }) this.LimitationsManager.hasPaidSubscription( this.user, (err, hasSubOrIsGroupMember) => { @@ -575,18 +532,18 @@ describe('LimitationsManager', function () { describe('userHasV1OrV2Subscription', function () { beforeEach(function () { - this.LimitationsManager.userHasV2Subscription = sinon + this.SubscriptionLocator.promises.getUsersSubscription = sinon .stub() - .yields(null, false) - this.LimitationsManager.userHasV1Subscription = sinon + .resolves() + this.V1SubscriptionManager.promises.userHasV1Subscription = sinon .stub() - .yields(null, false) + .resolves() }) it('should return true if userHasV2Subscription', function (done) { - this.LimitationsManager.userHasV2Subscription = sinon + this.SubscriptionLocator.promises.getUsersSubscription = sinon .stub() - .yields(null, true) + .resolves({ recurlySubscription_id: '123' }) this.LimitationsManager.userHasV1OrV2Subscription( this.user, (err, hasSub) => { @@ -598,9 +555,9 @@ describe('LimitationsManager', function () { }) it('should return true if userHasV1Subscription', function (done) { - this.LimitationsManager.userHasV1Subscription = sinon + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon .stub() - .yields(null, true) + .resolves({ has_subscription: true }) this.LimitationsManager.userHasV1OrV2Subscription( this.user, (err, hasSub) => { @@ -636,9 +593,7 @@ describe('LimitationsManager', function () { }) it('should return true if the limit is hit (including members and invites)', function (done) { - this.SubscriptionLocator.getSubscription.callsArgWith( - 1, - null, + this.SubscriptionLocator.promises.getSubscription.resolves( this.subscription ) this.LimitationsManager.hasGroupMembersLimitReached( @@ -653,9 +608,7 @@ describe('LimitationsManager', function () { it('should return false if the limit is not hit (including members and invites)', function (done) { this.subscription.membersLimit = 4 - this.SubscriptionLocator.getSubscription.callsArgWith( - 1, - null, + this.SubscriptionLocator.promises.getSubscription.resolves( this.subscription ) this.LimitationsManager.hasGroupMembersLimitReached( @@ -670,9 +623,7 @@ describe('LimitationsManager', function () { it('should return true if the limit has been exceded (including members and invites)', function (done) { this.subscription.membersLimit = 2 - this.SubscriptionLocator.getSubscription.callsArgWith( - 1, - null, + this.SubscriptionLocator.promises.getSubscription.resolves( this.subscription ) this.LimitationsManager.hasGroupMembersLimitReached( @@ -688,14 +639,14 @@ describe('LimitationsManager', function () { describe('userHasV1Subscription', function () { it('should return true if v1 returns has_subscription = true', function (done) { - this.V1SubscriptionManager.getSubscriptionsFromV1 = sinon + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon .stub() - .yields(null, { has_subscription: true }) + .resolves({ has_subscription: true }) this.LimitationsManager.userHasV1Subscription( this.user, (error, result) => { assert.equal(error, null) - this.V1SubscriptionManager.getSubscriptionsFromV1 + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 .calledWith(this.userId) .should.equal(true) result.should.equal(true) @@ -705,14 +656,14 @@ describe('LimitationsManager', function () { }) it('should return false if v1 returns has_subscription = false', function (done) { - this.V1SubscriptionManager.getSubscriptionsFromV1 = sinon + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon .stub() - .yields(null, { has_subscription: false }) + .resolves({ has_subscription: false }) this.LimitationsManager.userHasV1Subscription( this.user, (error, result) => { assert.equal(error, null) - this.V1SubscriptionManager.getSubscriptionsFromV1 + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 .calledWith(this.userId) .should.equal(true) result.should.equal(false) @@ -722,14 +673,14 @@ describe('LimitationsManager', function () { }) it('should return false if v1 returns nothing', function (done) { - this.V1SubscriptionManager.getSubscriptionsFromV1 = sinon + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon .stub() - .yields(null, null) + .resolves({ has_subscription: false }) this.LimitationsManager.userHasV1Subscription( this.user, (error, result) => { assert.equal(error, null) - this.V1SubscriptionManager.getSubscriptionsFromV1 + this.V1SubscriptionManager.promises.getSubscriptionsFromV1 .calledWith(this.userId) .should.equal(true) result.should.equal(false)