Merge pull request #17075 from overleaf/dp-mongoose-callback-subscription-group-handler

Promisify SubscriptionGroupHandler and SubscriptionGroupHandlerTests

GitOrigin-RevId: 998ebb56f9cffe59f7cb490220bccbeedb133a7b
This commit is contained in:
David
2024-03-05 09:03:19 +00:00
committed by Copybot
parent 6551aba1a5
commit db1508be69
2 changed files with 81 additions and 160 deletions
@@ -1,60 +1,41 @@
const { promisify } = require('util') const { callbackify } = require('util')
const SubscriptionUpdater = require('./SubscriptionUpdater') const SubscriptionUpdater = require('./SubscriptionUpdater')
const SubscriptionLocator = require('./SubscriptionLocator') const SubscriptionLocator = require('./SubscriptionLocator')
const { Subscription } = require('../../models/Subscription') const { Subscription } = require('../../models/Subscription')
function removeUserFromGroup(subscriptionId, userIdToRemove, callback) { async function removeUserFromGroup(subscriptionId, userIdToRemove) {
SubscriptionUpdater.removeUserFromGroup( await SubscriptionUpdater.promises.removeUserFromGroup(
subscriptionId, subscriptionId,
userIdToRemove, userIdToRemove
callback
) )
} }
function replaceUserReferencesInGroups(oldId, newId, callback) { async function replaceUserReferencesInGroups(oldId, newId) {
Subscription.updateOne( await Subscription.updateOne({ admin_id: oldId }, { admin_id: newId }).exec()
{ admin_id: oldId },
{ admin_id: newId },
function (error) {
if (error) {
return callback(error)
}
_replaceInArray( await _replaceInArray(Subscription, 'manager_ids', oldId, newId)
Subscription, await _replaceInArray(Subscription, 'member_ids', oldId, newId)
'manager_ids',
oldId,
newId,
function (error) {
if (error) {
return callback(error)
}
_replaceInArray(Subscription, 'member_ids', oldId, newId, callback)
}
)
}
)
} }
function isUserPartOfGroup(userId, subscriptionId, callback) { async function isUserPartOfGroup(userId, subscriptionId) {
SubscriptionLocator.getSubscriptionByMemberIdAndId( const subscription =
userId, await SubscriptionLocator.promises.getSubscriptionByMemberIdAndId(
subscriptionId, userId,
function (err, subscription) { subscriptionId
const partOfGroup = !!subscription )
callback(err, partOfGroup)
} return !!subscription
)
} }
function getTotalConfirmedUsersInGroup(subscriptionId, callback) { async function getTotalConfirmedUsersInGroup(subscriptionId) {
SubscriptionLocator.getSubscription(subscriptionId, (err, subscription) => const subscription = await SubscriptionLocator.promises.getSubscription(
callback(err, subscription?.member_ids?.length) subscriptionId
) )
return subscription?.member_ids?.length
} }
function _replaceInArray(model, property, oldValue, newValue, callback) { async function _replaceInArray(model, property, oldValue, newValue) {
// Mongo won't let us pull and addToSet in the same query, so do it in // Mongo won't let us pull and addToSet in the same query, so do it in
// two. Note we need to add first, since the query is based on the old user. // two. Note we need to add first, since the query is based on the old user.
const query = {} const query = {}
@@ -66,23 +47,19 @@ function _replaceInArray(model, property, oldValue, newValue, callback) {
const setOldValue = {} const setOldValue = {}
setOldValue[property] = oldValue setOldValue[property] = oldValue
model.updateMany(query, { $addToSet: setNewValue }, function (error) { await model.updateMany(query, { $addToSet: setNewValue })
if (error) { await model.updateMany(query, { $pull: setOldValue })
return callback(error)
}
model.updateMany(query, { $pull: setOldValue }, callback)
})
} }
module.exports = { module.exports = {
removeUserFromGroup, removeUserFromGroup: callbackify(removeUserFromGroup),
replaceUserReferencesInGroups, replaceUserReferencesInGroups: callbackify(replaceUserReferencesInGroups),
getTotalConfirmedUsersInGroup, getTotalConfirmedUsersInGroup: callbackify(getTotalConfirmedUsersInGroup),
isUserPartOfGroup, isUserPartOfGroup: callbackify(isUserPartOfGroup),
promises: { promises: {
removeUserFromGroup: promisify(removeUserFromGroup), removeUserFromGroup,
replaceUserReferencesInGroups: promisify(replaceUserReferencesInGroups), replaceUserReferencesInGroups,
getTotalConfirmedUsersInGroup: promisify(getTotalConfirmedUsersInGroup), getTotalConfirmedUsersInGroup,
isUserPartOfGroup: promisify(isUserPartOfGroup), isUserPartOfGroup,
}, },
} }
@@ -20,99 +20,57 @@ describe('SubscriptionGroupHandler', function () {
} }
this.SubscriptionLocator = { this.SubscriptionLocator = {
getUsersSubscription: sinon.stub(), promises: {
getSubscriptionByMemberIdAndId: sinon.stub(), getUsersSubscription: sinon.stub(),
getSubscription: sinon.stub().callsArgWith(1, null, this.subscription), getSubscriptionByMemberIdAndId: sinon.stub(),
} getSubscription: sinon.stub().resolves(this.subscription),
},
this.UserCreator = {
getUserOrCreateHoldingAccount: sinon
.stub()
.callsArgWith(1, null, this.user),
} }
this.SubscriptionUpdater = { this.SubscriptionUpdater = {
removeUserFromGroup: sinon.stub().callsArgWith(2), promises: {
getSubscription: sinon.stub().callsArgWith(2), removeUserFromGroup: sinon.stub().resolves(),
getSubscription: sinon.stub().resolves(),
},
} }
this.TeamInvitesHandler = { createInvite: sinon.stub().callsArgWith(2) }
this.UserGetter = {
getUser: sinon.stub(),
getUserByAnyEmail: sinon.stub(),
}
this.LimitationsManager = { hasGroupMembersLimitReached: sinon.stub() }
this.OneTimeTokenHandler = {
getValueFromTokenAndExpire: sinon.stub(),
getNewToken: sinon.stub(),
}
this.EmailHandler = { sendEmail: sinon.stub() }
this.Subscription = { this.Subscription = {
updateOne: sinon.stub().yields(), updateOne: sinon.stub().returns({ exec: sinon.stub().resolves }),
updateMany: sinon.stub().yields(), updateMany: sinon.stub().returns({ exec: sinon.stub().resolves }),
findOne: sinon.stub().yields(), findOne: sinon.stub().returns({ exec: sinon.stub().resolves }),
}
this.settings = { siteUrl: 'http://www.overleaf.com' }
this.readStub = sinon.stub()
this.NotificationsBuilder = {
groupPlan: sinon.stub().returns({ read: this.readStub }),
}
this.UserMembershipViewModel = {
build(email) {
return { email }
},
} }
this.Handler = SandboxedModule.require(modulePath, { this.Handler = SandboxedModule.require(modulePath, {
requires: { requires: {
'../User/UserCreator': this.UserCreator,
'./SubscriptionUpdater': this.SubscriptionUpdater, './SubscriptionUpdater': this.SubscriptionUpdater,
'./SubscriptionLocator': this.SubscriptionLocator, './SubscriptionLocator': this.SubscriptionLocator,
'../../models/Subscription': { '../../models/Subscription': {
Subscription: this.Subscription, Subscription: this.Subscription,
}, },
'../User/UserGetter': this.UserGetter,
'./LimitationsManager': this.LimitationsManager,
'../Security/OneTimeTokenHandler': this.OneTimeTokenHandler,
'../Email/EmailHandler': this.EmailHandler,
'@overleaf/settings': this.settings,
'../Notifications/NotificationsBuilder': this.NotificationsBuilder,
'../UserMembership/UserMembershipViewModel':
this.UserMembershipViewModel,
}, },
}) })
}) })
describe('removeUserFromGroup', function () { describe('removeUserFromGroup', function () {
it('should call the subscription updater to remove the user', function (done) { it('should call the subscription updater to remove the user', async function () {
this.Handler.removeUserFromGroup( await this.Handler.promises.removeUserFromGroup(
this.adminUser_id, this.adminUser_id,
this.user._id, this.user._id
err => {
if (err) return done(err)
this.SubscriptionUpdater.removeUserFromGroup
.calledWith(this.adminUser_id, this.user._id)
.should.equal(true)
done()
}
) )
this.SubscriptionUpdater.promises.removeUserFromGroup
.calledWith(this.adminUser_id, this.user._id)
.should.equal(true)
}) })
}) })
describe('replaceUserReferencesInGroups', function () { describe('replaceUserReferencesInGroups', function () {
beforeEach(function (done) { beforeEach(async function () {
this.oldId = 'ba5eba11' this.oldId = 'ba5eba11'
this.newId = '5ca1ab1e' this.newId = '5ca1ab1e'
this.Handler.replaceUserReferencesInGroups(this.oldId, this.newId, () => await this.Handler.promises.replaceUserReferencesInGroups(
done() this.oldId,
this.newId
) )
}) })
@@ -160,37 +118,28 @@ describe('SubscriptionGroupHandler', function () {
this.subscription_id = '123ed13123' this.subscription_id = '123ed13123'
}) })
it('should return true when user is part of subscription', function (done) { it('should return true when user is part of subscription', async function () {
this.SubscriptionLocator.getSubscriptionByMemberIdAndId.callsArgWith( this.SubscriptionLocator.promises.getSubscriptionByMemberIdAndId.resolves(
2, {
null, _id: this.subscription_id,
{ _id: this.subscription_id }
)
this.Handler.isUserPartOfGroup(
this.user_id,
this.subscription_id,
(err, partOfGroup) => {
if (err) return done(err)
partOfGroup.should.equal(true)
done()
} }
) )
const partOfGroup = await this.Handler.promises.isUserPartOfGroup(
this.user_id,
this.subscription_id
)
partOfGroup.should.equal(true)
}) })
it('should return false when no subscription is found', function (done) { it('should return false when no subscription is found', async function () {
this.SubscriptionLocator.getSubscriptionByMemberIdAndId.callsArgWith( this.SubscriptionLocator.promises.getSubscriptionByMemberIdAndId.resolves(
2,
null null
) )
this.Handler.isUserPartOfGroup( const partOfGroup = await this.Handler.promises.isUserPartOfGroup(
this.user_id, this.user_id,
this.subscription_id, this.subscription_id
(err, partOfGroup) => {
if (err) return done(err)
partOfGroup.should.equal(false)
done()
}
) )
partOfGroup.should.equal(false)
}) })
}) })
@@ -199,27 +148,22 @@ describe('SubscriptionGroupHandler', function () {
beforeEach(function () { beforeEach(function () {
this.subscription.member_ids = ['12321', '3121321'] this.subscription.member_ids = ['12321', '3121321']
}) })
it('should call the subscription locator and return 2 users', function (done) { it('should call the subscription locator and return 2 users', async function () {
this.Handler.getTotalConfirmedUsersInGroup( const count = await this.Handler.promises.getTotalConfirmedUsersInGroup(
this.subscription_id, this.subscription_id
(err, count) => {
if (err) return done(err)
this.SubscriptionLocator.getSubscription
.calledWith(this.subscription_id)
.should.equal(true)
count.should.equal(2)
done()
}
) )
this.SubscriptionLocator.promises.getSubscription
.calledWith(this.subscription_id)
.should.equal(true)
count.should.equal(2)
}) })
}) })
describe('for nonexistent subscriptions', function () { describe('for nonexistent subscriptions', function () {
it('should return undefined', function (done) { it('should return undefined', async function () {
this.Handler.getTotalConfirmedUsersInGroup('fake-id', (err, count) => { const count = await this.Handler.promises.getTotalConfirmedUsersInGroup(
if (err) return done(err) 'fake-id'
expect(count).not.to.exist )
done() expect(count).not.to.exist
})
}) })
}) })
}) })