mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 07:37:25 +01:00
increase Hourglasses and gemCapExtra promptly when multi-month subscription renews - fixes #4819 (#10147)
* allow Hourglasses and gemCapExtra to increase promptly after a multi-month subscription has renewed * fix existing Hourglass and Gem Cap tests that were wrong The scenario originally used for these two tests was a six-month recurring subscription (you can tell that from the starting offset having a non-zero value). For recurring subscriptions, we do NOT want to increase the consecutive month benefits as soon as the sixth month starts because the user has already been given a full six months' benefits in advance and they might cancel the subscription before it renews later in the sixth month. Therefore we want to give the extra benefits at the beginning of the seventh month (ideally we'd give them mid-month in the sixth month when the renewal happens but we don't have support for tracking renewal dates). So, the two changed tests were actually not correct for the case where the offset started as non-zero. These tests are correct for one-month recurring subscriptions (when the offset is never set to anything above zero). The user isn't meant to get any consecutive month benefits until a multiple of 3 months has been reached. * add tests for one-month recurring subscription before 3x months are reached * add tests for 3-, 6-, and 12-month recurring subscriptions The 3-month tests are the most thorough, stepping through the expected start and end values of consecutive data for a 7-month range. The 6-month tests are a bit less thorough since the same code is used for all multi-month periods. The discount Google subscription code is used to ensure we keep support for it. The 12-month tests are less thorough still, since again the same code is used. I'm about to try some more tests with `useFakeTimers`, which should be a better way to test the code since they won't rely on me having set the initial values correctly for each test. :) But I wanted to work through these cases manually first to ensure my understanding of how the values should change does actually match the code. * add tests for 1-, 3-, 6-, and 12-month recurring subscriptions using clock changes to simulate passing months Also fixed the clock call in an unrelated test because it was forming the date incorrectly (`unix()` can't be used to create a date). Also changed email@email.email to email@example.com because email@email.email is potentially a real email address. * add tests for 3-month gift subscriptions - no extra consecutive benefits given * add tests for consecutive benefits for 6-month recurring subscription that has incorrect consecutive month data because it started before issue #4819 was fixed * fix lint errors * remove outdated subscription tests
This commit is contained in:
@@ -23,7 +23,7 @@ describe('cron', () => {
|
||||
local: {
|
||||
username: 'username',
|
||||
lowerCaseUsername: 'username',
|
||||
email: 'email@email.email',
|
||||
email: 'email@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
@@ -82,7 +82,7 @@ describe('cron', () => {
|
||||
});
|
||||
|
||||
it('does not reset plan.gemsBought within the month', () => {
|
||||
let clock = sinon.useFakeTimers(moment().startOf('month').add(2, 'days').unix());
|
||||
let clock = sinon.useFakeTimers(moment().startOf('month').add(2, 'days').toDate());
|
||||
user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
|
||||
|
||||
user.purchased.plan.gemsBought = 10;
|
||||
@@ -117,21 +117,6 @@ describe('cron', () => {
|
||||
expect(user.purchased.plan.consecutive.offset).to.equal(1);
|
||||
});
|
||||
|
||||
it('increments plan.consecutive.trinkets when user has reached a month that is a multiple of 3', () => {
|
||||
user.purchased.plan.consecutive.count = 5;
|
||||
user.purchased.plan.consecutive.offset = 1;
|
||||
cron({user, tasksByType, daysMissed, analytics});
|
||||
expect(user.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user.purchased.plan.consecutive.offset).to.equal(0);
|
||||
});
|
||||
|
||||
it('increments plan.consecutive.trinkets multiple times if user has been absent with continuous subscription', () => {
|
||||
user.purchased.plan.dateUpdated = moment().subtract(6, 'months').toDate();
|
||||
user.purchased.plan.consecutive.count = 5;
|
||||
cron({user, tasksByType, daysMissed, analytics});
|
||||
expect(user.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||
});
|
||||
|
||||
it('does not award unearned plan.consecutive.trinkets if subscription ended during an absence', () => {
|
||||
user.purchased.plan.dateUpdated = moment().subtract(6, 'months').toDate();
|
||||
user.purchased.plan.dateTerminated = moment().subtract(3, 'months').toDate();
|
||||
@@ -143,21 +128,6 @@ describe('cron', () => {
|
||||
expect(user.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
});
|
||||
|
||||
it('increments plan.consecutive.gemCapExtra when user has reached a month that is a multiple of 3', () => {
|
||||
user.purchased.plan.consecutive.count = 5;
|
||||
user.purchased.plan.consecutive.offset = 1;
|
||||
cron({user, tasksByType, daysMissed, analytics});
|
||||
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
expect(user.purchased.plan.consecutive.offset).to.equal(0);
|
||||
});
|
||||
|
||||
it('increments plan.consecutive.gemCapExtra multiple times if user has been absent with continuous subscription', () => {
|
||||
user.purchased.plan.dateUpdated = moment().subtract(6, 'months').toDate();
|
||||
user.purchased.plan.consecutive.count = 5;
|
||||
cron({user, tasksByType, daysMissed, analytics});
|
||||
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||
});
|
||||
|
||||
it('does not increment plan.consecutive.gemCapExtra when user has reached the gemCap limit', () => {
|
||||
user.purchased.plan.consecutive.gemCapExtra = 25;
|
||||
user.purchased.plan.consecutive.count = 5;
|
||||
@@ -184,6 +154,465 @@ describe('cron', () => {
|
||||
expect(user.purchased.plan.consecutive.count).to.equal(0);
|
||||
expect(user.purchased.plan.consecutive.offset).to.equal(0);
|
||||
});
|
||||
|
||||
describe('for a 1-month recurring subscription', () => {
|
||||
let clock;
|
||||
// create a user that will be used for all of these tests without a reset before each
|
||||
let user1 = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username1',
|
||||
lowerCaseUsername: 'username1',
|
||||
email: 'email1@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
// user1 has a 1-month recurring subscription starting today
|
||||
user1.purchased.plan.customerId = 'subscribedId';
|
||||
user1.purchased.plan.dateUpdated = moment().toDate();
|
||||
user1.purchased.plan.planId = 'basic';
|
||||
user1.purchased.plan.consecutive.count = 0;
|
||||
user1.purchased.plan.consecutive.offset = 0;
|
||||
user1.purchased.plan.consecutive.trinkets = 0;
|
||||
user1.purchased.plan.consecutive.gemCapExtra = 0;
|
||||
|
||||
it('does not increment consecutive benefits after the first month', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
|
||||
// Add 1 month to simulate what happens a month after the subscription was created.
|
||||
// Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
|
||||
cron({user: user1, tasksByType, daysMissed, analytics});
|
||||
expect(user1.purchased.plan.consecutive.count).to.equal(1);
|
||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(0);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits after the second month', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
|
||||
// Add 1 month to simulate what happens a month after the subscription was created.
|
||||
// Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
|
||||
cron({user: user1, tasksByType, daysMissed, analytics});
|
||||
expect(user1.purchased.plan.consecutive.count).to.equal(2);
|
||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(0);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits after the third month', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
|
||||
// Add 1 month to simulate what happens a month after the subscription was created.
|
||||
// Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
|
||||
cron({user: user1, tasksByType, daysMissed, analytics});
|
||||
expect(user1.purchased.plan.consecutive.count).to.equal(3);
|
||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits after the fourth month', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(4, 'months').add(2, 'days').toDate());
|
||||
// Add 1 month to simulate what happens a month after the subscription was created.
|
||||
// Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
|
||||
cron({user: user1, tasksByType, daysMissed, analytics});
|
||||
expect(user1.purchased.plan.consecutive.count).to.equal(4);
|
||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(10, 'months').add(2, 'days').toDate());
|
||||
cron({user: user1, tasksByType, daysMissed, analytics});
|
||||
expect(user1.purchased.plan.consecutive.count).to.equal(10);
|
||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(3);
|
||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(15);
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a 3-month recurring subscription', () => {
|
||||
let clock;
|
||||
let user3 = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username3',
|
||||
lowerCaseUsername: 'username3',
|
||||
email: 'email3@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
// user3 has a 3-month recurring subscription starting today
|
||||
user3.purchased.plan.customerId = 'subscribedId';
|
||||
user3.purchased.plan.dateUpdated = moment().toDate();
|
||||
user3.purchased.plan.planId = 'basic_3mo';
|
||||
user3.purchased.plan.consecutive.count = 0;
|
||||
user3.purchased.plan.consecutive.offset = 3;
|
||||
user3.purchased.plan.consecutive.trinkets = 1;
|
||||
user3.purchased.plan.consecutive.gemCapExtra = 5;
|
||||
|
||||
it('does not increment consecutive benefits in the first month of the first paid period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(1);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the middle of the period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(3);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits the month after the second paid period has started', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(4, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(4);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the second month of the second period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(5, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(5);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the final month of the second period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(6, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(6);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits the month after the third paid period has started', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(7, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(7);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(3);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(15);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(10, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3, tasksByType, daysMissed, analytics});
|
||||
expect(user3.purchased.plan.consecutive.count).to.equal(10);
|
||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a 6-month recurring subscription', () => {
|
||||
let clock;
|
||||
let user6 = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username6',
|
||||
lowerCaseUsername: 'username6',
|
||||
email: 'email6@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
// user6 has a 6-month recurring subscription starting today
|
||||
user6.purchased.plan.customerId = 'subscribedId';
|
||||
user6.purchased.plan.dateUpdated = moment().toDate();
|
||||
user6.purchased.plan.planId = 'google_6mo';
|
||||
user6.purchased.plan.consecutive.count = 0;
|
||||
user6.purchased.plan.consecutive.offset = 6;
|
||||
user6.purchased.plan.consecutive.trinkets = 2;
|
||||
user6.purchased.plan.consecutive.gemCapExtra = 10;
|
||||
|
||||
it('does not increment consecutive benefits in the first month of the first paid period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6, tasksByType, daysMissed, analytics});
|
||||
expect(user6.purchased.plan.consecutive.count).to.equal(1);
|
||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(6, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6, tasksByType, daysMissed, analytics});
|
||||
expect(user6.purchased.plan.consecutive.count).to.equal(6);
|
||||
expect(user6.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits the month after the second paid period has started', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(7, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6, tasksByType, daysMissed, analytics});
|
||||
expect(user6.purchased.plan.consecutive.count).to.equal(7);
|
||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits the month after the third paid period has started', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(13, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6, tasksByType, daysMissed, analytics});
|
||||
expect(user6.purchased.plan.consecutive.count).to.equal(13);
|
||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(6);
|
||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(19, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6, tasksByType, daysMissed, analytics});
|
||||
expect(user6.purchased.plan.consecutive.count).to.equal(19);
|
||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(8);
|
||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a 12-month recurring subscription', () => {
|
||||
let clock;
|
||||
|
||||
let user12 = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username12',
|
||||
lowerCaseUsername: 'username12',
|
||||
email: 'email12@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
// user12 has a 12-month recurring subscription starting today
|
||||
user12.purchased.plan.customerId = 'subscribedId';
|
||||
user12.purchased.plan.dateUpdated = moment().toDate();
|
||||
user12.purchased.plan.planId = 'basic_12mo';
|
||||
user12.purchased.plan.consecutive.count = 0;
|
||||
user12.purchased.plan.consecutive.offset = 12;
|
||||
user12.purchased.plan.consecutive.trinkets = 4;
|
||||
user12.purchased.plan.consecutive.gemCapExtra = 20;
|
||||
|
||||
it('does not increment consecutive benefits in the first month of the first paid period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
|
||||
cron({user: user12, tasksByType, daysMissed, analytics});
|
||||
expect(user12.purchased.plan.consecutive.count).to.equal(1);
|
||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(12, 'months').add(2, 'days').toDate());
|
||||
cron({user: user12, tasksByType, daysMissed, analytics});
|
||||
expect(user12.purchased.plan.consecutive.count).to.equal(12);
|
||||
expect(user12.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits the month after the second paid period has started', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(13, 'months').add(2, 'days').toDate());
|
||||
cron({user: user12, tasksByType, daysMissed, analytics});
|
||||
expect(user12.purchased.plan.consecutive.count).to.equal(13);
|
||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(8);
|
||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits the month after the third paid period has started', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(25, 'months').add(2, 'days').toDate());
|
||||
cron({user: user12, tasksByType, daysMissed, analytics});
|
||||
expect(user12.purchased.plan.consecutive.count).to.equal(25);
|
||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(12);
|
||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(37, 'months').add(2, 'days').toDate());
|
||||
cron({user: user12, tasksByType, daysMissed, analytics});
|
||||
expect(user12.purchased.plan.consecutive.count).to.equal(37);
|
||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(16);
|
||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a 3-month gift subscription (non-recurring)', () => {
|
||||
let clock;
|
||||
let user3g = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username3g',
|
||||
lowerCaseUsername: 'username3g',
|
||||
email: 'email3g@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
// user3g has a 3-month gift subscription starting today
|
||||
user3g.purchased.plan.customerId = 'Gift';
|
||||
user3g.purchased.plan.dateUpdated = moment().toDate();
|
||||
user3g.purchased.plan.dateTerminated = moment().add(3, 'months').toDate();
|
||||
user3g.purchased.plan.planId = null;
|
||||
user3g.purchased.plan.consecutive.count = 0;
|
||||
user3g.purchased.plan.consecutive.offset = 3;
|
||||
user3g.purchased.plan.consecutive.trinkets = 1;
|
||||
user3g.purchased.plan.consecutive.gemCapExtra = 5;
|
||||
|
||||
it('does not increment consecutive benefits in the first month of the gift subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3g, tasksByType, daysMissed, analytics});
|
||||
expect(user3g.purchased.plan.consecutive.count).to.equal(1);
|
||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(2);
|
||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the second month of the gift subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3g, tasksByType, daysMissed, analytics});
|
||||
expect(user3g.purchased.plan.consecutive.count).to.equal(2);
|
||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(1);
|
||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the third month of the gift subscription', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3g, tasksByType, daysMissed, analytics});
|
||||
expect(user3g.purchased.plan.consecutive.count).to.equal(3);
|
||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the month after the gift subscription has ended', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(4, 'months').add(2, 'days').toDate());
|
||||
cron({user: user3g, tasksByType, daysMissed, analytics});
|
||||
expect(user3g.purchased.plan.consecutive.count).to.equal(0); // subscription has been erased by now
|
||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
|
||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(0); // erased
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a 6-month recurring subscription where the user has incorrect consecutive month data from prior bugs', () => {
|
||||
let clock;
|
||||
let user6x = new User({
|
||||
auth: {
|
||||
local: {
|
||||
username: 'username6x',
|
||||
lowerCaseUsername: 'username6x',
|
||||
email: 'email6x@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
},
|
||||
});
|
||||
// user6x has a 6-month recurring subscription starting 8 months in the past before issue #4819 was fixed
|
||||
user6x.purchased.plan.customerId = 'subscribedId';
|
||||
user6x.purchased.plan.dateUpdated = moment().toDate();
|
||||
user6x.purchased.plan.planId = 'basic_6mo';
|
||||
user6x.purchased.plan.consecutive.count = 8;
|
||||
user6x.purchased.plan.consecutive.offset = 0;
|
||||
user6x.purchased.plan.consecutive.trinkets = 3;
|
||||
user6x.purchased.plan.consecutive.gemCapExtra = 15;
|
||||
|
||||
it('increments consecutive benefits in the first month since the fix for #4819 goes live', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6x, tasksByType, daysMissed, analytics});
|
||||
expect(user6x.purchased.plan.consecutive.count).to.equal(9);
|
||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
|
||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the second month after the fix goes live', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6x, tasksByType, daysMissed, analytics});
|
||||
expect(user6x.purchased.plan.consecutive.count).to.equal(10);
|
||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(4);
|
||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('does not increment consecutive benefits in the third month after the fix goes live', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6x, tasksByType, daysMissed, analytics});
|
||||
expect(user6x.purchased.plan.consecutive.count).to.equal(11);
|
||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(3);
|
||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('increments consecutive benefits in the seventh month after the fix goes live', () => {
|
||||
clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(7, 'months').add(2, 'days').toDate());
|
||||
cron({user: user6x, tasksByType, daysMissed, analytics});
|
||||
expect(user6x.purchased.plan.consecutive.count).to.equal(15);
|
||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
|
||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(7);
|
||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('end of the month perks when user is not subscribed', () => {
|
||||
@@ -1348,7 +1777,7 @@ describe('recoverCron', () => {
|
||||
local: {
|
||||
username: 'username',
|
||||
lowerCaseUsername: 'username',
|
||||
email: 'email@email.email',
|
||||
email: 'email@example.com',
|
||||
salt: 'salt',
|
||||
hashed_password: 'hashed_password', // eslint-disable-line camelcase
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user