Add unit tests for some tracks in product editor (#48245)
* Add tests for ProductPage * Add tests for ProductVariationPage * Add test for product_tab_click event * Add test for product_editor_feedback_bar_turnoff_editor_click event * Add test for product_dropdown_option_click event * Add test for product_add_view track * Changelogs * Changelog * Lint * Add product_edit_view test and falsey test * Fix test name
This commit is contained in:
parent
1167b54a3d
commit
0d461fa6e7
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
Add tests for some product editor tracks
|
|
@ -51,6 +51,9 @@ module.exports = {
|
|||
'**/test/*.[jt]s?(x)',
|
||||
'**/?(*.)test.[jt]s?(x)',
|
||||
],
|
||||
testPathIgnorePatterns: [
|
||||
'\\.d\\.ts$', // This regex pattern matches any file that ends with .d.ts
|
||||
],
|
||||
// The keys for the transformed modules contains the name of the packages that should be transformed.
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(?:\\.pnpm|' + Object.keys( transformModules ).join( '|' ) + ')/)',
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
Add tests for some product editor tracks
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { createElement } from '@wordpress/element';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { FeedbackBar } from '../feedback-bar';
|
||||
import { useFeedbackBar } from '../../../hooks/use-feedback-bar';
|
||||
|
||||
jest.mock( '../../../hooks/use-feedback-bar', () => ( {
|
||||
...jest.requireActual( '../../../hooks/use-feedback-bar' ),
|
||||
useFeedbackBar: jest.fn(),
|
||||
} ) );
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( {
|
||||
...jest.requireActual( '@woocommerce/tracks' ),
|
||||
recordEvent: jest.fn(),
|
||||
} ) );
|
||||
|
||||
describe( 'FeedbackBar', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_editor_feedback_bar_turnoff_editor_click event when clicking turn off editor', () => {
|
||||
( useFeedbackBar as jest.Mock ).mockImplementation( () => ( {
|
||||
hideFeedbackBar: () => {},
|
||||
shouldShowFeedbackBar: true,
|
||||
} ) );
|
||||
render( <FeedbackBar productType={ 'testing' } /> );
|
||||
|
||||
act( () => {
|
||||
fireEvent.click( screen.getByText( 'turn it off' ) );
|
||||
} );
|
||||
expect( recordEvent ).toBeCalledWith(
|
||||
'product_editor_feedback_bar_turnoff_editor_click',
|
||||
{ product_type: 'testing' }
|
||||
);
|
||||
} );
|
||||
} );
|
|
@ -6,6 +6,8 @@ import { render, fireEvent, screen } from '@testing-library/react';
|
|||
import { getQuery, navigateTo } from '@woocommerce/navigation';
|
||||
import { SlotFillProvider } from '@wordpress/components';
|
||||
import { useState, createElement } from '@wordpress/element';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { select } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -15,6 +17,7 @@ import {
|
|||
TabBlockEdit as Tab,
|
||||
TabBlockAttributes,
|
||||
} from '../../../blocks/generic/tab/edit';
|
||||
import { TRACKS_SOURCE } from '../../../constants';
|
||||
|
||||
jest.mock( '@woocommerce/block-templates', () => ( {
|
||||
...jest.requireActual( '@woocommerce/block-templates' ),
|
||||
|
@ -27,6 +30,19 @@ jest.mock( '@woocommerce/navigation', () => ( {
|
|||
getQuery: jest.fn().mockReturnValue( {} ),
|
||||
} ) );
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( {
|
||||
...jest.requireActual( '@woocommerce/tracks' ),
|
||||
recordEvent: jest.fn(),
|
||||
} ) );
|
||||
|
||||
jest.mock( '@wordpress/data', () => {
|
||||
const originalModule = jest.requireActual( '@wordpress/data' );
|
||||
return {
|
||||
...originalModule,
|
||||
select: jest.fn( ( ...args ) => originalModule.select( ...args ) ),
|
||||
};
|
||||
} );
|
||||
|
||||
const blockProps = {
|
||||
setAttributes: () => {},
|
||||
className: '',
|
||||
|
@ -109,6 +125,7 @@ function MockTabs( { onChange = jest.fn() } ) {
|
|||
|
||||
describe( 'Tabs', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
( getQuery as jest.Mock ).mockReturnValue( {
|
||||
tab: null,
|
||||
} );
|
||||
|
@ -224,4 +241,21 @@ describe( 'Tabs', () => {
|
|||
expect( panel1.classList ).not.toContain( 'is-selected' );
|
||||
expect( panel2.classList ).toContain( 'is-selected' );
|
||||
} );
|
||||
|
||||
it( 'should trigger wcadmin_product_tab_click track event when tab is clicked', async () => {
|
||||
( select as jest.Mock ).mockImplementation( () => ( {
|
||||
getEditedEntityRecord: () => ( {
|
||||
type: 'simple',
|
||||
} ),
|
||||
} ) );
|
||||
render( <MockTabs /> );
|
||||
|
||||
const button = screen.getByText( 'Test button 2' );
|
||||
fireEvent.click( button );
|
||||
expect( recordEvent ).toBeCalledWith( 'product_tab_click', {
|
||||
product_tab: 'test2',
|
||||
product_type: 'simple',
|
||||
source: TRACKS_SOURCE,
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { DeleteVariationMenuItem } from '../delete-variation-menu-item';
|
||||
|
||||
jest.mock( '@wordpress/data', () => ( {
|
||||
...jest.requireActual( '@wordpress/data' ),
|
||||
useDispatch: jest.fn(),
|
||||
useSelect: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
|
||||
jest.mock( 'react-router-dom', () => ( { useParams: jest.fn() } ) );
|
||||
|
||||
jest.mock( '@wordpress/core-data', () => ( {
|
||||
useEntityId: jest.fn().mockReturnValue( 'variation_1' ),
|
||||
useEntityProp: jest
|
||||
.fn()
|
||||
.mockImplementation( ( _1, _2, propType ) => [ propType ] ),
|
||||
} ) );
|
||||
|
||||
describe( 'DeleteVariationMenuItem', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_dropdown_option_click track event when clicking the menu', async () => {
|
||||
( useDispatch as jest.Mock ).mockReturnValue( {
|
||||
deleteProductVariation: () => {},
|
||||
} );
|
||||
( useSelect as jest.Mock ).mockReturnValue( {
|
||||
type: 'simple',
|
||||
status: 'publish',
|
||||
} );
|
||||
( useParams as jest.Mock ).mockReturnValue( { productId: 1 } );
|
||||
const { getByText } = render(
|
||||
<DeleteVariationMenuItem onClose={ () => {} } />
|
||||
);
|
||||
fireEvent.click( getByText( 'Delete variation' ) );
|
||||
|
||||
expect( recordEvent ).toHaveBeenCalledWith(
|
||||
'product_dropdown_option_click',
|
||||
{
|
||||
product_id: 1,
|
||||
product_status: 'status',
|
||||
selected_option: 'delete_variation',
|
||||
variation_id: 'variation_1',
|
||||
}
|
||||
);
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { MoreMenuFill } from '../product-block-editor-fills';
|
||||
|
||||
jest.mock( '@wordpress/data', () => ( {
|
||||
...jest.requireActual( '@wordpress/data' ),
|
||||
useSelect: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
jest.mock( '../more-menu-items', () => ( {
|
||||
...jest.requireActual( '../more-menu-items' ),
|
||||
ClassicEditorMenuItem: jest.fn().mockImplementation( () => <div></div> ),
|
||||
FeedbackMenuItem: jest.fn().mockImplementation( ( { onClick } ) => (
|
||||
<div>
|
||||
<button onClick={ onClick }>Feedback button</button>
|
||||
</div>
|
||||
) ),
|
||||
} ) );
|
||||
|
||||
describe( 'MoreMenuFill', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_dropdown_option_click track event when clicking the menu', async () => {
|
||||
( useSelect as jest.Mock ).mockReturnValue( {
|
||||
type: 'simple',
|
||||
status: 'publish',
|
||||
} );
|
||||
const { getByText } = render( <MoreMenuFill onClose={ () => {} } /> );
|
||||
fireEvent.click( getByText( 'Feedback button' ) );
|
||||
|
||||
expect( recordEvent ).toHaveBeenCalledWith(
|
||||
'product_dropdown_option_click',
|
||||
{
|
||||
product_status: 'publish',
|
||||
product_type: 'simple',
|
||||
selected_option: 'feedback',
|
||||
}
|
||||
);
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { render } from '@testing-library/react';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { TRACKS_SOURCE } from '@woocommerce/product-editor';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import ProductPage from '../product-page';
|
||||
import ProductVariationPage from '../product-variation-page';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( {
|
||||
recordEvent: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( 'react-router-dom', () => ( { useParams: jest.fn() } ) );
|
||||
|
||||
// Mocks to prevent crashes.
|
||||
jest.mock( '@wordpress/api-fetch', () => ( {
|
||||
apiFetch: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '@wordpress/core-data', () => ( {
|
||||
apiFetch: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '../hooks/use-product-entity-record', () => ( {
|
||||
useProductEntityRecord: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '../hooks/use-product-variation-entity-record', () => ( {
|
||||
useProductVariationEntityRecord: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '@woocommerce/product-editor', () => ( {
|
||||
...jest.requireActual( '@woocommerce/product-editor' ),
|
||||
productEditorHeaderApiFetchMiddleware: jest.fn(),
|
||||
productApiFetchMiddleware: jest.fn(),
|
||||
__experimentalInitBlocks: jest.fn().mockImplementation( () => () => {} ),
|
||||
} ) );
|
||||
|
||||
describe( 'ProductPage', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_add_view on render without product_id defined', () => {
|
||||
( useParams as jest.Mock ).mockReturnValue( { productId: null } );
|
||||
render( <ProductPage /> );
|
||||
expect( recordEvent ).toBeCalledWith( 'product_add_view', {
|
||||
source: TRACKS_SOURCE,
|
||||
} );
|
||||
} );
|
||||
it( 'should trigger product_edit_view on render with product_id defined', () => {
|
||||
( useParams as jest.Mock ).mockReturnValue( { productId: 1 } );
|
||||
render( <ProductPage /> );
|
||||
expect( recordEvent ).toBeCalledWith( 'product_edit_view', {
|
||||
source: TRACKS_SOURCE,
|
||||
product_id: 1,
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'ProductVariationPage', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_add_view track event on render without product_id defined', () => {
|
||||
( useParams as jest.Mock ).mockReturnValue( { productId: null } );
|
||||
render( <ProductVariationPage /> );
|
||||
expect( recordEvent ).toBeCalledWith( 'product_add_view', {
|
||||
source: TRACKS_SOURCE,
|
||||
} );
|
||||
} );
|
||||
it( 'should trigger product_edit_view track event on render with product_id defined', () => {
|
||||
( useParams as jest.Mock ).mockReturnValue( { productId: 1 } );
|
||||
render( <ProductVariationPage /> );
|
||||
expect( recordEvent ).toBeCalledWith( 'product_edit_view', {
|
||||
source: TRACKS_SOURCE,
|
||||
product_id: 1,
|
||||
} );
|
||||
} );
|
||||
} );
|
4
plugins/woocommerce-admin/client/wp-admin-scripts/product-tracking/test/global.d.ts
vendored
Normal file
4
plugins/woocommerce-admin/client/wp-admin-scripts/product-tracking/test/global.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
declare const productScreen: { name: string };
|
||||
declare const global: typeof globalThis & {
|
||||
productScreen: typeof productScreen;
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( {
|
||||
recordEvent: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '../shared', () => ( {
|
||||
addExitPageListener: jest.fn().mockImplementation( () => {} ),
|
||||
initProductScreenTracks: jest.fn().mockImplementation( () => {} ),
|
||||
getProductData: jest.fn().mockImplementation( () => ( { product_id: 1 } ) ),
|
||||
} ) );
|
||||
|
||||
describe( 'Product Screen Tracking', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_edit_view event when productScreen.name is "edit"', () => {
|
||||
global.productScreen = { name: 'edit' };
|
||||
require( '../product-edit' );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'product_edit_view', {
|
||||
product_id: 1,
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should not trigger product_edit_view event when productScreen.name is not "edit"', () => {
|
||||
global.productScreen = { name: '' };
|
||||
require( '../product-edit' );
|
||||
expect( recordEvent ).not.toHaveBeenCalled();
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( {
|
||||
recordEvent: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '../shared', () => ( {
|
||||
addExitPageListener: jest.fn().mockImplementation( () => {} ),
|
||||
initProductScreenTracks: jest.fn().mockImplementation( () => {} ),
|
||||
} ) );
|
||||
|
||||
describe( 'Product Screen Tracking', () => {
|
||||
beforeEach( () => {
|
||||
jest.clearAllMocks();
|
||||
} );
|
||||
it( 'should trigger product_add_view event when productScreen.name is "new"', () => {
|
||||
global.productScreen = { name: 'new' };
|
||||
require( '../product-new' );
|
||||
expect( recordEvent ).toHaveBeenCalledWith( 'product_add_view' );
|
||||
} );
|
||||
|
||||
it( 'should not trigger product_add_view event when productScreen.name is not "new"', () => {
|
||||
global.productScreen = { name: '' };
|
||||
require( '../product-new' );
|
||||
expect( recordEvent ).not.toHaveBeenCalled();
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
Add tests for some product editor tracks
|
Loading…
Reference in New Issue