diff --git a/plugins/woocommerce-admin/client/tasks/fills/experimental-products/test/index.tsx b/plugins/woocommerce-admin/client/tasks/fills/experimental-products/test/index.tsx
new file mode 100644
index 00000000000..224bad51a48
--- /dev/null
+++ b/plugins/woocommerce-admin/client/tasks/fills/experimental-products/test/index.tsx
@@ -0,0 +1,80 @@
+/**
+ * External dependencies
+ */
+import { render, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+/**
+ * Internal dependencies
+ */
+import { Products } from '../';
+import { productTypes } from '../constants';
+import { getAdminSetting } from '~/utils/admin-settings';
+
+jest.mock( '@wordpress/data', () => ( {
+ ...jest.requireActual( '@wordpress/data' ),
+ useSelect: jest.fn(),
+} ) );
+
+jest.mock( '~/utils/admin-settings', () => ( {
+ getAdminSetting: jest.fn(),
+} ) );
+
+describe( 'Products', () => {
+ beforeEach( () => {
+ jest.clearAllMocks();
+ } );
+
+ it( 'should render all products types without view less button when onboardingData.profile.productType is null', () => {
+ ( getAdminSetting as jest.Mock ).mockImplementation( () => ( {
+ profile: {
+ product_types: null,
+ },
+ } ) );
+ const { queryByText } = render( );
+
+ productTypes.forEach( ( { title } ) => {
+ expect( queryByText( title ) ).toBeInTheDocument();
+ } );
+
+ expect(
+ queryByText( 'View more product types' )
+ ).not.toBeInTheDocument();
+ } );
+
+ it( 'should render digital products type with view more button', () => {
+ ( getAdminSetting as jest.Mock ).mockImplementation( () => ( {
+ profile: {
+ product_types: [ 'downloads' ],
+ },
+ } ) );
+ const { queryByText, queryByRole } = render( );
+
+ expect( queryByText( 'Digital product' ) ).toBeInTheDocument();
+ expect( queryByRole( 'menu' )?.childElementCount ).toBe( 1 );
+ expect( queryByText( 'View more product types' ) ).toBeInTheDocument();
+ } );
+
+ it( 'should render all products type when clicking view more button', async () => {
+ ( getAdminSetting as jest.Mock ).mockImplementation( () => ( {
+ profile: {
+ product_types: [ 'downloads' ],
+ },
+ } ) );
+ const { queryByText, getByRole, queryByRole } = render( );
+
+ expect( queryByText( 'View more product types' ) ).toBeInTheDocument();
+
+ userEvent.click(
+ getByRole( 'button', { name: 'View more product types' } )
+ );
+
+ await waitFor( () =>
+ expect( queryByRole( 'menu' )?.childElementCount ).toBe(
+ productTypes.length
+ )
+ );
+
+ expect( queryByText( 'View less product types' ) ).toBeInTheDocument();
+ } );
+} );
diff --git a/plugins/woocommerce-admin/client/tasks/fills/experimental-products/test/utils.ts b/plugins/woocommerce-admin/client/tasks/fills/experimental-products/test/utils.ts
new file mode 100644
index 00000000000..5570a6a0f14
--- /dev/null
+++ b/plugins/woocommerce-admin/client/tasks/fills/experimental-products/test/utils.ts
@@ -0,0 +1,41 @@
+/**
+ * Internal dependencies
+ */
+import { getProductTypes, getSurfacedProductKeys } from '../utils';
+import { productTypes, onboardingProductTypesToSurfaced } from '../constants';
+
+describe( 'getProductTypes', () => {
+ it( 'should return the product types', () => {
+ expect( getProductTypes() ).toEqual( productTypes );
+ } );
+
+ it( 'should return the product types without excluded items', () => {
+ expect(
+ getProductTypes( [ 'external', 'digital' ] ).map( ( p ) => p.key )
+ ).toEqual( [ 'physical', 'variable', 'subscription', 'grouped' ] );
+ } );
+} );
+
+describe( 'getSurfacedProductKeys', () => {
+ test.each( [
+ {
+ selectedTypes: [ 'physical' ],
+ expected: onboardingProductTypesToSurfaced.physical,
+ },
+ {
+ selectedTypes: [ 'physical', 'downloads' ],
+ expected: onboardingProductTypesToSurfaced[ 'downloads,physical' ],
+ },
+ {
+ selectedTypes: [],
+ expected: productTypes.map( ( p ) => p.key ),
+ },
+ ] )(
+ 'should return expected surfaced product keys when onboarding product type contains $selected',
+ ( { selectedTypes, expected } ) => {
+ expect( getSurfacedProductKeys( selectedTypes ) ).toEqual(
+ expected
+ );
+ }
+ );
+} );