mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-27 19:11:56 +02:00
[web] mv PaymentService to modules
GitOrigin-RevId: 73d739f53d96ff9e9d51a535907dbdc878aa6624
This commit is contained in:
committed by
Copybot
parent
04d36122bd
commit
f8f2585164
@@ -1,81 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
const RecurlyClient = require('./RecurlyClient.js')
|
||||
const logger = require('@overleaf/logger')
|
||||
const { callbackify } = require('util')
|
||||
|
||||
/**
|
||||
* @import { PaymentProviderSubscription, PaymentProviderAccount, PaymentProviderCoupon } from "./PaymentProviderEntities.js"
|
||||
* @import { ObjectId } from 'mongodb'
|
||||
*/
|
||||
|
||||
/**
|
||||
* this represents a subset of the Mongo Subscription record
|
||||
*
|
||||
* @typedef {object} MongoSubscription
|
||||
* @property {ObjectId} admin_id
|
||||
* @property {string} [recurlySubscription_id]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} PaymentRecord
|
||||
* @property {PaymentProviderSubscription} subscription
|
||||
* @property {PaymentProviderAccount | null} account
|
||||
* @property {PaymentProviderCoupon[]} coupons
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get payment information from our Mongo record
|
||||
*
|
||||
* @param {MongoSubscription} subscription
|
||||
* @return {Promise<PaymentRecord | null>}
|
||||
*/
|
||||
async function getPaymentFromRecord(subscription) {
|
||||
if (subscription == null) {
|
||||
logger.debug('no subscription provided')
|
||||
return null
|
||||
}
|
||||
const userId = (subscription.admin_id._id || subscription.admin_id).toString()
|
||||
const recurlySubscriptionId = subscription.recurlySubscription_id
|
||||
|
||||
// TODO: handle non-recurly payment records
|
||||
if (recurlySubscriptionId == null || recurlySubscriptionId === '') {
|
||||
logger.debug(
|
||||
{ userId },
|
||||
"no recurly subscription id found for user's subscription"
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const subscriptionResponse = await RecurlyClient.promises.getSubscription(
|
||||
recurlySubscriptionId
|
||||
)
|
||||
if (!subscriptionResponse) {
|
||||
logger.debug(
|
||||
{ recurlySubscriptionId },
|
||||
'no recurly subscription found for subscription id'
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const accountResponse =
|
||||
await RecurlyClient.promises.getAccountForUserId(userId)
|
||||
const accountCoupons =
|
||||
await RecurlyClient.promises.getActiveCouponsForUserId(userId)
|
||||
|
||||
// TODO: include account and coupons in subscription class instead of separately here
|
||||
// if Recurly is removed (Recurly needs 2 extra requests to get account & coupon data)
|
||||
return {
|
||||
subscription: subscriptionResponse,
|
||||
account: accountResponse,
|
||||
coupons: accountCoupons,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPaymentFromRecord: callbackify(getPaymentFromRecord),
|
||||
|
||||
promises: {
|
||||
getPaymentFromRecord,
|
||||
},
|
||||
}
|
||||
@@ -23,8 +23,8 @@ const {
|
||||
V1ConnectionError,
|
||||
} = require('../Errors/Errors')
|
||||
const FeaturesHelper = require('./FeaturesHelper')
|
||||
const PaymentService = require('./PaymentService')
|
||||
const { formatCurrency } = require('../../util/currency')
|
||||
const Modules = require('../../infrastructure/Modules')
|
||||
|
||||
/**
|
||||
* @import { Subscription } from "../../../../types/project/dashboard/subscription"
|
||||
@@ -82,16 +82,16 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') {
|
||||
currentInstitutionsWithLicence,
|
||||
managedInstitutions,
|
||||
managedPublishers,
|
||||
paymentRecord,
|
||||
fetchedPaymentRecord,
|
||||
plan,
|
||||
} = await async.auto({
|
||||
personalSubscription(cb) {
|
||||
SubscriptionLocator.getUsersSubscription(user, cb)
|
||||
},
|
||||
paymentRecord: [
|
||||
fetchedPaymentRecord: [
|
||||
'personalSubscription',
|
||||
({ personalSubscription }, cb) => {
|
||||
PaymentService.getPaymentFromRecord(personalSubscription, cb)
|
||||
Modules.hooks.fire('getPaymentFromRecord', personalSubscription, cb)
|
||||
},
|
||||
],
|
||||
plan: [
|
||||
@@ -138,6 +138,8 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') {
|
||||
},
|
||||
})
|
||||
|
||||
const paymentRecord = fetchedPaymentRecord && fetchedPaymentRecord[0]
|
||||
|
||||
if (memberGroupSubscriptions == null) {
|
||||
memberGroupSubscriptions = []
|
||||
} else {
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
const sinon = require('sinon')
|
||||
const { expect } = require('chai')
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const {
|
||||
PaymentProviderSubscription,
|
||||
PaymentProviderAccount,
|
||||
PaymentProviderCoupon,
|
||||
} = require('../../../../app/src/Features/Subscription/PaymentProviderEntities')
|
||||
|
||||
const MODULE_PATH = '../../../../app/src/Features/Subscription/PaymentService'
|
||||
|
||||
describe('PaymentService', function () {
|
||||
beforeEach(function () {
|
||||
this.user = {
|
||||
_id: '123456',
|
||||
}
|
||||
this.recurlySubscription = new PaymentProviderSubscription({
|
||||
id: 'subscription-id',
|
||||
userId: this.user._id,
|
||||
currency: 'EUR',
|
||||
planCode: 'plan-code',
|
||||
planName: 'plan-name',
|
||||
planPrice: 13,
|
||||
addOns: [],
|
||||
subtotal: 15,
|
||||
taxRate: 0.1,
|
||||
taxAmount: 1.5,
|
||||
total: 14.5,
|
||||
periodStart: new Date(),
|
||||
periodEnd: new Date(),
|
||||
collectionMethod: 'automatic',
|
||||
})
|
||||
this.recurlyAccount = new PaymentProviderAccount({
|
||||
code: this.user._id,
|
||||
email: 'example@example.com',
|
||||
hasPastDueInvoice: true,
|
||||
})
|
||||
this.recurlyCoupons = [
|
||||
new PaymentProviderCoupon({
|
||||
code: 'coupon-code',
|
||||
name: 'coupon name',
|
||||
description: 'coupon description',
|
||||
}),
|
||||
]
|
||||
this.mongoSubscription = {
|
||||
admin_id: this.user,
|
||||
recurlySubscription_id: this.recurlySubscription.id,
|
||||
}
|
||||
this.RecurlyClient = {
|
||||
promises: {
|
||||
getSubscription: sinon.stub(),
|
||||
getAccountForUserId: sinon.stub(),
|
||||
getActiveCouponsForUserId: sinon.stub(),
|
||||
},
|
||||
}
|
||||
return (this.PaymentService = SandboxedModule.require(MODULE_PATH, {
|
||||
requires: {
|
||||
'./RecurlyClient': this.RecurlyClient,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
describe('getPaymentFromRecord', function () {
|
||||
it('should return null for a missing subscription', async function () {
|
||||
const response =
|
||||
await this.PaymentService.promises.getPaymentFromRecord(null)
|
||||
expect(response).to.equal(null)
|
||||
})
|
||||
|
||||
it('should return null if payment service subscription id is missing', async function () {
|
||||
this.mongoSubscription.recurlySubscription_id = null
|
||||
const response = await this.PaymentService.promises.getPaymentFromRecord(
|
||||
this.mongoSubscription
|
||||
)
|
||||
expect(response).to.equal(null)
|
||||
})
|
||||
|
||||
it('should return the subscription', async function () {
|
||||
this.RecurlyClient.promises.getSubscription.returns(
|
||||
this.recurlySubscription
|
||||
)
|
||||
const response = await this.PaymentService.promises.getPaymentFromRecord(
|
||||
this.mongoSubscription
|
||||
)
|
||||
expect(response.subscription).to.deep.equal(this.recurlySubscription)
|
||||
})
|
||||
|
||||
it('should return account information if found', async function () {
|
||||
this.RecurlyClient.promises.getSubscription.returns(
|
||||
this.recurlySubscription
|
||||
)
|
||||
this.RecurlyClient.promises.getAccountForUserId.returns(
|
||||
this.recurlyAccount
|
||||
)
|
||||
const response = await this.PaymentService.promises.getPaymentFromRecord(
|
||||
this.mongoSubscription
|
||||
)
|
||||
expect(response.account.email).to.equal(this.recurlyAccount.email)
|
||||
expect(response.account.hasPastDueInvoice).to.equal(
|
||||
this.recurlyAccount.hasPastDueInvoice
|
||||
)
|
||||
})
|
||||
|
||||
it('should include coupons if found', async function () {
|
||||
this.RecurlyClient.promises.getSubscription.returns(
|
||||
this.recurlySubscription
|
||||
)
|
||||
this.RecurlyClient.promises.getActiveCouponsForUserId.returns(
|
||||
this.recurlyCoupons
|
||||
)
|
||||
const response = await this.PaymentService.promises.getPaymentFromRecord(
|
||||
this.mongoSubscription
|
||||
)
|
||||
expect(response.coupons).to.deep.equal(this.recurlyCoupons)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -143,9 +143,6 @@ describe('SubscriptionViewModelBuilder', function () {
|
||||
this.PlansLocator = {
|
||||
findLocalPlanInSettings: sinon.stub(),
|
||||
}
|
||||
this.PaymentService = {
|
||||
getPaymentFromRecord: sinon.stub().yields(),
|
||||
}
|
||||
this.SubscriptionViewModelBuilder = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'@overleaf/settings': this.Settings,
|
||||
@@ -155,7 +152,11 @@ describe('SubscriptionViewModelBuilder', function () {
|
||||
'./RecurlyWrapper': this.RecurlyWrapper,
|
||||
'./SubscriptionUpdater': this.SubscriptionUpdater,
|
||||
'./PlansLocator': this.PlansLocator,
|
||||
'./PaymentService': this.PaymentService,
|
||||
'../../infrastructure/Modules': (this.Modules = {
|
||||
hooks: {
|
||||
fire: sinon.stub().yields(null, []),
|
||||
},
|
||||
}),
|
||||
'./V1SubscriptionManager': {},
|
||||
'../Publishers/PublishersGetter': this.PublishersGetter,
|
||||
'./SubscriptionHelper': {},
|
||||
@@ -512,14 +513,18 @@ describe('SubscriptionViewModelBuilder', function () {
|
||||
null,
|
||||
this.individualSubscription
|
||||
)
|
||||
this.PaymentService.getPaymentFromRecord.yields(null, {
|
||||
subscription: this.paymentRecord,
|
||||
account: new PaymentProviderAccount({
|
||||
email: 'example@example.com',
|
||||
hasPastDueInvoice: false,
|
||||
}),
|
||||
coupons: [],
|
||||
})
|
||||
this.Modules.hooks.fire
|
||||
.withArgs('getPaymentFromRecord', this.individualSubscription)
|
||||
.yields(null, [
|
||||
{
|
||||
subscription: this.paymentRecord,
|
||||
account: new PaymentProviderAccount({
|
||||
email: 'example@example.com',
|
||||
hasPastDueInvoice: false,
|
||||
}),
|
||||
coupons: [],
|
||||
},
|
||||
])
|
||||
const result =
|
||||
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
||||
this.user
|
||||
@@ -585,11 +590,15 @@ describe('SubscriptionViewModelBuilder', function () {
|
||||
}),
|
||||
],
|
||||
})
|
||||
this.PaymentService.getPaymentFromRecord.yields(null, {
|
||||
subscription: this.paymentRecord,
|
||||
account: {},
|
||||
coupons: [],
|
||||
})
|
||||
this.Modules.hooks.fire
|
||||
.withArgs('getPaymentFromRecord', this.individualSubscription)
|
||||
.yields(null, [
|
||||
{
|
||||
subscription: this.paymentRecord,
|
||||
account: {},
|
||||
coupons: [],
|
||||
},
|
||||
])
|
||||
const result =
|
||||
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
||||
this.user
|
||||
|
||||
Reference in New Issue
Block a user