Async/awaitify LimitationsManager for link sharing changes (#19110)

* Move functions to top level

* Async/awaitify LimitationsManager methods

* Promisify LimitationsManagerTests

GitOrigin-RevId: ece7d2ea5160aa95924840044e2f225e1f2848e7
This commit is contained in:
Thomas 2024-06-28 14:02:53 +02:00 committed by Copybot
parent 687b56f18e
commit 2ce71b0b4d
2 changed files with 321 additions and 413 deletions

View file

@ -1,4 +1,3 @@
const OError = require('@overleaf/o-error')
const logger = require('@overleaf/logger') const logger = require('@overleaf/logger')
const ProjectGetter = require('../Project/ProjectGetter') const ProjectGetter = require('../Project/ProjectGetter')
const UserGetter = require('../User/UserGetter') const UserGetter = require('../User/UserGetter')
@ -8,208 +7,166 @@ const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
const CollaboratorsInvitesHandler = require('../Collaborators/CollaboratorsInviteHandler') const CollaboratorsInvitesHandler = require('../Collaborators/CollaboratorsInviteHandler')
const V1SubscriptionManager = require('./V1SubscriptionManager') const V1SubscriptionManager = require('./V1SubscriptionManager')
const { V1ConnectionError } = require('../Errors/Errors') 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 = { const LimitationsManager = {
allowedNumberOfCollaboratorsInProject(projectId, callback) { allowedNumberOfCollaboratorsInProject: callbackify(
ProjectGetter.getProject( allowedNumberOfCollaboratorsInProject
projectId, ),
{ owner_ref: true }, allowedNumberOfCollaboratorsForUser: callbackify(
(error, project) => { allowedNumberOfCollaboratorsForUser
if (error) { ),
return callback(error) canAddXCollaborators: callbackify(canAddXCollaborators),
} hasPaidSubscription: callbackifyMultiResult(hasPaidSubscription, [
this.allowedNumberOfCollaboratorsForUser(project.owner_ref, callback) '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) { teamHasReachedMemberLimit,
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)
}
})
},
canAddXCollaborators(projectId, numberOfNewCollaborators, callback) { promises: {
this.allowedNumberOfCollaboratorsInProject( allowedNumberOfCollaboratorsInProject,
projectId, allowedNumberOfCollaboratorsForUser,
(error, allowedNumber) => { canAddXCollaborators,
if (error) { hasPaidSubscription,
return callback(error) userHasSubscriptionOrIsGroupMember,
} userHasV2Subscription,
CollaboratorsGetter.getInvitedCollaboratorCount( userHasV1OrV2Subscription,
projectId, userIsMemberOfGroupSubscription,
(error, currentNumber) => { userHasV1Subscription,
if (error) { hasGroupMembersLimitReached,
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)
}
)
}, },
} }
LimitationsManager.promises = promisifyAll(LimitationsManager, {
multiResult: {
userHasV2Subscription: ['hasSubscription', 'subscription'],
userIsMemberOfGroupSubscription: ['isMember', 'subscriptions'],
hasGroupMembersLimitReached: ['limitReached', 'subscription'],
},
})
module.exports = LimitationsManager module.exports = LimitationsManager

View file

@ -8,30 +8,57 @@ const modulePath = require('path').join(
describe('LimitationsManager', function () { describe('LimitationsManager', function () {
beforeEach(function () { beforeEach(function () {
this.project = { _id: (this.projectId = 'project-id') } this.user = {
this.user = { _id: (this.userId = 'user-id'), features: {} } _id: (this.userId = 'user-id'),
features: { collaborators: 1 },
}
this.project = {
_id: (this.projectId = 'project-id'),
owner_ref: this.userId,
}
this.ProjectGetter = { this.ProjectGetter = {
getProject: (projectId, fields, callback) => { promises: {
if (projectId === this.projectId) { getProject: sinon.stub().callsFake(async (projectId, fields) => {
callback(null, this.project) if (projectId === this.projectId) {
} else { return this.project
callback(null, null) } else {
} return null
}
}),
}, },
} }
this.UserGetter = { this.UserGetter = {
getUser: (userId, filter, callback) => { promises: {
if (userId === this.userId) { getUser: sinon.stub().callsFake(async (userId, filter) => {
callback(null, this.user) if (userId === this.userId) {
} else { return this.user
callback(null, null) } else {
} return null
}
}),
}, },
} }
this.SubscriptionLocator = { this.SubscriptionLocator = {
getUsersSubscription: sinon.stub(), promises: {
getSubscription: sinon.stub(), 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, { this.LimitationsManager = SandboxedModule.require(modulePath, {
@ -40,21 +67,21 @@ describe('LimitationsManager', function () {
'../User/UserGetter': this.UserGetter, '../User/UserGetter': this.UserGetter,
'./SubscriptionLocator': this.SubscriptionLocator, './SubscriptionLocator': this.SubscriptionLocator,
'@overleaf/settings': (this.Settings = {}), '@overleaf/settings': (this.Settings = {}),
'../Collaborators/CollaboratorsGetter': (this.CollaboratorsGetter = {}), '../Collaborators/CollaboratorsGetter': this.CollaboratorsGetter,
'../Collaborators/CollaboratorsInviteHandler': '../Collaborators/CollaboratorsInviteHandler':
(this.CollaboratorsInviteHandler = {}), this.CollaboratorsInviteHandler,
'./V1SubscriptionManager': (this.V1SubscriptionManager = {}), './V1SubscriptionManager': this.V1SubscriptionManager,
}, },
}) })
}) })
describe('allowedNumberOfCollaboratorsInProject', function () { describe('allowedNumberOfCollaboratorsInProject', function () {
describe('when the project is owned by a user without a subscription', 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.Settings.defaultFeatures = { collaborators: 23 }
this.project.owner_ref = this.userId this.project.owner_ref = this.userId
delete this.user.features delete this.user.features
this.callback = sinon.stub() this.callback = sinon.stub().callsFake(() => done())
this.LimitationsManager.allowedNumberOfCollaboratorsInProject( this.LimitationsManager.allowedNumberOfCollaboratorsInProject(
this.projectId, this.projectId,
this.callback this.callback
@ -69,10 +96,10 @@ describe('LimitationsManager', function () {
}) })
describe('when the project is owned by a user with a subscription', 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.project.owner_ref = this.userId
this.user.features = { collaborators: 21 } this.user.features = { collaborators: 21 }
this.callback = sinon.stub() this.callback = sinon.stub().callsFake(() => done())
this.LimitationsManager.allowedNumberOfCollaboratorsInProject( this.LimitationsManager.allowedNumberOfCollaboratorsInProject(
this.projectId, this.projectId,
this.callback this.callback
@ -89,10 +116,10 @@ describe('LimitationsManager', function () {
describe('allowedNumberOfCollaboratorsForUser', function () { describe('allowedNumberOfCollaboratorsForUser', function () {
describe('when the user has no features', function () { describe('when the user has no features', function () {
beforeEach(function () { beforeEach(function (done) {
this.Settings.defaultFeatures = { collaborators: 23 } this.Settings.defaultFeatures = { collaborators: 23 }
delete this.user.features delete this.user.features
this.callback = sinon.stub() this.callback = sinon.stub().callsFake(() => done())
this.LimitationsManager.allowedNumberOfCollaboratorsForUser( this.LimitationsManager.allowedNumberOfCollaboratorsForUser(
this.userId, this.userId,
this.callback this.callback
@ -107,9 +134,9 @@ describe('LimitationsManager', function () {
}) })
describe('when the user has features', function () { describe('when the user has features', function () {
beforeEach(function () { beforeEach(function (done) {
this.user.features = { collaborators: 21 } this.user.features = { collaborators: 21 }
this.callback = sinon.stub() this.callback = sinon.stub().callsFake(() => done())
this.LimitationsManager.allowedNumberOfCollaboratorsForUser( this.LimitationsManager.allowedNumberOfCollaboratorsForUser(
this.userId, this.userId,
this.callback this.callback
@ -126,27 +153,17 @@ describe('LimitationsManager', function () {
describe('canAddXCollaborators', function () { describe('canAddXCollaborators', function () {
describe('when the project has fewer collaborators than allowed', function () { describe('when the project has fewer collaborators than allowed', function () {
beforeEach(function () { beforeEach(function (done) {
this.current_number = 1 this.current_number = 1
this.allowed_number = 2 this.user.features.collaborators = 2
this.invite_count = 0 this.invite_count = 0
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
1, 1,
@ -160,27 +177,17 @@ describe('LimitationsManager', function () {
}) })
describe('when the project has fewer collaborators and invites than allowed', function () { describe('when the project has fewer collaborators and invites than allowed', function () {
beforeEach(function () { beforeEach(function (done) {
this.current_number = 1 this.current_number = 1
this.allowed_number = 4 this.user.features.collaborators = 4
this.invite_count = 1 this.invite_count = 1
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
1, 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 () { 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.current_number = 1
this.allowed_number = 2 this.user.features.collaborators = 2
this.invite_count = 0 this.invite_count = 0
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
2, 2,
@ -228,27 +225,17 @@ describe('LimitationsManager', function () {
}) })
describe('when the project has more collaborators than allowed', function () { describe('when the project has more collaborators than allowed', function () {
beforeEach(function () { beforeEach(function (done) {
this.current_number = 3 this.current_number = 3
this.allowed_number = 2 this.user.features.collaborators = 2
this.invite_count = 0 this.invite_count = 0
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
1, 1,
@ -262,27 +249,17 @@ describe('LimitationsManager', function () {
}) })
describe('when the project has infinite collaborators', function () { describe('when the project has infinite collaborators', function () {
beforeEach(function () { beforeEach(function (done) {
this.current_number = 100 this.current_number = 100
this.allowed_number = -1 this.user.features.collaborators = -1
this.invite_count = 0 this.invite_count = 0
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
1, 1,
@ -296,27 +273,17 @@ describe('LimitationsManager', function () {
}) })
describe('when the project has more invites than allowed', function () { describe('when the project has more invites than allowed', function () {
beforeEach(function () { beforeEach(function (done) {
this.current_number = 0 this.current_number = 0
this.allowed_number = 2 this.user.features.collaborators = 2
this.invite_count = 2 this.invite_count = 2
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
1, 1,
@ -330,27 +297,17 @@ describe('LimitationsManager', function () {
}) })
describe('when the project has more invites and collaborators than allowed', function () { describe('when the project has more invites and collaborators than allowed', function () {
beforeEach(function () { beforeEach(function (done) {
this.current_number = 1 this.current_number = 1
this.allowed_number = 2 this.user.features.collaborators = 2
this.invite_count = 1 this.invite_count = 1
this.CollaboratorsGetter.getInvitedCollaboratorCount = ( this.CollaboratorsGetter.promises.getInvitedCollaboratorCount = sinon
projectId, .stub()
callback .resolves(this.current_number)
) => callback(null, this.current_number) this.CollaboratorsInviteHandler.promises.getInviteCount = sinon
this.CollaboratorsInviteHandler.getInviteCount = ( .stub()
projectId, .resolves(this.invite_count)
callback this.callback = sinon.stub().callsFake(() => done())
) => callback(null, this.invite_count)
sinon
.stub(
this.LimitationsManager,
'allowedNumberOfCollaboratorsInProject'
)
.callsFake((projectId, callback) => {
callback(null, this.allowed_number)
})
this.callback = sinon.stub()
this.LimitationsManager.canAddXCollaborators( this.LimitationsManager.canAddXCollaborators(
this.projectId, this.projectId,
1, 1,
@ -366,13 +323,17 @@ describe('LimitationsManager', function () {
describe('userHasV2Subscription', function () { describe('userHasV2Subscription', function () {
beforeEach(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) { it('should return true if the recurly token is set', function (done) {
this.SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, { this.SubscriptionLocator.promises.getUsersSubscription = sinon
recurlySubscription_id: '1234', .stub()
}) .resolves({
recurlySubscription_id: '1234',
})
this.LimitationsManager.userHasV2Subscription( this.LimitationsManager.userHasV2Subscription(
this.user, this.user,
(err, hasSubscription) => { (err, hasSubscription) => {
@ -384,7 +345,7 @@ describe('LimitationsManager', function () {
}) })
it('should return false if the recurly token is not set', function (done) { 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.subscription = {}
this.LimitationsManager.userHasV2Subscription( this.LimitationsManager.userHasV2Subscription(
this.user, this.user,
@ -397,7 +358,7 @@ describe('LimitationsManager', function () {
}) })
it('should return false if the subscription is undefined', function (done) { 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.LimitationsManager.userHasV2Subscription(
this.user, this.user,
(err, hasSubscription) => { (err, hasSubscription) => {
@ -410,9 +371,7 @@ describe('LimitationsManager', function () {
it('should return the subscription', function (done) { it('should return the subscription', function (done) {
const stubbedSubscription = { freeTrial: {}, token: '' } const stubbedSubscription = { freeTrial: {}, token: '' }
this.SubscriptionLocator.getUsersSubscription.callsArgWith( this.SubscriptionLocator.promises.getUsersSubscription.resolves(
1,
null,
stubbedSubscription stubbedSubscription
) )
this.LimitationsManager.userHasV2Subscription( this.LimitationsManager.userHasV2Subscription(
@ -428,9 +387,7 @@ describe('LimitationsManager', function () {
describe('when user has a custom account', function () { describe('when user has a custom account', function () {
beforeEach(function () { beforeEach(function () {
this.fakeSubscription = { customAccount: true } this.fakeSubscription = { customAccount: true }
this.SubscriptionLocator.getUsersSubscription.callsArgWith( this.SubscriptionLocator.promises.getUsersSubscription.resolves(
1,
null,
this.fakeSubscription this.fakeSubscription
) )
}) })
@ -461,11 +418,13 @@ describe('LimitationsManager', function () {
describe('userIsMemberOfGroupSubscription', function () { describe('userIsMemberOfGroupSubscription', function () {
beforeEach(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) { 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.LimitationsManager.userIsMemberOfGroupSubscription(
this.user, this.user,
(err, isMember) => { (err, isMember) => {
@ -478,9 +437,7 @@ describe('LimitationsManager', function () {
it('should return true if there are no groups subcriptions', function (done) { it('should return true if there are no groups subcriptions', function (done) {
let subscriptions let subscriptions
this.SubscriptionLocator.getMemberSubscriptions.callsArgWith( this.SubscriptionLocator.promises.getMemberSubscriptions.resolves(
1,
null,
(subscriptions = ['mock-subscription']) (subscriptions = ['mock-subscription'])
) )
this.LimitationsManager.userIsMemberOfGroupSubscription( this.LimitationsManager.userIsMemberOfGroupSubscription(
@ -497,21 +454,21 @@ describe('LimitationsManager', function () {
describe('hasPaidSubscription', function () { describe('hasPaidSubscription', function () {
beforeEach(function () { beforeEach(function () {
this.LimitationsManager.userIsMemberOfGroupSubscription = sinon this.SubscriptionLocator.promises.getMemberSubscriptions = sinon
.stub() .stub()
.yields(null, false) .resolves([])
this.LimitationsManager.userHasV2Subscription = sinon this.SubscriptionLocator.promises.getUsersSubscription = sinon
.stub() .stub()
.yields(null, false) .resolves(null)
this.LimitationsManager.userHasV1Subscription = sinon this.V1SubscriptionManager.promises.userHasV1Subscription = sinon
.stub() .stub()
.yields(null, false) .yields(null, null)
}) })
it('should return true if userIsMemberOfGroupSubscription', function (done) { it('should return true if userIsMemberOfGroupSubscription', function (done) {
this.LimitationsManager.userIsMemberOfGroupSubscription = sinon this.SubscriptionLocator.promises.getMemberSubscriptions = sinon
.stub() .stub()
.yields(null, true) .resolves([{ _id: '123' }])
this.LimitationsManager.hasPaidSubscription( this.LimitationsManager.hasPaidSubscription(
this.user, this.user,
(err, hasSubOrIsGroupMember) => { (err, hasSubOrIsGroupMember) => {
@ -523,9 +480,9 @@ describe('LimitationsManager', function () {
}) })
it('should return true if userHasV2Subscription', function (done) { it('should return true if userHasV2Subscription', function (done) {
this.LimitationsManager.userHasV2Subscription = sinon this.SubscriptionLocator.promises.getUsersSubscription = sinon
.stub() .stub()
.yields(null, true) .resolves({ recurlySubscription_id: '123' })
this.LimitationsManager.hasPaidSubscription( this.LimitationsManager.hasPaidSubscription(
this.user, this.user,
(err, hasSubOrIsGroupMember) => { (err, hasSubOrIsGroupMember) => {
@ -537,9 +494,9 @@ describe('LimitationsManager', function () {
}) })
it('should return true if userHasV1Subscription', function (done) { it('should return true if userHasV1Subscription', function (done) {
this.LimitationsManager.userHasV1Subscription = sinon this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
.stub() .stub()
.yields(null, true) .resolves({ has_subscription: true })
this.LimitationsManager.hasPaidSubscription( this.LimitationsManager.hasPaidSubscription(
this.user, this.user,
(err, hasSubOrIsGroupMember) => { (err, hasSubOrIsGroupMember) => {
@ -575,18 +532,18 @@ describe('LimitationsManager', function () {
describe('userHasV1OrV2Subscription', function () { describe('userHasV1OrV2Subscription', function () {
beforeEach(function () { beforeEach(function () {
this.LimitationsManager.userHasV2Subscription = sinon this.SubscriptionLocator.promises.getUsersSubscription = sinon
.stub() .stub()
.yields(null, false) .resolves()
this.LimitationsManager.userHasV1Subscription = sinon this.V1SubscriptionManager.promises.userHasV1Subscription = sinon
.stub() .stub()
.yields(null, false) .resolves()
}) })
it('should return true if userHasV2Subscription', function (done) { it('should return true if userHasV2Subscription', function (done) {
this.LimitationsManager.userHasV2Subscription = sinon this.SubscriptionLocator.promises.getUsersSubscription = sinon
.stub() .stub()
.yields(null, true) .resolves({ recurlySubscription_id: '123' })
this.LimitationsManager.userHasV1OrV2Subscription( this.LimitationsManager.userHasV1OrV2Subscription(
this.user, this.user,
(err, hasSub) => { (err, hasSub) => {
@ -598,9 +555,9 @@ describe('LimitationsManager', function () {
}) })
it('should return true if userHasV1Subscription', function (done) { it('should return true if userHasV1Subscription', function (done) {
this.LimitationsManager.userHasV1Subscription = sinon this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
.stub() .stub()
.yields(null, true) .resolves({ has_subscription: true })
this.LimitationsManager.userHasV1OrV2Subscription( this.LimitationsManager.userHasV1OrV2Subscription(
this.user, this.user,
(err, hasSub) => { (err, hasSub) => {
@ -636,9 +593,7 @@ describe('LimitationsManager', function () {
}) })
it('should return true if the limit is hit (including members and invites)', function (done) { it('should return true if the limit is hit (including members and invites)', function (done) {
this.SubscriptionLocator.getSubscription.callsArgWith( this.SubscriptionLocator.promises.getSubscription.resolves(
1,
null,
this.subscription this.subscription
) )
this.LimitationsManager.hasGroupMembersLimitReached( 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) { it('should return false if the limit is not hit (including members and invites)', function (done) {
this.subscription.membersLimit = 4 this.subscription.membersLimit = 4
this.SubscriptionLocator.getSubscription.callsArgWith( this.SubscriptionLocator.promises.getSubscription.resolves(
1,
null,
this.subscription this.subscription
) )
this.LimitationsManager.hasGroupMembersLimitReached( 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) { it('should return true if the limit has been exceded (including members and invites)', function (done) {
this.subscription.membersLimit = 2 this.subscription.membersLimit = 2
this.SubscriptionLocator.getSubscription.callsArgWith( this.SubscriptionLocator.promises.getSubscription.resolves(
1,
null,
this.subscription this.subscription
) )
this.LimitationsManager.hasGroupMembersLimitReached( this.LimitationsManager.hasGroupMembersLimitReached(
@ -688,14 +639,14 @@ describe('LimitationsManager', function () {
describe('userHasV1Subscription', function () { describe('userHasV1Subscription', function () {
it('should return true if v1 returns has_subscription = true', function (done) { it('should return true if v1 returns has_subscription = true', function (done) {
this.V1SubscriptionManager.getSubscriptionsFromV1 = sinon this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
.stub() .stub()
.yields(null, { has_subscription: true }) .resolves({ has_subscription: true })
this.LimitationsManager.userHasV1Subscription( this.LimitationsManager.userHasV1Subscription(
this.user, this.user,
(error, result) => { (error, result) => {
assert.equal(error, null) assert.equal(error, null)
this.V1SubscriptionManager.getSubscriptionsFromV1 this.V1SubscriptionManager.promises.getSubscriptionsFromV1
.calledWith(this.userId) .calledWith(this.userId)
.should.equal(true) .should.equal(true)
result.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) { it('should return false if v1 returns has_subscription = false', function (done) {
this.V1SubscriptionManager.getSubscriptionsFromV1 = sinon this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
.stub() .stub()
.yields(null, { has_subscription: false }) .resolves({ has_subscription: false })
this.LimitationsManager.userHasV1Subscription( this.LimitationsManager.userHasV1Subscription(
this.user, this.user,
(error, result) => { (error, result) => {
assert.equal(error, null) assert.equal(error, null)
this.V1SubscriptionManager.getSubscriptionsFromV1 this.V1SubscriptionManager.promises.getSubscriptionsFromV1
.calledWith(this.userId) .calledWith(this.userId)
.should.equal(true) .should.equal(true)
result.should.equal(false) result.should.equal(false)
@ -722,14 +673,14 @@ describe('LimitationsManager', function () {
}) })
it('should return false if v1 returns nothing', function (done) { it('should return false if v1 returns nothing', function (done) {
this.V1SubscriptionManager.getSubscriptionsFromV1 = sinon this.V1SubscriptionManager.promises.getSubscriptionsFromV1 = sinon
.stub() .stub()
.yields(null, null) .resolves({ has_subscription: false })
this.LimitationsManager.userHasV1Subscription( this.LimitationsManager.userHasV1Subscription(
this.user, this.user,
(error, result) => { (error, result) => {
assert.equal(error, null) assert.equal(error, null)
this.V1SubscriptionManager.getSubscriptionsFromV1 this.V1SubscriptionManager.promises.getSubscriptionsFromV1
.calledWith(this.userId) .calledWith(this.userId)
.should.equal(true) .should.equal(true)
result.should.equal(false) result.should.equal(false)