From f6b9bb2ef708809f08d6c6fa9970acfbfffa6343 Mon Sep 17 00:00:00 2001 From: Rupert Bates Date: Wed, 11 Dec 2024 14:39:57 +0000 Subject: [PATCH 1/4] Upgrade support-dotcom-components to 3.2.0 --- dotcom-rendering/package.json | 2 +- pnpm-lock.yaml | 67 ++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/dotcom-rendering/package.json b/dotcom-rendering/package.json index 9905ae938bc..6ab042c52b6 100644 --- a/dotcom-rendering/package.json +++ b/dotcom-rendering/package.json @@ -53,7 +53,7 @@ "@guardian/shimport": "1.0.2", "@guardian/source": "8.0.0", "@guardian/source-development-kitchen": "12.0.0", - "@guardian/support-dotcom-components": "3.1.0", + "@guardian/support-dotcom-components": "3.2.0", "@guardian/tsconfig": "0.2.0", "@playwright/test": "1.45.3", "@sentry/browser": "7.75.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2457e5e83f0..1a72b4251eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -374,8 +374,8 @@ importers: specifier: 12.0.0 version: 12.0.0(@emotion/react@11.11.3)(@guardian/libs@19.2.1)(@guardian/source@8.0.0)(@types/react@18.3.1)(react@18.3.1)(tslib@2.6.2)(typescript@5.5.3) '@guardian/support-dotcom-components': - specifier: 3.1.0 - version: 3.1.0(@guardian/libs@19.2.1)(zod@3.22.4) + specifier: 3.2.0 + version: 3.2.0(@guardian/libs@19.2.1)(zod@3.22.4) '@guardian/tsconfig': specifier: 0.2.0 version: 0.2.0 @@ -4378,8 +4378,8 @@ packages: - utf-8-validate dev: false - /@guardian/support-dotcom-components@3.1.0(@guardian/libs@19.2.1)(zod@3.22.4): - resolution: {integrity: sha512-JzXo3QGITIyehVFEeM2ZvUsCWbjEkAAxtl+zsTpWniEnmylFuyb9YH7DS+uT7GeXUnSBzkHFle/pkL2WPDa1kA==} + /@guardian/support-dotcom-components@3.2.0(@guardian/libs@19.2.1)(zod@3.22.4): + resolution: {integrity: sha512-jxsOmP+DTGdpy3oitRGFjnRfznvOAW+ojRltZQT3qT6Eoe5nkuNc5ip0ok0y4qSnov/3MKn1UxJpvqTQT6okTw==} peerDependencies: '@guardian/libs': ^17.0.0 zod: ^3.22.4 @@ -4389,7 +4389,7 @@ packages: compression: 1.7.4 cors: 2.8.5 date-fns: 2.30.0 - express: 4.21.0 + express: 4.21.2 jsonschema: 1.4.1 lodash.debounce: 4.0.8 log4js: 6.9.1 @@ -9360,6 +9360,11 @@ packages: engines: {node: '>= 0.6'} dev: false + /cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + dev: false + /copy-file@11.0.0: resolution: {integrity: sha512-mFsNh/DIANLqFt5VHZoGirdg7bK5+oTWlhnGu6tgRhzBlnEKWaPX2xrFaLltii/6rmhqFMJqffUgknuRdpYlHw==} engines: {node: '>=18'} @@ -10244,7 +10249,7 @@ packages: is-string: 1.0.7 is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.13.2 + object-inspect: 1.13.3 object-keys: 1.1.1 object.assign: 4.1.5 regexp.prototype.flags: 1.5.2 @@ -11158,6 +11163,45 @@ packages: - supports-color dev: false + /express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: false + /ext-list@2.2.2: resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} engines: {node: '>=0.10.0'} @@ -14605,11 +14649,6 @@ packages: engines: {node: '>= 6'} dev: false - /object-inspect@1.13.2: - resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} - engines: {node: '>= 0.4'} - dev: false - /object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} @@ -15005,6 +15044,10 @@ packages: resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} dev: false + /path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -16238,7 +16281,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - object-inspect: 1.13.2 + object-inspect: 1.13.3 dev: false /signal-exit@3.0.7: From d3935811fdc77e7b06273e2db375e88c7e446d6b Mon Sep 17 00:00:00 2001 From: Rupert Bates Date: Wed, 11 Dec 2024 14:41:05 +0000 Subject: [PATCH 2/4] Remove isRecurringContributor --- .../components/LiveBlogEpic.importable.tsx | 2 -- .../SlotBodyEnd/ReaderRevenueEpic.tsx | 4 --- dotcom-rendering/src/lib/contributions.ts | 36 +------------------ 3 files changed, 1 insertion(+), 41 deletions(-) diff --git a/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx b/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx index c0b5dcf67da..05e87ba470f 100644 --- a/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx +++ b/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx @@ -10,7 +10,6 @@ import { submitComponentEvent } from '../client/ophan/ophan'; import { useArticleCounts } from '../lib/articleCount'; import { getLastOneOffContributionTimestamp, - isRecurringContributor, shouldHideSupportMessaging, useHasOptedOutOfArticleCount, } from '../lib/contributions'; @@ -125,7 +124,6 @@ const usePayload = ({ isPaidContent, tags, showSupportMessaging: !hideSupportMessagingForUser, - isRecurringContributor: isRecurringContributor(isSignedIn), lastOneOffContributionDate: getLastOneOffContributionTimestamp() ?? undefined, mvtId, diff --git a/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx b/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx index d84aa777432..9c2c9be1e2e 100644 --- a/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx +++ b/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx @@ -16,7 +16,6 @@ import { hasCmpConsentForBrowserId, hasCmpConsentForWeeklyArticleCount, hasOptedOutOfArticleCount, - isRecurringContributor, shouldHideSupportMessaging, } from '../../lib/contributions'; import { lazyFetchEmailWithTimeout } from '../../lib/fetchEmail'; @@ -70,9 +69,6 @@ const buildPayload = async ( isPaidContent: data.isPaidContent, tags: data.tags, showSupportMessaging: !data.hideSupportMessagingForUser, - isRecurringContributor: isRecurringContributor( - data.isSignedIn ?? false, - ), lastOneOffContributionDate: getLastOneOffContributionTimestamp(), epicViewLog: getEpicViewLog(storage.local), weeklyArticleHistory: await data.asyncArticleCount, diff --git a/dotcom-rendering/src/lib/contributions.ts b/dotcom-rendering/src/lib/contributions.ts index de91bc67ee0..71b3a8d9eaf 100644 --- a/dotcom-rendering/src/lib/contributions.ts +++ b/dotcom-rendering/src/lib/contributions.ts @@ -61,36 +61,6 @@ export const hasSupporterCookie = ( } }; -// Determine if user is a recurring contributor by checking if they are signed in -// AND have at least one of the relevant cookies. -// We need to look at both User Attributes and Frontend Support cookies -// as the former might not reflect the latest contributor status, since it's set upon signing in. -// Frontend Support cookies are set when a contribution is made. -export const isRecurringContributor = (isSignedIn: boolean): boolean => { - // Attributes cookie - we want this to have a specific value - const isRecurringContributorFromAttrs = - getCookie({ name: RECURRING_CONTRIBUTOR_COOKIE }) === 'true'; - - // Support cookies - we only care whether these exist - const hasMonthlyContributionCookie = - getCookie({ - name: SUPPORT_RECURRING_CONTRIBUTOR_MONTHLY_COOKIE, - shouldMemoize: true, - }) !== null; - const hasAnnualContributionCookie = - getCookie({ - name: SUPPORT_RECURRING_CONTRIBUTOR_ANNUAL_COOKIE, - shouldMemoize: true, - }) !== null; - - return ( - isSignedIn && - (isRecurringContributorFromAttrs || - hasMonthlyContributionCookie || - hasAnnualContributionCookie) - ); -}; - // looks at attribute and support cookies // ONE_OFF_CONTRIBUTION_DATE_COOKIE (attributes cookie, when loggin in) // SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE (support cookie, when making one-off contribution) @@ -168,11 +138,7 @@ export const shouldHideSupportMessaging = ( if (hasCookie === 'Pending') { return 'Pending'; } else { - return ( - hasCookie || - isRecurringContributor(isSignedIn) || - isRecentOneOffContributor() - ); + return hasCookie || isRecentOneOffContributor(); } }; From d8edd0087bc14aff3a9d292afa602ccfc497c75f Mon Sep 17 00:00:00 2001 From: Rupert Bates Date: Wed, 11 Dec 2024 14:46:13 +0000 Subject: [PATCH 3/4] Remove lastOneOffContributionDate --- .../components/LiveBlogEpic.importable.tsx | 3 - .../SlotBodyEnd/ReaderRevenueEpic.tsx | 10 ++-- .../ReaderRevenueBanner.tsx | 2 - .../components/TopBarSupport.importable.tsx | 2 - .../src/lib/contributions.test.ts | 58 ++++--------------- dotcom-rendering/src/lib/contributions.ts | 45 ++------------ 6 files changed, 24 insertions(+), 96 deletions(-) diff --git a/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx b/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx index 05e87ba470f..a834d1f25b6 100644 --- a/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx +++ b/dotcom-rendering/src/components/LiveBlogEpic.importable.tsx @@ -9,7 +9,6 @@ import { createPortal } from 'react-dom'; import { submitComponentEvent } from '../client/ophan/ophan'; import { useArticleCounts } from '../lib/articleCount'; import { - getLastOneOffContributionTimestamp, shouldHideSupportMessaging, useHasOptedOutOfArticleCount, } from '../lib/contributions'; @@ -124,8 +123,6 @@ const usePayload = ({ isPaidContent, tags, showSupportMessaging: !hideSupportMessagingForUser, - lastOneOffContributionDate: - getLastOneOffContributionTimestamp() ?? undefined, mvtId, countryCode, epicViewLog: getEpicViewLog(storage.local), diff --git a/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx b/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx index 9c2c9be1e2e..7553ef049b3 100644 --- a/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx +++ b/dotcom-rendering/src/components/SlotBodyEnd/ReaderRevenueEpic.tsx @@ -1,6 +1,10 @@ import { css } from '@emotion/react'; -import { cmp } from '@guardian/libs'; -import { getCookie, startPerformanceMeasure, storage } from '@guardian/libs'; +import { + cmp, + getCookie, + startPerformanceMeasure, + storage, +} from '@guardian/libs'; import type { ComponentEvent } from '@guardian/ophan-tracker-js'; import { getEpic, getEpicViewLog } from '@guardian/support-dotcom-components'; import type { @@ -12,7 +16,6 @@ import type { import { useEffect, useState } from 'react'; import { submitComponentEvent } from '../../client/ophan/ophan'; import { - getLastOneOffContributionTimestamp, hasCmpConsentForBrowserId, hasCmpConsentForWeeklyArticleCount, hasOptedOutOfArticleCount, @@ -69,7 +72,6 @@ const buildPayload = async ( isPaidContent: data.isPaidContent, tags: data.tags, showSupportMessaging: !data.hideSupportMessagingForUser, - lastOneOffContributionDate: getLastOneOffContributionTimestamp(), epicViewLog: getEpicViewLog(storage.local), weeklyArticleHistory: await data.asyncArticleCount, diff --git a/dotcom-rendering/src/components/StickyBottomBanner/ReaderRevenueBanner.tsx b/dotcom-rendering/src/components/StickyBottomBanner/ReaderRevenueBanner.tsx index ee6903663f2..b0828463e2a 100644 --- a/dotcom-rendering/src/components/StickyBottomBanner/ReaderRevenueBanner.tsx +++ b/dotcom-rendering/src/components/StickyBottomBanner/ReaderRevenueBanner.tsx @@ -16,7 +16,6 @@ import { useEffect, useState } from 'react'; import { submitComponentEvent } from '../../client/ophan/ophan'; import type { ArticleCounts } from '../../lib/articleCount'; import { - getLastOneOffContributionDate, getPurchaseInfo, hasCmpConsentForBrowserId, hasOptedOutOfArticleCount, @@ -165,7 +164,6 @@ const buildPayload = async ({ : undefined, purchaseInfo: getPurchaseInfo(), isSignedIn, - lastOneOffContributionDate: getLastOneOffContributionDate(), hasConsented: userConsent, abandonedBasket: parseAbandonedBasket( getCookie({ name: 'GU_CO_INCOMPLETE', shouldMemoize: true }), diff --git a/dotcom-rendering/src/components/TopBarSupport.importable.tsx b/dotcom-rendering/src/components/TopBarSupport.importable.tsx index 625a33d04ca..871131f69e0 100644 --- a/dotcom-rendering/src/components/TopBarSupport.importable.tsx +++ b/dotcom-rendering/src/components/TopBarSupport.importable.tsx @@ -14,7 +14,6 @@ import type { import { useEffect, useState } from 'react'; import { submitComponentEvent } from '../client/ophan/ophan'; import { - getLastOneOffContributionDate, getPurchaseInfo, shouldHideSupportMessaging, } from '../lib/contributions'; @@ -81,7 +80,6 @@ const ReaderRevenueLinksRemote = ({ mvtId: Number( getCookie({ name: 'GU_mvt_id', shouldMemoize: true }), ), - lastOneOffContributionDate: getLastOneOffContributionDate(), purchaseInfo: getPurchaseInfo(), isSignedIn, }, diff --git a/dotcom-rendering/src/lib/contributions.test.ts b/dotcom-rendering/src/lib/contributions.test.ts index ee59149c44a..dcd998d15a8 100644 --- a/dotcom-rendering/src/lib/contributions.test.ts +++ b/dotcom-rendering/src/lib/contributions.test.ts @@ -6,7 +6,6 @@ import { HIDE_SUPPORT_MESSAGING_COOKIE, isRecentOneOffContributor, NO_RR_BANNER_KEY, - ONE_OFF_CONTRIBUTION_DATE_COOKIE, recentlyClosedBanner, setLocalNoBannerCachePeriod, SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, @@ -22,23 +21,10 @@ const clearAllCookies = () => { } }; -describe('getLastOneOffContributionDate', () => { +describe('getLastOneOffContributionTimestamp', () => { beforeEach(clearAllCookies); - it('returns date from attributes cookie if only cookie found', () => { - const somePastDate = '2020-01-28'; - setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: somePastDate, - }); - const lastOneOffContributionDate = getLastOneOffContributionTimestamp(); - - // Our function will convert YYYY-MM-DD into a timestamp - const somePastDateToTimestamp = Date.parse(somePastDate); - expect(lastOneOffContributionDate).toBe(somePastDateToTimestamp); - }); - - it('returns a support cookie date if only cookie found', () => { + it('returns a support cookie date if found', () => { const somePastDate = 1582567969093; setCookie({ name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, @@ -48,31 +34,10 @@ describe('getLastOneOffContributionDate', () => { expect(lastOneOffContributionDate).toBe(somePastDate); }); - it('returns the most recent date if both cookies present', () => { - const muchLongerAgo = '2020-01-28'; - setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: muchLongerAgo, - }); - - const notSoLongAgo = 1582567969093; + it('returns undefined if the date cannot be parsed correctly', () => { setCookie({ name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, - value: String(notSoLongAgo), - }); - - const lastOneOffContributionDate = getLastOneOffContributionTimestamp(); - expect(lastOneOffContributionDate).toBe(notSoLongAgo); - }); - - it('returns an empty string if no dates can be parsed correctly', () => { - setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: 'CANT_TOUCH_THIS', - }); - setCookie({ - name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, - value: 'OR_THIS', + value: 'NOT_A_DATE', }); const lastOneOffContributionDate = getLastOneOffContributionTimestamp(); @@ -97,8 +62,8 @@ describe('isRecentOneOffContributor', () => { it('returns true if there are 5 days between the last contribution date and now', () => { setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: '2018-08-01', + name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, + value: Date.parse('2018-08-01').toString(), }); MockDate.set(Date.parse('2018-08-07T10:50:34')); @@ -106,18 +71,19 @@ describe('isRecentOneOffContributor', () => { }); it('returns true if there are 0 days between the last contribution date and now', () => { + const theDate = Date.parse('2018-08-01T13:00:30'); setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: '2018-08-01', + name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, + value: theDate.toString(), }); - MockDate.set(Date.parse('2018-08-01T13:00:30')); + MockDate.set(theDate); expect(isRecentOneOffContributor()).toBe(true); }); it('returns false if the one-off contribution was more than 3 months ago', () => { setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: '2018-08-01', + name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, + value: Date.parse('2018-08-01').toString(), }); MockDate.set(Date.parse('2019-08-01T13:00:30')); expect(isRecentOneOffContributor()).toBe(false); diff --git a/dotcom-rendering/src/lib/contributions.ts b/dotcom-rendering/src/lib/contributions.ts index 71b3a8d9eaf..9729ce31fde 100644 --- a/dotcom-rendering/src/lib/contributions.ts +++ b/dotcom-rendering/src/lib/contributions.ts @@ -14,14 +14,13 @@ import type { DCRTagPageType } from '../types/tagPage'; // User Attributes API cookies (created on sign-in) export const HIDE_SUPPORT_MESSAGING_COOKIE = 'gu_hide_support_messaging'; export const RECURRING_CONTRIBUTOR_COOKIE = 'gu_recurring_contributor'; -export const ONE_OFF_CONTRIBUTION_DATE_COOKIE = 'gu_one_off_contribution_date'; export const OPT_OUT_OF_ARTICLE_COUNT_COOKIE = 'gu_article_count_opt_out'; // Support Frontend cookies (created when a contribution is made) export const SUPPORT_RECURRING_CONTRIBUTOR_MONTHLY_COOKIE = - 'gu.contributions.recurring.contrib-timestamp.Monthly'; + 'gu.contributions.recurring.contrib-timestamp.Monthly'; // TODO: delete this, no longer needed export const SUPPORT_RECURRING_CONTRIBUTOR_ANNUAL_COOKIE = - 'gu.contributions.recurring.contrib-timestamp.Annual'; + 'gu.contributions.recurring.contrib-timestamp.Annual'; // TODO: delete this, no longer needed export const SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE = 'gu.contributions.contrib-timestamp'; @@ -61,58 +60,26 @@ export const hasSupporterCookie = ( } }; -// looks at attribute and support cookies -// ONE_OFF_CONTRIBUTION_DATE_COOKIE (attributes cookie, when loggin in) -// SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE (support cookie, when making one-off contribution) -// Get the date of the latest one-off contribution by looking at the two relevant cookies -// and returning a Unix epoch string of the latest date found. +// looks at the SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE (set by support-frontend when making one-off contribution) +// and returns a Unix epoch int of the date if it exists. export const getLastOneOffContributionTimestamp = (): number | undefined => { - // Attributes cookie - expects YYYY-MM-DD - const contributionDateFromAttributes = getCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - }); - // Support cookies - expects Unix epoch const contributionDateFromSupport = getCookie({ name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, }); - if (!contributionDateFromAttributes && !contributionDateFromSupport) { + if (!contributionDateFromSupport) { return undefined; } - // Parse dates into common format so they can be compared - const parsedDateFromAttributes = contributionDateFromAttributes - ? Date.parse(contributionDateFromAttributes) - : 0; + // Parse dates into common a number const parsedDateFromSupport = contributionDateFromSupport ? parseInt(contributionDateFromSupport, 10) : 0; - // Return most recent date - // Condition only passed if 'parsedDateFromAttributes' is NOT NaN - if (parsedDateFromAttributes > parsedDateFromSupport) { - return parsedDateFromAttributes; - } - return parsedDateFromSupport || undefined; // This guards against 'parsedDateFromSupport' being NaN }; -export const getLastOneOffContributionDate = (): string | undefined => { - const timestamp = getLastOneOffContributionTimestamp(); - - if (isUndefined(timestamp)) { - return undefined; - } - - const date = new Date(timestamp); - const year = date.getFullYear(); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const day = date.getDate().toString().padStart(2, '0'); - - return `${year}-${month}-${day}`; -}; - const dateDiffDays = (from: number, to: number): number => { const oneDayMs = 1000 * 60 * 60 * 24; const diffMs = to - from; From 5d2f6a9cfb8447d694c216a9a9949784a820b315 Mon Sep 17 00:00:00 2001 From: Rupert Bates Date: Thu, 12 Dec 2024 11:08:09 +0000 Subject: [PATCH 4/4] Remove redundant cookies --- .../client/userFeatures/user-features.test.ts | 55 ------------------- .../src/client/userFeatures/user-features.ts | 24 -------- dotcom-rendering/src/lib/contributions.ts | 6 +- .../src/lib/readerRevenueDevUtils.ts | 4 -- 4 files changed, 1 insertion(+), 88 deletions(-) diff --git a/dotcom-rendering/src/client/userFeatures/user-features.test.ts b/dotcom-rendering/src/client/userFeatures/user-features.test.ts index e96a1fc0eec..a720abd3697 100644 --- a/dotcom-rendering/src/client/userFeatures/user-features.test.ts +++ b/dotcom-rendering/src/client/userFeatures/user-features.test.ts @@ -35,18 +35,11 @@ const getAuthStatus = getAuthStatus_ as jest.MockedFunction< const PERSISTENCE_KEYS = { USER_FEATURES_EXPIRY_COOKIE: 'gu_user_features_expiry', - PAYING_MEMBER_COOKIE: 'gu_paying_member', - RECURRING_CONTRIBUTOR_COOKIE: 'gu_recurring_contributor', AD_FREE_USER_COOKIE: 'GU_AF1', ACTION_REQUIRED_FOR_COOKIE: 'gu_action_required_for', DIGITAL_SUBSCRIBER_COOKIE: 'gu_digital_subscriber', SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE: 'gu.contributions.contrib-timestamp', - ONE_OFF_CONTRIBUTION_DATE_COOKIE: 'gu_one_off_contribution_date', HIDE_SUPPORT_MESSAGING_COOKIE: 'gu_hide_support_messaging', - SUPPORT_MONTHLY_CONTRIBUTION_COOKIE: - 'gu.contributions.recurring.contrib-timestamp.Monthly', - SUPPORT_ANNUAL_CONTRIBUTION_COOKIE: - 'gu.contributions.recurring.contrib-timestamp.Annual', }; const setAllFeaturesData = (opts: { isExpired: boolean }) => { @@ -58,11 +51,6 @@ const setAllFeaturesData = (opts: { isExpired: boolean }) => { const adFreeExpiryDate = opts.isExpired ? new Date(currentTime - msInOneDay * 2) : new Date(currentTime + msInOneDay * 2); - setCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE, value: 'true' }); - setCookie({ - name: PERSISTENCE_KEYS.RECURRING_CONTRIBUTOR_COOKIE, - value: 'true', - }); setCookie({ name: PERSISTENCE_KEYS.DIGITAL_SUBSCRIBER_COOKIE, value: 'true', @@ -86,8 +74,6 @@ const setAllFeaturesData = (opts: { isExpired: boolean }) => { }; const deleteAllFeaturesData = () => { - removeCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE }); - removeCookie({ name: PERSISTENCE_KEYS.RECURRING_CONTRIBUTOR_COOKIE }); removeCookie({ name: PERSISTENCE_KEYS.DIGITAL_SUBSCRIBER_COOKIE }); removeCookie({ name: PERSISTENCE_KEYS.USER_FEATURES_EXPIRY_COOKIE }); removeCookie({ name: PERSISTENCE_KEYS.AD_FREE_USER_COOKIE }); @@ -125,14 +111,6 @@ describe('Refreshing the features data', () => { it('Does not delete the data just because it has expired', async () => { setAllFeaturesData({ isExpired: true }); await refresh(); - expect( - getCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE }), - ).toBe('true'); - expect( - getCookie({ - name: PERSISTENCE_KEYS.RECURRING_CONTRIBUTOR_COOKIE, - }), - ).toBe('true'); expect( getCookie({ name: PERSISTENCE_KEYS.USER_FEATURES_EXPIRY_COOKIE, @@ -148,15 +126,6 @@ describe('Refreshing the features data', () => { await refresh(); expect(fetchJsonSpy).not.toHaveBeenCalled(); }); - - it('Performs an update if membership-frontend wipes just the paying-member cookie', async () => { - // Set everything except paying-member cookie - setAllFeaturesData({ isExpired: true }); - removeCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE }); - - await refresh(); - expect(fetchJsonSpy).toHaveBeenCalledTimes(1); - }); }); }); describe('If user signed out', () => { @@ -178,14 +147,6 @@ describe('If user signed out', () => { expect( getCookie({ name: PERSISTENCE_KEYS.AD_FREE_USER_COOKIE }), ).toBeNull(); - expect( - getCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE }), - ).toBeNull(); - expect( - getCookie({ - name: PERSISTENCE_KEYS.RECURRING_CONTRIBUTOR_COOKIE, - }), - ).toBeNull(); expect( getCookie({ name: PERSISTENCE_KEYS.DIGITAL_SUBSCRIBER_COOKIE }), ).toBeNull(); @@ -270,14 +231,6 @@ describe('Storing new feature data', () => { }), ); return refresh().then(() => { - expect( - getCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE }), - ).toBe('false'); - expect( - getCookie({ - name: PERSISTENCE_KEYS.RECURRING_CONTRIBUTOR_COOKIE, - }), - ).toBe('false'); expect( getCookie({ name: PERSISTENCE_KEYS.DIGITAL_SUBSCRIBER_COOKIE }), ).toBe('false'); @@ -300,14 +253,6 @@ describe('Storing new feature data', () => { }), ); return refresh().then(() => { - expect( - getCookie({ name: PERSISTENCE_KEYS.PAYING_MEMBER_COOKIE }), - ).toBe('true'); - expect( - getCookie({ - name: PERSISTENCE_KEYS.RECURRING_CONTRIBUTOR_COOKIE, - }), - ).toBe('true'); expect( getCookie({ name: PERSISTENCE_KEYS.DIGITAL_SUBSCRIBER_COOKIE }), ).toBe('true'); diff --git a/dotcom-rendering/src/client/userFeatures/user-features.ts b/dotcom-rendering/src/client/userFeatures/user-features.ts index 6229e1ef83f..333c9a2424f 100644 --- a/dotcom-rendering/src/client/userFeatures/user-features.ts +++ b/dotcom-rendering/src/client/userFeatures/user-features.ts @@ -27,15 +27,11 @@ import { import type { UserFeaturesResponse } from './user-features-lib'; const USER_FEATURES_EXPIRY_COOKIE = 'gu_user_features_expiry'; -const PAYING_MEMBER_COOKIE = 'gu_paying_member'; const ACTION_REQUIRED_FOR_COOKIE = 'gu_action_required_for'; const DIGITAL_SUBSCRIBER_COOKIE = 'gu_digital_subscriber'; const HIDE_SUPPORT_MESSAGING_COOKIE = 'gu_hide_support_messaging'; const AD_FREE_USER_COOKIE = 'GU_AF1'; -const RECURRING_CONTRIBUTOR_COOKIE = 'gu_recurring_contributor'; -const ONE_OFF_CONTRIBUTION_DATE_COOKIE = 'gu_one_off_contribution_date'; - const forcedAdFreeMode = !!/[#&]noadsaf(&.*)?$/.exec(window.location.hash); const userHasData = () => { @@ -43,9 +39,6 @@ const userHasData = () => { getAdFreeCookie() ?? getCookie({ name: ACTION_REQUIRED_FOR_COOKIE }) ?? getCookie({ name: USER_FEATURES_EXPIRY_COOKIE }) ?? - getCookie({ name: PAYING_MEMBER_COOKIE }) ?? - getCookie({ name: RECURRING_CONTRIBUTOR_COOKIE }) ?? - getCookie({ name: ONE_OFF_CONTRIBUTION_DATE_COOKIE }) ?? getCookie({ name: DIGITAL_SUBSCRIBER_COOKIE }) ?? getCookie({ name: HIDE_SUPPORT_MESSAGING_COOKIE }); return !!cookie; @@ -69,14 +62,6 @@ const persistResponse = (JsonResponse: UserFeaturesResponse) => { name: USER_FEATURES_EXPIRY_COOKIE, value: timeInDaysFromNow(1), }); - setCookie({ - name: PAYING_MEMBER_COOKIE, - value: String(JsonResponse.contentAccess.paidMember), - }); - setCookie({ - name: RECURRING_CONTRIBUTOR_COOKIE, - value: String(JsonResponse.contentAccess.recurringContributor), - }); setCookie({ name: DIGITAL_SUBSCRIBER_COOKIE, value: String(JsonResponse.contentAccess.digitalPack), @@ -85,12 +70,6 @@ const persistResponse = (JsonResponse: UserFeaturesResponse) => { name: HIDE_SUPPORT_MESSAGING_COOKIE, value: String(!JsonResponse.showSupportMessaging), }); - if (JsonResponse.oneOffContributionDate) { - setCookie({ - name: ONE_OFF_CONTRIBUTION_DATE_COOKIE, - value: JsonResponse.oneOffContributionDate, - }); - } removeCookie({ name: ACTION_REQUIRED_FOR_COOKIE }); if (JsonResponse.alertAvailableFor) { @@ -110,12 +89,9 @@ const persistResponse = (JsonResponse: UserFeaturesResponse) => { const deleteOldData = (): void => { removeCookie({ name: AD_FREE_USER_COOKIE }); removeCookie({ name: USER_FEATURES_EXPIRY_COOKIE }); - removeCookie({ name: PAYING_MEMBER_COOKIE }); - removeCookie({ name: RECURRING_CONTRIBUTOR_COOKIE }); removeCookie({ name: ACTION_REQUIRED_FOR_COOKIE }); removeCookie({ name: DIGITAL_SUBSCRIBER_COOKIE }); removeCookie({ name: HIDE_SUPPORT_MESSAGING_COOKIE }); - removeCookie({ name: ONE_OFF_CONTRIBUTION_DATE_COOKIE }); }; const requestNewData = () => { diff --git a/dotcom-rendering/src/lib/contributions.ts b/dotcom-rendering/src/lib/contributions.ts index 9729ce31fde..59c03659964 100644 --- a/dotcom-rendering/src/lib/contributions.ts +++ b/dotcom-rendering/src/lib/contributions.ts @@ -16,11 +16,7 @@ export const HIDE_SUPPORT_MESSAGING_COOKIE = 'gu_hide_support_messaging'; export const RECURRING_CONTRIBUTOR_COOKIE = 'gu_recurring_contributor'; export const OPT_OUT_OF_ARTICLE_COUNT_COOKIE = 'gu_article_count_opt_out'; -// Support Frontend cookies (created when a contribution is made) -export const SUPPORT_RECURRING_CONTRIBUTOR_MONTHLY_COOKIE = - 'gu.contributions.recurring.contrib-timestamp.Monthly'; // TODO: delete this, no longer needed -export const SUPPORT_RECURRING_CONTRIBUTOR_ANNUAL_COOKIE = - 'gu.contributions.recurring.contrib-timestamp.Annual'; // TODO: delete this, no longer needed +// Support Frontend cookie (created when a contribution is made) export const SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE = 'gu.contributions.contrib-timestamp'; diff --git a/dotcom-rendering/src/lib/readerRevenueDevUtils.ts b/dotcom-rendering/src/lib/readerRevenueDevUtils.ts index 082407e1177..53f2975ab72 100644 --- a/dotcom-rendering/src/lib/readerRevenueDevUtils.ts +++ b/dotcom-rendering/src/lib/readerRevenueDevUtils.ts @@ -3,16 +3,12 @@ import { HIDE_SUPPORT_MESSAGING_COOKIE, RECURRING_CONTRIBUTOR_COOKIE, SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, - SUPPORT_RECURRING_CONTRIBUTOR_ANNUAL_COOKIE, - SUPPORT_RECURRING_CONTRIBUTOR_MONTHLY_COOKIE, } from './contributions'; import { getLocaleCode } from './getCountryCode'; const readerRevenueCookies = [ HIDE_SUPPORT_MESSAGING_COOKIE, RECURRING_CONTRIBUTOR_COOKIE, - SUPPORT_RECURRING_CONTRIBUTOR_MONTHLY_COOKIE, - SUPPORT_RECURRING_CONTRIBUTOR_ANNUAL_COOKIE, SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE, ];