Skip to content

Commit

Permalink
PLANET-7344 Make featured image mandatory for publishing (#1190)
Browse files Browse the repository at this point in the history
This should be applied to all post types. It required a lot of test updates.
  • Loading branch information
mleray authored Apr 16, 2024
1 parent 3405169 commit 61a7f28
Show file tree
Hide file tree
Showing 19 changed files with 70 additions and 84 deletions.
9 changes: 8 additions & 1 deletion assets/src/BlockEditorValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ let canPublish = true;
export const blockEditorValidation = () => {
subscribe(() => {
const title = select('core/editor').getEditedPostAttribute('title');
const featuredImage = select('core/editor').getEditedPostAttribute('featured_media');
const postContent = select('core/editor').getEditedPostContent();
const blocks = select('core/block-editor').getBlocks();
const currentMessages = [];

Expand All @@ -19,6 +21,11 @@ export const blockEditorValidation = () => {
currentMessages.push('Title is required.');
}

const hasImageInContent = /<img.+wp-image-(\d+).*>/i.test(postContent);
if (!featuredImage && !hasImageInContent) {
currentMessages.push('Featured image is required.');
}

const invalidBlocks = blocks.reduce((invalidBlocksArray, block) => {
// Normally `blocks` contains a valid list of blocks, however it can happen that one of them is `null` in rare
// cases. It happened to me once while running with WordPress 5.8.1 and undoing multiple edits. This made the
Expand All @@ -45,7 +52,7 @@ export const blockEditorValidation = () => {
}, []);
invalidBlocks.forEach(block => currentMessages.push(...block.messages));

const currentlyValid = (0 === invalidBlocks.length) && !invalidTitle;
const currentlyValid = (0 === invalidBlocks.length) && !invalidTitle && (featuredImage || hasImageInContent);
messages = currentMessages;

if (canPublish === currentlyValid) {
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/articles.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

const TEST_TITLE = 'All Articles';
const TEST_DESCRIPTION = 'All articles in date order';
Expand All @@ -8,7 +8,7 @@ const TEST_BUTTON_TEXT = 'Load';
test.useAdminLoggedIn();

test('Test Articles block', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title:'Test Articles', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Articles', postType: 'page'});

// Add Articles block.
await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/carousel-header.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Create and check carousel header block', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title:'Test Carousel', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Carousel', postType: 'page'});

await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
await page.keyboard.type('/carousel');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/columns-icons.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';
import {addColumnsBlock, checkColumnsBlock} from './tools/lib/columns.js';

test.useAdminLoggedIn();

test('Test Columns block with Icons style', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title: 'Test Columns block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Columns block', postType: 'page'});

// Add Columns block.
await addColumnsBlock(page, editor, 'Icons');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/columns-images.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {addColumnsBlock, checkColumnsBlock} from './tools/lib/columns.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Test Columns block with Images style', async ({page, editor, admin}) => {
await admin.createNewPost({postType: 'page', title: 'Test Columns block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Columns block', postType: 'page'});

// Add Columns block.
await addColumnsBlock(page, editor, 'Images');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/columns-no-image.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {addColumnsBlock, checkColumnsBlock} from './tools/lib/columns.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Test Columns block with No Image style', async ({page, editor, admin}) => {
await admin.createNewPost({postType: 'page', title: 'Test Columns block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Columns block', postType: 'page'});

// Add Columns block.
await addColumnsBlock(page, editor);
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/columns-tasks.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {addColumnsBlock, checkColumnsBlock} from './tools/lib/columns.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Test Columns block with Tasks style', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title: 'Test Columns block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Columns block', postType: 'page'});

// Add Columns block.
await addColumnsBlock(page, editor, 'Tasks');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/covers-campaign.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {addCoversBlock, checkCoversBlock} from './tools/lib/covers.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Test Covers block with Campaign covers style', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title: 'Test Covers block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Covers block', postType: 'page'});

// Add Covers block.
await addCoversBlock(page, editor, 'Campaign');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/covers-content.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {addCoversBlock, checkCoversBlock} from './tools/lib/covers.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Test Covers block with Content covers style', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title: 'Test Covers block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Covers block', postType: 'page'});

// Add Covers block.
await addCoversBlock(page, editor, 'Content');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/covers-take-action.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test} from './tools/lib/test-utils.js';
import {addCoversBlock, checkCoversBlock} from './tools/lib/covers.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test('Test Covers block with Take Action covers style', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title: 'Test Covers block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Covers block', postType: 'page'});

// Add Covers block.
await addCoversBlock(page, editor, 'Take Action');
Expand Down
13 changes: 8 additions & 5 deletions tests/e2e/editor-selector.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

