@@ -438,19 +292,13 @@ export const RelatedPostsPanel = (): React.JSX.Element => {
{
-
-
- { getTopRelatedPostsMessage() }
-
-
{ error && (
error.Message()
) }
@@ -463,7 +311,7 @@ export const RelatedPostsPanel = (): React.JSX.Element => {
+
{ __( 'No related posts found.', 'wp-parsely' ) }
) }
diff --git a/src/content-helper/editor-sidebar/related-posts/provider.ts b/src/content-helper/editor-sidebar/related-posts/provider.ts
index 6051c4ca84..ebaa7cd732 100644
--- a/src/content-helper/editor-sidebar/related-posts/provider.ts
+++ b/src/content-helper/editor-sidebar/related-posts/provider.ts
@@ -1,47 +1,20 @@
/**
* WordPress dependencies
*/
-import { __, sprintf } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';
/**
* Internal dependencies
*/
import { BaseProvider } from '../../common/base-provider';
-import {
- ContentHelperError,
- ContentHelperErrorCode,
-} from '../../common/content-helper-error';
-import {
- AnalyticsApiOptionalQueryParams,
- getApiPeriodParams,
-} from '../../common/utils/api';
+import { getApiPeriodParams } from '../../common/utils/api';
import {
Metric,
Period,
- PostFilter,
- PostFilterType,
- getPeriodDescription,
+ PostFilters,
} from '../../common/utils/constants';
import { PostData } from '../../common/utils/post';
-/**
- * The form of the query that gets posted to the analytics/posts WordPress REST
- * API endpoint.
- */
-interface RelatedPostsApiQuery {
- message: string; // Selected filter message to be displayed to the user.
- query: AnalyticsApiOptionalQueryParams
-}
-
-/**
- * The form of the result returned by the getRelatedPosts() function.
- */
-export interface GetRelatedPostsResult {
- message: string;
- posts: PostData[];
-}
-
export const RELATED_POSTS_DEFAULT_LIMIT = 5;
export class RelatedPostsProvider extends BaseProvider {
@@ -63,145 +36,57 @@ export class RelatedPostsProvider extends BaseProvider {
if ( ! this.instance ) {
this.instance = new RelatedPostsProvider();
}
+
return this.instance;
}
/**
- * Returns related posts to the one that is currently being edited within
- * the WordPress Block Editor.
+ * Returns posts based on the passed period, metric, and filters.
*
- * The 'related' status is determined by the current post's Author, Category
- * or tag.
+ * @param {Period} period The period for which to fetch data.
+ * @param {Metric} metric The metric to sort by.
+ * @param {PostFilters} filters The filters to use in the request.
*
- * @param {Period} period The period for which to fetch data.
- * @param {Metric} metric The metric to sort by.
- * @param {PostFilter} filter The selected filter type and value to use.
- *
- * @return {Promise
} Object containing message and posts.
+ * @return {Promise>} The array of fetched posts.
*/
public async getRelatedPosts(
- period: Period, metric: Metric, filter: PostFilter
- ): Promise {
- // Create API query.
- let apiQuery;
- try {
- apiQuery = this.buildRelatedPostsApiQuery(
- period, metric, filter
- );
- } catch ( contentHelperError ) {
- return Promise.reject( contentHelperError );
- }
+ period: Period, metric: Metric, filters: PostFilters
+ ): Promise {
+ let posts: PostData[] = [];
- // Fetch results from API and set the message.
- let data;
try {
- data = await this.fetchRelatedPostsFromWpEndpoint( apiQuery );
+ posts = await this.fetchRelatedPostsFromWpEndpoint(
+ period, metric, filters
+ );
} catch ( contentHelperError ) {
return Promise.reject( contentHelperError );
}
- const message = this.generateMessage(
- data.length === 0, period, apiQuery.message
- );
-
- return { message, posts: data };
- }
-
- /**
- * Generates the message that will be displayed above the related posts.
- *
- * @since 3.11.0
- *
- * @param {boolean} dataIsEmpty Whether the API returned no data.
- * @param {Period} period The period for which data was fetched.
- * @param {string} apiQueryMessage The message within the query.
- *
- * @return {string} The generated message.
- */
- private generateMessage(
- dataIsEmpty: boolean, period: Period, apiQueryMessage: string
- ): string {
- if ( dataIsEmpty ) {
- return sprintf(
- /* translators: 1: message such as "in category Foo" */
- __(
- 'No related posts %1$s were found for the specified period and metric.',
- 'wp-parsely'
- ), apiQueryMessage
- );
- }
-
- return sprintf(
- /* translators: 1: message such as "in category Foo", 2: period such as "last 7 days"*/
- __( 'Related posts %1$s in the %2$s.', 'wp-parsely' ),
- apiQueryMessage, getPeriodDescription( period, true )
- );
+ return posts;
}
/**
* Fetches the related posts data from the WordPress REST API.
*
- * @param {RelatedPostsApiQuery} query
- * @return {Promise>} Array of fetched posts.
- */
- private async fetchRelatedPostsFromWpEndpoint( query: RelatedPostsApiQuery ): Promise {
- const response = this.fetch( {
- path: addQueryArgs( '/wp-parsely/v2/stats/posts', {
- ...query.query,
- itm_source: 'wp-parsely-content-helper',
- } ),
- } );
-
- return response ?? [];
- }
-
- /**
- * Builds the query object used in the API for performing the related
- * posts request.
- *
- * @param {Period} period The period for which to fetch data.
- * @param {Metric} metric The metric to sort by.
- * @param {PostFilter} filter The selected filter type and value to use.
+ * @param {Period} period The period for which to fetch data.
+ * @param {Metric} metric The metric to sort by.
+ * @param {PostFilters} filters The filters to use in the request.
*
- * @return {RelatedPostsApiQuery} The query object.
+ * @return {Promise>} The array of fetched posts.
*/
- private buildRelatedPostsApiQuery(
- period: Period, metric:Metric, filter: PostFilter
- ): RelatedPostsApiQuery {
- const commonQueryParams = {
+ private async fetchRelatedPostsFromWpEndpoint(
+ period: Period, metric:Metric, filters: PostFilters
+ ): Promise {
+ const path = addQueryArgs( '/wp-parsely/v2/stats/posts', {
+ author: filters.author,
+ section: filters.section,
+ tag: filters.tags,
...getApiPeriodParams( period ),
limit: RELATED_POSTS_DEFAULT_LIMIT,
sort: metric,
- };
-
- if ( PostFilterType.Tag === filter.type ) {
- return ( {
- query: { tag: filter.value, ...commonQueryParams },
- /* translators: %s: message such as "with tag Foo" */
- message: sprintf( __( 'with tag "%1$s"', 'wp-parsely' ), filter.value ),
- } );
- }
-
- if ( PostFilterType.Section === filter.type ) {
- return ( {
- query: { section: filter.value, ...commonQueryParams },
- /* translators: %s: message such as "in category Foo" */
- message: sprintf( __( 'in section "%1$s"', 'wp-parsely' ), filter.value ),
- } );
- }
-
- if ( PostFilterType.Author === filter.type ) {
- return ( {
- query: { author: filter.value, ...commonQueryParams },
- /* translators: %s: message such as "by author John" */
- message: sprintf( __( 'by author "%1$s"', 'wp-parsely' ), filter.value ),
- } );
- }
+ itm_source: 'wp-parsely-content-helper',
+ } );
- // No filter type has been specified. The query cannot be formulated.
- throw new ContentHelperError(
- __( 'No valid filter type has been specified.', 'wp-parsely' ),
- ContentHelperErrorCode.CannotFormulateApiQuery
- );
+ return this.fetch( { path } ) ?? [];
}
}
diff --git a/src/content-helper/editor-sidebar/related-posts/related-posts.scss b/src/content-helper/editor-sidebar/related-posts/related-posts.scss
index a829d0f510..458650fcef 100644
--- a/src/content-helper/editor-sidebar/related-posts/related-posts.scss
+++ b/src/content-helper/editor-sidebar/related-posts/related-posts.scss
@@ -91,28 +91,9 @@
}
}
}
-
- .related-posts-filter-values {
- width: 100%;
-
- .components-combobox-control__suggestions-container .components-flex {
- height: to_rem(36px);
-
- input {
- margin: 0 var(--grid-unit-15);
- }
- }
- }
}
.related-posts-wrapper {
- .related-posts-descr {
- font-size: to_rem(13px);
- font-style: normal;
- font-weight: 400;
- line-height: to_rem(20px); /* 153.846% */
- }
-
.related-posts-loading-message,
.related-posts-empty {
overflow: hidden;
diff --git a/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php b/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php
index b405c83f3a..a4068b5124 100644
--- a/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php
+++ b/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php
@@ -81,18 +81,14 @@ protected function get_subvalues_specs(): array {
),
'RelatedPosts' => array(
'values' => array(
- 'FilterBy' => array( 'unavailable', 'tag', 'section', 'author' ),
- 'FilterValue' => array(),
- 'Metric' => array( 'views', 'avg_engaged' ),
- 'Open' => array( true, false ),
- 'Period' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ),
+ 'Metric' => array( 'views', 'avg_engaged' ),
+ 'Open' => array( true, false ),
+ 'Period' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ),
),
'default' => array(
- 'FilterBy' => 'unavailable',
- 'FilterValue' => '',
- 'Metric' => 'views',
- 'Open' => false,
- 'Period' => '7d',
+ 'Metric' => 'views',
+ 'Open' => false,
+ 'Period' => '7d',
),
),
'SmartLinking' => array(
diff --git a/src/services/content-api/endpoints/class-endpoint-analytics-posts.php b/src/services/content-api/endpoints/class-endpoint-analytics-posts.php
index 9036135748..685141b5af 100644
--- a/src/services/content-api/endpoints/class-endpoint-analytics-posts.php
+++ b/src/services/content-api/endpoints/class-endpoint-analytics-posts.php
@@ -118,9 +118,9 @@ public function get_endpoint_url( array $query_args = array() ): string {
$endpoint_url = parent::get_endpoint_url( $query_args );
// Append the author, tag, and section parameters to the endpoint URL.
- $endpoint_url = $this->append_multiple_params_to_url( $endpoint_url, $authors, 'author' );
- $endpoint_url = $this->append_multiple_params_to_url( $endpoint_url, $tags, 'tag' );
- $endpoint_url = $this->append_multiple_params_to_url( $endpoint_url, $sections, 'section' );
+ $endpoint_url = $this->append_same_key_params_to_url( $endpoint_url, $authors, 'author' );
+ $endpoint_url = $this->append_same_key_params_to_url( $endpoint_url, $tags, 'tag' );
+ $endpoint_url = $this->append_same_key_params_to_url( $endpoint_url, $sections, 'section' );
return $endpoint_url;
}
@@ -154,25 +154,35 @@ public function call( array $args = array() ) {
}
/**
- * Appends multiple parameters to the URL.
- *
- * This is required because the Parsely API requires the multiple values for the author, tag,
- * and section parameters to share the same key.
+ * Appends multiple parameters with the same key to the passed URL.
*
* @since 3.17.0
*
* @param string $url The URL to append the parameters to.
- * @param array $params The parameters to append.
- * @param string $param_name The name of the parameter.
+ * @param array $values The parameter values to append.
+ * @param string $key The common key to be used for the parameters.
* @return string The URL with the appended parameters.
*/
- protected function append_multiple_params_to_url( string $url, array $params, string $param_name ): string {
- foreach ( $params as $param ) {
- $param = rawurlencode( $param );
- if ( strpos( $url, $param_name . '=' ) === false ) {
- $url = add_query_arg( $param_name, $param, $url );
+ protected function append_same_key_params_to_url(
+ string $url,
+ array $values,
+ string $key
+ ): string {
+ if ( '' === $key ) {
+ return $url;
+ }
+
+ foreach ( $values as $value ) {
+ if ( '' === $value ) {
+ continue;
+ }
+
+ $value = rawurlencode( $value );
+
+ if ( false === strpos( $url, '?' ) ) {
+ $url .= '?' . $key . '=' . $value;
} else {
- $url .= '&' . $param_name . '=' . $param;
+ $url .= '&' . $key . '=' . $value;
}
}
diff --git a/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php b/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php
index 7bde554d24..0e1b91025c 100644
--- a/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php
+++ b/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php
@@ -74,11 +74,9 @@ public function get_default_value(): array {
'VisiblePanels' => array( 'overview', 'categories', 'referrers' ),
),
'RelatedPosts' => array(
- 'FilterBy' => 'unavailable',
- 'FilterValue' => '',
- 'Metric' => 'views',
- 'Open' => false,
- 'Period' => '7d',
+ 'Metric' => 'views',
+ 'Open' => false,
+ 'Period' => '7d',
),
'SmartLinking' => array(
'MaxLinks' => 10,
diff --git a/tests/Integration/Services/ContentAPI/Endpoints/EndpointAnalyticsPostsTest.php b/tests/Integration/Services/ContentAPI/Endpoints/EndpointAnalyticsPostsTest.php
index 4d522fe481..4947ecce5a 100644
--- a/tests/Integration/Services/ContentAPI/Endpoints/EndpointAnalyticsPostsTest.php
+++ b/tests/Integration/Services/ContentAPI/Endpoints/EndpointAnalyticsPostsTest.php
@@ -12,6 +12,7 @@
use Parsely\Services\Base_Service_Endpoint;
use Parsely\Services\Content_API\Content_API_Service;
+use Parsely\Services\Content_API\Endpoints\Endpoint_Analytics_Posts;
/**
* Tests the /analytics/posts endpoint.
@@ -45,4 +46,114 @@ public function data_api_url(): iterable {
Content_API_Service::get_base_url() . '/analytics/posts?limit=5&apikey=my-key&secret=my-secret',
);
}
+
+ /**
+ * Verifies that append_same_key_params_to_url() returns the expected
+ * results.
+ *
+ * @since 3.18.0
+ *
+ * @covers \Parsely\Services\Content_API\Endpoints\Endpoint_Analytics_Posts::append_same_key_params_to_url
+ * @uses \Parsely\Services\Base_Service_Endpoint::__construct
+ *
+ * @param string $url The URL to append the parameters to.
+ * @param array $values The parameter values to append.
+ * @param string $key The common key to be used for the parameters.
+ * @param string $expected The expected URL after appending the parameters.
+ *
+ * @dataProvider provide_data_for_test_append_same_key_params_to_url
+ */
+ public function test_append_same_key_params_to_url(
+ string $url,
+ array $values,
+ string $key,
+ string $expected
+ ): void {
+ $function = self::get_method(
+ 'append_same_key_params_to_url',
+ Endpoint_Analytics_Posts::class
+ );
+
+ $endpoint = new Endpoint_Analytics_Posts( $this->get_content_api() );
+ $actual = $function->invoke( $endpoint, $url, $values, $key );
+
+ self::assertSame( $expected, $actual );
+ }
+
+ /**
+ * Provides data for test_append_same_key_params_to_url().
+ *
+ * @since 3.18.0
+ *
+ * @return iterable
+ */
+ public function provide_data_for_test_append_same_key_params_to_url(): iterable {
+ // Basic delimiter handling.
+ yield 'Add 1 tag parameter to a URL without parameters' => array(
+ 'url' => 'https://example.com/',
+ 'values' => array( 'tag1' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/?tag=tag1',
+ );
+ yield 'Add 2 tag parameters to a URL without parameters' => array(
+ 'url' => 'https://example.com/',
+ 'values' => array( 'tag1', 'tag2' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/?tag=tag1&tag=tag2',
+ );
+
+ // Handling URLs that already contain parameters.
+ yield 'Add 2 tag parameters to a URL containing a param1 parameter' => array(
+ 'url' => 'https://example.com/?param1=value1',
+ 'values' => array( 'tag1', 'tag2' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/?param1=value1&tag=tag1&tag=tag2',
+ );
+ yield 'Add 2 tag parameters to a URL already containing a tag parameter' => array(
+ 'url' => 'https://example.com/?tag=tag1',
+ 'values' => array( 'tag2', 'tag3' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/?tag=tag1&tag=tag2&tag=tag3',
+ );
+ yield 'Add 2 author parameters to a URL containing 2 tag parameters' => array(
+ 'url' => 'https://example.com/?tag=tag1&tag=tag2',
+ 'values' => array( 'author1', 'author2' ),
+ 'key' => 'author',
+ 'expected' => 'https://example.com/?tag=tag1&tag=tag2&author=author1&author=author2',
+ );
+
+ // Handling special characters in values.
+ yield 'Add 2 tag parameters with special character values' => array(
+ 'url' => 'https://example.com/',
+ 'values' => array( 'tag@1', 'tag#2' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/?tag=tag%401&tag=tag%232',
+ );
+
+ // Handling empty values and arguments.
+ yield 'Allow empty URLs' => array(
+ 'url' => '',
+ 'values' => array( 'tag1', 'tag2' ),
+ 'key' => 'tag',
+ 'expected' => '?tag=tag1&tag=tag2',
+ );
+ yield 'Do not modify the URL if an empty key was provided' => array(
+ 'url' => 'https://example.com/',
+ 'values' => array( 'tag1' ),
+ 'key' => '',
+ 'expected' => 'https://example.com/',
+ );
+ yield 'Do not add empty parameters (single value)' => array(
+ 'url' => 'https://example.com/',
+ 'values' => array( '' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/',
+ );
+ yield 'Do not add empty parameters (multiple values)' => array(
+ 'url' => 'https://example.com/',
+ 'values' => array( 'tag1', '', 'tag2', '' ),
+ 'key' => 'tag',
+ 'expected' => 'https://example.com/?tag=tag1&tag=tag2',
+ );
+ }
}
diff --git a/tests/e2e/specs/content-helper/errors.spec.ts b/tests/e2e/specs/content-helper/errors.spec.ts
index fd80fa73d5..ee7eec6894 100644
--- a/tests/e2e/specs/content-helper/errors.spec.ts
+++ b/tests/e2e/specs/content-helper/errors.spec.ts
@@ -34,9 +34,7 @@ test.describe( 'PCH Editor Sidebar Related Posts panel', () => {
test( 'Should display an error when an invalid Site ID is provided', async ( { admin } ) => {
await setSiteKeys( admin.page, INVALID_SITE_ID, VALID_API_SECRET );
- expect( await getRelatedPostsMessage(
- admin, '', '', 'author', '.content-helper-error-message'
- ) ).toMatch( 'Error: Forbidden' );
+ expect( await getRelatedPostsMessage( admin ) ).toMatch( 'Error: Forbidden' );
} );
/**
@@ -85,7 +83,7 @@ test.describe( 'PCH Editor Sidebar Related Posts panel', () => {
await setSiteKeys( admin.page, VALID_SITE_ID, VALID_API_SECRET );
expect( await getRelatedPostsMessage(
- admin, '', '', 'author', '.related-posts-descr' )
- ).not.toMatch( contactMessage );
+ admin, '.wp-parsely-related-posts' )
+ ).toMatch( 'Find top-performing related posts.' );
} );
} );
diff --git a/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts b/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts
index 3b03192f9d..a81761328d 100644
--- a/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts
+++ b/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts
@@ -43,21 +43,7 @@ test.describe( 'PCH Editor Sidebar Related Post panel filters', () => {
*/
test( 'Should attempt to fetch results when a Site ID and API Secret are provided', async ( { admin } ) => {
expect( await getRelatedPostsMessage(
- admin, '', '', 'author', '.related-posts-empty'
- ) ).toMatch( `No related posts found.` );
- } );
-
- /**
- * Verifies that the Related Posts panel will work correctly when a new
- * taxonomy is added from within the WordPress Post Editor.
- *
- * @since 3.17.0 Migrated to Playwright.
- */
- test( 'Should work correctly when a taxonomy is added from within the WordPress Post Editor', async ( { admin } ) => {
- const categoryName = 'Analytics That Matter';
-
- expect( await getRelatedPostsMessage(
- admin, categoryName, '', 'section', '.related-posts-descr'
- ) ).toMatch( `Top related posts in the “${ categoryName }” section in the last 7 days.` );
+ admin, '.related-posts-loading-message'
+ ) ).toMatch( `Loading…` );
} );
} );
diff --git a/tests/e2e/specs/content-helper/top-bar-icon.spec.ts b/tests/e2e/specs/content-helper/top-bar-icon.spec.ts
index 327491e116..e952234edf 100644
--- a/tests/e2e/specs/content-helper/top-bar-icon.spec.ts
+++ b/tests/e2e/specs/content-helper/top-bar-icon.spec.ts
@@ -23,7 +23,6 @@ import {
* @since 3.17.0 Migrated to Playwright.
*/
test.describe( 'PCH Editor Sidebar top bar icon in the WordPress Post Editor', () => {
- const noRelatedPostsMessage = 'No related posts found.';
const emptyCredentialsMessage = 'Contact us about advanced plugin features and the Parse.ly dashboard.Existing Parse.ly customers can enable this feature by setting their Site ID and API Secret in wp-parsely options.';
/**
@@ -76,8 +75,8 @@ test.describe( 'PCH Editor Sidebar top bar icon in the WordPress Post Editor', (
expect( await utils.testContentHelperIcon(
VALID_SITE_ID, VALID_API_SECRET,
- '.related-posts-empty'
- ) ).toMatch( noRelatedPostsMessage );
+ '.wp-parsely-related-posts'
+ ) ).toMatch( 'Find top-performing related posts.' );
} );
/**
diff --git a/tests/e2e/utils.ts b/tests/e2e/utils.ts
index 4eb56629b8..116404eb8e 100644
--- a/tests/e2e/utils.ts
+++ b/tests/e2e/utils.ts
@@ -41,54 +41,23 @@ export const setSiteKeys = async (
*
* @since 3.17.0 Migrated to Playwright.
*
- * @param {Admin} admin The Admin object of the calling function.
- * @param {string} category Name of the category to select in the Post Editor.
- * @param {string} tag Name of the tag to select in the Post Editor.
- * @param {string} filterType The filter type to select in the dropdown.
- * @param {string} selector The selector from which to extract the message.
+ * @param {Admin} admin The Admin object of the calling function.
+ * @param {string} selector The selector from which to extract the message.
*
* @return {Promise} The message returned.
*/
export const getRelatedPostsMessage = async (
- admin: Admin, category: string = '', tag: string = '',
- filterType: string = '', selector: string = '.content-helper-error-message'
+ admin: Admin, selector: string = '.content-helper-error-message'
): Promise => {
const page = admin.page;
const contentHelperMessageSelector = '.wp-parsely-content-helper div.components-panel__body.is-opened ' + selector;
- // Run basic operations.
await admin.createNewPost();
- await admin.editor.openDocumentSettingsSidebar();
- // Select/add category in the Post Editor.
- if ( category !== '' ) {
- const categoryToggleButton = page.getByRole( 'button', { name: 'Categories' } );
- await categoryToggleButton.click();
- await page.getByRole( 'button', { name: 'Add New Category' } ).first().click();
- await page.getByLabel( 'New Category Name' ).fill( category );
- await page.getByRole( 'button', { name: 'Add New Category' } ).last().click();
- await categoryToggleButton.click();
- }
-
- // Select/add tag in the Post Editor.
- if ( tag !== '' ) {
- const tagToggleButton = page.getByRole( 'button', { name: 'Tags' } );
- await tagToggleButton.click();
- await page.getByLabel( 'Add New Tag' ).fill( tag );
- await page.keyboard.press( 'Enter' );
- await tagToggleButton.click();
- }
-
- // Show the Content Helper Sidebar.
+ // Show the Content Helper Sidebar and expand the Related Posts panel.
await page.getByRole( 'button', { name: 'Parse.ly' } ).click();
await setSidebarPanelExpanded( page, 'Related Posts', true );
- // Set the filter type.
- if ( '' !== filterType ) {
- await page.keyboard.press( 'Tab' );
- await page.keyboard.type( filterType.charAt( 0 ) );
- }
-
return await page.locator( contentHelperMessageSelector ).textContent() ?? '';
};
diff --git a/tests/js/content-helper/structure.test.tsx b/tests/js/content-helper/structure.test.tsx
index 9f1ed5e2d2..a5d641f8c4 100644
--- a/tests/js/content-helper/structure.test.tsx
+++ b/tests/js/content-helper/structure.test.tsx
@@ -18,11 +18,11 @@ import {
import {
DASHBOARD_BASE_URL,
} from '../../../src/content-helper/common/utils/constants';
+import { PostData } from '../../../src/content-helper/common/utils/post';
import {
RelatedPostsPanel,
} from '../../../src/content-helper/editor-sidebar/related-posts/component';
import {
- GetRelatedPostsResult,
RELATED_POSTS_DEFAULT_LIMIT,
RelatedPostsProvider,
} from '../../../src/content-helper/editor-sidebar/related-posts/provider';
@@ -125,10 +125,7 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
} );
test( 'should display spinner when starting', async () => {
- const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve( {
- message: 'Testing that the spinner appears and disappears.',
- posts: [],
- } ) );
+ const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve( [] ) );
await waitFor( async () => {
render( relatedPostsPanel );
@@ -182,36 +179,10 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
);
} );
- test( 'should show no results message when there is no tag or category in the post', async () => {
- const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve( {
- message: 'The Parse.ly API did not return any results for posts by "author".',
- posts: [],
- } ) );
-
- setMockPostData( [ 'admin' ], [], [] );
-
- await waitFor( async () => {
- render( relatedPostsPanel );
- expect( getLoadingMessage() ).toBeInTheDocument();
- } );
-
- expect( getRelatedPostsFn ).toHaveBeenCalled();
- expect( getLoadingMessage() ).toBeNull();
-
- const relatedPostDescr = getRelatedPostDescr();
- expect( relatedPostDescr ).toBeInTheDocument();
- expect( relatedPostDescr ).toBeVisible();
-
- // When there is no tag or category in the post, it should fallback to the author.
- expect( relatedPostDescr?.textContent ).toEqual( 'Top related posts by admin in the last 7 days.' );
- expect( getRelatedPostsEmptyMessage() ).toBeInTheDocument();
- } );
-
test( 'should show a single post with description and proper attributes', async () => {
- const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve( {
- message: `Posts in category "Developers" in last 7 days.`,
- posts: getRelatedPostsMockData( 1 ),
- } ) );
+ const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve(
+ getRelatedPostsMockData( 1 ),
+ ) );
setMockPostData( [], [ 'Developers' ], [] );
@@ -223,11 +194,6 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
expect( getRelatedPostsFn ).toHaveBeenCalled();
expect( getLoadingMessage() ).toBeNull();
- const relatedPostDescr = getRelatedPostDescr();
- expect( relatedPostDescr ).toBeInTheDocument();
- expect( relatedPostDescr ).toBeVisible();
- expect( relatedPostDescr?.textContent ).toEqual( `Top related posts in the “Developers” section in the last 7 days.` );
-
const relatedPosts = getRelatedPosts();
expect( relatedPosts.length ).toEqual( 1 );
const firstPost = relatedPosts[ 0 ];
@@ -250,10 +216,9 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
} );
test( 'should show 5 posts by default', async () => {
- const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve( {
- message: `Top related posts with the “Developers” tag in the last 7 days.`,
- posts: getRelatedPostsMockData(),
- } ) );
+ const getRelatedPostsFn = getRelatedPostsMockFn( () => Promise.resolve(
+ getRelatedPostsMockData()
+ ) );
setMockPostData( [ 'admin' ], [ 'Developers' ], [ 'Developers' ] );
@@ -264,7 +229,6 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
expect( getRelatedPostsFn ).toHaveBeenCalled();
expect( getLoadingMessage() ).toBeNull();
- expect( getRelatedPostDescr()?.textContent ).toEqual( `Top related posts with the “Developers” tag in the last 7 days.` );
expect( getRelatedPosts().length ).toEqual( 5 );
} );
@@ -287,23 +251,15 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
return screen.queryByTestId( 'parsely-related-posts-loading-message' );
}
- function getRelatedPostDescr() {
- return screen.queryByTestId( 'parsely-related-posts-descr' );
- }
-
function getRelatedPosts() {
return screen.queryAllByTestId( 'related-post-single' );
}
- function getRelatedPostsEmptyMessage() {
- return screen.queryByTestId( 'parsely-related-posts-empty' );
- }
-
function getCredentialsNotSetMessage() {
return screen.queryByTestId( 'empty-credentials-message' );
}
- function getRelatedPostsMockFn( mockFn: () => Promise ) {
+ function getRelatedPostsMockFn( mockFn: () => Promise ) {
return jest
.spyOn( RelatedPostsProvider.getInstance(), 'getRelatedPosts' )
.mockImplementation( mockFn );
@@ -331,7 +287,9 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
return posts;
}
- async function verifyCredentialsNotSetMessage( getRelatedPostsFn: jest.SpyInstance> ) {
+ async function verifyCredentialsNotSetMessage(
+ getRelatedPostsFn: jest.SpyInstance>
+ ) {
render( relatedPostsPanel );
expect( getLoadingMessage() ).toBeInTheDocument();
@@ -347,7 +305,9 @@ describe( 'PCH Editor Sidebar Related Post panel', () => {
return true;
}
- async function verifyApiErrorMessage( getRelatedPostsFn: jest.SpyInstance> ) {
+ async function verifyApiErrorMessage(
+ getRelatedPostsFn: jest.SpyInstance>
+ ) {
render( relatedPostsPanel );
expect( getLoadingMessage() ).toBeInTheDocument();