diff --git a/_inc/client/components/jetpack-notices/index.jsx b/_inc/client/components/jetpack-notices/index.jsx
index bed0e3bef0ec..7b97a1017683 100644
--- a/_inc/client/components/jetpack-notices/index.jsx
+++ b/_inc/client/components/jetpack-notices/index.jsx
@@ -25,6 +25,7 @@ import { isDevVersion, userCanConnectSite, userIsSubscriber } from 'state/initia
import DismissableNotices from './dismissable';
import JetpackBanner from 'components/jetpack-banner';
import { JETPACK_CONTACT_BETA_SUPPORT } from 'constants/urls';
+import PlanConflictWarning from './plan-conflict-warning';
export class DevVersionNotice extends React.Component {
static displayName = 'DevVersionNotice';
@@ -199,6 +200,7 @@ class JetpackNotices extends React.Component {
isStaging={ this.props.isStaging }
isInIdentityCrisis={ this.props.isInIdentityCrisis }
/>
+
( {
+ ...props,
+ product_slug: product_slug.replace( '_monthly', '' ),
+ } ) );
+
+ // Gets the current backup, if any.
+ const backupPurchase = activeSitePurchasesTrimmed.find( ( { product_slug } ) =>
+ product_slug.includes( 'backup' )
+ );
+ if ( ! backupPurchase ) {
+ return null;
+ }
+
+ // Get the site plan purchase.
+ const sitePlanPurchase = activeSitePurchasesTrimmed.find(
+ ( { product_slug } ) =>
+ 'jetpack_personal' === product_slug ||
+ 'jetpack_premium' === product_slug ||
+ 'jetpack_business' === product_slug
+ );
+ if ( ! sitePlanPurchase ) {
+ return null;
+ }
+
+ // If the user purchased real-time backups and doesn't have Professional plan, it's not a conflict.
+ if (
+ 'jetpack_backup_realtime' === backupPurchase.product_slug &&
+ 'jetpack_business' !== sitePlanPurchase.product_slug
+ ) {
+ return null;
+ }
+
+ let featureName = __( 'daily backups' );
+ if ( 'jetpack_business' === sitePlanPurchase.product_slug ) {
+ featureName = __( 'real-time backups' );
+ }
+
+ return (
+
+ );
+}
+
+const PlanConflictWarningWithRouter = withRouter( PlanConflictWarning );
+
+export default connect( state => ( {
+ activeSitePurchases: getActiveSitePurchases( state ),
+} ) )( PlanConflictWarningWithRouter );
diff --git a/_inc/client/components/jetpack-notices/test/component.js b/_inc/client/components/jetpack-notices/test/component.js
new file mode 100644
index 000000000000..a5ccb4344692
--- /dev/null
+++ b/_inc/client/components/jetpack-notices/test/component.js
@@ -0,0 +1,89 @@
+/**
+ * External dependencies
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import { expect } from 'chai';
+
+/**
+ * Internal dependencies
+ */
+import { PlanConflictWarning } from '../plan-conflict-warning';
+
+describe( 'PlanConflictWarning', () => {
+ const router = { location: { pathname: '/plans' } };
+
+ const personalPlan = {
+ product_slug: 'jetpack_personal',
+ product_name: 'Jetpack Personal',
+ };
+
+ const professionalPlan = {
+ product_slug: 'jetpack_business',
+ product_name: 'Jetpack Professional',
+ };
+
+ const dailyBackups = {
+ product_slug: 'jetpack_backup_daily',
+ product_name: 'Jetpack Backup (Daily)',
+ };
+
+ const realTimeBackups = {
+ product_slug: 'jetpack_backup_realtime',
+ product_name: 'Jetpack Backup (Real-time)',
+ };
+
+ it( 'should not render when not in correct path', () => {
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should not render when there are no purchases', () => {
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should not render when there is one purchase', () => {
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should not render when there is no backup purchase', () => {
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should not render when there is no site plan purchase', () => {
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should not render with both real-time backups and a non-professional plan', () => {
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should not render with both real-time monthly backups and a non-professional plan', () => {
+ const realTimeBackupsMontly = { product_slug: 'jetpack_backups_realtime_monthly', ...realTimeBackups };
+ const wrapper = shallow( );
+ expect( wrapper.isEmptyRender() ).to.equal( true );
+ } );
+
+ it( 'should show warning with both daily backups and a plan', () => {
+ const wrapper = shallow( );
+ expect( wrapper.prop( 'text' ) ).to.equal(
+ 'Your Jetpack Personal Plan includes daily backups. ' +
+ 'Looks like you also purchased the Jetpack Backup (Daily) product. ' +
+ 'Consider removing Jetpack Backup (Daily).'
+ );
+ } );
+
+ it( 'should show warning with both real-time backups and a Professional plan', () => {
+ const wrapper = shallow( );
+ expect( wrapper.prop( 'text' ) ).to.equal(
+ 'Your Jetpack Professional Plan includes real-time backups. ' +
+ 'Looks like you also purchased the Jetpack Backup (Real-time) product. ' +
+ 'Consider removing Jetpack Backup (Real-time).'
+ );
+ } );
+} );