diff --git a/plugins/woocommerce-admin/client/marketplace/components/content/content.tsx b/plugins/woocommerce-admin/client/marketplace/components/content/content.tsx
index 160200017f6..0f3f23d3a75 100644
--- a/plugins/woocommerce-admin/client/marketplace/components/content/content.tsx
+++ b/plugins/woocommerce-admin/client/marketplace/components/content/content.tsx
@@ -23,6 +23,8 @@ import MySubscriptions from '../my-subscriptions/my-subscriptions';
import { MarketplaceContext } from '../../contexts/marketplace-context';
import { fetchSearchResults } from '../../utils/functions';
import { SubscriptionsContextProvider } from '../../contexts/subscriptions-context';
+import { SearchResultsCountType } from '../../contexts/types';
+
import {
recordMarketplaceView,
recordLegacyTabView,
@@ -39,8 +41,12 @@ export default function Content(): JSX.Element {
const [ products, setProducts ] = useState< Product[] >( [] );
const [ hasMore, setHasMore ] = useState( false );
const [ page, setPage ] = useState( 1 );
- const { setIsLoading, selectedTab, setHasBusinessServices } =
- marketplaceContextValue;
+ const {
+ setIsLoading,
+ selectedTab,
+ setHasBusinessServices,
+ setSearchResultsCount,
+ } = marketplaceContextValue;
const query = useQuery();
const lastProductRef = useRef< HTMLDivElement >( null );
@@ -51,35 +57,42 @@ export default function Content(): JSX.Element {
// On initial load of the in-app marketplace, fetch extensions, themes and business services
// and check if there are any business services available on WCCOM
useEffect( () => {
- const categories = [ '', 'themes', 'business-services' ];
+ const categories: Array< keyof SearchResultsCountType > = [
+ 'extensions',
+ 'themes',
+ 'business-services',
+ ];
const abortControllers = categories.map( () => new AbortController() );
- categories.forEach( ( category: string, index ) => {
- const params = new URLSearchParams();
- if ( category !== '' ) {
- params.append( 'category', category );
- }
+ categories.forEach(
+ ( category: keyof SearchResultsCountType, index ) => {
+ const params = new URLSearchParams();
+ if ( category !== 'extensions' ) {
+ params.append( 'category', category );
+ }
- const wccomSettings = getAdminSetting( 'wccomHelper', false );
- if ( wccomSettings.storeCountry ) {
- params.append( 'country', wccomSettings.storeCountry );
- }
+ const wccomSettings = getAdminSetting( 'wccomHelper', false );
+ if ( wccomSettings.storeCountry ) {
+ params.append( 'country', wccomSettings.storeCountry );
+ }
- fetchSearchResults( params, abortControllers[ index ].signal ).then(
- ( productList ) => {
+ fetchSearchResults(
+ params,
+ abortControllers[ index ].signal
+ ).then( ( productList ) => {
if ( category === 'business-services' ) {
setHasBusinessServices(
productList.products.length > 0
);
}
- }
- );
- return () => {
- abortControllers.forEach( ( controller ) => {
- controller.abort();
} );
- };
- } );
+ return () => {
+ abortControllers.forEach( ( controller ) => {
+ controller.abort();
+ } );
+ };
+ }
+ );
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );
@@ -144,6 +157,20 @@ export default function Content(): JSX.Element {
return newProducts;
} );
setHasMore( productList.hasMore );
+
+ if ( query.term ) {
+ setSearchResultsCount( {
+ extensions: productList.filter(
+ ( p ) => p.type === 'extension'
+ ).length,
+ themes: productList.filter(
+ ( p ) => p.type === 'theme'
+ ).length,
+ 'business-services': productList.filter(
+ ( p ) => p.type === 'business-service'
+ ).length,
+ } );
+ }
} )
.catch( () => {
if ( page === 1 ) {
diff --git a/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.scss b/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.scss
index 008fe4e1b84..354a1797917 100644
--- a/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.scss
+++ b/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.scss
@@ -45,6 +45,10 @@
text-align: center;
z-index: 26;
}
+
+ &__update-count {
+ background-color: #000;
+ }
}
@media (width <= $breakpoint-medium) {
diff --git a/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.tsx b/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.tsx
index 1f852a2b982..fd6fc62809f 100644
--- a/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.tsx
+++ b/plugins/woocommerce-admin/client/marketplace/components/tabs/tabs.tsx
@@ -35,45 +35,6 @@ interface Tabs {
const wccomSettings = getAdminSetting( 'wccomHelper', {} );
const wooUpdateCount = wccomSettings?.wooUpdateCount ?? 0;
-const tabs: Tabs = {
- search: {
- name: 'search',
- title: __( 'Search results', 'woocommerce' ),
- showUpdateCount: false,
- updateCount: 0,
- },
- discover: {
- name: 'discover',
- title: __( 'Discover', 'woocommerce' ),
- showUpdateCount: false,
- updateCount: 0,
- },
- extensions: {
- name: 'extensions',
- title: __( 'Extensions', 'woocommerce' ),
- showUpdateCount: false,
- updateCount: 0,
- },
- themes: {
- name: 'themes',
- title: __( 'Themes', 'woocommerce' ),
- showUpdateCount: false,
- updateCount: 0,
- },
- 'business-services': {
- name: 'business-services',
- title: __( 'Business services', 'woocommerce' ),
- showUpdateCount: false,
- updateCount: 0,
- },
- 'my-subscriptions': {
- name: 'my-subscriptions',
- title: __( 'My subscriptions', 'woocommerce' ),
- showUpdateCount: true,
- updateCount: wooUpdateCount,
- },
-};
-
const setUrlTabParam = ( tabKey: string ) => {
navigateTo( {
url: getNewPath(
@@ -84,7 +45,11 @@ const setUrlTabParam = ( tabKey: string ) => {
} );
};
-const getVisibleTabs = ( selectedTab: string, hasBusinessServices = false ) => {
+const getVisibleTabs = (
+ selectedTab: string,
+ hasBusinessServices = false,
+ tabs: Tabs
+) => {
if ( selectedTab === '' ) {
return tabs;
}
@@ -101,7 +66,8 @@ const getVisibleTabs = ( selectedTab: string, hasBusinessServices = false ) => {
const renderTabs = (
marketplaceContextValue: MarketplaceContextType,
- visibleTabs: Tabs
+ visibleTabs: Tabs,
+ tabs: Tabs
) => {
const { selectedTab, setSelectedTab } = marketplaceContextValue;
@@ -141,12 +107,13 @@ const renderTabs = (
key={ tabKey }
>
{ tabs[ tabKey ]?.title }
- { tabs[ tabKey ]?.showUpdateCount &&
- tabs[ tabKey ]?.updateCount > 0 && (
-
- { tabs[ tabKey ]?.updateCount }
-
- ) }
+ { tabs[ tabKey ]?.showUpdateCount && (
+
+ { tabs[ tabKey ]?.updateCount }
+
+ ) }
)
);
@@ -159,10 +126,53 @@ const Tabs = ( props: TabsProps ): JSX.Element => {
const marketplaceContextValue = useContext( MarketplaceContext );
const { selectedTab, setSelectedTab, hasBusinessServices } =
marketplaceContextValue;
- const [ visibleTabs, setVisibleTabs ] = useState( getVisibleTabs( '' ) );
+ const { searchResultsCount } = marketplaceContextValue;
const query: Record< string, string > = useQuery();
+ const tabs: Tabs = {
+ search: {
+ name: 'search',
+ title: __( 'Search results', 'woocommerce' ),
+ showUpdateCount: false,
+ updateCount: 0,
+ },
+ discover: {
+ name: 'discover',
+ title: __( 'Discover', 'woocommerce' ),
+ showUpdateCount: false,
+ updateCount: 0,
+ },
+ extensions: {
+ name: 'extensions',
+ title: __( 'Extensions', 'woocommerce' ),
+ showUpdateCount: !! query.term,
+ updateCount: searchResultsCount.extensions,
+ },
+ themes: {
+ name: 'themes',
+ title: __( 'Themes', 'woocommerce' ),
+ showUpdateCount: !! query.term,
+ updateCount: searchResultsCount.themes,
+ },
+ 'business-services': {
+ name: 'business-services',
+ title: __( 'Business services', 'woocommerce' ),
+ showUpdateCount: !! query.term,
+ updateCount: searchResultsCount[ 'business-services' ],
+ },
+ 'my-subscriptions': {
+ name: 'my-subscriptions',
+ title: __( 'My subscriptions', 'woocommerce' ),
+ showUpdateCount: true,
+ updateCount: wooUpdateCount,
+ },
+ };
+
+ const [ visibleTabs, setVisibleTabs ] = useState(
+ getVisibleTabs( '', false, tabs )
+ );
+
useEffect( () => {
if ( query?.tab && tabs[ query.tab ] ) {
setSelectedTab( query.tab );
@@ -172,8 +182,11 @@ const Tabs = ( props: TabsProps ): JSX.Element => {
}, [ query, setSelectedTab ] );
useEffect( () => {
- setVisibleTabs( getVisibleTabs( selectedTab, hasBusinessServices ) );
+ setVisibleTabs(
+ getVisibleTabs( selectedTab, hasBusinessServices, tabs )
+ );
}, [ selectedTab, hasBusinessServices ] );
+
return (
);
};
diff --git a/plugins/woocommerce-admin/client/marketplace/contexts/marketplace-context.tsx b/plugins/woocommerce-admin/client/marketplace/contexts/marketplace-context.tsx
index 53dd1bb5789..0631bf5725e 100644
--- a/plugins/woocommerce-admin/client/marketplace/contexts/marketplace-context.tsx
+++ b/plugins/woocommerce-admin/client/marketplace/contexts/marketplace-context.tsx
@@ -1,12 +1,17 @@
/**
* External dependencies
*/
-import { useState, useEffect, createContext } from '@wordpress/element';
+import {
+ useState,
+ useEffect,
+ useCallback,
+ createContext,
+} from '@wordpress/element';
/**
* Internal dependencies
*/
-import { MarketplaceContextType } from './types';
+import { SearchResultsCountType, MarketplaceContextType } from './types';
import { getAdminSetting } from '../../utils/admin-settings';
export const MarketplaceContext = createContext< MarketplaceContextType >( {
@@ -18,6 +23,12 @@ export const MarketplaceContext = createContext< MarketplaceContextType >( {
addInstalledProduct: () => {},
hasBusinessServices: false,
setHasBusinessServices: () => {},
+ searchResultsCount: {
+ extensions: 0,
+ themes: 0,
+ 'business-services': 0,
+ },
+ setSearchResultsCount: () => {},
} );
export function MarketplaceContextProvider( props: {
@@ -29,6 +40,22 @@ export function MarketplaceContextProvider( props: {
[]
);
const [ hasBusinessServices, setHasBusinessServices ] = useState( false );
+ const [ searchResultsCount, setSearchResultsCountState ] =
+ useState< SearchResultsCountType >( {
+ extensions: 0,
+ themes: 0,
+ 'business-services': 0,
+ } );
+
+ const setSearchResultsCount = useCallback(
+ ( updatedCounts: Partial< SearchResultsCountType > ) => {
+ setSearchResultsCountState( ( prev ) => ( {
+ ...prev,
+ ...updatedCounts,
+ } ) );
+ },
+ []
+ );
/**
* Knowing installed products will help us to determine which products
@@ -59,6 +86,8 @@ export function MarketplaceContextProvider( props: {
addInstalledProduct,
hasBusinessServices,
setHasBusinessServices,
+ searchResultsCount,
+ setSearchResultsCount,
};
return (
diff --git a/plugins/woocommerce-admin/client/marketplace/contexts/types.ts b/plugins/woocommerce-admin/client/marketplace/contexts/types.ts
index 969ce88d2e1..3240729871e 100644
--- a/plugins/woocommerce-admin/client/marketplace/contexts/types.ts
+++ b/plugins/woocommerce-admin/client/marketplace/contexts/types.ts
@@ -8,6 +8,12 @@ import { Options } from '@wordpress/notices';
*/
import { Subscription } from '../components/my-subscriptions/types';
+export interface SearchResultsCountType {
+ extensions: number;
+ themes: number;
+ 'business-services': number;
+}
+
export type MarketplaceContextType = {
isLoading: boolean;
setIsLoading: ( isLoading: boolean ) => void;
@@ -17,6 +23,10 @@ export type MarketplaceContextType = {
addInstalledProduct: ( slug: string ) => void;
hasBusinessServices: boolean;
setHasBusinessServices: ( hasBusinessServices: boolean ) => void;
+ searchResultsCount: SearchResultsCountType;
+ setSearchResultsCount: (
+ updatedCounts: Partial< SearchResultsCountType >
+ ) => void;
};
export type SubscriptionsContextType = {
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/coming-soon/entire-site.scss b/plugins/woocommerce-blocks/assets/js/blocks/coming-soon/entire-site.scss
index 7ad342e5079..6bd8ba151e8 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/coming-soon/entire-site.scss
+++ b/plugins/woocommerce-blocks/assets/js/blocks/coming-soon/entire-site.scss
@@ -73,22 +73,20 @@ body:has(.woocommerce-coming-soon-banner) {
}
.wp-block-loginout {
- background-color: #000;
- border-radius: 6px;
display: flex;
- height: 40px;
- width: 74px;
- justify-content: center;
- align-items: center;
- gap: 10px;
- box-sizing: border-box;
a {
+ box-sizing: border-box;
+ background-color: #000;
+ border-radius: 6px;
color: #fff;
- text-decoration: none;
- line-height: 17px;
+ gap: 10px;
font-size: 14px;
- font-weight: 500;
+ font-style: normal;
+ line-height: normal;
+ text-align: center;
+ text-decoration: none;
+ padding: 17px 16px;
}
}
diff --git a/plugins/woocommerce/changelog/fix-coming-soon-login-button b/plugins/woocommerce/changelog/fix-coming-soon-login-button
new file mode 100644
index 00000000000..44c9292e8a0
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-coming-soon-login-button
@@ -0,0 +1,5 @@
+Significance: patch
+Type: fix
+Comment: Fix size for coming soon banner button
+
+
diff --git a/plugins/woocommerce/changelog/fix-duplicate-spec-evaluation b/plugins/woocommerce/changelog/fix-duplicate-spec-evaluation
new file mode 100644
index 00000000000..299eaf7c9d6
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-duplicate-spec-evaluation
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix duplicate spec evaluation in evaluate_specs()
diff --git a/plugins/woocommerce/changelog/tweak-21597-in-app-search-results-count b/plugins/woocommerce/changelog/tweak-21597-in-app-search-results-count
new file mode 100644
index 00000000000..b0edda219c3
--- /dev/null
+++ b/plugins/woocommerce/changelog/tweak-21597-in-app-search-results-count
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add search result counts to the in-app marketplace header tabs (Extensions area)
diff --git a/plugins/woocommerce/changelog/update-remove-purchase-task b/plugins/woocommerce/changelog/update-remove-purchase-task
new file mode 100644
index 00000000000..20806d693a2
--- /dev/null
+++ b/plugins/woocommerce/changelog/update-remove-purchase-task
@@ -0,0 +1,4 @@
+Significance: minor
+Type: update
+
+Clean up Purchase task
diff --git a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Purchase.php b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Purchase.php
deleted file mode 100644
index 2c9383f4a60..00000000000
--- a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Purchase.php
+++ /dev/null
@@ -1,203 +0,0 @@
-undo_dismiss();
- }
-
- /**
- * Get the task arguments.
- * ID.
- *
- * @return string
- */
- public function get_id() {
- return 'purchase';
- }
-
- /**
- * Title.
- *
- * @return string
- */
- public function get_title() {
- $products = $this->get_paid_products_and_themes();
- $first_product = count( $products['purchaseable'] ) >= 1 ? $products['purchaseable'][0] : false;
-
- if ( ! $first_product ) {
- return null;
- }
-
- $product_label = isset( $first_product['label'] ) ? $first_product['label'] : $first_product['title'];
- $additional_count = count( $products['purchaseable'] ) - 1;
-
- if ( $this->get_parent_option( 'use_completed_title' ) && $this->is_complete() ) {
- return count( $products['purchaseable'] ) === 1
- ? sprintf(
- /* translators: %1$s: a purchased product name */
- __(
- 'You added %1$s',
- 'woocommerce'
- ),
- $product_label
- )
- : sprintf(
- /* translators: %1$s: a purchased product name, %2$d the number of other products purchased */
- _n(
- 'You added %1$s and %2$d other product',
- 'You added %1$s and %2$d other products',
- $additional_count,
- 'woocommerce'
- ),
- $product_label,
- $additional_count
- );
- }
-
- return count( $products['purchaseable'] ) === 1
- ? sprintf(
- /* translators: %1$s: a purchaseable product name */
- __(
- 'Add %s to my store',
- 'woocommerce'
- ),
- $product_label
- )
- : sprintf(
- /* translators: %1$s: a purchaseable product name, %2$d the number of other products to purchase */
- _n(
- 'Add %1$s and %2$d more product to my store',
- 'Add %1$s and %2$d more products to my store',
- $additional_count,
- 'woocommerce'
- ),
- $product_label,
- $additional_count
- );
- }
-
- /**
- * Content.
- *
- * @return string
- */
- public function get_content() {
- $products = $this->get_paid_products_and_themes();
-
- if ( count( $products['remaining'] ) === 1 ) {
- return isset( $products['purchaseable'][0]['description'] ) ? $products['purchaseable'][0]['description'] : $products['purchaseable'][0]['excerpt'];
- }
- return sprintf(
- /* translators: %1$s: list of product names comma separated, %2%s the last product name */
- __(
- 'Good choice! You chose to add %1$s and %2$s to your store.',
- 'woocommerce'
- ),
- implode( ', ', array_slice( $products['remaining'], 0, -1 ) ) . ( count( $products['remaining'] ) > 2 ? ',' : '' ),
- end( $products['remaining'] )
- );
- }
-
- /**
- * Action label.
- *
- * @return string
- */
- public function get_action_label() {
- return __( 'Purchase & install now', 'woocommerce' );
- }
-
-
- /**
- * Time.
- *
- * @return string
- */
- public function get_time() {
- return __( '2 minutes', 'woocommerce' );
- }
-
- /**
- * Task completion.
- *
- * @return bool
- */
- public function is_complete() {
- $products = $this->get_paid_products_and_themes();
- return count( $products['remaining'] ) === 0;
- }
-
- /**
- * Dismissable.
- *
- * @return bool
- */
- public function is_dismissable() {
- return true;
- }
-
- /**
- * Task visibility.
- *
- * @return bool
- */
- public function can_view() {
- $products = $this->get_paid_products_and_themes();
- return count( $products['purchaseable'] ) > 0;
- }
-
- /**
- * Get purchaseable and remaining products.
- *
- * @return array purchaseable and remaining products and themes.
- */
- public static function get_paid_products_and_themes() {
- $relevant_products = OnboardingProducts::get_relevant_products();
-
- $profiler_data = get_option( OnboardingProfile::DATA_OPTION, array() );
- $theme = isset( $profiler_data['theme'] ) ? $profiler_data['theme'] : null;
- $paid_theme = $theme ? OnboardingThemes::get_paid_theme_by_slug( $theme ) : null;
- if ( $paid_theme ) {
-
- $relevant_products['purchaseable'][] = $paid_theme;
-
- if ( isset( $paid_theme['is_installed'] ) && false === $paid_theme['is_installed'] ) {
- $relevant_products['remaining'][] = $paid_theme['title'];
- }
- }
- return $relevant_products;
- }
-}
diff --git a/plugins/woocommerce/src/Admin/Features/PaymentGatewaySuggestions/EvaluateSuggestion.php b/plugins/woocommerce/src/Admin/Features/PaymentGatewaySuggestions/EvaluateSuggestion.php
index 45d609da940..4b614367199 100644
--- a/plugins/woocommerce/src/Admin/Features/PaymentGatewaySuggestions/EvaluateSuggestion.php
+++ b/plugins/woocommerce/src/Admin/Features/PaymentGatewaySuggestions/EvaluateSuggestion.php
@@ -13,6 +13,13 @@ use Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\RuleEvaluator;
* Evaluates the spec and returns the evaluated suggestion.
*/
class EvaluateSuggestion {
+ /**
+ * Stores memoized results of evaluate_specs.
+ *
+ * @var array
+ */
+ protected static $memo = array();
+
/**
* Evaluates the spec and returns the suggestion.
*
@@ -58,6 +65,12 @@ class EvaluateSuggestion {
* @return array The visible suggestions and errors.
*/
public static function evaluate_specs( $specs, $logger_args = array() ) {
+ $specs_key = self::get_memo_key( $specs );
+
+ if ( isset( self::$memo[ $specs_key ] ) ) {
+ return self::$memo[ $specs_key ];
+ }
+
$suggestions = array();
$errors = array();
@@ -72,9 +85,43 @@ class EvaluateSuggestion {
}
}
- return array(
+ $result = array(
'suggestions' => $suggestions,
'errors' => $errors,
);
+
+ // Memoize results, with a fail safe to prevent unbounded memory growth.
+ // This limit is unlikely to be reached under normal circumstances.
+ if ( count( self::$memo ) > 50 ) {
+ self::reset_memo();
+ }
+ self::$memo[ $specs_key ] = $result;
+
+ return $result;
+ }
+
+ /**
+ * Resets the memoized results. Useful for testing.
+ */
+ public static function reset_memo() {
+ self::$memo = array();
+ }
+
+ /**
+ * Returns a memoization key for the given specs.
+ *
+ * @param array $specs The specs to generate a key for.
+ *
+ * @return string The memoization key.
+ */
+ private static function get_memo_key( $specs ) {
+ $data = wp_json_encode( $specs );
+
+ if ( function_exists( 'hash' ) && in_array( 'xxh3', hash_algos(), true ) ) {
+ // Use xxHash (xxh3) if available.
+ return hash( 'xxh3', $data );
+ }
+ // Fall back to CRC32.
+ return (string) crc32( $data );
}
}
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/onboarding-tasks/tasks/purchase.php b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/onboarding-tasks/tasks/purchase.php
deleted file mode 100644
index 043052a0371..00000000000
--- a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/onboarding-tasks/tasks/purchase.php
+++ /dev/null
@@ -1,186 +0,0 @@
-task = new Purchase( new TaskList() );
- set_transient(
- OnboardingThemes::THEMES_TRANSIENT,
- array(
- 'free' => array(
- 'slug' => 'free',
- 'is_installed' => false,
- ),
- 'paid' => array(
- 'slug' => 'paid',
- 'id' => 12312,
- 'price' => '$79.00',
- 'title' => 'theme title',
- 'is_installed' => false,
- ),
- 'paid_installed' => array(
- 'slug' => 'paid_installed',
- 'id' => 12312,
- 'price' => '$79.00',
- 'title' => 'theme title',
- 'is_installed' => true,
- ),
- 'free_with_price' => array(
- 'slug' => 'free_with_price',
- 'id' => 12312,
- 'price' => '$0.00',
- 'title' => 'theme title',
- 'is_installed' => false,
- ),
- )
- );
- }
-
- /**
- * Tear down.
- */
- public function tearDown(): void {
- parent::tearDown();
- delete_transient( OnboardingThemes::THEMES_TRANSIENT );
- delete_option( OnboardingProfile::DATA_OPTION );
- }
-
- /**
- * Test is_complete function of Purchase task.
- */
- public function test_is_complete_if_no_remaining_products() {
- update_option( OnboardingProfile::DATA_OPTION, array( 'product_types' => array( 'physical' ) ) );
- $this->assertEquals( true, $this->task->is_complete() );
- }
-
- /**
- * Test is_complete function of Purchase task.
- */
- public function test_is_not_complete_if_remaining_paid_products() {
- update_option( OnboardingProfile::DATA_OPTION, array( 'product_types' => array( 'memberships' ) ) );
- $this->assertEquals( false, $this->task->is_complete() );
- }
-
- /**
- * Test is_complete function of Purchase task.
- */
- public function test_is_complete_if_no_paid_themes() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array(),
- 'theme' => 'free',
- )
- );
- $this->assertEquals( true, $this->task->is_complete() );
- }
-
- /**
- * Test is_complete function of Purchase task.
- */
- public function test_is_not_complete_if_paid_theme_that_is_not_installed() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array(),
- 'theme' => 'paid',
- )
- );
- $this->assertEquals( false, $this->task->is_complete() );
- }
-
- /**
- * Test is_complete function of Purchase task.
- */
- public function test_is_complete_if_paid_theme_that_is_installed() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array(),
- 'theme' => 'paid_installed',
- )
- );
- $this->assertEquals( true, $this->task->is_complete() );
- }
-
- /**
- * Test is_complete function of Purchase task.
- */
- public function test_is_complete_if_free_theme_with_set_price() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array(),
- 'theme' => 'free_with_price',
- )
- );
- $this->assertEquals( true, $this->task->is_complete() );
- }
-
- /**
- * Test the task title for a single paid item.
- */
- public function test_get_title_if_single_paid_item() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array(),
- 'theme' => 'paid',
- )
- );
- $this->assertEquals( 'Add theme title to my store', $this->task->get_title() );
- }
-
- /**
- * Test the task title if 2 paid items exist.
- */
- public function test_get_title_if_multiple_paid_themes() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array( 'memberships' ),
- 'theme' => 'paid',
- )
- );
- $this->assertEquals( 'Add Memberships and 1 more product to my store', $this->task->get_title() );
- }
-
- /**
- * Test the task title if multiple additional paid items exist.
- */
- public function test_get_title_if_multiple_paid_products() {
- update_option(
- OnboardingProfile::DATA_OPTION,
- array(
- 'product_types' => array( 'memberships', 'bookings' ),
- 'theme' => 'paid',
- )
- );
- $this->assertEquals( 'Add Memberships and 2 more products to my store', $this->task->get_title() );
- }
-}
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php
index 15fee01caea..3b0a70952c6 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php
@@ -323,6 +323,31 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_EvaluateSuggestion extends WC_Uni
remove_filter( 'woocommerce_admin_remote_specs_evaluator_should_log', '__return_true' );
}
+ /**
+ * Test that the memo is set correctly.
+ */
+ public function test_memo_set_correctly() {
+ $specs = array(
+ array(
+ 'id' => 'test-gateway-1',
+ 'is_visible' => true,
+ ),
+ array(
+ 'id' => 'test-gateway-2',
+ 'is_visible' => false,
+ ),
+ );
+
+ $result = TestableEvaluateSuggestion::evaluate_specs( $specs );
+ $memo = TestableEvaluateSuggestion::get_memo_for_tests();
+
+ $this->assertCount( 1, $memo );
+ $memo_key = array_keys( $memo )[0];
+ $this->assertEquals( $result, $memo[ $memo_key ] );
+ $this->assertCount( 1, $result['suggestions'] );
+ $this->assertEquals( 'test-gateway-1', $result['suggestions'][0]->id );
+ }
+
/**
* Overrides the WC logger.
*
@@ -359,3 +384,19 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_EvaluateSuggestion extends WC_Uni
);
}
}
+
+//phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
+/**
+ * TestableEvaluateSuggestion class.
+ */
+class TestableEvaluateSuggestion extends EvaluateSuggestion {
+ /**
+ * Get the memo for testing.
+ *
+ * @return array
+ */
+ public static function get_memo_for_tests() {
+ return self::$memo;
+ }
+}
+//phpcs:enable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/payment-gateway-suggestions.php b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/payment-gateway-suggestions.php
index 728c78ce286..bb2ef0f93f1 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/payment-gateway-suggestions.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/payment-gateway-suggestions.php
@@ -25,7 +25,7 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_Init extends WC_Unit_Test_Case {
delete_option( 'woocommerce_show_marketplace_suggestions' );
add_filter(
'transient_woocommerce_admin_' . PaymentGatewaySuggestionsDataSourcePoller::ID . '_specs',
- function( $value ) {
+ function ( $value ) {
if ( $value ) {
return $value;
}
@@ -37,6 +37,8 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_Init extends WC_Unit_Test_Case {
);
}
);
+
+ EvaluateSuggestion::reset_memo();
}
/**
@@ -57,7 +59,7 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_Init extends WC_Unit_Test_Case {
remove_all_filters( 'transient_woocommerce_admin_' . PaymentGatewaySuggestionsDataSourcePoller::ID . '_specs' );
add_filter(
DataSourcePoller::FILTER_NAME,
- function() {
+ function () {
return array();
}
);
@@ -242,7 +244,7 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_Init extends WC_Unit_Test_Case {
add_filter(
'locale',
- function( $_locale ) {
+ function () {
return 'zh_TW';
}
);
@@ -364,5 +366,4 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_Init extends WC_Unit_Test_Case {
// Clean up.
delete_option( PaymentGatewaySuggestions::RECOMMENDED_PAYMENT_PLUGINS_DISMISS_OPTION );
}
-
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/ShippingPartnerSuggestions/DefaultShippingPartnersTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/ShippingPartnerSuggestions/DefaultShippingPartnersTest.php
similarity index 97%
rename from plugins/woocommerce/tests/php/src/Admin/ShippingPartnerSuggestions/DefaultShippingPartnersTest.php
rename to plugins/woocommerce/tests/php/src/Admin/Features/ShippingPartnerSuggestions/DefaultShippingPartnersTest.php
index ecea313caa7..44b15c965f6 100644
--- a/plugins/woocommerce/tests/php/src/Admin/ShippingPartnerSuggestions/DefaultShippingPartnersTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/ShippingPartnerSuggestions/DefaultShippingPartnersTest.php
@@ -1,7 +1,7 @@
mock_logger = $this->getMockBuilder( 'WC_Logger_Interface' )->getMock();
add_filter( 'woocommerce_logging_class', array( $this, 'override_wc_logger' ) );
+
+ EvaluateSuggestion::reset_memo();
}
/**
@@ -91,7 +94,7 @@ class ShippingPartnerSuggestionsTest extends WC_Unit_Test_Case {
remove_all_filters( 'transient_woocommerce_admin_' . ShippingPartnerSuggestionsDataSourcePoller::ID . '_specs' );
add_filter(
DataSourcePoller::FILTER_NAME,
- function() {
+ function () {
return array();
}
);
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/DefaultPromotionsTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/DefaultPromotionsTest.php
index 893cc7a9753..29351fce779 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/DefaultPromotionsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/DefaultPromotionsTest.php
@@ -29,6 +29,8 @@ class DefaultPromotionsTest extends WC_Unit_Test_Case {
update_option( 'woocommerce_store_address', 'foo' );
update_option( 'active_plugins', array( 'foo/foo.php' ) );
+
+ EvaluateSuggestion::reset_memo();
}
/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/InitTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/InitTest.php
index 3a51a919fa3..cfe7b606f69 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/InitTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/WCPayPromotion/InitTest.php
@@ -26,7 +26,7 @@ class InitTest extends WC_Unit_Test_Case {
delete_option( 'woocommerce_show_marketplace_suggestions' );
add_filter(
'transient_woocommerce_admin_' . WCPayPromotionDataSourcePoller::ID . '_specs',
- function( $value ) {
+ function ( $value ) {
if ( $value ) {
return $value;
}
@@ -38,6 +38,8 @@ class InitTest extends WC_Unit_Test_Case {
);
}
);
+
+ EvaluateSuggestion::reset_memo();
}
/**
@@ -59,7 +61,7 @@ class InitTest extends WC_Unit_Test_Case {
remove_all_filters( 'transient_woocommerce_admin_' . WCPayPromotionDataSourcePoller::ID . '_specs' );
add_filter(
DataSourcePoller::FILTER_NAME,
- function() {
+ function () {
return array();
}
);