2020-03-27 20:42:58 +00:00
/ * *
* External dependencies
* /
2021-07-14 20:38:57 +00:00
import { createElement , Fragment } from '@wordpress/element' ;
2020-08-20 04:59:52 +00:00
import { recordEvent } from '@woocommerce/tracks' ;
2020-10-15 12:41:39 +00:00
import { render , waitFor } from '@testing-library/react' ;
import userEvent from '@testing-library/user-event' ;
2020-08-20 04:59:52 +00:00
2020-03-27 20:42:58 +00:00
/ * *
* Internal dependencies
* /
import { acceptWcsTos , getWcsAssets } from '../../wcs-api.js' ;
2020-10-15 12:41:39 +00:00
import { ShippingBanner } from '../index.js' ;
2020-03-27 20:42:58 +00:00
2020-08-13 02:05:22 +00:00
jest . mock ( '../../wcs-api.js' ) ;
2020-03-27 20:42:58 +00:00
acceptWcsTos . mockReturnValue ( Promise . resolve ( ) ) ;
2020-08-20 04:59:52 +00:00
jest . mock ( '@woocommerce/tracks' ) ;
2020-03-27 20:42:58 +00:00
jest . mock ( '@woocommerce/wc-admin-settings' ) ;
2020-10-15 12:41:39 +00:00
const wcsPluginSlug = 'woocommerce-services' ;
2020-03-27 20:42:58 +00:00
describe ( 'Tracking impression in shippingBanner' , ( ) => {
const expectedTrackingData = {
banner _name : 'wcadmin_install_wcs_prompt' ,
jetpack _connected : true ,
jetpack _installed : true ,
wcs _installed : true ,
} ;
2020-10-15 12:41:39 +00:00
it ( 'should record an event when user sees banner loaded' , ( ) => {
render (
2020-03-27 20:42:58 +00:00
< ShippingBanner
isJetpackConnected = { true }
activePlugins = { [ wcsPluginSlug , 'jetpack' ] }
itemsCount = { 1 }
activatePlugins = { jest . fn ( ) }
2020-08-31 15:13:14 +00:00
installPlugins = { jest . fn ( ) }
2020-03-27 20:42:58 +00:00
isRequesting = { false }
/ >
) ;
expect ( recordEvent ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( recordEvent ) . toHaveBeenCalledWith (
'banner_impression' ,
expectedTrackingData
) ;
} ) ;
} ) ;
describe ( 'Tracking clicks in shippingBanner' , ( ) => {
2020-10-15 12:41:39 +00:00
const getExpectedTrackingData = ( element , wcsInstalled = true ) => {
2020-03-27 20:42:58 +00:00
return {
banner _name : 'wcadmin_install_wcs_prompt' ,
jetpack _connected : true ,
jetpack _installed : true ,
2020-10-15 12:41:39 +00:00
wcs _installed : wcsInstalled ,
2020-03-27 20:42:58 +00:00
element ,
} ;
} ;
2020-10-15 12:41:39 +00:00
it ( 'should record an event when user clicks "Create shipping label"' , async ( ) => {
const { getByRole } = render (
2020-03-27 20:42:58 +00:00
< ShippingBanner
2020-10-15 12:41:39 +00:00
isJetpackConnected = { true }
2020-03-27 20:42:58 +00:00
activePlugins = { [ wcsPluginSlug , 'jetpack' ] }
2020-08-31 15:13:14 +00:00
installPlugins = { jest . fn ( ) }
2020-03-27 20:42:58 +00:00
activatePlugins = { jest . fn ( ) }
isRequesting = { false }
itemsCount = { 1 }
/ >
) ;
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , { name : 'Create shipping label' } )
) ;
await waitFor ( ( ) =>
expect ( recordEvent ) . toHaveBeenCalledWith (
'banner_element_clicked' ,
getExpectedTrackingData ( 'shipping_banner_create_label' )
)
2020-03-27 20:42:58 +00:00
) ;
} ) ;
2020-10-15 12:41:39 +00:00
it ( 'should record an event when user clicks "WooCommerce Shipping"' , async ( ) => {
// Render the banner without WCS being active.
const { getByRole } = render (
< ShippingBanner
isJetpackConnected = { true }
activePlugins = { [ 'jetpack' ] }
installPlugins = { jest . fn ( ) }
activatePlugins = { jest . fn ( ) }
isRequesting = { false }
itemsCount = { 1 }
/ >
) ;
userEvent . click (
getByRole ( 'link' , { name : /WooCommerce Shipping/ } )
) ;
await waitFor ( ( ) =>
expect ( recordEvent ) . toHaveBeenCalledWith (
'banner_element_clicked' ,
getExpectedTrackingData (
'shipping_banner_woocommerce_service_link' ,
false
)
)
2020-03-27 20:42:58 +00:00
) ;
} ) ;
2020-10-15 12:41:39 +00:00
it ( 'should record an event when user clicks "x" to dismiss the banner' , async ( ) => {
const { getByRole } = render (
< ShippingBanner
isJetpackConnected = { true }
activePlugins = { [ wcsPluginSlug , 'jetpack' ] }
installPlugins = { jest . fn ( ) }
activatePlugins = { jest . fn ( ) }
isRequesting = { false }
itemsCount = { 1 }
/ >
2020-03-27 20:42:58 +00:00
) ;
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , { name : 'Close Print Label Banner.' } )
) ;
await waitFor ( ( ) =>
expect ( recordEvent ) . toHaveBeenCalledWith (
'banner_element_clicked' ,
getExpectedTrackingData ( 'shipping_banner_dimiss' )
)
2020-03-27 20:42:58 +00:00
) ;
} ) ;
} ) ;
describe ( 'Create shipping label button' , ( ) => {
2020-08-31 15:13:14 +00:00
const installPlugins = jest . fn ( ) . mockReturnValue ( {
success : true ,
2020-04-16 23:58:36 +00:00
} ) ;
const activatePlugins = jest . fn ( ) . mockReturnValue ( {
2020-08-31 15:13:14 +00:00
success : true ,
2020-04-16 23:58:36 +00:00
} ) ;
2020-03-27 20:42:58 +00:00
delete window . location ; // jsdom won't allow to rewrite window.location unless deleted first
window . location = {
href : 'http://wcship.test/wp-admin/post.php?post=1000&action=edit' ,
} ;
2020-10-15 12:41:39 +00:00
it ( 'should install WooCommerce Shipping when button is clicked' , async ( ) => {
const { getByRole } = render (
2020-03-27 20:42:58 +00:00
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { activatePlugins }
activePlugins = { [ ] }
2020-08-31 15:13:14 +00:00
installPlugins = { installPlugins }
2020-03-27 20:42:58 +00:00
isRequesting = { false }
itemsCount = { 1 }
/ >
) ;
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , {
name : 'Create shipping label' ,
} )
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
await waitFor ( ( ) =>
expect ( installPlugins ) . toHaveBeenCalledWith ( [
'woocommerce-services' ,
] )
) ;
2020-03-27 20:42:58 +00:00
} ) ;
2020-10-15 12:41:39 +00:00
it ( 'should activate WooCommerce Shipping when installation finishes' , async ( ) => {
const { getByRole } = render (
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { activatePlugins }
activePlugins = { [ ] }
installPlugins = { installPlugins }
isRequesting = { false }
itemsCount = { 1 }
/ >
) ;
userEvent . click (
getByRole ( 'button' , {
name : 'Create shipping label' ,
} )
) ;
2020-04-16 23:58:36 +00:00
2020-10-15 12:41:39 +00:00
await waitFor ( ( ) =>
expect ( activatePlugins ) . toHaveBeenCalledWith ( [
'woocommerce-services' ,
] )
) ;
2020-03-27 20:42:58 +00:00
} ) ;
it ( 'should perform a request to accept the TOS and get WCS assets to load' , async ( ) => {
2020-10-15 12:41:39 +00:00
getWcsAssets . mockReturnValueOnce ( Promise . resolve ( { } ) ) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
const { getByRole } = render (
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { activatePlugins }
activePlugins = { [ wcsPluginSlug ] }
installPlugins = { installPlugins }
isRequesting = { false }
itemsCount = { 1 }
/ >
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , {
name : 'Create shipping label' ,
} )
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
await waitFor ( ( ) => expect ( acceptWcsTos ) . toHaveBeenCalled ( ) ) ;
2020-03-27 20:42:58 +00:00
expect ( getWcsAssets ) . toHaveBeenCalled ( ) ;
} ) ;
2020-10-15 12:41:39 +00:00
it ( 'should load WCS assets when a path is provided' , async ( ) => {
const mockAssets = {
wc _connect _admin _script : '/path/to/wcs.js' ,
wc _connect _admin _style : '/path/to/wcs.css' ,
2020-03-27 20:42:58 +00:00
} ;
2020-10-15 12:41:39 +00:00
getWcsAssets . mockReturnValueOnce (
Promise . resolve ( {
assets : mockAssets ,
} )
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
const { getByRole } = render (
< Fragment >
< div id = "woocommerce-order-data" / >
< div id = "woocommerce-order-actions" / >
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { activatePlugins }
activePlugins = { [ wcsPluginSlug , 'jetpack' ] }
installPlugins = { installPlugins }
isRequesting = { false }
itemsCount = { 1 }
/ >
< / F r a g m e n t >
2020-07-30 01:51:15 +00:00
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , {
name : 'Create shipping label' ,
} )
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
// Check that the metaboxes have been created.
await waitFor ( ( ) =>
expect (
getByRole ( 'heading' , { level : 2 , name : 'Shipping Label' } )
) . toBeInTheDocument ( )
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
expect (
getByRole ( 'heading' , { level : 2 , name : 'Shipment Tracking' } )
) . toBeInTheDocument ( ) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
// Check that the script and style elements have been created.
expect ( document . getElementsByTagName ( 'script' ) [ 0 ] . src ) . toBe (
'http://localhost' + mockAssets . wc _connect _admin _script
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
expect ( document . getElementsByTagName ( 'link' ) [ 0 ] . href ) . toBe (
'http://localhost' + mockAssets . wc _connect _admin _style
) ;
2020-03-27 20:42:58 +00:00
} ) ;
2020-08-31 15:13:14 +00:00
it ( 'should open WCS modal' , async ( ) => {
window . wcsGetAppStoreAsync = jest . fn ( ) ;
2020-03-27 20:42:58 +00:00
const getState = jest . fn ( ) ;
const dispatch = jest . fn ( ) ;
const subscribe = jest . fn ( ) ;
2020-08-31 15:13:14 +00:00
window . wcsGetAppStoreAsync . mockReturnValueOnce (
Promise . resolve ( {
getState ,
dispatch ,
subscribe ,
} )
) ;
2020-03-27 20:42:58 +00:00
getState . mockReturnValueOnce ( {
ui : {
selectedSiteId : 'SITE_ID' ,
} ,
} ) ;
2020-10-15 12:41:39 +00:00
getWcsAssets . mockReturnValueOnce (
Promise . resolve ( {
assets : {
// Easy to identify string in our hijacked setter function.
wc _connect _admin _script : 'wc_connect_admin_script' ,
// Empty string to avoid creating a script tag we also have to hijack.
wc _connect _admin _style : '' ,
} ,
} )
) ;
// Force the script tag to trigger its onload().
// Adapted from https://stackoverflow.com/a/49204336.
// const scriptSrcProperty = window.HTMLScriptElement.prototype.src;
Object . defineProperty ( window . HTMLScriptElement . prototype , 'src' , {
set ( src ) {
if ( src === 'wc_connect_admin_script' ) {
setTimeout ( ( ) => this . onload ( ) ) ;
}
} ,
2020-03-27 20:42:58 +00:00
} ) ;
2020-10-15 12:41:39 +00:00
const { getByRole } = render (
< Fragment >
< div id = "woocommerce-order-data" / >
< div id = "woocommerce-order-actions" / >
< div id = "woocommerce-admin-print-label" / >
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { activatePlugins }
activePlugins = { [ wcsPluginSlug , 'jetpack' ] }
installPlugins = { installPlugins }
isRequesting = { false }
itemsCount = { 1 }
/ >
< / F r a g m e n t >
2020-03-27 20:42:58 +00:00
) ;
2020-10-15 12:41:39 +00:00
// Initiate the loading of WCS assets on first click.
userEvent . click (
getByRole ( 'button' , {
name : 'Create shipping label' ,
} )
) ;
await waitFor ( ( ) =>
expect ( window . wcsGetAppStoreAsync ) . toHaveBeenCalledWith (
'wc-connect-create-shipping-label'
)
2020-03-27 20:42:58 +00:00
) ;
2020-10-15 12:41:39 +00:00
await waitFor ( ( ) => expect ( getState ) . toHaveBeenCalledTimes ( 1 ) ) ;
await waitFor ( ( ) => expect ( subscribe ) . toHaveBeenCalledTimes ( 1 ) ) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
expect (
document . getElementById ( 'woocommerce-admin-print-label' )
) . not . toBeVisible ( ) ;
2020-03-27 20:42:58 +00:00
} ) ;
} ) ;
describe ( 'In the process of installing, activating, loading assets for WooCommerce Service' , ( ) => {
2020-10-15 12:41:39 +00:00
it ( 'should show a busy loading state on "Create shipping label" and should disable "Close Print Label Banner"' , async ( ) => {
const { getByRole } = render (
2020-03-27 20:42:58 +00:00
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { jest . fn ( ) }
2020-10-15 12:41:39 +00:00
activePlugins = { [ 'jetpack' ] }
2020-08-31 15:13:14 +00:00
installPlugins = { jest . fn ( ) }
2020-03-27 20:42:58 +00:00
isRequesting = { true }
itemsCount = { 1 }
/ >
) ;
2020-10-15 12:41:39 +00:00
expect (
getByRole ( 'button' , { name : 'Create shipping label' } )
) . not . toHaveClass ( 'is-busy' ) ;
expect (
getByRole ( 'button' , { name : 'Close Print Label Banner.' } )
) . toBeEnabled ( ) ;
userEvent . click (
getByRole ( 'button' , { name : 'Create shipping label' } )
) ;
await waitFor ( ( ) =>
expect (
getByRole ( 'button' , { name : 'Create shipping label' } )
) . toHaveClass ( 'is-busy' )
) ;
2020-03-27 20:42:58 +00:00
2020-10-15 12:41:39 +00:00
expect (
getByRole ( 'button' , { name : 'Close Print Label Banner.' } )
) . toBeDisabled ( ) ;
2020-03-27 20:42:58 +00:00
} ) ;
} ) ;
describe ( 'Setup error message' , ( ) => {
2020-10-15 12:41:39 +00:00
it ( 'should not show if there is no error (no interaction)' , ( ) => {
const { container } = render (
2020-03-27 20:42:58 +00:00
< ShippingBanner
isJetpackConnected = { true }
2020-10-15 12:41:39 +00:00
activatePlugins = { jest . fn ( ) }
2020-04-16 23:58:36 +00:00
activePlugins = { [ 'jetpack' ] }
2020-10-15 12:41:39 +00:00
installPlugins = { jest . fn ( ) }
2020-03-27 20:42:58 +00:00
itemsCount = { 1 }
isRequesting = { false }
/ >
) ;
2020-10-15 12:41:39 +00:00
expect (
container . getElementsByClassName (
'wc-admin-shipping-banner-install-error'
)
) . toHaveLength ( 0 ) ;
2020-03-27 20:42:58 +00:00
} ) ;
2020-04-16 23:58:36 +00:00
it ( 'should show if there is installation error' , async ( ) => {
2020-10-15 12:41:39 +00:00
const { getByRole , getByText } = render (
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { jest . fn ( ) }
activePlugins = { [ 'jetpack' ] }
installPlugins = { jest . fn ( ) . mockReturnValue ( {
success : false ,
} ) }
itemsCount = { 1 }
isRequesting = { false }
/ >
) ;
2020-04-16 23:58:36 +00:00
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , { name : 'Create shipping label' } )
) ;
await waitFor ( ( ) =>
expect (
getByText (
'Unable to install the plugin. Refresh the page and try again.'
)
) . toBeInTheDocument ( )
2020-03-27 20:42:58 +00:00
) ;
} ) ;
2020-04-16 23:58:36 +00:00
it ( 'should show if there is activation error' , async ( ) => {
2020-10-15 12:41:39 +00:00
const { getByRole , getByText } = render (
2020-04-16 23:58:36 +00:00
< ShippingBanner
isJetpackConnected = { true }
2020-10-15 12:41:39 +00:00
activatePlugins = { jest . fn ( ) . mockReturnValue ( {
success : false ,
} ) }
2020-04-16 23:58:36 +00:00
activePlugins = { [ 'jetpack' ] }
2020-08-31 15:13:14 +00:00
installPlugins = { jest . fn ( ) . mockReturnValue ( {
success : true ,
2020-04-16 23:58:36 +00:00
} ) }
itemsCount = { 1 }
isRequesting = { false }
/ >
2020-03-27 20:42:58 +00:00
) ;
2020-04-16 23:58:36 +00:00
2020-10-15 12:41:39 +00:00
userEvent . click (
getByRole ( 'button' , { name : 'Create shipping label' } )
) ;
2020-04-16 23:58:36 +00:00
2020-10-15 12:41:39 +00:00
await waitFor ( ( ) =>
expect (
getByText (
'Unable to activate the plugin. Refresh the page and try again.'
)
) . toBeInTheDocument ( )
2020-03-27 20:42:58 +00:00
) ;
} ) ;
} ) ;
describe ( 'The message in the banner' , ( ) => {
2020-04-16 23:58:36 +00:00
const createShippingBannerWrapper = ( { activePlugins } ) =>
2020-10-15 12:41:39 +00:00
render (
2020-03-27 20:42:58 +00:00
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { jest . fn ( ) }
activePlugins = { activePlugins }
2020-08-31 15:13:14 +00:00
installPlugins = { jest . fn ( ) }
2020-03-27 20:42:58 +00:00
wcsPluginSlug = { 'woocommerce-services' }
isRequesting = { true }
itemsCount = { 1 }
/ >
) ;
const notActivatedMessage =
2020-10-15 12:41:39 +00:00
'By clicking "Create shipping label", WooCommerce Shipping(opens in a new tab) will be installed and you agree to its Terms of Service(opens in a new tab).' ;
2020-03-27 20:42:58 +00:00
const activatedMessage =
2020-10-15 12:41:39 +00:00
'You\'ve already installed WooCommerce Shipping. By clicking "Create shipping label", you agree to its Terms of Service(opens in a new tab).' ;
2020-03-27 20:42:58 +00:00
it ( 'should show install text "By clicking "Create shipping label"..." when first loaded.' , ( ) => {
2020-10-15 12:41:39 +00:00
const { container } = createShippingBannerWrapper ( {
2020-03-27 20:42:58 +00:00
activePlugins : [ ] ,
} ) ;
2020-10-15 12:41:39 +00:00
expect (
container . querySelector ( '.wc-admin-shipping-banner-blob p' )
. textContent
) . toBe ( notActivatedMessage ) ;
2020-03-27 20:42:58 +00:00
} ) ;
it ( 'should continue to show the initial message "By clicking "Create shipping label"..." after WooCommerce Service is installed successfully.' , ( ) => {
2020-10-15 12:41:39 +00:00
const { container , rerender } = createShippingBannerWrapper ( {
2020-03-27 20:42:58 +00:00
activePlugins : [ ] ,
} ) ;
2020-10-15 12:41:39 +00:00
rerender (
< ShippingBanner
isJetpackConnected = { true }
activatePlugins = { jest . fn ( ) }
activePlugins = { [ 'woocommerce-services' ] }
installPlugins = { jest . fn ( ) }
wcsPluginSlug = { 'woocommerce-services' }
isRequesting = { true }
itemsCount = { 1 }
/ >
) ;
expect (
container . querySelector ( '.wc-admin-shipping-banner-blob p' )
. textContent
) . toBe ( notActivatedMessage ) ;
2020-03-27 20:42:58 +00:00
} ) ;
it ( 'should show install text "By clicking "You\'ve already installed WooCommerce Shipping."..." when WooCommerce Service is already installed.' , ( ) => {
2020-10-15 12:41:39 +00:00
const { container } = createShippingBannerWrapper ( {
2020-03-27 20:42:58 +00:00
activePlugins : [ 'woocommerce-services' ] ,
} ) ;
2020-10-15 12:41:39 +00:00
expect (
container . querySelector ( '.wc-admin-shipping-banner-blob p' )
. textContent
) . toBe ( activatedMessage ) ;
2020-03-27 20:42:58 +00:00
} ) ;
} ) ;