Skip to content

Commit

Permalink
We don't need one-time cookie to work out whether to hide support mes…
Browse files Browse the repository at this point in the history
…saging
  • Loading branch information
rupertbates committed Dec 19, 2024
1 parent b834ecf commit ed87b45
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 146 deletions.
2 changes: 0 additions & 2 deletions dotcom-rendering/src/client/userFeatures/user-features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ const validateResponse = (
isObject(response) &&
isBoolean(response.showSupportMessaging) &&
isObject(response.contentAccess) &&
isBoolean(response.contentAccess.paidMember) &&
isBoolean(response.contentAccess.recurringContributor) &&
isBoolean(response.contentAccess.digitalPack)
);
};
Expand Down
85 changes: 6 additions & 79 deletions dotcom-rendering/src/lib/contributions.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { setCookie, storage } from '@guardian/libs';
import MockDate from 'mockdate';
import {
getLastOneOffContributionTimestamp,
hasSupporterCookie,
HIDE_SUPPORT_MESSAGING_COOKIE,
isRecentOneOffContributor,
NO_RR_BANNER_KEY,
recentlyClosedBanner,
setLocalNoBannerCachePeriod,
SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE,
shouldHideSupportMessaging,
withinLocalNoBannerCachePeriod,
} from './contributions';

Expand All @@ -21,75 +17,6 @@ const clearAllCookies = () => {
}
};

describe('getLastOneOffContributionTimestamp', () => {
beforeEach(clearAllCookies);

it('returns a support cookie date if found', () => {
const somePastDate = 1582567969093;
setCookie({
name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE,
value: String(somePastDate),
});
const lastOneOffContributionDate = getLastOneOffContributionTimestamp();
expect(lastOneOffContributionDate).toBe(somePastDate);
});

it('returns undefined if the date cannot be parsed correctly', () => {
setCookie({
name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE,
value: 'NOT_A_DATE',
});

const lastOneOffContributionDate = getLastOneOffContributionTimestamp();
expect(lastOneOffContributionDate).toBeUndefined();
});

it('returns an empty string if no one-off contribution found', () => {
const lastOneOffContributionDate = getLastOneOffContributionTimestamp();
expect(lastOneOffContributionDate).toBeUndefined();
});
});

describe('isRecentOneOffContributor', () => {
beforeEach(clearAllCookies);
afterEach(() => {
MockDate.reset();
});

it('returns false if there is no one-off contribution cookie', () => {
expect(isRecentOneOffContributor()).toBe(false);
});

it('returns true if there are 5 days between the last contribution date and now', () => {
setCookie({
name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE,
value: Date.parse('2018-08-01').toString(),
});

MockDate.set(Date.parse('2018-08-07T10:50:34'));
expect(isRecentOneOffContributor()).toBe(true);
});

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: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE,
value: theDate.toString(),
});
MockDate.set(theDate);
expect(isRecentOneOffContributor()).toBe(true);
});

it('returns false if the one-off contribution was more than 3 months ago', () => {
setCookie({
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);
});
});

describe('getPurchaseInfo', () => {
let getPurchaseInfo: () => any;

Expand Down Expand Up @@ -176,30 +103,30 @@ describe('withinLocalNoBannerCachePeriod', () => {
});
});

