woocommerce/plugins/woocommerce-admin/client/header/test/index.js

132 lines
3.6 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import { render, fireEvent } from '@testing-library/react';
/**
* Internal dependencies
*/
import { Header, getPageTitle } from '../index.js';
jest.mock( '@woocommerce/settings', () => ( {
...jest.requireActual( '@woocommerce/settings' ),
getSetting() {
return 'Fake Site Title';
},
} ) );
jest.mock( '@woocommerce/tracks', () => ( {
...jest.requireActual( '@woocommerce/tracks' ),
recordEvent: jest.fn(),
} ) );
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
jest.mock( '@woocommerce/data', () => ( {
...jest.requireActual( '@woocommerce/data' ),
useUserPreferences: () => ( {
updateUserPreferences: () => {},
// mock to disable the mobile app banner while testing this component
android_app_banner_dismissed: 'yes',
} ),
} ) );
jest.mock( '@wordpress/data', () => {
// Require the original module to not be mocked...
const originalModule = jest.requireActual( '@wordpress/data' );
return {
__esModule: true, // Use it when dealing with esModules
...originalModule,
useSelect: jest.fn().mockReturnValue( {
menuItems: [],
} ),
};
} );
global.window.wcNavigation = {};
const encodedBreadcrumb = [
[ 'admin.php?page=wc-settings', 'Settings' ],
'Accounts & Privacy',
];
describe( 'Header', () => {
beforeEach( () => {
// Mock RAF to be synchronous for testing
jest.spyOn( window, 'requestAnimationFrame' ).mockImplementation(
( cb ) => {
cb();
}
);
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
// Mock user preferences to avoid testing the MobileAppBanner here
// Disable the ActivityPanel so it isn't tested here
window.wcAdminFeatures[ 'activity-panels' ] = false;
} );
afterEach( () => {
window.requestAnimationFrame.mockRestore();
} );
it( 'should render decoded breadcrumb name', () => {
const { queryByText } = render(
<Header sections={ encodedBreadcrumb } isEmbedded={ true } />
);
expect( queryByText( 'Accounts &amp; Privacy' ) ).toBe( null );
expect( queryByText( 'Accounts & Privacy' ) ).not.toBe( null );
} );
it( 'should only have the is-scrolled class if the page is scrolled', () => {
const { container } = render(
<Header sections={ encodedBreadcrumb } isEmbedded={ false } />
);
const topLevelElement = container.firstChild;
expect( Object.values( topLevelElement.classList ) ).not.toContain(
'is-scrolled'
);
Object.defineProperty( window, 'pageYOffset', {
value: 200,
writable: false,
} );
fireEvent.scroll( window, { target: { scrollY: 200 } } );
expect( Object.values( topLevelElement.classList ) ).toContain(
'is-scrolled'
);
} );
it( 'correctly updates the document title to reflect the navigation state', () => {
render(
<Header sections={ encodedBreadcrumb } isEmbedded={ false } />
);
expect( document.title ).toBe(
'Accounts & Privacy Settings Fake Site Title — WooCommerce'
);
} );
} );
describe( 'getPageTitle', () => {
test( 'should get page title as the last item if section length is less than 3', () => {
const sections = [ 'Payments' ];
expect( getPageTitle( sections ) ).toBe( 'Payments' );
} );
test( "should get page title as the second item's second element if section length is 3 or more and second item has a second element", () => {
const sections = [
[ 'admin.php?page=wc-admin', 'WooCommerce' ],
[ 'admin.php?page=wc-settings', 'Settings' ],
'Payments',
];
expect( getPageTitle( sections ) ).toBe( 'Settings' );
} );
test( "should get page title as the last item if section length is 3 or more but second item doesn't have a second element", () => {
const sections = [
[ 'admin.php?page=wc-admin', 'WooCommerce' ],
'Payments',
];
expect( getPageTitle( sections ) ).toBe( 'Payments' );
} );
} );