From 37b07d2a87c9cc9389e683a799a6940697b6ebd6 Mon Sep 17 00:00:00 2001 From: robicse11127 Date: Thu, 2 Jul 2026 21:13:51 +0600 Subject: [PATCH 1/2] test(Example Modules): Add StaticModule test stack for EX-02 (#50791) Add PHP registration and FE snapshot tests plus metadata and RTL edit snapshot coverage for StaticModule without changing module runtime code. Co-authored-by: Cursor --- README.md | 4 +- package-lock.json | 126 ++++++++++++++++++ package.json | 3 +- .../__tests__/__mock-data__/attrs.ts | 4 + .../__snapshots__/edit.test.tsx.snap | 3 + .../static-module/__tests__/edit.test.tsx | 52 ++++++++ .../static-module/__tests__/metadata.test.ts | 30 +++++ .../__tests__/module-json.test.ts | 20 --- .../static-module/__tests__/test-cases.json | 11 ++ test-config/babel-transformer.js | 16 ++- test-config/jest.config.js | 5 +- test-config/jest.modules.config.js | 24 ++++ test-config/jest.smoke.config.js | 2 +- test-config/mocks/divi-module.js | 18 +++ tests/php/.env.example | 2 +- tests/php/Snapshot/StaticModuleRenderTest.php | 69 ++++++++++ ...nder_outputs_summary_html_snapshot__1.html | 12 ++ tests/php/Support/StaticModuleTestSupport.php | 63 +++++++++ .../php/Unit/StaticModuleRegistrationTest.php | 76 +++++++++++ .../fixtures/static-module-render-attrs.json | 70 ++++++++++ 20 files changed, 583 insertions(+), 27 deletions(-) create mode 100644 src/components/static-module/__tests__/__mock-data__/attrs.ts create mode 100644 src/components/static-module/__tests__/__snapshots__/edit.test.tsx.snap create mode 100644 src/components/static-module/__tests__/edit.test.tsx create mode 100644 src/components/static-module/__tests__/metadata.test.ts delete mode 100644 src/components/static-module/__tests__/module-json.test.ts create mode 100644 src/components/static-module/__tests__/test-cases.json create mode 100644 test-config/jest.modules.config.js create mode 100644 test-config/mocks/divi-module.js create mode 100644 tests/php/Snapshot/StaticModuleRenderTest.php create mode 100644 tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html create mode 100644 tests/php/Support/StaticModuleTestSupport.php create mode 100644 tests/php/Unit/StaticModuleRegistrationTest.php create mode 100644 tests/php/fixtures/static-module-render-attrs.json diff --git a/README.md b/README.md index ac4ba9b..3509fee 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,9 @@ npm test npm run test:modules ``` -`npm test` runs the EX-01 smoke test harness. `npm run test:modules` uses the full Divi and WordPress Jest setup for upcoming module tests. +`npm test` runs the EX-01 smoke and StaticModule metadata unit tests. `npm run test:modules` runs StaticModule edit snapshot tests with RTL. The full Divi and WordPress Jest setup in `test-config/jest.config.js` is reserved for upcoming module integration tests. + +Run `npm run build` before PHP StaticModule registration tests so `modules-json/static-module/` exists locally. PHPUnit requires a PHP binary with the `mysqli` extension enabled. If `composer test` fails with a missing MySQL extension error, run PHPUnit with a compatible PHP binary such as `php vendor/bin/phpunit`. diff --git a/package-lock.json b/package-lock.json index 207943e..d752773 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@divi/types": "npm:divi-types@^1.0.10", "@emotion/jest": "^11.11.0", "@mdx-js/react": "^3.0.1", + "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@tinymce/tinymce-react": "^5.0.1", @@ -4809,6 +4810,61 @@ "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==", "dev": true }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/@testing-library/jest-dom": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", @@ -4893,6 +4949,13 @@ "node": ">=10.13.0" } }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -18604,6 +18667,16 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -30332,6 +30405,47 @@ "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==", "dev": true }, + "@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true + }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + } + } + } + }, "@testing-library/jest-dom": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", @@ -30383,6 +30497,12 @@ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true }, + "@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true + }, "@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -40729,6 +40849,12 @@ "yallist": "^3.0.2" } }, + "lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true + }, "make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", diff --git a/package.json b/package.json index 939f372..088a583 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "start": "NODE_ENV=development webpack -w --config webpack.config.js --progress", "build": "NODE_ENV=production webpack --config webpack.config.js --progress", "test": "wp-scripts test-unit-js --config ./test-config/jest.smoke.config.js", - "test:modules": "wp-scripts test-unit-js --config ./test-config/jest.config.js", + "test:modules": "wp-scripts test-unit-js --config ./test-config/jest.modules.config.js", "zip": "gulp zip", "reset-install": "rm -rf ./package-lock.json ./node_modules/ && npm install", "reset-install:divi-4": "cd divi-4 && rm -rf ./package-lock.json ./node_modules/ && npm install", @@ -33,6 +33,7 @@ "@divi/types": "npm:divi-types@^1.0.10", "@emotion/jest": "^11.11.0", "@mdx-js/react": "^3.0.1", + "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@tinymce/tinymce-react": "^5.0.1", diff --git a/src/components/static-module/__tests__/__mock-data__/attrs.ts b/src/components/static-module/__tests__/__mock-data__/attrs.ts new file mode 100644 index 0000000..4f39db4 --- /dev/null +++ b/src/components/static-module/__tests__/__mock-data__/attrs.ts @@ -0,0 +1,4 @@ +import defaultRenderAttributes from '../../module-default-render-attributes.json'; +import { StaticModuleAttrs } from '../types'; + +export const staticModuleDefaultAttrs: StaticModuleAttrs = defaultRenderAttributes as StaticModuleAttrs; diff --git a/src/components/static-module/__tests__/__snapshots__/edit.test.tsx.snap b/src/components/static-module/__tests__/__snapshots__/edit.test.tsx.snap new file mode 100644 index 0000000..c6125ea --- /dev/null +++ b/src/components/static-module/__tests__/__snapshots__/edit.test.tsx.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` matches snapshot when "Default Static Module edit props" 1`] = `"
Static badgeStatic image
Static titleStatic summary
Static content
"`; diff --git a/src/components/static-module/__tests__/edit.test.tsx b/src/components/static-module/__tests__/edit.test.tsx new file mode 100644 index 0000000..add929e --- /dev/null +++ b/src/components/static-module/__tests__/edit.test.tsx @@ -0,0 +1,52 @@ +import React, { createElement, ReactElement } from 'react'; +import { render } from '@testing-library/react'; + +import { StaticModuleEdit } from '../edit'; +import { StaticModuleEditProps } from '../types'; +import { staticModuleDefaultAttrs } from './__mock-data__/attrs'; +import testCases from './test-cases.json'; + +interface StaticModuleEditTestCase { + title: string; + args: { + attrs: StaticModuleEditProps['attrs']; + id: string; + name: string; + childrenIds: string[]; + }; +} + +const createMockElements = () => ( { + render: ( { attrName }: { attrName: string } ): ReactElement => createElement( + 'span', + { + className: `example_static_module__${ attrName }`, + 'data-et-element': attrName, + }, + `Static ${ attrName }`, + ), + styleComponents: () => null, + style: () => null, + scriptData: () => null, +} ); + +describe.each( testCases as StaticModuleEditTestCase[] )( '', ( { title, args } ) => { + it( `matches snapshot when "${ title }"`, () => { + const mockElements = createMockElements(); + const editComponentProps: StaticModuleEditProps = { + attrs: { + ...staticModuleDefaultAttrs, + ...args.attrs, + }, + elements: mockElements as StaticModuleEditProps['elements'], + id: args.id, + name: args.name, + }; + + const { container } = render( createElement( StaticModuleEdit, editComponentProps ) ); + + expect( container.innerHTML ).toContain( 'example_static_module__inner' ); + expect( container.innerHTML ).toContain( 'Static summary' ); + expect( container.innerHTML ).toMatchSnapshot(); + } ); +} ); diff --git a/src/components/static-module/__tests__/metadata.test.ts b/src/components/static-module/__tests__/metadata.test.ts new file mode 100644 index 0000000..646fb86 --- /dev/null +++ b/src/components/static-module/__tests__/metadata.test.ts @@ -0,0 +1,30 @@ +import defaultRenderAttributes from '../module-default-render-attributes.json'; +import moduleMetadata from '../module.json'; +import { StaticModuleAttrs } from '../types'; + +interface StaticModuleMetadata { + name: string; + title: string; + moduleClassName: string; + attributes: Record; +} + +describe( 'Static Module metadata unit tests', () => { + it( 'parses module.json with expected module metadata', () => { + const staticModuleMetadata = moduleMetadata as StaticModuleMetadata; + + expect( staticModuleMetadata.name ).toBe( 'example/static-module' ); + expect( staticModuleMetadata.title ).toBe( 'Static Module' ); + expect( staticModuleMetadata.moduleClassName ).toBe( 'example_static_module' ); + expect( staticModuleMetadata.attributes ).toHaveProperty( 'summary' ); + expect( staticModuleMetadata.attributes ).toHaveProperty( 'title' ); + } ); + + it( 'parses default render attributes with summary content', () => { + const staticModuleDefaultAttrs = defaultRenderAttributes as StaticModuleAttrs; + + expect( staticModuleDefaultAttrs.summary?.innerContent?.desktop?.value ).toContain( 'brief summary' ); + expect( staticModuleDefaultAttrs.badge?.innerContent?.desktop?.value ).toBe( 'New' ); + expect( staticModuleDefaultAttrs.module?.meta?.adminLabel?.desktop?.value ).toBe( 'Static Module' ); + } ); +} ); diff --git a/src/components/static-module/__tests__/module-json.test.ts b/src/components/static-module/__tests__/module-json.test.ts deleted file mode 100644 index b679109..0000000 --- a/src/components/static-module/__tests__/module-json.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'path'; - -interface StaticModuleMetadata { - name: string; - title: string; - moduleClassName: string; -} - -describe( 'Static Module module.json smoke test', () => { - it( 'parses with expected module metadata', () => { - const moduleJsonPath = resolve( __dirname, '../module.json' ); - const moduleJsonContents = readFileSync( moduleJsonPath, 'utf8' ); - const staticModuleMetadata = JSON.parse( moduleJsonContents ) as StaticModuleMetadata; - - expect( staticModuleMetadata.name ).toBe( 'example/static-module' ); - expect( staticModuleMetadata.title ).toBe( 'Static Module' ); - expect( staticModuleMetadata.moduleClassName ).toBe( 'example_static_module' ); - } ); -} ); diff --git a/src/components/static-module/__tests__/test-cases.json b/src/components/static-module/__tests__/test-cases.json new file mode 100644 index 0000000..0773098 --- /dev/null +++ b/src/components/static-module/__tests__/test-cases.json @@ -0,0 +1,11 @@ +[ + { + "title": "Default Static Module edit props", + "args": { + "attrs": {}, + "id": "static-module-edit-test-1", + "name": "example/static-module", + "childrenIds": [] + } + } +] diff --git a/test-config/babel-transformer.js b/test-config/babel-transformer.js index db767bf..fe4b4ff 100644 --- a/test-config/babel-transformer.js +++ b/test-config/babel-transformer.js @@ -28,7 +28,13 @@ module.exports = { process(source, file, ...args) { if (file.indexOf('/wp-includes/js/dist/') > 0) { if (file.match(isWPGlobal)) { - const name = source.split('(window.wp = window.wp || {}).')[1].split(' =')[0].trim(); + const wpGlobalMarker = '(window.wp = window.wp || {}).'; + + if (-1 === source.indexOf(wpGlobalMarker)) { + return babelJestTransformer.process(source, file, ...args); + } + + const name = source.split(wpGlobalMarker)[1].split(' =')[0].trim(); source = source.split('this["wp"]').join('global["wp"]'); @@ -48,7 +54,13 @@ module.exports = { // TODO: This one will work with unminified code. But after production, we need to recheck. if (file.indexOf('/wp-content/themes/Divi/includes/builder-5/visual-builder/build/') > 0) { if (file.match(isDiviGlobal)) { - const name = source.match(diviModuleName)[1]; + const diviGlobalMatch = source.match(diviModuleName); + + if ( ! diviGlobalMatch) { + return babelJestTransformer.process(source, file, ...args); + } + + const name = diviGlobalMatch[1]; source = source.split('(window.divi = window.divi || {}).').join('(global.divi = global.divi || {}).'); const exporter = `; diff --git a/test-config/jest.config.js b/test-config/jest.config.js index f526337..c504e6c 100644 --- a/test-config/jest.config.js +++ b/test-config/jest.config.js @@ -91,6 +91,9 @@ module.exports = { '/__test-cases__', '/__mock-data__', '/test-config', - '/src/components/static-module/__tests__/module-json.test.ts', + '/src/components/static-module/__tests__/metadata.test.ts', + ], + testMatch: [ + '/src/components/static-module/__tests__/edit.test.tsx', ], }; diff --git a/test-config/jest.modules.config.js b/test-config/jest.modules.config.js new file mode 100644 index 0000000..d0b4d59 --- /dev/null +++ b/test-config/jest.modules.config.js @@ -0,0 +1,24 @@ +const { resolve } = require('path'); + +const pluginRootDirectory = resolve(__dirname, '..'); + +module.exports = { + rootDir: pluginRootDirectory, + preset: '@wordpress/jest-preset-default', + moduleNameMapper: { + '^@divi/module$': resolve( __dirname, 'mocks/divi-module.js' ), + }, + testMatch: [ + '/src/components/static-module/__tests__/edit.test.tsx', + ], + transform: { + '^.+\\.[jt]sx?$': resolve(__dirname, 'babel-transformer.js'), + }, + setupFilesAfterEnv: [ + resolve(__dirname, 'jest-rtl-setup.js'), + ], + testPathIgnorePatterns: [ + '/node_modules/', + '/test-config/', + ], +}; diff --git a/test-config/jest.smoke.config.js b/test-config/jest.smoke.config.js index cee6054..fac2c93 100644 --- a/test-config/jest.smoke.config.js +++ b/test-config/jest.smoke.config.js @@ -6,7 +6,7 @@ module.exports = { rootDir: pluginRootDirectory, preset: '@wordpress/jest-preset-default', testMatch: [ - '/src/components/static-module/__tests__/module-json.test.ts', + '/src/components/static-module/__tests__/metadata.test.ts', ], transform: { '^.+\\.[jt]sx?$': resolve(__dirname, 'babel-transformer.js'), diff --git a/test-config/mocks/divi-module.js b/test-config/mocks/divi-module.js new file mode 100644 index 0000000..e2b6e19 --- /dev/null +++ b/test-config/mocks/divi-module.js @@ -0,0 +1,18 @@ +const React = require( 'react' ); + +module.exports = { + ModuleContainer: ( { children, name } ) => React.createElement( + 'div', + { + className: 'static-module-test-container', + 'data-module-name': name, + }, + children, + ), + StyleContainer: ( { children } ) => React.createElement( + React.Fragment, + null, + children, + ), + CssStyle: () => null, +}; diff --git a/tests/php/.env.example b/tests/php/.env.example index 724b71e..e7c2ae3 100644 --- a/tests/php/.env.example +++ b/tests/php/.env.example @@ -1,6 +1,6 @@ # Copy this file to tests/php/.env and update the values for your local environment. DIVI_PATH=/absolute/path/to/wp-content/themes/Divi -WP_VERSION=6.7.2 +WP_VERSION=7.0 WP_ROOT_DIRECTORY=/absolute/path/to/wordpress/root/folder WP_TESTS_DOMAIN=wordpress.test WP_TESTS_EMAIL=admin@wordpress.test diff --git a/tests/php/Snapshot/StaticModuleRenderTest.php b/tests/php/Snapshot/StaticModuleRenderTest.php new file mode 100644 index 0000000..ddaa4dc --- /dev/null +++ b/tests/php/Snapshot/StaticModuleRenderTest.php @@ -0,0 +1,69 @@ +get_registered( 'example/static-module' ); + + $this->assertNotNull( $registered_block_type ); + + $prepared_attributes = $registered_block_type->prepare_attributes_for_render( $render_attributes ); + + $parsed_block = new BlockParserBlock( + $registered_block_type->name, + $prepared_attributes, + [], + '', + [], + 0 + ); + + $block = new \WP_Block( + (array) BlockParserStore::add( $parsed_block ) + ); + + $rendered_html = $block->render(); + + ob_start(); + Style::enqueue(); + $rendered_html .= ob_get_clean(); + + $this->assertNotSame( '', trim( $rendered_html ) ); + $this->assertStringContainsString( 'Static module summary text for snapshot testing.', $rendered_html ); + $this->assertStringNotContainsString( '<p>Static module summary text for snapshot testing.</p>', $rendered_html ); + $this->assertMatchesHtmlSnapshot( $rendered_html ); + } +} diff --git a/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html b/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html new file mode 100644 index 0000000..8dcd323 --- /dev/null +++ b/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html @@ -0,0 +1,12 @@ + +
+
New
+
+
Static module summary text for snapshot testing.
+
+
+
+ + diff --git a/tests/php/Support/StaticModuleTestSupport.php b/tests/php/Support/StaticModuleTestSupport.php new file mode 100644 index 0000000..c6bed97 --- /dev/null +++ b/tests/php/Support/StaticModuleTestSupport.php @@ -0,0 +1,63 @@ +get_registered( 'example/static-module' ); + + if ( null !== $registered_block_type ) { + return; + } + + ( new StaticModule() )->load(); + do_action( 'init' ); +} + +/** + * Loads StaticModule render fixture attributes from JSON. + * + * @return array + */ +function d5_extension_example_modules_load_static_module_render_fixture(): array { + $fixture_file_path = dirname( __DIR__ ) . '/fixtures/static-module-render-attrs.json'; + $fixture_contents = file_get_contents( $fixture_file_path ); + + if ( false === $fixture_contents ) { + throw new RuntimeException( 'StaticModule render fixture file could not be read.' ); + } + + $fixture_attributes = json_decode( $fixture_contents, true ); + + if ( ! is_array( $fixture_attributes ) ) { + throw new RuntimeException( 'StaticModule render fixture file contains invalid JSON.' ); + } + + return $fixture_attributes; +} diff --git a/tests/php/Unit/StaticModuleRegistrationTest.php b/tests/php/Unit/StaticModuleRegistrationTest.php new file mode 100644 index 0000000..1e43473 --- /dev/null +++ b/tests/php/Unit/StaticModuleRegistrationTest.php @@ -0,0 +1,76 @@ +get_registered( 'example/static-module' ); + + $this->assertNotNull( $registered_block_type ); + $this->assertSame( 'example/static-module', $registered_block_type->name ); + } + + /** + * Verifies StaticModule exposes a callable render callback. + * + * @return void + */ + public function test_static_module_render_callback_is_callable(): void { + $registered_block_type = \WP_Block_Type_Registry::get_instance()->get_registered( 'example/static-module' ); + + $this->assertNotNull( $registered_block_type ); + $this->assertTrue( is_callable( $registered_block_type->render_callback ) ); + $this->assertTrue( is_callable( [ StaticModule::class, 'render_callback' ] ) ); + } + + /** + * Verifies frontend asset enqueue hook is registered without PHP warnings. + * + * @return void + */ + public function test_static_module_frontend_assets_hook_is_registered(): void { + $this->assertNotFalse( + has_action( 'wp_enqueue_scripts', 'd5_extension_example_module_enqueue_frontend_scripts' ) + ); + } + + /** + * Verifies Visual Builder asset enqueue hook is registered without PHP warnings. + * + * @return void + */ + public function test_static_module_visual_builder_assets_hook_is_registered(): void { + $this->assertNotFalse( + has_action( 'divi_visual_builder_assets_before_enqueue_scripts', 'd5_extension_example_module_enqueue_vb_scripts' ) + ); + } +} diff --git a/tests/php/fixtures/static-module-render-attrs.json b/tests/php/fixtures/static-module-render-attrs.json new file mode 100644 index 0000000..f10b228 --- /dev/null +++ b/tests/php/fixtures/static-module-render-attrs.json @@ -0,0 +1,70 @@ +{ + "module": { + "meta": { + "adminLabel": { + "desktop": { + "value": "Static Module" + } + } + }, + "advanced": { + "text": { + "text": { + "desktop": { + "value": { + "color": "light" + } + } + } + } + }, + "decoration": { + "spacing": { + "desktop": { + "value": { + "padding": { + "top": "30px", + "right": "30px", + "bottom": "30px", + "left": "30px" + } + } + } + } + } + }, + "title": { + "decoration": { + "font": { + "font": { + "desktop": { + "value": { + "headingLevel": "h2" + } + } + } + } + } + }, + "summary": { + "innerContent": { + "desktop": { + "value": "Static module summary text for snapshot testing." + } + } + }, + "badge": { + "innerContent": { + "desktop": { + "value": "New" + } + }, + "decoration": { + "color": { + "desktop": { + "value": "#ffffff" + } + } + } + } +} From 6b58e3f3187dc8f3d32d61ae867d8e4106b1f612 Mon Sep 17 00:00:00 2001 From: robicse11127 Date: Sun, 5 Jul 2026 17:10:57 +0600 Subject: [PATCH 2/2] test(Example Modules): Align StaticModule render snapshot with review Divi (#50791) Update the PHP HTML snapshot to match newer Divi element render output so composer test passes in the ET review environment. Co-authored-by: Cursor --- ...est__test_render_outputs_summary_html_snapshot__1.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html b/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html index 8dcd323..025fb60 100644 --- a/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html +++ b/tests/php/Snapshot/__snapshots__/StaticModuleRenderTest__test_render_outputs_summary_html_snapshot__1.html @@ -1,12 +1,12 @@ -
-
New
+
+
New
-
Static module summary text for snapshot testing.
+
Static module summary text for snapshot testing.
+.example_static_module_0 .example_static_module__badge {color: #ffffff;}