Added added maxPeriodical checks

refs https://github.com/TryGhost/Team/issues/588

- This bit is putting together all the pieces for periodical limit checks. More tests are to come
This commit is contained in:
Naz 2021-05-06 17:48:31 +04:00
parent ebfad4bea4
commit 9c738b13d1
2 changed files with 94 additions and 1 deletions

View File

@ -1,6 +1,6 @@
// run in context allows us to change the templateSettings without causing havoc
const _ = require('lodash').runInContext();
const {SUPPORTED_INTERVALS} = require('./date-utils');
const {lastPeriodStart, SUPPORTED_INTERVALS} = require('./date-utils');
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
@ -155,6 +155,63 @@ class MaxPeriodicLimit extends Limit {
this.startDate = config.startDate;
this.fallbackMessage = `This action would exceed the ${_.lowerCase(this.name)} limit on your current plan.`;
}
generateError(count) {
let errorObj = super.generateError();
errorObj.message = this.fallbackMessage;
if (this.error) {
try {
errorObj.message = _.template(this.error)(
{
max: Intl.NumberFormat().format(this.maxPeriodic),
count: Intl.NumberFormat().format(count)
});
} catch (e) {
errorObj.message = this.fallbackMessage;
}
}
errorObj.errorDetails.limit = this.maxPeriodic;
errorObj.errorDetails.total = count;
return new this.errors.HostLimitError(errorObj);
}
async currentCountQuery() {
const lastPeriodStartDate = lastPeriodStart(this.startDate, this.interval);
return await this.currentCountQueryFn(this.db, lastPeriodStartDate);
}
/**
* Throws a HostLimitError if the configured or passed max limit is ecceded by currentCountQuery
*
* @param {Object} options
* @param {Number} [options.max] - overrides configured default maxPeriodic value to perform checks against
*/
async errorIfWouldGoOverLimit({max} = {}) {
let currentCount = await this.currentCountQuery(this.db);
if ((currentCount + 1) > (max || this.maxPeriodic)) {
throw this.generateError(currentCount);
}
}
/**
* Throws a HostLimitError if the configured or passed max limit is ecceded by currentCountQuery
*
* @param {Object} options
* @param {Number} [options.max] - overrides configured default maxPeriodic value to perform checks against
*/
async errorIfIsOverLimit({max} = {}) {
let currentCount = await this.currentCountQuery(this.db);
if (currentCount > (max || this.maxPeriodic)) {
throw this.generateError(currentCount);
}
}
}
class FlagLimit extends Limit {

View File

@ -294,6 +294,42 @@ describe('Limit Service', function () {
}
});
});
describe('Is over limit', function () {
it('throws if is over the limit', async function () {
const currentCountyQueryMock = sinon.mock().returns(11);
const config = {
maxPeriodic: 3,
error: 'You have exceeded the number of emails you can send within your billing period.',
interval: 'month',
startDate: '2021-01-01T00:00:00Z',
currentCountQuery: currentCountyQueryMock
};
try {
const limit = new MaxPeriodicLimit({name: 'mailguard', config, errors});
await limit.errorIfIsOverLimit();
} catch (error) {
error.errorType.should.equal('HostLimitError');
error.errorDetails.name.should.equal('mailguard');
error.errorDetails.limit.should.equal(3);
error.errorDetails.total.should.equal(11);
currentCountyQueryMock.callCount.should.equal(1);
should(currentCountyQueryMock.args).not.be.undefined();
should(currentCountyQueryMock.args[0][0]).be.undefined(); //knex db connection
const nowDate = new Date();
const startOfTheMonthDate = new Date(Date.UTC(
nowDate.getUTCFullYear(),
nowDate.getUTCMonth()
)).toISOString();
currentCountyQueryMock.args[0][1].should.equal(startOfTheMonthDate);
}
});
});
});
describe('Allowlist limit', function () {