{t('Comments')}
{t('Get notified when someone replies to your comment')}
diff --git a/apps/portal/src/components/pages/AccountEmailPage.js b/apps/portal/src/components/pages/AccountEmailPage.js
index b971c09440..ed31a676f4 100644
--- a/apps/portal/src/components/pages/AccountEmailPage.js
+++ b/apps/portal/src/components/pages/AccountEmailPage.js
@@ -9,7 +9,10 @@ export default function AccountEmailPage() {
useEffect(() => {
if (!member) {
onAction('switchPage', {
- page: 'signin'
+ page: 'signin',
+ pageData: {
+ redirect: window.location.href // This includes the search/fragment of the URL (#/portal/account) which is missing from the default referer header
+ }
});
}
}, [member, onAction]);
diff --git a/apps/portal/src/components/pages/AccountEmailPage.test.js b/apps/portal/src/components/pages/AccountEmailPage.test.js
new file mode 100644
index 0000000000..8bd6a2f082
--- /dev/null
+++ b/apps/portal/src/components/pages/AccountEmailPage.test.js
@@ -0,0 +1,117 @@
+import {getSiteData, getNewslettersData, getMemberData} from '../../utils/fixtures-generator';
+import {render, fireEvent} from '../../utils/test-utils';
+import AccountEmailPage from './AccountEmailPage';
+
+const setup = (overrides) => {
+ const {mockOnActionFn, context, ...utils} = render(
+
,
+ {
+ overrideContext: {
+ ...overrides
+ }
+ }
+ );
+ const unsubscribeAllBtn = utils.getByText('Unsubscribe from all emails');
+ const closeBtn = utils.getByTestId('close-popup');
+
+ return {
+ unsubscribeAllBtn,
+ closeBtn,
+ mockOnActionFn,
+ context,
+ ...utils
+ };
+};
+
+describe('Account Email Page', () => {
+ test('renders', () => {
+ const newsletterData = getNewslettersData({numOfNewsletters: 2});
+ const siteData = getSiteData({
+ newsletters: newsletterData,
+ member: getMemberData({newsletters: newsletterData})
+ });
+ const {unsubscribeAllBtn, getAllByTestId, getByText} = setup({site: siteData});
+ const unsubscribeBtns = getAllByTestId(`toggle-wrapper`);
+ expect(getByText('Email preferences')).toBeInTheDocument();
+ // one for each newsletter and one for comments
+ expect(unsubscribeBtns).toHaveLength(3);
+ expect(unsubscribeAllBtn).toBeInTheDocument();
+ });
+
+ test('can unsubscribe from all emails', async () => {
+ const newsletterData = getNewslettersData({numOfNewsletters: 2});
+ const siteData = getSiteData({
+ newsletters: newsletterData
+ });
+ const {mockOnActionFn, unsubscribeAllBtn, getAllByTestId} = setup({site: siteData, member: getMemberData({newsletters: newsletterData})});
+ let checkmarkContainers = getAllByTestId('checkmark-container');
+ // each newsletter should have the checked class (this is how we know they're enabled/subscribed to)
+ expect(checkmarkContainers[0]).toHaveClass('gh-portal-toggle-checked');
+ expect(checkmarkContainers[1]).toHaveClass('gh-portal-toggle-checked');
+
+ fireEvent.click(unsubscribeAllBtn);
+ expect(mockOnActionFn).toHaveBeenCalledTimes(2);
+ expect(mockOnActionFn).toHaveBeenCalledWith('showPopupNotification', {action: 'updated:success', message: 'Unsubscribed from all emails.'});
+ expect(mockOnActionFn).toHaveBeenLastCalledWith('updateNewsletterPreference', {newsletters: [], enableCommentNotifications: false});
+
+ checkmarkContainers = getAllByTestId('checkmark-container');
+ expect(checkmarkContainers).toHaveLength(3);
+ checkmarkContainers.forEach((newsletter) => {
+ // each newsletter htmlElement should not have the checked class
+ expect(newsletter).not.toHaveClass('gh-portal-toggle-checked');
+ });
+ });
+
+ test('unsubscribe all is disabled when no newsletters are subscribed to', async () => {
+ const siteData = getSiteData({
+ newsletters: getNewslettersData({numOfNewsletters: 2})
+ });
+ const {unsubscribeAllBtn} = setup({site: siteData, member: getMemberData()});
+ expect(unsubscribeAllBtn).toBeDisabled();
+ });
+
+ test('can update newsletter preferences', async () => {
+ const newsletterData = getNewslettersData({numOfNewsletters: 2});
+ const siteData = getSiteData({
+ newsletters: newsletterData
+ });
+ const {mockOnActionFn, getAllByTestId} = setup({site: siteData, member: getMemberData({newsletters: newsletterData})});
+ let checkmarkContainers = getAllByTestId('checkmark-container');
+ // each newsletter should have the checked class (this is how we know they're enabled/subscribed to)
+ expect(checkmarkContainers[0]).toHaveClass('gh-portal-toggle-checked');
+ let subscriptionToggles = getAllByTestId('switch-input');
+ fireEvent.click(subscriptionToggles[0]);
+ expect(mockOnActionFn).toHaveBeenCalledWith('updateNewsletterPreference', {newsletters: [{id: newsletterData[1].id}]});
+ fireEvent.click(subscriptionToggles[0]);
+ expect(mockOnActionFn).toHaveBeenCalledWith('updateNewsletterPreference', {newsletters: [{id: newsletterData[1].id}, {id: newsletterData[0].id}]});
+ });
+
+ test('can update comment notifications', async () => {
+ const siteData = getSiteData();
+ const {mockOnActionFn, getAllByTestId} = setup({site: siteData, member: getMemberData()});
+ let subscriptionToggles = getAllByTestId('switch-input');
+ fireEvent.click(subscriptionToggles[0]);
+ expect(mockOnActionFn).toHaveBeenCalledWith('updateNewsletterPreference', {enableCommentNotifications: true});
+ fireEvent.click(subscriptionToggles[0]);
+ expect(mockOnActionFn).toHaveBeenCalledWith('updateNewsletterPreference', {enableCommentNotifications: false});
+ });
+
+ test('displays help for members with email suppressions', async () => {
+ const newsletterData = getNewslettersData({numOfNewsletters: 2});
+ const siteData = getSiteData({
+ newsletters: newsletterData
+ });
+ const {getByText} = setup({site: siteData, member: getMemberData({newsletters: newsletterData, email_suppressions: {suppressed: false}})});
+ expect(getByText('Not receiving emails?')).toBeInTheDocument();
+ expect(getByText('Get help →')).toBeInTheDocument();
+ });
+
+ test('redirects to signin page if no member', async () => {
+ const newsletterData = getNewslettersData({numOfNewsletters: 2});
+ const siteData = getSiteData({
+ newsletters: newsletterData
+ });
+ const {mockOnActionFn} = setup({site: siteData, member: null});
+ expect(mockOnActionFn).toHaveBeenCalledWith('switchPage', {page: 'signin', pageData: {redirect: window.location.href}});
+ });
+});
diff --git a/apps/portal/src/components/pages/AccountHomePage/AccountHomePage.test.js b/apps/portal/src/components/pages/AccountHomePage/AccountHomePage.test.js
index 98ab7bebcd..6b4c6aa143 100644
--- a/apps/portal/src/components/pages/AccountHomePage/AccountHomePage.test.js
+++ b/apps/portal/src/components/pages/AccountHomePage/AccountHomePage.test.js
@@ -1,6 +1,7 @@
import {render, fireEvent} from '../../../utils/test-utils';
import AccountHomePage from './AccountHomePage';
import {site} from '../../../utils/fixtures';
+import {getSiteData} from '../../../utils/fixtures-generator';
const setup = (overrides) => {
const {mockOnActionFn, ...utils} = render(
@@ -21,7 +22,8 @@ const setup = (overrides) => {
describe('Account Home Page', () => {
test('renders', () => {
- const {logoutBtn, utils} = setup();
+ const siteData = getSiteData({commentsEnabled: 'off'});
+ const {logoutBtn, utils} = setup({site: siteData});
expect(logoutBtn).toBeInTheDocument();
expect(utils.queryByText('You\'re currently not receiving emails')).not.toBeInTheDocument();
expect(utils.queryByText('Email newsletter')).toBeInTheDocument();
@@ -46,4 +48,11 @@ describe('Account Home Page', () => {
fireEvent.click(manageBtn);
expect(mockOnActionFn).toHaveBeenCalledWith('switchPage', {lastPage: 'accountHome', page: 'accountEmail'});
});
+
+ test('hides Newsletter toggle if newsletters are disabled', () => {
+ const siteData = getSiteData({editorDefaultEmailRecipients: 'disabled'});
+ const {logoutBtn, utils} = setup({site: siteData});
+ expect(logoutBtn).toBeInTheDocument();
+ expect(utils.queryByText('Email newsletter')).not.toBeInTheDocument();
+ });
});
diff --git a/apps/portal/src/components/pages/AccountHomePage/components/AccountActions.js b/apps/portal/src/components/pages/AccountHomePage/components/AccountActions.js
index 6a0a03402f..f243f431ae 100644
--- a/apps/portal/src/components/pages/AccountHomePage/components/AccountActions.js
+++ b/apps/portal/src/components/pages/AccountHomePage/components/AccountActions.js
@@ -1,6 +1,6 @@
import AppContext from '../../../../AppContext';
import {useContext} from 'react';
-import {hasCommentsEnabled, hasMultipleNewsletters, isEmailSuppressed} from '../../../../utils/helpers';
+import {hasCommentsEnabled, hasMultipleNewsletters, isEmailSuppressed, hasNewsletterSendingEnabled} from '../../../../utils/helpers';
import PaidAccountActions from './PaidAccountActions';
import EmailNewsletterAction from './EmailNewsletterAction';
@@ -19,6 +19,8 @@ const AccountActions = () => {
const showEmailPreferences = hasMultipleNewsletters({site}) || hasCommentsEnabled({site}) || isEmailSuppressed({member});
+ const showEmailUnsubscribe = hasNewsletterSendingEnabled({site});
+
return (
@@ -40,7 +42,13 @@ const AccountActions = () => {
{
showEmailPreferences
?
- :
+ : <>>
+ }
+
+ {
+ showEmailUnsubscribe && !showEmailPreferences
+ ?
+ : <>>
}
diff --git a/apps/portal/src/components/pages/AccountHomePage/components/AccountWelcome.js b/apps/portal/src/components/pages/AccountHomePage/components/AccountWelcome.js
index 0669f49882..ea05241b5a 100644
--- a/apps/portal/src/components/pages/AccountHomePage/components/AccountWelcome.js
+++ b/apps/portal/src/components/pages/AccountHomePage/components/AccountWelcome.js
@@ -32,6 +32,10 @@ const AccountWelcome = () => {
return null;
}
+ if (isComplimentary) {
+ return null;
+ }
+
if (subscriptionHasFreeTrial({sub: subscription})) {
const trialEnd = getDateString(subscription.trial_end_at);
return (
diff --git a/apps/portal/src/components/pages/NewsletterSelectionPage.js b/apps/portal/src/components/pages/NewsletterSelectionPage.js
index 4707fa8bae..067c9aa2e5 100644
--- a/apps/portal/src/components/pages/NewsletterSelectionPage.js
+++ b/apps/portal/src/components/pages/NewsletterSelectionPage.js
@@ -11,7 +11,7 @@ function NewsletterPrefSection({newsletter, subscribedNewsletters, setSubscribed
});
if (newsletter.paid) {
return (
-
+
{newsletter.name}
{newsletter.description}
@@ -23,7 +23,7 @@ function NewsletterPrefSection({newsletter, subscribedNewsletters, setSubscribed
);
}
return (
-