const TEST_TITLE = 'Test post';
const TEST_TEXT = 'This is a test post.';

test.useAdminLoggedIn();

test('Test Editor basic functionalities', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'post', title: 'Test Post', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: TEST_TITLE});

await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
await page.keyboard.type('This is a test Post.');
await page.keyboard.type(TEST_TEXT);
await page.keyboard.press('Enter');
await page.keyboard.type('/youtube');
await page.getByRole('option', {name: 'Youtube'}).click();
Expand All @@ -24,7 +27,7 @@ test('Test Editor basic functionalities', async ({page, admin, editor}) => {
const h1 = await page.innerHTML('h1.page-header-title');
const paragraph = await page.innerHTML('.post-details p');
const video = page.locator('figure.is-provider-youtube');
expect(h1).toBe('Test Post');
expect(paragraph).toBe('This is a test Post.');
expect(h1).toBe(TEST_TITLE);
expect(paragraph).toBe(TEST_TEXT);
await expect(video).toBeVisible();
});
7 changes: 5 additions & 2 deletions tests/e2e/enform.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPost} from './tools/lib/post.js';
import {publishPost, createPostWithFeaturedImage} from './tools/lib/post.js';

import fieldsData from './fixtures/enform/ensapi_sample_fields_response.json';
import questionsData from './fixtures/enform/ensapi_sample_questions_response.json';
Expand Down Expand Up @@ -192,7 +192,10 @@ test.describe('create, use and submit EN Form', () => {
});

