diff --git a/includes/admin/feedzy-rss-feeds-import.php b/includes/admin/feedzy-rss-feeds-import.php index 15753f95..7d36b806 100644 --- a/includes/admin/feedzy-rss-feeds-import.php +++ b/includes/admin/feedzy-rss-feeds-import.php @@ -1663,20 +1663,20 @@ private function run_job( $job, $max ) { $image_source_url = ''; $img_success = true; $new_post_id = 0; - $default_img_tag = ! empty( $import_featured_img ) && is_string( $import_featured_img ) ? $import_featured_img : ''; + $feed_img_tag = ! empty( $import_featured_img ) && is_string( $import_featured_img ) ? $import_featured_img : ''; // image tag - if ( strpos( $default_img_tag, '[#item_image]' ) !== false ) { + if ( strpos( $feed_img_tag, '[#item_image]' ) !== false ) { // image exists in item if ( ! empty( $item['item_img_path'] ) ) { - $image_source_url = str_replace( '[#item_image]', $item['item_img_path'], $default_img_tag ); + $image_source_url = str_replace( '[#item_image]', $item['item_img_path'], $feed_img_tag ); } else { $img_success = false; } - } elseif ( strpos( $default_img_tag, '[#item_custom' ) !== false ) { + } elseif ( strpos( $feed_img_tag, '[#item_custom' ) !== false ) { // custom image tag if ( $this->feedzy_is_business() || $this->feedzy_is_personal() ) { - $value = apply_filters( 'feedzy_parse_custom_tags', $default_img_tag, $item_obj ); + $value = apply_filters( 'feedzy_parse_custom_tags', $feed_img_tag, $item_obj ); } if ( ! empty( $value ) && strpos( $value, '[#item_custom' ) === false ) { @@ -1685,7 +1685,7 @@ private function run_job( $job, $max ) { $img_success = false; } } else { - $image_source_url = $default_img_tag; + $image_source_url = $feed_img_tag; } if ( ! empty( $image_source_url ) ) { @@ -1770,24 +1770,24 @@ function( $term ) { do_action( 'feedzy_import_extra', $job, $item_obj, $new_post_id, $import_errors, $import_info ); - $default_img_tag = ! empty( $import_featured_img ) && is_string( $import_featured_img ) ? $import_featured_img : ''; - if ( ! empty( $default_img_tag ) && 'attachment' !== $import_post_type ) { + if ( ! empty( $import_featured_img ) && 'attachment' !== $import_post_type ) { $image_source_url = ''; $img_success = true; - // image tag - if ( strpos( $default_img_tag, '[#item_image]' ) !== false ) { - // image exists in item - if ( ! empty( $item['item_img_path'] ) ) { - $image_source_url = str_replace( '[#item_image]', $item['item_img_path'], $default_img_tag ); + $feed_img_tag = false === strpos( $import_featured_img, '[[{"value":' ) ? $import_featured_img : '[#item_image]'; // Use feed default image when we are using chained actions. + + // Set the feed image as default value for the image source. + if ( strpos( $feed_img_tag, '[#item_image]' ) !== false ) { + if ( ! empty( $item['item_img_path'] ) ) { // image exists in item + $image_source_url = str_replace( '[#item_image]', $item['item_img_path'], $feed_img_tag ); } else { $img_success = false; } - } elseif ( strpos( $default_img_tag, '[#item_custom' ) !== false ) { - // custom image tag - if ( $this->feedzy_is_business() || $this->feedzy_is_personal() ) { - $value = apply_filters( 'feedzy_parse_custom_tags', $default_img_tag, $item_obj ); - } + } elseif ( + ( $this->feedzy_is_business() || $this->feedzy_is_personal() ) && // PRO feature. + false !== strpos( $feed_img_tag, '[#item_custom' ) + ) { + $value = apply_filters( 'feedzy_parse_custom_tags', $feed_img_tag, $item_obj ); // custom image tag if ( ! empty( $value ) && strpos( $value, '[#item_custom' ) === false ) { $image_source_url = $value; } else { @@ -1840,12 +1840,12 @@ function( $term ) { } if ( 'yes' === $import_item_img_url || ! $this->tryReuseExistingFeaturedImage( $img_success, $item['item_title'], $new_post_id ) ) { - // Item image action. + // Run chained actions. $import_featured_img = rawurldecode( $import_featured_img ); $import_featured_img = trim( $import_featured_img ); $img_action = $this->get_actions_runner( $import_featured_img, 'item_image' ); // Item image action process. - $image_source_url = $img_action->run_action_job( $import_featured_img, $import_translation_lang, $job, $language_code, $item, $image_source_url ); + $image_source_url = $img_action->run_action_job( $img_action->get_serialized_actions(), $import_translation_lang, $job, $language_code, $item, $image_source_url ); if ( ! empty( $image_source_url ) ) { if ( 'yes' === $import_item_img_url ) { diff --git a/tests/e2e/specs/import.spec.js b/tests/e2e/specs/import.spec.js index 72328ebc..682eaf90 100644 --- a/tests/e2e/specs/import.spec.js +++ b/tests/e2e/specs/import.spec.js @@ -8,7 +8,12 @@ import { addFeeds, runFeedImport, addFeaturedImage, - addContentMapping + addContentMapping, + getEmptyChainedActions, + serializeChainedActions, + wrapSerializedChainedActions, + setItemLimit, + getPostsByFeedzy } from '../utils'; test.describe( 'Feed Import', () => { @@ -41,7 +46,7 @@ test.describe( 'Feed Import', () => { }); test( 'import lazy loading feeds with shortcode', async({ editor, page, admin }) => { - const lazyShortcode = "[feedzy-rss feeds='https://s3.amazonaws.com/verti-utils/sample-feed.xml' max='11' offset='1' feed_title='yes' refresh='1_hours' meta='yes' multiple_meta='yes' summary='yes' price='yes' mapping='price=im:price' thumb='yes' keywords_title='God, Mendes, Cyrus, Taylor' keywords_ban='Cyrus' template='style1' lazy='yes']"; + const lazyShortcode = "[feedzy-rss feeds='https://s3.amazonaws.com/verti-utils/sample-feed.xml' max='2' offset='1' feed_title='yes' refresh='1_hours' meta='yes' multiple_meta='yes' summary='yes' price='yes' mapping='price=im:price' thumb='yes' keywords_title='God, Mendes, Cyrus, Taylor' keywords_ban='Cyrus' template='style1' lazy='yes']"; await admin.createNewPost(); @@ -63,7 +68,7 @@ test.describe( 'Feed Import', () => { } ); test( 'import multiple feeds with shortcode', async({ editor, page, admin }) => { - const multipleFeedsShortCode = "[feedzy-rss feeds='https://s3.amazonaws.com/verti-utils/sample-feed-multiple1.xml, https://s3.amazonaws.com/verti-utils/sample-feed-multiple2.xml' max='10' feed_title='no' refresh='1_hours' meta='yes' multiple_meta='yes' summary='yes' thumb='yes' template='style1']"; + const multipleFeedsShortCode = "[feedzy-rss feeds='https://s3.amazonaws.com/verti-utils/sample-feed-multiple1.xml, https://s3.amazonaws.com/verti-utils/sample-feed-multiple2.xml' max='1' feed_title='no' refresh='1_hours' meta='yes' multiple_meta='yes' summary='yes' thumb='yes' template='style1']"; await admin.createNewPost(); @@ -114,6 +119,7 @@ test.describe( 'Feed Import', () => { await page.getByPlaceholder('Add a name for your import').fill(importName); await addFeeds( page, [FEED_URL] ); + await setItemLimit(page, 1); await page.getByRole('button', { name: 'Save & Activate importing' }).click({ force: true }); await runFeedImport( page ); @@ -130,6 +136,7 @@ test.describe( 'Feed Import', () => { await page.getByPlaceholder('Add a name for your import').fill(importName); await addFeeds( page, [FEED_URL] ); await addFeaturedImage( page, '[#item_image]' ); + await setItemLimit(page, 1); await page.getByRole('button', { name: 'Save & Activate importing' }).click({ force: true }); await runFeedImport( page ); @@ -141,7 +148,7 @@ test.describe( 'Feed Import', () => { await expect( page.getByLabel('Edit or replace the image') ).toBeVisible(); // Featured image is added. }); - test( 'importing feed with chained actions', async({ admin, page }) => { + test( 'importing feed with chained actions', async({ admin, page, requestUtils }) => { await admin.createNewPost(); const importName = 'Test Title: importing feed from URL with featured image'; @@ -151,26 +158,50 @@ test.describe( 'Feed Import', () => { await page.getByPlaceholder('Add a name for your import').fill(importName); await addFeeds( page, [FEED_URL] ); - await addContentMapping( page, '[[{"value":"%5B%7B%22id%22%3A%22trim%22%2C%22tag%22%3A%22item_content%22%2C%22data%22%3A%7B%22trimLength%22%3A%2230%22%7D%7D%5D"}]] '); // Trim the content with 30 words max. - await addFeaturedImage( page, '[[{"value":"%5B%7B%22id%22%3A%22%22%2C%22tag%22%3A%22item_image%22%2C%22data%22%3A%7B%7D%7D%5D"}]] ' ); + await addContentMapping( page, wrapSerializedChainedActions( serializeChainedActions( [ + { + "id": "trim", + "tag": "item_content", + "data": { + "trimLength": "30" + } + } + ] ) ) ); + await addFeaturedImage( page, getEmptyChainedActions( 'item_image' ) ); + await setItemLimit(page, 1); await page.getByRole('button', { name: 'Save & Activate importing' }).click({ force: true }); await runFeedImport( page ); + const posts = await getPostsByFeedzy( requestUtils ); - // Select the first post created by feeds import. Check the featured image. - await page.getByRole('link', { name: 'Posts', exact: true }).click({ force: true }); - await page.locator('#the-list tr').first().locator('a.row-title').click({ force: true }); + for ( const post of posts ) { + expect( post.featured_media ).toBeGreaterThan(0); + expect( post.content.rendered.split(' ').length ).toBeLessThanOrEqual(30); + } + }); + + test( 'image gallery for feeds imported with featured image chained actions', async({ admin, page }) => { + await admin.createNewPost(); + + const importName = 'Test Title: image gallery for feeds imported with featured image chained actions'; + + await page.goto('/wp-admin/post-new.php?post_type=feedzy_imports'); + await tryCloseTourModal( page ); + + await page.getByPlaceholder('Add a name for your import').fill(importName); + await addFeeds( page, [FEED_URL] ); + await addFeaturedImage( page, getEmptyChainedActions( 'item_image' ) ); + + await page.getByRole('button', { name: 'Save & Activate importing' }).click({ force: true }); - await expect( page.getByLabel('Add title') ).toBeVisible(); // Post title. + await page.goto('/wp-admin/edit.php?post_type=feedzy_imports'); - // Content should be trimmed to 30 words. - const content = await page.getByPlaceholder('Write HTML…').inputValue(); - expect( content ).toContain('

'); - expect( content.split(' ').length ).toBeLessThanOrEqual(30); + await runFeedImport( page ); - // Enable this test for https://github.com/Codeinwp/feedzy-rss-feeds/pull/946 when the PR is merged. - // await page.getByRole('button', { name: 'Featured image' }).click({ force: true }); - // await expect( page.getByLabel('Edit or replace the image') ).toBeVisible(); // Featured image is added. + // All the imported image should be available in the media library. + await page.goto('/wp-admin/upload.php'); + await page.waitForSelector('#wp-media-grid'); + await expect( page.locator('.attachment').count() ).resolves.toBeGreaterThan(0); // We should have some imported images. }); }); diff --git a/tests/e2e/utils.js b/tests/e2e/utils.js index 36baa821..d7b407d5 100644 --- a/tests/e2e/utils.js +++ b/tests/e2e/utils.js @@ -55,6 +55,45 @@ export async function addContentMapping( page, mapping ) { }, mapping ); } +/** + * Set the item limit on the Feed Edit page. + * @param {import('playwright').Page} page The page object. + * @param {number} limit The limit to set. + * @returns {Promise} + */ +export async function setItemLimit( page, limit ) { + await page.evaluate( ( limit ) => { + document.querySelector( 'input[name="feedzy_meta_data[import_feed_limit]"]' ).value = limit; + } , limit ); +} + +/** + * Create an empty chained actions. + * @param {string} defaultFeedTag The default feed tag. + * @returns {string} The empty chained actions. + */ +export function getEmptyChainedActions( defaultFeedTag ) { + return wrapSerializedChainedActions(serializeChainedActions([ { id: '', tag: defaultFeedTag, data: {} } ] ) ); +} + +/** + * Serialize the chained actions. + * @param {any[]} actions The actions to serialize. + * @returns {string} The serialized actions. + */ +export function serializeChainedActions( actions ) { + return encodeURIComponent( JSON.stringify( actions ) ); +} + +/** + * Wrap the serialized chained actions to match the format used in the input. + * @param {string} actions The serialized actions. + * @returns {string} The wrapped actions. + */ +export function wrapSerializedChainedActions( actions ) { + return `[[{"value":"${actions}"}]]`; +} + /** * Run the feed import. * @@ -120,3 +159,21 @@ export async function deleteAllFeedImports( requestUtils ) { ) ); } + +/** + * Get post created with Feedzy. + * @param {RequestUtils} requestUtils The request utils object. + * @returns {Promise<*>} + */ +export async function getPostsByFeedzy( requestUtils ) { + return await requestUtils.rest({ + path: '/wp/v2/posts', + params: { + per_page: 100, + status: 'publish', + meta_key: 'feedzy', + meta_value: 1, + meta_compare: '=', + }, + }); +}