From 8cb8411cc616df1784092a427717322447064372 Mon Sep 17 00:00:00 2001 From: negue Date: Wed, 6 Apr 2022 23:30:13 +0200 Subject: [PATCH] Show "Next Hourglass" Month (#13860) * Show "Next Hourglass" Month * fix lint * lint, * lint * lint.. * linting bad * ui fixes * remove additional margin * show next hourglass date to debug further * WIP tests - maybe broken logic * flex:1 doesn't work - so stats columns now at 33% width * fix(cron): lint and short circuit * refactor logic * update test dates using timezone * also check for the timezone date * fix timezone for tests * fixing the test dates? * fixing the test dates? * change nextHourglass logic + update gem cap label / value * fix lint * dont add gemsBought to it * remove tooltip Co-authored-by: SabreCat --- test/common/libs/cron.test.js | 61 +++++++- website/client/config/storybook/mock.data.js | 23 ++++ .../payments/buttons/list.stories.js | 2 +- .../settings/subscription.stories.js | 37 +++++ .../src/components/settings/subscription.vue | 130 ++++++++++++------ website/common/locales/en/settings.json | 3 + website/common/script/cron.js | 50 +++++++ website/common/script/index.js | 21 +-- website/server/libs/cron.js | 27 ++-- 9 files changed, 282 insertions(+), 72 deletions(-) create mode 100644 website/client/src/components/settings/subscription.stories.js 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/subscription.stories.js b/website/client/src/components/settings/subscription.stories.js new file mode 100644 index 0000000000..f392cd0586 --- /dev/null +++ b/website/client/src/components/settings/subscription.stories.js @@ -0,0 +1,37 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { storiesOf } from '@storybook/vue'; + +import Subscription from './subscription.vue'; +import { mockStore } from '../../../config/storybook/mock.data'; + +storiesOf('Subscriptions/Detail Page', module) + .add('subscribed', () => ({ + components: { Subscription }, + template: ` +
+ +
+ `, + data () { + return { + }; + }, + store: mockStore({ + userData: { + purchased: { + plan: { + customerId: 'customer-id', + planId: 'plan-id', + subscriptionId: 'sub-id', + gemsBought: 22, + dateUpdated: new Date(2021, 0, 15), + consecutive: { + count: 2, + gemCapExtra: 4, + offset: 2, + }, + }, + }, + }, + }), + })); diff --git a/website/client/src/components/settings/subscription.vue b/website/client/src/components/settings/subscription.vue index 0a52fbefd4..1bc59834d0 100644 --- a/website/client/src/components/settings/subscription.vue +++ b/website/client/src/components/settings/subscription.vue @@ -93,7 +93,7 @@