diff --git a/.dev/mailhog.php b/.dev/mailhog.php index 19508dc0dbc..ce686a6f912 100644 --- a/.dev/mailhog.php +++ b/.dev/mailhog.php @@ -1,13 +1,18 @@ isSMTP(); +add_action( + 'phpmailer_init', + function( $phpmailer ) { + // Define that we are sending with SMTP. + $phpmailer->isSMTP(); - // Set options. - $phpmailer->Host = 'localhost'; - $phpmailer->SMTPAuth = false; - $phpmailer->Port = '1025'; - $phpmailer->From = 'admin@wp.dev'; - $phpmailer->FromName = 'WP DEV'; -}, 10, 1 ); + // Set options. + $phpmailer->Host = 'localhost'; + $phpmailer->SMTPAuth = false; + $phpmailer->Port = '1025'; + $phpmailer->From = 'admin@wp.dev'; + $phpmailer->FromName = 'WP DEV'; + }, + 10, + 1 +); diff --git a/.dev/tests/cypress/helpers.js b/.dev/tests/cypress/helpers.js index ad2de6542a1..ab514137f4f 100644 --- a/.dev/tests/cypress/helpers.js +++ b/.dev/tests/cypress/helpers.js @@ -34,7 +34,7 @@ export function addFormChild( name ) { cy.get( '[data-type="coblocks/form"] [data-type="core/paragraph"]' ).click( { force: true } ); cy.get( '.edit-post-header-toolbar' ).find( '.edit-post-header-toolbar__inserter-toggle' ).click( { force: true } ); - cy.get( '.block-editor-inserter__search' ).click().type( name ); + cy.get( '.block-editor-inserter__search .components-search-control__input' ).click().type( name ); cy.get( '.editor-block-list-item-coblocks-field-' + name ).first().click( { force: true } ); cy.get( `[data-type="coblocks/field-${ name }"]` ).should( 'exist' ).click( { force: true } ); @@ -69,7 +69,7 @@ export function goTo( path = '/wp-admin', login = false ) { } /** - * Safely obtain the window object or error + * Safely obtain the window data object or error * when the window object is not available. */ export function getWPDataObject() { @@ -78,6 +78,16 @@ export function getWPDataObject() { } ); } +/** + * Safely obtain the window blocks object or error + * when the window object is not available. + */ +export function getWPBlocksObject() { + return cy.window().its( 'wp' ).then( ( wp ) => { + return wp.blocks; + } ); +} + /** * Disable Gutenberg Tips */ @@ -97,7 +107,9 @@ export function disableGutenbergFeatures() { } /** - * From inside the WordPress editor open the CoBlocks Gutenberg editor panel + * From inside the WordPress editor insert a block by blockName. + * This function has changed to insert blocks by the via dispatch to `core/block-editor`. + * The old method, using the inserter with Cypress triggers a race condition crashing the editor. * * @param {string} blockName The name to find in the block inserter * e.g 'core/image' or 'coblocks/accordion'. @@ -115,29 +127,28 @@ export function addBlockToPost( blockName, clearEditor = false ) { clearBlocks(); } - if ( Cypress.$( '.edit-post-header-toolbar__inserter-toggle[aria-pressed="false"]' ) ) { - cy.get( '.edit-post-header [aria-label="Add block"], .edit-site-header [aria-label="Add block"], .edit-post-header-toolbar__inserter-toggle[aria-pressed="false"]' ).click(); - } - - cy.get( '.block-editor-inserter__search-input,input.block-editor-inserter__search, .components-search-control__input' ).click().type( blockName ); + // Ensure editor is ready for blocks. + cy.get( '.is-root-container.wp-block-post-content' ); /** - * The network request to block-directory may be cached and is not consistently fired with each test. - * Instead of intercepting we can await known dom elements that appear only when search results are present. - * This should correct a race condition in CI. + * Insert the block using dispatch to avoid the block inserter + * + * Note: This method is preferred over the old method because + * we do not need to test the Core controls around block insertion. */ - cy.get( 'div.block-editor-inserter__main-area:not(.show-as-tabs)' ); - - const targetClassName = ( blockCategory === 'core' ? '' : `-${ blockCategory }` ) + `-${ blockID }`; - cy.get( '.editor-block-list-item' + targetClassName ).first().click( { force: true } ); + getWPDataObject().then( ( data ) => { + getWPBlocksObject().then( ( blocks ) => { + data.dispatch( 'core/block-editor' ).insertBlock( + blocks.createBlock( blockName ) + ); + } ); + } ); // Make sure the block was added to our page cy.get( `[class*="-visual-editor"] [data-type="${ blockName }"]` ).should( 'exist' ); - // Then close the block inserter if still open. - const inserterButton = Cypress.$( 'button[class*="__inserter-toggle"].is-pressed' ); - if ( !! inserterButton.length ) { - cy.get( 'button[class*="__inserter-toggle"].is-pressed' ).click(); - } + + // Give a short delay for blocks to render. + cy.wait( 250 ); } export function addNewGroupToPost() { @@ -184,6 +195,9 @@ export function savePage() { */ export function checkForBlockErrors( blockName ) { + // Ensure editor is ready for blocks. + cy.get( '.is-root-container.wp-block-post-content' ); + disableGutenbergFeatures(); cy.get( '.block-editor-warning' ).should( 'not.exist' ); @@ -295,26 +309,27 @@ export function setNewBlockStyle( style ) { * Input parameter is the name of the block to select. * Allows chaining. * - * @param {string} name The name of the block to select eg: highlight or click-to-tweet - * @param {boolean} isChildBlock Optional selector for children blocks. Default will be top level blocks. + * @param {string} name The name of the block to select eg: highlight or click-to-tweet */ -export function selectBlock( name, isChildBlock = false ) { - openBlockNavigator(); - - if ( isChildBlock ) { - cy.get( '.block-editor-list-view__expander svg' ).first().click(); - } - - // A small wait seems needed to make sure that the list of blocks on the left is complete - cy.wait( 250 ); - - // Returning the cy.get function allows to chain off of selectBlock - return cy.get( '.block-editor-block-navigation-leaf,.block-editor-list-view-leaf' ) - .contains( isChildBlock ? RegExp( `${ name }$`, 'i' ) : RegExp( name, 'i' ) ) - .click() - .then( () => { - // Then close the block navigator if still open. - closeBlockNavigator(); +export function selectBlock( name ) { + /** + * There are network requests taking place to the REST API to get the blocks and block patterns. + * Sometimes these requests occur and other times they are cached and are not called. + * For that reason is difficult to assert against those requests from core code. + * We introduce an arbitrary wait to avoid a race condition by interacting too quickly. + */ + cy.wait( 1000 ); + + // `data-type` includes lower case name and `data-title` includes upper case name. + // Allows for case insensitive search. + cy.get( `[data-type*="${ name }"], [data-title*="${ name }"]` ) + .invoke( 'attr', 'data-block' ) + .then( ( clientId ) => { + cy.window().then( ( win ) => { + // Open the block sidebar. + win.wp.data.dispatch( 'core/edit-post' ).openGeneralSidebar( 'edit-post/block' ); + win.wp.data.dispatch( 'core/block-editor' ).selectBlock( clientId ); + } ); } ); } @@ -387,20 +402,28 @@ export const upload = { /** * Upload image to input element. * - * @param {string} blockName The name of the block that is upload target - * e.g 'core/image' or 'coblocks/accordion'. + * @param {string} blockName The name of the block that is upload target + * e.g 'core/image' or 'coblocks/accordion'. + * @param {boolean} allBlocks Whether to iterate and upload to all block dropzone selectors. */ - imageToBlock: ( blockName ) => { + imageToBlock: ( blockName, allBlocks = false ) => { const { fileName, pathToFixtures } = upload.spec; let fileContent; + cy.fixture( pathToFixtures + fileName, { encoding: null } ).then( ( fileCont ) => { fileContent = fileCont; - cy.get( `[data-type="${ blockName }"] input[type="file"]` ).first() - .selectFile( { contents: fileContent, fileName: pathToFixtures + fileName, mimeType: 'image/png' }, { force: true } ); - } ); - // Now validate upload is complete and is not a blob. - cy.get( `[class*="-visual-editor"] [data-type="${ blockName }"] [src^="http"]` ); + if ( allBlocks ) { + cy.get( `[data-type="${ blockName }"] .components-drop-zone` ).each( ( zone ) => { + cy.wrap( zone ).selectFile( { contents: fileContent, fileName: pathToFixtures + fileName, mimeType: 'image/png' }, { action: 'drag-drop', force: true } ); + } ); + } else { + cy.get( `[data-type="${ blockName }"] .components-drop-zone` ).first() + .selectFile( { contents: fileContent, fileName: pathToFixtures + fileName, mimeType: 'image/png' }, { action: 'drag-drop', force: true } ); + } + // Now validate upload is complete and is not a blob. + cy.get( `[class*="-visual-editor"] [data-type="${ blockName }"] [src^="http"]` ); + } ); }, spec: { fileName: '150x150.png', @@ -445,6 +468,11 @@ export function setColorPanelSetting( settingName, hexColor ) { * @param {RegExp} panelText The panel label text to open. eg: Color Settings */ export function openSettingsPanel( panelText ) { + // Ensure block tab is selected. + if ( Cypress.$( 'button[data-label="Block"]:not(.is-active)' ) ) { + cy.get( 'button[data-label="Block"]' ).click(); + } + cy.get( '.components-panel__body' ) .contains( panelText ) .then( ( $panelTop ) => { @@ -461,12 +489,20 @@ export function openSettingsPanel( panelText ) { * @param {number} headingLevel The button that should be located and clicked */ export function openHeadingToolbarAndSelect( headingLevel ) { - cy.get( '.block-editor-block-toolbar .block-editor-block-toolbar__slot button' ).each( ( button, index ) => { - if ( index === 1 ) { // represents the second position in the toolbar - cy.get( button ).click( { force: true } ); - } - } ); - cy.get( '.components-popover__content div[role="menu"] button' ).contains( headingLevel ).focus().click(); + // Button has aria label select the heading + if ( Cypress.$( '.block-editor-block-toolbar .block-editor-block-toolbar__slot button[aria-label="Change heading level"]' ) ) { + cy.get( '.block-editor-block-toolbar .block-editor-block-toolbar__slot button[aria-label="Change heading level"]' ).click(); + cy.get( '.components-popover__content div[role="menu"] button' ).contains( headingLevel ).focus().click(); + } else { + // No aria label present. Attempt to set using old method. + + cy.get( '.block-editor-block-toolbar .block-editor-block-toolbar__slot button' ).each( ( button, index ) => { + if ( index === 1 ) { // represents the second position in the toolbar + cy.get( button ).click( { force: true } ); + } + } ); + cy.get( '.components-popover__content div[role="menu"] button' ).contains( headingLevel ).focus().click(); + } } /** diff --git a/.dev/tests/jest/helpers.js b/.dev/tests/jest/helpers.js index 16f9e3b2f61..fd8915cf233 100644 --- a/.dev/tests/jest/helpers.js +++ b/.dev/tests/jest/helpers.js @@ -12,27 +12,28 @@ import '../../../src/extensions/button-controls'; import '../../../src/extensions/colors'; import '../../../src/extensions/image-crop'; import '../../../src/extensions/typography'; +import { registerBlock } from '../../../src/utils/helper'; // Imports used for registerGalleryBlocks(). -import { metadata as carouselMeta, name as carouselName, settings as carouselSettings } from '../../../src/blocks/gallery-carousel'; -import { metadata as collageMeta, name as collageName, settings as collageSettings } from '../../../src/blocks/gallery-collage/'; -import { metadata as masonryMeta, name as masonryName, settings as masonrySettings } from '../../../src/blocks/gallery-masonry'; -import { metadata as offsetMeta, name as offsetName, settings as offsetSettings } from '../../../src/blocks/gallery-offset'; -import { metadata as stackedMeta, name as stackedName, settings as stackedSettings } from '../../../src/blocks/gallery-stacked'; +import * as carouselSettings from '../../../src/blocks/gallery-carousel'; +import * as collageSettings from '../../../src/blocks/gallery-collage/'; +import * as masonrySettings from '../../../src/blocks/gallery-masonry'; +import * as offsetSettings from '../../../src/blocks/gallery-offset'; +import * as stackedSettings from '../../../src/blocks/gallery-stacked'; // Imports used for registerFormBlocks(). // Form, Name, Date, Textarea, Phone, Text, Website, Hidden -import { name as formBlockName, settings as formBlockSettings } from '../../../src/blocks/form'; -import { name as formCheckboxBlockName, settings as formCheckboxBlockSettings } from '../../../src/blocks/form/fields/checkbox'; -import { name as formDateBlockName, settings as formDateBlockSettings } from '../../../src/blocks/form/fields/date'; -import { name as formHiddenBlockName, settings as formHiddenBlockSettings } from '../../../src/blocks/form/fields/hidden'; -import { name as formNameBlockName, settings as formNameBlockSettings } from '../../../src/blocks/form/fields/name'; -import { name as formPhoneBlockName, settings as formPhoneBlockSettings } from '../../../src/blocks/form/fields/phone'; -import { name as formRadioBlockName, settings as formRadioBlockSettings } from '../../../src/blocks/form/fields/radio'; -import { name as formSelectBlockName, settings as formSelectBlockSettings } from '../../../src/blocks/form/fields/select'; -import { name as formTextareaBlockName, settings as formTextareaBlockSettings } from '../../../src/blocks/form/fields/textarea'; -import { name as formTextBlockName, settings as formTextBlockSettings } from '../../../src/blocks/form/fields/text'; -import { name as formWebsiteBlockName, settings as formWebsiteBlockSettings } from '../../../src/blocks/form/fields/website'; +import { metadata as formMetaData, settings as formBlockSettings } from '../../../src/blocks/form'; +import { metadata as formCheckboxMetaData, settings as formCheckboxBlockSettings } from '../../../src/blocks/form/fields/field-checkbox'; +import { metadata as formDateMetaData, settings as formDateBlockSettings } from '../../../src/blocks/form/fields/field-date'; +import { metadata as formHiddenMetaData, settings as formHiddenBlockSettings } from '../../../src/blocks/form/fields/field-hidden'; +import { metadata as formNameMetaData, settings as formNameBlockSettings } from '../../../src/blocks/form/fields/field-name'; +import { metadata as formPhoneMetaData, settings as formPhoneBlockSettings } from '../../../src/blocks/form/fields/field-phone'; +import { metadata as formRadioMetaData, settings as formRadioBlockSettings } from '../../../src/blocks/form/fields/field-radio'; +import { metadata as formSelectMetaData, settings as formSelectBlockSettings } from '../../../src/blocks/form/fields/field-select'; +import { metadata as formTextareaMetaData, settings as formTextareaBlockSettings } from '../../../src/blocks/form/fields/field-textarea'; +import { metadata as formTextMetaData, settings as formTextBlockSettings } from '../../../src/blocks/form/fields/field-text'; +import { metadata as formWebsiteMetaData, settings as formWebsiteBlockSettings } from '../../../src/blocks/form/fields/field-website'; /** * WordPress dependencies @@ -45,42 +46,26 @@ import { createBlock, getBlockTransforms, parse, registerBlockType, serialize, u * */ export const registerGalleryBlocks = () => { - const getV2Settings = ( blockMeta, blockSettings ) => { - const metaClone = { ...blockMeta }; - if ( !! blockSettings?.attributes ) { - metaClone.attributes = { ...metaClone.attributes, ...blockSettings?.attributes }; - } - return metaClone; - }; - - const v2Carousel = stackedMeta?.apiVersion === 2 ? getV2Settings( carouselMeta, carouselSettings ) : {}; - const v2Collage = stackedMeta?.apiVersion === 2 ? getV2Settings( collageMeta, collageSettings ) : {}; - const v2Masonry = stackedMeta?.apiVersion === 2 ? getV2Settings( masonryMeta, masonrySettings ) : {}; - const v2Offset = stackedMeta?.apiVersion === 2 ? getV2Settings( offsetMeta, offsetSettings ) : {}; - const v2Stacked = stackedMeta?.apiVersion === 2 ? getV2Settings( stackedMeta, stackedSettings ) : {}; - - registerBlockType( carouselName, { category: 'common', ...carouselSettings, ...v2Carousel } ); // Register carousel block - registerBlockType( collageName, { category: 'common', ...collageSettings, ...v2Collage } ); // Register collage block - registerBlockType( masonryName, { category: 'common', ...masonrySettings, ...v2Masonry } ); // Register masonry block - registerBlockType( offsetName, { category: 'common', ...offsetSettings, ...v2Offset } ); // Register offset block - registerBlockType( stackedName, { category: 'common', ...stackedSettings, ...v2Stacked } ); // Register stacked block + [ carouselSettings, masonrySettings, offsetSettings, stackedSettings, collageSettings ].forEach( ( settings ) => { + registerBlock( settings ); + } ); }; export const registerFormBlocks = () => { // Form, Name, Date, Textarea, Phone, Text, Website, Hidden - registerBlockType( formBlockName, { category: 'common', ...formBlockSettings } ); // Register form block - registerBlockType( formNameBlockName, { category: 'common', ...formNameBlockSettings } ); // Register form name block - registerBlockType( formDateBlockName, { category: 'common', ...formDateBlockSettings } ); // Register form name block - registerBlockType( formTextareaBlockName, { category: 'common', ...formTextareaBlockSettings } ); // Register form textarea block - registerBlockType( formPhoneBlockName, { category: 'common', ...formPhoneBlockSettings } ); // Register form phone block - registerBlockType( formTextBlockName, { category: 'common', ...formTextBlockSettings } ); // Register form text block - registerBlockType( formWebsiteBlockName, { category: 'common', ...formWebsiteBlockSettings } ); // Register form website block - registerBlockType( formHiddenBlockName, { category: 'common', ...formHiddenBlockSettings } ); // Register form hidden block + registerBlockType( formMetaData, { category: 'common', ...formBlockSettings } ); // Register form block + registerBlockType( formNameMetaData, { category: 'common', ...formNameBlockSettings } ); // Register form name block + registerBlockType( formDateMetaData, { category: 'common', ...formDateBlockSettings } ); // Register form name block + registerBlockType( formTextareaMetaData, { category: 'common', ...formTextareaBlockSettings } ); // Register form textarea block + registerBlockType( formPhoneMetaData, { category: 'common', ...formPhoneBlockSettings } ); // Register form phone block + registerBlockType( formTextMetaData, { category: 'common', ...formTextBlockSettings } ); // Register form text block + registerBlockType( formWebsiteMetaData, { category: 'common', ...formWebsiteBlockSettings } ); // Register form website block + registerBlockType( formHiddenMetaData, { category: 'common', ...formHiddenBlockSettings } ); // Register form hidden block // Select, Checkbox, Radio - registerBlockType( formSelectBlockName, { category: 'common', ...formSelectBlockSettings } ); // Register form name block - registerBlockType( formCheckboxBlockName, { category: 'common', ...formCheckboxBlockSettings } ); // Register form name block - registerBlockType( formRadioBlockName, { category: 'common', ...formRadioBlockSettings } ); // Register form name block + registerBlockType( formSelectMetaData, { category: 'common', ...formSelectBlockSettings } ); // Register form name block + registerBlockType( formCheckboxMetaData, { category: 'common', ...formCheckboxBlockSettings } ); // Register form name block + registerBlockType( formRadioMetaData, { category: 'common', ...formRadioBlockSettings } ); // Register form name block }; /** @@ -122,16 +107,15 @@ export const testDeprecatedBlockVariations = ( blockName, blockSettings, blockVa // Register the deprecated block to get the attributes with filters applied. deprecatedSettings = Object.assign( { category: 'common' }, - omit( blockSettings, [ 'attributes', 'save', 'deprecated' ] ), + + // We may need updated exclusion logic once we start deprecated v2 blocks. + // For example blocks with 'apiVersion: 2` will not have block wrapper by default. + omit( blockSettings, [ 'attributes', 'save', 'deprecated', 'apiVersion' ] ), { attributes: deprecated.attributes, save: deprecated.save, } ); - deprecatedBlockType = registerBlockType( blockName, deprecatedSettings ); - - // Unregister the registered block. - unregisterBlockType( blockName ); describe( `${ blockName } deprecation ${ index }`, () => { beforeEach( () => { @@ -163,7 +147,7 @@ export const testDeprecatedBlockVariations = ( blockName, blockSettings, blockVa ).toEqual( [] ); } ); - Object.keys( deprecatedBlockType.attributes ).forEach( ( attribute ) => { + Object.keys( deprecatedBlockType?.attributes ?? {} ).forEach( ( attribute ) => { // This test helps expose attributes we need variations for. it( `should have variations for attribute.${ attribute }`, () => { expect( blockVariations.hasOwnProperty( attribute ) ).toBe( true ); diff --git a/.dev/tests/phpunit/includes/admin/test-coblocks-action-links.php b/.dev/tests/phpunit/includes/admin/test-coblocks-action-links.php index e97e75b3cb8..83256f006c5 100644 --- a/.dev/tests/phpunit/includes/admin/test-coblocks-action-links.php +++ b/.dev/tests/phpunit/includes/admin/test-coblocks-action-links.php @@ -33,15 +33,15 @@ public function tear_down(): void { */ public function test_construct_actions() { - $actions = [ - [ 'plugin_row_meta', 'plugin_row_meta', 10 ], - ]; + $actions = array( + array( 'plugin_row_meta', 'plugin_row_meta', 10 ), + ); foreach ( $actions as $action_data ) { $priority = isset( $action_data[2] ) ? $action_data[2] : 10; - if ( ! has_action( $action_data[0], [ $this->coblocks_action_links, $action_data[1] ] ) ) { + if ( ! has_action( $action_data[0], array( $this->coblocks_action_links, $action_data[1] ) ) ) { $this->fail( "$action_data[0] is not attached to CoBlocks:$action_data[1]. It might also have the wrong priority (validated priority: $priority)" ); @@ -57,7 +57,7 @@ public function test_construct_actions() { */ public function test_plugin_row_meta_non_coblocks() { - $this->assertFalse( array_key_exists( 'review', $this->coblocks_action_links->plugin_row_meta( [], 'some-plugin' ) ) ); + $this->assertFalse( array_key_exists( 'review', $this->coblocks_action_links->plugin_row_meta( array(), 'some-plugin' ) ) ); } @@ -66,7 +66,7 @@ public function test_plugin_row_meta_non_coblocks() { */ public function test_plugin_row_meta() { - $this->assertTrue( array_key_exists( 'review', $this->coblocks_action_links->plugin_row_meta( [], COBLOCKS_PLUGIN_BASE ) ) ); + $this->assertTrue( array_key_exists( 'review', $this->coblocks_action_links->plugin_row_meta( array(), COBLOCKS_PLUGIN_BASE ) ) ); } } diff --git a/.dev/tests/phpunit/includes/test-class-register-blocks.php b/.dev/tests/phpunit/includes/test-class-register-blocks.php index 5eeb85f9baf..84b86179291 100644 --- a/.dev/tests/phpunit/includes/test-class-register-blocks.php +++ b/.dev/tests/phpunit/includes/test-class-register-blocks.php @@ -52,17 +52,17 @@ public function test_construct_properties() { $reflection = new ReflectionClass( $this->coblocks_register_blocks ); $new_reflection = new CoBlocks_Register_Blocks(); - $expected = [ + $expected = array( 'slug' => 'coblocks', - ]; + ); $slug = $reflection->getProperty( 'slug' ); $slug->setAccessible( true ); - $check = [ + $check = array( 'slug' => $slug->getValue( $new_reflection ), - ]; + ); $this->assertEquals( $expected, $check ); @@ -73,15 +73,15 @@ public function test_construct_properties() { */ public function test_construct_actions() { - $actions = [ - [ 'init', 'register_blocks', 99 ], - ]; + $actions = array( + array( 'init', 'register_blocks', 99 ), + ); foreach ( $actions as $action_data ) { $priority = isset( $action_data[2] ) ? $action_data[2] : 10; - if ( ! has_action( $action_data[0], [ $this->coblocks_register_blocks, $action_data[1] ] ) ) { + if ( ! has_action( $action_data[0], array( $this->coblocks_register_blocks, $action_data[1] ) ) ) { $this->fail( "$action_data[0] is not attached to CoBlocks:$action_data[1]. It might also have the wrong priority (validated priority: $priority)" ); @@ -101,18 +101,63 @@ public function test_register_blocks() { $this->coblocks_register_blocks->register_blocks(); - $expected_registered_blocks = [ + $expected_registered_blocks = array( 'coblocks/accordion', + 'coblocks/accordion-item', 'coblocks/alert', 'coblocks/author', + 'coblocks/buttons', + 'coblocks/field-checkbox', 'coblocks/click-to-tweet', + 'coblocks/column', + 'coblocks/counter', + 'coblocks/field-date', 'coblocks/dynamic-separator', - 'coblocks/gif', - 'coblocks/highlight', + 'coblocks/field-email', + 'coblocks/event-item', + 'coblocks/events', + 'coblocks/faq', + 'coblocks/faq-item', + 'coblocks/feature', + 'coblocks/features', + 'coblocks/food-and-drinks', + 'coblocks/food-item', + 'coblocks/form', 'coblocks/gallery-carousel', 'coblocks/gallery-masonry', + 'coblocks/gallery-offset', 'coblocks/gallery-stacked', - ]; + 'coblocks/gif', + 'coblocks/gist', + 'coblocks/hero', + 'coblocks/field-hidden', + 'coblocks/highlight', + 'coblocks/icon', + 'coblocks/logos', + 'coblocks/map', + 'coblocks/media-card', + 'coblocks/field-name', + 'coblocks/opentable', + 'coblocks/field-phone', + 'coblocks/post-carousel', + 'coblocks/posts', + 'coblocks/pricing-table', + 'coblocks/pricing-table-item', + 'coblocks/field-radio', + 'coblocks/row', + 'coblocks/field-select', + 'coblocks/service', + 'coblocks/services', + 'coblocks/social', // AKA Share block. + 'coblocks/shape-divider', + 'coblocks/social-profiles', + 'coblocks/field-submit-button', + 'coblocks/testimonials', + 'coblocks/testimonial', + 'coblocks/field-text', + 'coblocks/field-textarea', + 'coblocks/field-website', + ); $registered_blocks = WP_Block_Type_Registry::get_instance()->get_all_registered(); diff --git a/.dev/tests/phpunit/includes/test-coblocks-accordion-ie-support.php b/.dev/tests/phpunit/includes/test-coblocks-accordion-ie-support.php index 57565035836..f719de854b3 100644 --- a/.dev/tests/phpunit/includes/test-coblocks-accordion-ie-support.php +++ b/.dev/tests/phpunit/includes/test-coblocks-accordion-ie-support.php @@ -36,10 +36,10 @@ public function test_properties() { $new_reflection::register(); - $expected = [ + $expected = array( 'slug' => 'coblocks', 'url' => str_replace( '/.dev/tests/phpunit', '', untrailingslashit( plugins_url( '/', dirname( __FILE__ ) ) ) ), // Fix inconsistencies path between plugin and unit tests - ]; + ); $slug = $reflection->getProperty( 'slug' ); $url = $reflection->getProperty( 'url' ); @@ -47,10 +47,10 @@ public function test_properties() { $slug->setAccessible( true ); $url->setAccessible( true ); - $check = [ + $check = array( 'slug' => $slug->getValue( $new_reflection ), 'url' => $url->getValue( $new_reflection ), - ]; + ); $this->assertEquals( $expected, $check ); @@ -89,12 +89,12 @@ public function test_assets() { $new_reflection = new CoBlocks_Accordion_IE_Support(); $post_id = wp_insert_post( - [ + array( 'post_author' => 1, 'post_content' => '
Accordion Title 1

Accordion Content 1

', 'post_title' => 'CoBlocks Accordion', 'post_status' => 'publish', - ] + ) ); update_post_meta( $post_id, '_coblocks_accordion_ie_support', "'true'" ); diff --git a/.dev/tests/phpunit/includes/test-coblocks-block-assets.php b/.dev/tests/phpunit/includes/test-coblocks-block-assets.php index 8e7db44fde2..cde0b260867 100644 --- a/.dev/tests/phpunit/includes/test-coblocks-block-assets.php +++ b/.dev/tests/phpunit/includes/test-coblocks-block-assets.php @@ -19,7 +19,7 @@ public function set_up(): void { // Reset queued scripts and styles. global $wp_scripts, $wp_styles; $wp_scripts = new WP_Scripts(); - $wp_styles = new WP_Styles(); + $wp_styles = new WP_Styles(); } public function tear_down(): void { @@ -56,17 +56,17 @@ public function test_construct_actions() { $reflection = new ReflectionClass( $this->coblocks_block_assets ); $new_reflection = new CoBlocks_Block_Assets(); - $actions = [ - [ 'enqueue_block_assets', 'block_assets' ], - [ 'enqueue_block_editor_assets', 'editor_assets' ], - [ 'wp_enqueue_scripts', 'frontend_scripts' ], - ]; + $actions = array( + array( 'enqueue_block_assets', 'block_assets' ), + array( 'enqueue_block_editor_assets', 'editor_assets' ), + array( 'wp_enqueue_scripts', 'frontend_scripts' ), + ); foreach ( $actions as $action_data ) { $priority = isset( $action_data[2] ) ? $action_data[2] : 10; - if ( ! has_action( $action_data[0], [ $this->coblocks_block_assets, $action_data[1] ] ) ) { + if ( ! has_action( $action_data[0], array( $this->coblocks_block_assets, $action_data[1] ) ) ) { $this->fail( "$action_data[0] is not attached to CoBlocks:$action_data[1]. It might also have the wrong priority (validated priority: $priority)" ); @@ -116,12 +116,14 @@ public function test_block_assets_not_loaded_when_no_coblocks_block() { global $post, $wp_styles; unset( $GLOBALS['current_screen'] ); - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => 'NoBlocks', - 'post_title' => 'NoBlocks', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => 'NoBlocks', + 'post_title' => 'NoBlocks', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -136,12 +138,14 @@ public function test_block_assets_loaded_with_coblocks_block() { global $post, $wp_styles; unset( $GLOBALS['current_screen'] ); - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'CoBlocks', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'CoBlocks', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -156,12 +160,14 @@ public function test_block_assets_loaded_with_any_reusable_block() { global $post, $wp_styles; unset( $GLOBALS['current_screen'] ); - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'CoBlocks', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'CoBlocks', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -176,7 +182,7 @@ public function test_block_assets_loaded_on_archive_pages() { global $wp_styles; unset( $GLOBALS['current_screen'] ); - $this->go_to( "/?cat=1" ); + $this->go_to( '/?cat=1' ); $this->assertTrue( is_archive() ); @@ -191,12 +197,14 @@ public function test_block_assets_loaded_with_core_image_block() { unset( $GLOBALS['current_screen'] ); // core/image - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Image Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Image Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -212,12 +220,14 @@ public function test_typography_styles_loaded_with_core_button_block() { unset( $GLOBALS['current_screen'] ); // core/button - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Button Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Button Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -233,12 +243,14 @@ public function test_typography_styles_loaded_with_core_cover_block() { unset( $GLOBALS['current_screen'] ); // core/cover - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Cover Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Cover Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -254,12 +266,14 @@ public function test_typography_styles_loaded_with_core_heading_block() { unset( $GLOBALS['current_screen'] ); // core/heading - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Heading Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Heading Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -275,12 +289,14 @@ public function test_typography_styles_loaded_with_core_list_block() { unset( $GLOBALS['current_screen'] ); // core/list - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core List Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core List Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -296,12 +312,14 @@ public function test_typography_styles_loaded_with_core_paragraph_block() { unset( $GLOBALS['current_screen'] ); // core/paragraph - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Paragraph Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Paragraph Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -317,12 +335,14 @@ public function test_typography_styles_loaded_with_core_pullquote_block() { unset( $GLOBALS['current_screen'] ); // core/pullquote - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Pullquote Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Pullquote Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); @@ -338,12 +358,14 @@ public function test_typography_styles_loaded_with_core_quote_block() { unset( $GLOBALS['current_screen'] ); // core/quote - $post_id = wp_insert_post( [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'Core Quote Block', - 'post_status' => 'publish', - ] ); + $post_id = wp_insert_post( + array( + 'post_author' => 1, + 'post_content' => '', + 'post_title' => 'Core Quote Block', + 'post_status' => 'publish', + ) + ); $this->go_to( "/?p={$post_id}" ); $post = get_post( $post_id ); diff --git a/.dev/tests/phpunit/includes/test-coblocks-body-classes.php b/.dev/tests/phpunit/includes/test-coblocks-body-classes.php index aa9ce8c4394..e198d404585 100644 --- a/.dev/tests/phpunit/includes/test-coblocks-body-classes.php +++ b/.dev/tests/phpunit/includes/test-coblocks-body-classes.php @@ -31,16 +31,16 @@ public function tear_down(): void { */ public function test_construct() { - $actions = [ - [ 'body_class', 'body_class' ], - [ 'admin_body_class', 'admin_body_class' ], - ]; + $actions = array( + array( 'body_class', 'body_class' ), + array( 'admin_body_class', 'admin_body_class' ), + ); foreach ( $actions as $action_data ) { $priority = isset( $action_data[2] ) ? $action_data[2] : 10; - if ( ! has_action( $action_data[0], [ $this->coblocks_body_classes, $action_data[1] ] ) ) { + if ( ! has_action( $action_data[0], array( $this->coblocks_body_classes, $action_data[1] ) ) ) { $this->fail( "$action_data[0] is not attached to CoBlocks:$action_data[1]. It might also have the wrong priority (validated priority: $priority)" ); @@ -65,7 +65,7 @@ public function test_is_active_theme() { */ public function test_themes() { - $expected = [ + $expected = array( 'twentytwentyone', 'twentytwenty', 'twentynineteen', @@ -76,7 +76,7 @@ public function test_themes() { 'twentythirteen', 'twentyeleven', 'twentytwelve', - ]; + ); $this->assertEquals( $expected, $this->coblocks_body_classes->themes() ); @@ -87,7 +87,7 @@ public function test_themes() { */ public function test_filtered_themes() { - $expected = [ + $expected = array( 'twentytwentyone', 'twentytwenty', 'twentynineteen', @@ -99,7 +99,7 @@ public function test_filtered_themes() { 'twentyeleven', 'twentytwelve', 'test', - ]; + ); add_filter( 'coblocks_theme_body_classes', @@ -141,7 +141,7 @@ function( $theme ) { } ); - $this->assertEquals( $this->coblocks_body_classes->body_class( [ 'existing' ] ), [ 'existing', 'is-twentynineteen' ] ); + $this->assertEquals( $this->coblocks_body_classes->body_class( array( 'existing' ) ), array( 'existing', 'is-twentynineteen' ) ); } @@ -150,7 +150,7 @@ function( $theme ) { */ public function test_non_admin_body_class() { - $this->assertEquals( $this->coblocks_body_classes->admin_body_class( [ 'existing' ] ), [ 'existing' ] ); + $this->assertEquals( $this->coblocks_body_classes->admin_body_class( array( 'existing' ) ), array( 'existing' ) ); } diff --git a/.dev/tests/phpunit/includes/test-coblocks-font-loader.php b/.dev/tests/phpunit/includes/test-coblocks-font-loader.php index 6e2657ee917..861bbc6f317 100644 --- a/.dev/tests/phpunit/includes/test-coblocks-font-loader.php +++ b/.dev/tests/phpunit/includes/test-coblocks-font-loader.php @@ -49,16 +49,16 @@ public function test_register() { */ public function test_construct_actions() { - $actions = [ - [ 'wp_enqueue_scripts', 'fonts_loader' ], - [ 'admin_enqueue_scripts', 'fonts_loader' ], - ]; + $actions = array( + array( 'wp_enqueue_scripts', 'fonts_loader' ), + array( 'admin_enqueue_scripts', 'fonts_loader' ), + ); foreach ( $actions as $action_data ) { $priority = isset( $action_data[2] ) ? $action_data[2] : 10; - if ( ! has_action( $action_data[0], [ $this->coblocks_font_loader, $action_data[1] ] ) ) { + if ( ! has_action( $action_data[0], array( $this->coblocks_font_loader, $action_data[1] ) ) ) { $this->fail( "$action_data[0] is not attached to CoBlocks:$action_data[1]. It might also have the wrong priority (validated priority: $priority)" ); @@ -75,12 +75,12 @@ public function test_construct_actions() { public function test_font_loader() { $post_id = wp_insert_post( - [ + array( 'post_author' => 1, 'post_content' => 'Font Loader Test', 'post_title' => 'Font Loader Test', 'post_status' => 'publish', - ] + ) ); update_post_meta( $post_id, '_coblocks_attr', 'Roboto,Lato' ); diff --git a/.dev/tests/phpunit/includes/test-coblocks-form.php b/.dev/tests/phpunit/includes/test-coblocks-form.php deleted file mode 100644 index ebc059a71bf..00000000000 --- a/.dev/tests/phpunit/includes/test-coblocks-form.php +++ /dev/null @@ -1,678 +0,0 @@ -coblocks_form = new CoBlocks_Form(); - - set_current_screen( 'dashboard' ); - - } - - public function tear_down(): void { - - parent::tear_down(); - - unset( $GLOBALS['current_screen'] ); - - } - - /** - * Test the class constants - */ - public function test_class_constants() { - - $reflection = new ReflectionClass( $this->coblocks_form ); - - $expected = [ - 'GCAPTCHA_VERIFY_URL', - ]; - - foreach ( $expected as $constant ) { - - if ( ! array_key_exists( $constant, $reflection->getConstants() ) ) { - - $this->fail( "$constant is not defined." ); - - } - } - - $this->assertTrue( true ); - - } - - /** - * Test the constructor - */ - public function test_construct() { - - $actions = [ - [ 'init', 'register_settings' ], - [ 'init', 'register_form_blocks' ], - [ 'wp_enqueue_scripts', 'form_recaptcha_assets' ], - ]; - - foreach ( $actions as $action_data ) { - - $priority = isset( $action_data[2] ) ? $action_data[2] : 10; - - if ( ! has_action( $action_data[0], [ $this->coblocks_form, $action_data[1] ] ) ) { - - $this->fail( "$action_data[0] is not attached to CoBlocks:$action_data[1]. It might also have the wrong priority (validated priority: $priority)" ); - - } - } - - $this->assertTrue( true ); - - } - - /** - * Test the settings are registered correctly - */ - public function test_register_settings() { - - $this->coblocks_form->register_settings(); - - $settings = [ - 'coblocks_google_recaptcha_site_key', - 'coblocks_google_recaptcha_secret_key', - ]; - - foreach ( $settings as $registered_setting ) { - - if ( ! array_key_exists( $registered_setting, get_registered_settings() ) ) { - - $this->fail( "$registered_setting is not defined." ); - - } - } - - $this->assertTrue( true ); - - } - - /** - * Test the form block assets DO NOT load when no form block is present - */ - public function test_no_form_assets_load() { - - $post_id = wp_insert_post( - [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'CoBlocks No Form', - 'post_status' => 'publish', - ] - ); - - global $post; - - $post = get_post( $post_id ); - - $this->coblocks_form->form_recaptcha_assets(); - - do_action( 'wp_enqueue_scripts' ); - - $wp_scripts = wp_scripts(); - - $this->assertNotContains( 'google-recaptcha', $wp_scripts->queue ); - - } - - /** - * Test the form block assets load when a form block is present - */ - public function test_form_assets_load() { - - update_option( 'coblocks_google_recaptcha_site_key', '123' ); - update_option( 'coblocks_google_recaptcha_secret_key', '123' ); - - $post_id = wp_insert_post( - [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'CoBlocks Form', - 'post_status' => 'publish', - ] - ); - - global $post; - - $post = get_post( $post_id ); - - $this->coblocks_form->form_recaptcha_assets(); - - do_action( 'wp_enqueue_scripts' ); - - $wp_scripts = wp_scripts(); - - $form_block_assets = [ - 'google-recaptcha', - 'coblocks-google-recaptcha', - ]; - - foreach ( $form_block_assets as $form_block_asset ) { - - if ( ! in_array( $form_block_asset, $wp_scripts->queue, true ) ) { - - $this->fail( "$form_block_asset is not enqueued." ); - - } - } - - $this->assertTrue( true ); - - } - - /** - * Test the form block assets localized data is set correctly - */ - public function test_form_assets_localized_data() { - - update_option( 'coblocks_google_recaptcha_site_key', '123' ); - update_option( 'coblocks_google_recaptcha_secret_key', '123' ); - - $post_id = wp_insert_post( - [ - 'post_author' => 1, - 'post_content' => '', - 'post_title' => 'CoBlocks Form', - 'post_status' => 'publish', - ] - ); - - global $post; - - $post = get_post( $post_id ); - - $this->coblocks_form->form_recaptcha_assets(); - - do_action( 'wp_enqueue_scripts' ); - - $wp_scripts = wp_scripts(); - - $this->assertMatchesRegularExpression( '/"recaptchaSiteKey":"123"/', $wp_scripts->registered['coblocks-google-recaptcha']->extra['data'] ); - - } - - /** - * Test the blocks are registered properly - * - * @expectedIncorrectUsage WP_Block_Type_Registry::register - */ - public function test_register_blocks() { - - $this->coblocks_form->register_form_blocks(); - - $registered_blocks = WP_Block_Type_Registry::get_instance()->get_all_registered(); - - $coblocks_blocks = [ - 'coblocks/form', - 'coblocks/field-name', - 'coblocks/field-email', - 'coblocks/field-textarea', - ]; - - foreach ( $coblocks_blocks as $registered_block ) { - - if ( ! array_key_exists( $registered_block, $registered_blocks ) ) { - - $this->fail( "$registered_block is not registered." ); - - } - } - - $this->assertTrue( true ); - - } - - /** - * Test the form markup is as expected - */ - public function test_render_form() { - - update_option( 'coblocks_google_recaptcha_site_key', '123' ); - update_option( 'coblocks_google_recaptcha_secret_key', '123' ); - - $this->expectOutputRegex( '/
/' ); - - echo $this->coblocks_form->render_form( [], '' ); - - } - - /** - * Test the form markup is as expected when it is submitted - */ - public function test_render_form_submission() { - - $this->markTestSkipped( 'Todo: Figure out how to set the global $_POST to simulate a form submission.' ); - - $_POST['form-hash'] = '99f3a3add5da5d0bb04ce41c7142688f64e73ab6'; - - $coblocks_form = new CoBlocks_Form(); - - $this->expectOutputRegex( '/
Your message was sent:/' ); - - echo $coblocks_form->render_form( [], '' ); - - } - - /** - * Test the name field markup is as expected, when it's a single field - */ - public function test_render_field_name() { - - $this->expectOutputRegex( '//' ); - - $atts = [ - 'label' => 'Name', - 'required' => true, - 'hasLastName' => false, - ]; - - echo $this->coblocks_form->render_field_name( $atts, '' ); - - } - - /** - * Test the name field markup is as expected, when the last name is displayed - */ - public function test_render_field_name_has_last_name() { - - $this->expectOutputRegex( '/
/' ); - - $atts = [ - 'label' => 'Name', - 'required' => true, - 'hasLastName' => true, - 'labelFirstName' => 'First name', - 'labelLastName' => 'Last name', - ]; - - echo $this->coblocks_form->render_field_name( $atts, '' ); - - } - - /** - * Test the email field markup is as expected - */ - public function test_render_field_email() { - - $this->expectOutputRegex( '//' ); - - echo $this->coblocks_form->render_field_email( [], '' ); - - } - - /** - * Test the message field markup is as expected - */ - public function test_render_field_textarea() { - - $this->expectOutputRegex( '/