Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import useViewOnly from '@/js/hooks/useViewOnly';
import PermissionsErrorNotice from '@/js/components/email-reporting/notices/errors/PermissionsErrorNotice';
import ReportErrorNotice from '@/js/components/email-reporting/notices/errors/ReportErrorNotice';
import SendingErrorNotice from '@/js/components/email-reporting/notices/errors/SendingErrorNotice';
import CronSchedulerErrorNotice from '@/js/components/email-reporting/notices/errors/CronSchedulerErrorNotice';
import ServerErrorNotice from '@/js/components/email-reporting/notices/errors/ServerErrorNotice';

export default function EmailReportingErrorNotices() {
Expand Down Expand Up @@ -66,6 +67,8 @@ export default function EmailReportingErrorNotices() {
);
case 'sending_error':
return <SendingErrorNotice />;
case 'cron_scheduler_error':
return <CronSchedulerErrorNotice />;
default:
return <ServerErrorNotice />;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,39 @@ describe( 'EmailReportingErrorNotices', () => {
).toBeInTheDocument();
} );

it( 'should render the cron scheduler error notice when there is a cron_scheduler_error category ID', () => {
registry.dispatch( CORE_SITE ).receiveGetEmailReportingSettings( {
enabled: true,
} );
registry.dispatch( CORE_SITE ).receiveGetEmailReportingErrors( {
errors: {
cron_scheduler_error: [ 'Cron issue.' ],
},
error_data: {
cron_scheduler_error: {
category_id: 'cron_scheduler_error',
},
},
} );

const { container, getByText } = render(
<EmailReportingErrorNotices />,
{
registry,
}
);

expect( container ).not.toBeEmptyDOMElement();
expect(
getByText( 'Email reports are failing to send' )
).toBeInTheDocument();
expect(
getByText(
'We were unable to deliver your report, likely due to a WP-Cron configuration error in your WordPress site’s system settings. To fix this, contact your administrator or get help. Report delivery will automatically resume once the issue is resolved.'
)
).toBeInTheDocument();
} );

it( 'should not render when email reporting is not enabled', () => {
registry.dispatch( CORE_SITE ).receiveGetEmailReportingSettings( {
enabled: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* CronSchedulerErrorNotice component.
*
* Site Kit by Google, Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import Notice from '@/js/components/Notice';
import { TYPES } from '@/js/components/Notice/constants';
import useNotificationEvents from '@/js/googlesitekit/notifications/hooks/useNotificationEvents';
import withIntersectionObserver from '@/js/util/withIntersectionObserver';

export const EMAIL_REPORTING_CRON_SCHEDULER_ERROR_NOTICE =
'email_reporting_cron_scheduler_error_notice';

const NoticeWithIntersectionObserver = withIntersectionObserver( Notice );

export default function CronSchedulerErrorNotice() {
const trackEvents = useNotificationEvents(
EMAIL_REPORTING_CRON_SCHEDULER_ERROR_NOTICE
);

return (
<NoticeWithIntersectionObserver
className="googlesitekit-email-reporting__admin-settings-notice"
type={ TYPES.ERROR }
title={ __(
'Email reports are failing to send',
'google-site-kit'
) }
description={ __(
'We were unable to deliver your report, likely due to a WP-Cron configuration error in your WordPress site’s system settings. To fix this, contact your administrator or get help. Report delivery will automatically resume once the issue is resolved.',
'google-site-kit'
) }
onInView={ trackEvents.view }
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* CronSchedulerErrorNotice component tests.
*
* Site Kit by Google, Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Internal dependencies
*/
import CronSchedulerErrorNotice from './CronSchedulerErrorNotice';
import { render } from '../../../../../../tests/js/test-utils';

describe( 'CronSchedulerErrorNotice', () => {
it( 'renders expected title and description', () => {
const { getByText } = render( <CronSchedulerErrorNotice /> );

expect(
getByText( 'Email reports are failing to send' )
).toBeInTheDocument();
expect(
getByText(
'We were unable to deliver your report, likely due to a WP-Cron configuration error in your WordPress site’s system settings. To fix this, contact your administrator or get help. Report delivery will automatically resume once the issue is resolved.'
)
).toBeInTheDocument();
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@

// Ensure every notice after the first notice has a margin
// so the notices don't render with no gap.
//
// See: https://github.com/google/site-kit-wp/issues/12279
.googlesitekit-notice-container:nth-of-type(n + 2) {
margin-top: $grid-gap-phone;
Expand Down
10 changes: 7 additions & 3 deletions includes/Core/Email_Reporting/Content_Map.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,10 @@ function ( $paragraph ) use ( $args ) {
protected static function get_all_titles() {
return array(
/* translators: 1: opening anchor tag with mailto link, 2: inviter email address, 3: closing anchor tag */
'invitation-email' => __( '%1$s%2$s%3$s invited you to receive periodic performance reports', 'google-site-kit' ),
'subscription-confirmation' => __( 'Success! You’re subscribed to Site Kit reports', 'google-site-kit' ),
'error-email' => __( 'Action needed: your Site Kit report couldn’t be generated', 'google-site-kit' ),
'invitation-email' => __( '%1$s%2$s%3$s invited you to receive periodic performance reports', 'google-site-kit' ),
'subscription-confirmation' => __( 'Success! You’re subscribed to Site Kit reports', 'google-site-kit' ),
'error-email' => __( 'Action needed: your Site Kit report couldn’t be generated', 'google-site-kit' ),
'error-email-cron-scheduler' => __( 'Email reports are failing to send', 'google-site-kit' ),
);
}

Expand All @@ -135,6 +136,9 @@ protected static function get_all_bodies() {
'error-email' => array(
__( 'We were unable to generate your report due to a server error. To fix this, contact your host. Report delivery will automatically resume once the issue is resolved.', 'google-site-kit' ),
),
'error-email-cron-scheduler' => array(
__( 'We were unable to deliver your report, likely due to a WP-Cron configuration error in your WordPress site’s system settings. To fix this, contact your administrator or get help. Report delivery will automatically resume once the issue is resolved.', 'google-site-kit' ),
),
// Opening/closing tag placeholders keep inline styles and HTML
// out of translation strings. Inline color styles are required
// because many email clients strip or ignore CSS classes.
Expand Down
Loading
Loading