diff --git a/package-lock.json b/package-lock.json
index 1312c3946c..3d13b25a79 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13779,12 +13779,12 @@
}
},
"stripe": {
- "version": "8.212.0",
- "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.212.0.tgz",
- "integrity": "sha512-xQ2uPMRAmRyOiMZktw3hY8jZ8LFR9lEQRPEaQ5WcDcn51kMyn46GeikOikxiFTHEN8PeKRdwtpz4yNArAvu/Kg==",
+ "version": "8.215.0",
+ "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.215.0.tgz",
+ "integrity": "sha512-M+7iTZ9bzTkU1Ms+Zsuh0mTQfEzOjMoqyEaVBpuUmdbWTvshavzpAihsOkfabEu+sNY0vdbQxxHZ4kI3W8pKHQ==",
"requires": {
"@types/node": ">=8.1.0",
- "qs": "^6.6.0"
+ "qs": "^6.10.3"
},
"dependencies": {
"qs": {
diff --git a/package.json b/package.json
index 1c11c7dfec..482ae20f32 100644
--- a/package.json
+++ b/package.json
@@ -67,7 +67,7 @@
"remove-markdown": "^0.3.0",
"rimraf": "^3.0.2",
"short-uuid": "^4.2.0",
- "stripe": "^8.212.0",
+ "stripe": "^8.215.0",
"superagent": "^7.1.2",
"universal-analytics": "^0.5.3",
"useragent": "^2.1.9",
diff --git a/test/common/libs/cron.test.js b/test/common/libs/cron.test.js
index 0894a6afa3..bd84de1e80 100644
--- a/test/common/libs/cron.test.js
+++ b/test/common/libs/cron.test.js
@@ -1,6 +1,6 @@
import moment from 'moment';
-import { startOfDay, daysSince } from '../../../website/common/script/cron';
+import { startOfDay, daysSince, getPlanContext } from '../../../website/common/script/cron';
function localMoment (timeString, utcOffset) {
return moment(timeString).utcOffset(utcOffset, true);
@@ -181,4 +181,63 @@ describe('cron utility functions', () => {
expect(result).to.equal(0);
});
});
+
+ describe('getPlanContext', () => {
+ const now = new Date(2022, 5, 1);
+
+ function baseUserData (count, offset, planId) {
+ return {
+ purchased: {
+ plan: {
+ consecutive: {
+ count,
+ offset,
+ gemCapExtra: 25,
+ trinkets: 19,
+ },
+ quantity: 1,
+ extraMonths: 0,
+ gemsBought: 0,
+ owner: '116b4133-8fb7-43f2-b0de-706621a8c9d8',
+ nextBillingDate: null,
+ nextPaymentProcessing: null,
+ planId,
+ customerId: 'group-plan',
+ dateUpdated: '2022-05-10T03:00:00.144+01:00',
+ paymentMethod: 'Group Plan',
+ dateTerminated: null,
+ lastBillingDate: null,
+ dateCreated: '2017-02-10T19:00:00.355+01:00',
+ },
+ },
+ };
+ }
+
+ it('offset 0, next date in 3 months', () => {
+ const user = baseUserData(60, 0, 'group_plan_auto');
+
+ const planContext = getPlanContext(user, now);
+
+ expect(planContext.nextHourglassDate)
+ .to.be.sameMoment('2022-08-10T02:00:00.144Z');
+ });
+
+ it('offset 1, next date in 1 months', () => {
+ const user = baseUserData(60, 1, 'group_plan_auto');
+
+ const planContext = getPlanContext(user, now);
+
+ expect(planContext.nextHourglassDate)
+ .to.be.sameMoment('2022-06-10T02:00:00.144Z');
+ });
+
+ it('offset 2, next date in 2 months - with any plan', () => {
+ const user = baseUserData(60, 2, 'basic_3mo');
+
+ const planContext = getPlanContext(user, now);
+
+ expect(planContext.nextHourglassDate)
+ .to.be.sameMoment('2022-07-10T02:00:00.144Z');
+ });
+ });
});
diff --git a/website/client/config/storybook/mock.data.js b/website/client/config/storybook/mock.data.js
index 0d9a57a8b2..5143c23348 100644
--- a/website/client/config/storybook/mock.data.js
+++ b/website/client/config/storybook/mock.data.js
@@ -1,4 +1,5 @@
import { v4 as generateUUID } from 'uuid';
+import getters from '@/store/getters';
export const userStyles = {
contributor: {
@@ -82,3 +83,25 @@ export const userStyles = {
classSelected: true,
},
};
+
+
+export function mockStore ({
+ userData,
+ ...state
+}) {
+ return {
+ getters,
+ dispatch: () => {
+ },
+ watch: () => {
+ },
+ state: {
+ user: {
+ data: {
+ ...userData,
+ },
+ },
+ ...state,
+ },
+ };
+}
diff --git a/website/client/src/components/payments/buttons/list.stories.js b/website/client/src/components/payments/buttons/list.stories.js
index 780f365c01..2142cb9bef 100644
--- a/website/client/src/components/payments/buttons/list.stories.js
+++ b/website/client/src/components/payments/buttons/list.stories.js
@@ -7,7 +7,7 @@ import { setup as setupPayments } from '@/libs/payments';
setupPayments();
-storiesOf('Payments Buttons', module)
+storiesOf('Subscriptions/Payments Buttons', module)
.add('simple', () => ({
components: { PaymentsButtonsList },
template: `
diff --git a/website/client/src/components/settings/dayStartAdjustment.vue b/website/client/src/components/settings/dayStartAdjustment.vue
new file mode 100644
index 0000000000..54d312740c
--- /dev/null
+++ b/website/client/src/components/settings/dayStartAdjustment.vue
@@ -0,0 +1,132 @@
+
+ {{ $t('dayStartAdjustment') }}
+ {{ $t('adjustment') }}
+