describe('hasSupporterCookie', () => {
describe('shouldHideSupportMessaging', () => {
beforeEach(clearAllCookies);

it('returns false if cookie exists and is set to false', () => {
setCookie({
name: HIDE_SUPPORT_MESSAGING_COOKIE,
value: 'false',
});
expect(hasSupporterCookie(true)).toEqual(false);
expect(shouldHideSupportMessaging(true)).toEqual(false);
});

it('returns true if cookie exists and is set to true', () => {
setCookie({
name: HIDE_SUPPORT_MESSAGING_COOKIE,
value: 'true',
});
expect(hasSupporterCookie(true)).toEqual(true);
expect(shouldHideSupportMessaging(true)).toEqual(true);
});

it('returns false if cookie does not exist and user is signed out', () => {
expect(hasSupporterCookie(false)).toEqual(false);
expect(shouldHideSupportMessaging(false)).toEqual(false);
});

it('returns Pending if cookie does not exist and user is signed in', () => {
expect(hasSupporterCookie(true)).toEqual('Pending');
expect(shouldHideSupportMessaging(true)).toEqual('Pending');
});
});
68 changes: 3 additions & 65 deletions dotcom-rendering/src/lib/contributions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
getCookie,
isUndefined,
onConsentChange,
storage,
} from '@guardian/libs';
import { getCookie, onConsentChange, storage } from '@guardian/libs';
import type { HeaderPayload } from '@guardian/support-dotcom-components/dist/dotcom/types';
import { useEffect, useState } from 'react';
import type { ArticleDeprecated } from '../types/article';
Expand All @@ -16,10 +11,6 @@ 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 cookie (created when a contribution is made)
export const SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE =
'gu.contributions.contrib-timestamp';

// Local storage keys
const WEEKLY_ARTICLE_COUNT_KEY = 'gu.history.weeklyArticleCount';
export const NO_RR_BANNER_KEY = 'gu.noRRBanner';
Expand All @@ -28,12 +19,8 @@ export const NO_RR_BANNER_KEY = 'gu.noRRBanner';
export const MODULES_VERSION = 'v3';

// Returns true if we should hide support messaging because the user is a supporter.
// Checks the cookie that is set by the User Attributes API upon signing in.
// Value computed server-side and looks at all of the user's active products,
// including but not limited to recurring & one-off contributions,
// paper & digital subscriptions, as well as user tiers (GU supporters/staff/partners/patrons).
// https://github.com/guardian/members-data-api/blob/3a72dc00b9389968d91e5930686aaf34d8040c52/membership-attribute-service/app/models/Attributes.scala
export const hasSupporterCookie = (
// Checks the cookie that is set by support-frontend on checkout and the User Attributes API upon signing in.
export const shouldHideSupportMessaging = (
isSignedIn: boolean,
): boolean | 'Pending' => {
const cookie = getCookie({ name: HIDE_SUPPORT_MESSAGING_COOKIE });
Expand All @@ -56,55 +43,6 @@ export const hasSupporterCookie = (
}
};

// 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 => {
// Support cookies - expects Unix epoch
const contributionDateFromSupport = getCookie({
name: SUPPORT_ONE_OFF_CONTRIBUTION_COOKIE,
});

if (!contributionDateFromSupport) {
return undefined;
}

// Parse dates into common a number
const parsedDateFromSupport = contributionDateFromSupport
? parseInt(contributionDateFromSupport, 10)
: 0;

return parsedDateFromSupport || undefined; // This guards against 'parsedDateFromSupport' being NaN
};

const dateDiffDays = (from: number, to: number): number => {
const oneDayMs = 1000 * 60 * 60 * 24;
const diffMs = to - from;
return Math.floor(diffMs / oneDayMs);
};

const AskPauseDays = 90;

export const isRecentOneOffContributor = (): boolean => {
const lastContributionDate = getLastOneOffContributionTimestamp();
if (!isUndefined(lastContributionDate)) {
const now = Date.now();
return dateDiffDays(lastContributionDate, now) <= AskPauseDays;
}

return false;
};

export const shouldHideSupportMessaging = (
isSignedIn: boolean,
): boolean | 'Pending' => {
const hasCookie = hasSupporterCookie(isSignedIn);
if (hasCookie === 'Pending') {
return 'Pending';
} else {
return hasCookie || isRecentOneOffContributor();
}
};

export const REQUIRED_CONSENTS_FOR_ARTICLE_COUNT = [1, 3, 7];
const REQUIRED_CONSENTS_FOR_BROWSER_ID = [1, 3, 5, 7];

Expand Down

0 comments on commit ed87b45

Please sign in to comment.