async function createPageWithENForm(page, admin, editor, style) {
await admin.createNewPost({postType: 'page', title: 'Test page with enform (style)', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {
title: 'Test page with enform (style)',
postType: 'page',
});

await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
await page.keyboard.type('/enform');
Expand Down
10 changes: 4 additions & 6 deletions tests/e2e/related-articles.spec.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPost, updatePost} from './tools/lib/post.js';
import {publishPost, updatePost, createPostWithFeaturedImage} from './tools/lib/post.js';
import {
openPostSettingsPanel,
addCategory, addTag, addPostType,
removeAllPostTypes, addFeaturedImage,
removeAllPostTypes,
} from './tools/lib/editor.js';

test.useAdminLoggedIn();

test('Test Related Articles block', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'post', title: 'Test post for Related articles', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test post for Related articles'});

await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
await page.keyboard.type('Test paragraph.');

//
// Add post category, type and tag
//
await openPostSettingsPanel({editor, page});
await editor.openDocumentSettingsSidebar();
await addCategory({editor}, 'Energy');
await removeAllPostTypes({editor});
await addPostType({editor}, 'Press Release');
await addTag({editor}, 'Renewables');
await addFeaturedImage({editor}, 328);

//
// Related articles enabled
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/split-two-columns.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

Expand All @@ -11,7 +11,7 @@ test('Create and check check split two column block', async ({page, admin, edito
test.skip();
}

await admin.createNewPost({postType: 'page', title: 'Test S2C block', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test S2C block', postType: 'page'});

// Adding Split Two Column Block
await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/spreadsheet.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

const SHEET_ID = '2PACX-1vR2LTvb__ifqY0ayZzqWyzkJGPyMUyUvili9YotHs_1YymJqjSeECFImhzlJfN3k9xw0CVBwR4HuTOg';
const TEST_URL = `https://docs.google.com/spreadsheets/d/e/${SHEET_ID}/pubhtml`;

test.useAdminLoggedIn();

test('Test Spreadsheet block', async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'page', title: 'Test Spreadsheet', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Spreadsheet', postType: 'page'});

// Add Spreadsheet block.
await editor.canvas.getByRole('button', {name: 'Add default block'}).click();
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/take-action-boxout.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {test, expect} from './tools/lib/test-utils.js';
import {publishPostAndVisit} from './tools/lib/post.js';
import {publishPostAndVisit, createPostWithFeaturedImage} from './tools/lib/post.js';

test.useAdminLoggedIn();

test.describe('Test Take Action Boxout block', () => {
test.beforeEach(async ({page, admin, editor}) => {
await admin.createNewPost({postType: 'post', title: 'Test Take action boxout', legacyCanvas: true});
await createPostWithFeaturedImage({admin, editor}, {title: 'Test Take action boxout'});

// Add Take Action Boxout block.
const actionRequest = page.waitForRequest(/.*\/wp-json\/wp\/v2\/p4_action.*/);//NOSONAR
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/tools/lib/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ async function addColumnsBlock(page, editor, style) {
await column.locator('.columns-image-placeholder').hover({noWaitAfter: true});
await column.locator('.dashicons-plus-alt2').click();
// Select image from media library modal.
const mediaModal = page.locator('.media-modal').nth(index);
await mediaModal.locator('button#menu-item-browse').click();
await mediaModal.locator('.attachments-wrapper ul.attachments li').nth(-1-index).click();
await mediaModal.locator('button.media-button-select').click();
const imageModal = await editor.canvas.getByLabel(/Select or Upload Media/);
await imageModal.getByRole('tab', {name: 'Media Library'}).click();
await imageModal.getByRole('tabpanel', {name: 'Media Library'}).locator(`[data-id="${style === 'Images' ? 357 : 318}"]`).click();
await imageModal.getByRole('button', {name: 'Select', exact: true}).click();
}
}
};
Expand Down
43 changes: 2 additions & 41 deletions tests/e2e/tools/lib/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,15 @@
* @property {Function} getByLabel - Get by label
*/

/**
* Open side panel settings for edited post/page/etc.
*
* @param {{Editor, Page}} editor
* @return {Locator} Playwright Locator
*/
async function openPostSettingsPanel({editor, page}) {
const topBar = await page.getByRole('region', {name: 'Editor top bar'});
const settingsButton = await topBar.getByRole('button', {name: 'Settings', exact: true});
const settingsExpanded = await settingsButton.getAttribute('aria-expanded');
if (settingsExpanded === 'false') {
await settingsButton.click();
}

const editorSettings = await editor.canvas.getByRole('region', {name: 'Editor settings'});
await editorSettings.locator('.components-panel__header').getByRole('button', {name: /Post|Page/}).click();

return editorSettings;
}

/**
* @param {{Editor}} editor
* @param {string} panelTitle - Panel title
* @return {Locator} Playwright Locator
*/
async function openComponentPanel({editor}, panelTitle) {
await editor.openDocumentSettingsSidebar();
const editorSettings = await editor.canvas.getByRole('region', {name: 'Editor settings'});
await editorSettings.locator('.edit-post-sidebar__panel-tab').first().click();
const panelButton = await editorSettings.getByRole('button', {name: panelTitle, exact: true});
const panelExpanded = await panelButton.getAttribute('aria-expanded');
if (panelExpanded === 'false') {
Expand Down Expand Up @@ -90,31 +72,10 @@ async function removeAllPostTypes({editor}) {
}
}

/**
* Add a Featured image to a Post
*
* @param {{Editor}} editor
* @param {number} imageId - The image ID from the Image Library
*/
async function addFeaturedImage({editor}, imageId) {
const editorSettings = await openComponentPanel({editor}, 'Featured image');

await editorSettings.getByRole('button', {name: 'Set featured image'}).click();
const imageModal = await editor.canvas.getByRole('dialog', {name: 'Featured image'});
const mediaLibTab = await imageModal.getByRole('tab', {name: 'Media Library'});
await mediaLibTab.click();
await imageModal.getByRole('tabpanel', {name: 'Media Library'});

await imageModal.locator(`[data-id="${imageId}"]`).click();
await imageModal.getByRole('button', {name: 'Set featured image'}).click();
}

export {
openPostSettingsPanel,
openComponentPanel,
addCategory,
addTag,
addPostType,
removeAllPostTypes,
addFeaturedImage,
};
16 changes: 15 additions & 1 deletion tests/e2e/tools/lib/post.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {openComponentPanel} from './editor.js';

async function publishPost({page, editor}) {
await editor.publishPost();

Expand All @@ -22,4 +24,16 @@ async function updatePost({page}) {
return page.waitForSelector('.components-snackbar');
}

export {publishPost, publishPostAndVisit, updatePost};
async function createPostWithFeaturedImage({admin, editor}, params) {
await admin.createNewPost({...params, legacyCanvas: true});
const editorSettings = await openComponentPanel({editor}, 'Featured image');
await editorSettings.getByRole('button', {name: 'Set featured image'}).click();
const imageModal = await editor.canvas.getByRole('dialog', {name: 'Featured image'});
const mediaLibTab = await imageModal.getByRole('tab', {name: 'Media Library'});
await mediaLibTab.click();
await imageModal.getByRole('tabpanel', {name: 'Media Library'});
await imageModal.getByRole('checkbox', {name: 'OCEANS-GP0STOM6C'}).click();
await imageModal.getByRole('button', {name: 'Set featured image'}).click();
}

export {publishPost, publishPostAndVisit, updatePost, createPostWithFeaturedImage};

0 comments on commit 61a7f28

Please sign in to comment.