Skip to content

Commit

Permalink
Add integration tests (#393)
Browse files Browse the repository at this point in the history
* Add and configure PHPUnit

Co-authored-by: Jason Crist <jcrist@pbking.com>
  • Loading branch information
vcanales and pbking authored Mar 11, 2024
1 parent ddcff99 commit 1545d48
Show file tree
Hide file tree
Showing 14 changed files with 4,119 additions and 199 deletions.
27 changes: 23 additions & 4 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ jobs:
node-version-file: '.nvmrc'
cache: npm

- name: Setup Composer
- name: Install dependencies
uses: php-actions/composer@v6
with:
args: --ignore-platform-reqs

- name: Install Dependencies
run: npm i
Expand All @@ -43,8 +45,8 @@ jobs:
if: success() || failure()
run: npm run lint:pkg-json

unit-test-js:
name: JavaScript Unit Test
tests:
name: Test Suite
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -56,11 +58,28 @@ jobs:
node-version-file: '.nvmrc'
cache: npm

- name: Install Dependencies
- name: Install Composer
uses: php-actions/composer@v6
with:
args: --ignore-platform-reqs

- name: Install Node Dependencies
run: npm i

- name: Compile JavaScript App
run: npm run build

- name: Setup MySQL
if: success() || failure()
uses: shogo82148/actions-setup-mysql@v1
with:
mysql-version: '8.0'

- name: Run JavaScript unit tests
run: npm run test:unit

- name: Run PHP tests
run: |
mysql -uroot -h127.0.0.1 -e 'SELECT version()' \
&& ./bin/install-wp-tests.sh --recreate-db wordpress_test root '' > /dev/null \
&& composer run-script test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ build/

# Ignore local override files
.wp-env.override.json

# phpunit
*.result.*
47 changes: 47 additions & 0 deletions .phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0"?>
<ruleset name="WordPress Coding Standards based custom ruleset for your plugin">
<description>Generally-applicable sniffs for WordPress plugins.</description>

<!-- What to scan -->
<file>.</file>
<exclude-pattern>/vendor/</exclude-pattern>
<exclude-pattern>/node_modules/</exclude-pattern>

<!-- How to scan -->
<!-- Usage instructions: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage -->
<!-- Annotated ruleset: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml -->
<arg value="sp"/> <!-- Show sniff and progress -->
<arg name="basepath" value="./"/><!-- Strip the file paths down to the relevant bit -->
<arg name="colors"/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="8"/><!-- Enables parallel processing when available for faster results. -->

<!-- Rules: Check PHP version compatibility -->
<!-- https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions -->
<config name="testVersion" value="5.6-"/>
<!-- https://github.com/PHPCompatibility/PHPCompatibilityWP -->
<rule ref="PHPCompatibilityWP"/>

<!-- Rules: WordPress Coding Standards -->
<!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards -->
<!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties -->
<config name="minimum_supported_wp_version" value="4.6"/>
<rule ref="WordPress"/>
<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
<properties>
<!-- Value: replace the function, class, and variable prefixes used. Separate multiple prefixes with a comma. -->
<property name="prefixes" type="array" value="create_block_theme"/>
</properties>
</rule>
<rule ref="WordPress.WP.I18n">
<properties>
<!-- Value: replace the text domain used. -->
<property name="text_domain" type="array" value="create_block_theme"/>
</properties>
</rule>
<rule ref="WordPress.WhiteSpace.ControlStructureSpacing">
<properties>
<property name="blank_line_check" value="true"/>
</properties>
</rule>
</ruleset>
6 changes: 5 additions & 1 deletion .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"core": "WordPress/WordPress",
"plugins": [ "." ]
"plugins": [ "." ],
"config": {
"WP_UPLOAD_MAX_FILESIZE": "128M",
"WP_MEMORY_LIMIT": "256M"
}
}
64 changes: 37 additions & 27 deletions admin/class-create-theme.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<?php

require_once( __DIR__ . '/resolver_additions.php' );
require_once( __DIR__ . '/create-theme/theme-tags.php' );
require_once( __DIR__ . '/create-theme/theme-zip.php' );
require_once( __DIR__ . '/create-theme/theme-media.php' );
require_once( __DIR__ . '/create-theme/theme-blocks.php' );
require_once( __DIR__ . '/create-theme/theme-patterns.php' );
require_once( __DIR__ . '/create-theme/theme-templates.php' );
require_once( __DIR__ . '/create-theme/theme-styles.php' );
require_once( __DIR__ . '/create-theme/theme-json.php' );
require_once( __DIR__ . '/create-theme/theme-utils.php' );
require_once( __DIR__ . '/create-theme/theme-readme.php' );
require_once( __DIR__ . '/create-theme/theme-form.php' );
require_once( __DIR__ . '/create-theme/form-messages.php' );
require_once __DIR__ . '/resolver_additions.php';
require_once __DIR__ . '/create-theme/theme-tags.php';
require_once __DIR__ . '/create-theme/theme-zip.php';
require_once __DIR__ . '/create-theme/theme-media.php';
require_once __DIR__ . '/create-theme/theme-blocks.php';
require_once __DIR__ . '/create-theme/theme-patterns.php';
require_once __DIR__ . '/create-theme/theme-templates.php';
require_once __DIR__ . '/create-theme/theme-styles.php';
require_once __DIR__ . '/create-theme/theme-json.php';
require_once __DIR__ . '/create-theme/theme-utils.php';
require_once __DIR__ . '/create-theme/theme-readme.php';
require_once __DIR__ . '/create-theme/theme-form.php';
require_once __DIR__ . '/create-theme/form-messages.php';

/**
* The admin-specific functionality of the plugin.
Expand All @@ -22,6 +22,7 @@
* @author WordPress.org
*/
class Create_Block_Theme_Admin {
public $theme;

/**
* Initialize the class and set its properties.
Expand All @@ -30,6 +31,8 @@ public function __construct() {
add_action( 'admin_menu', array( $this, 'create_admin_menu' ) );
add_action( 'admin_init', array( $this, 'blockbase_save_theme' ) );
add_action( 'enqueue_block_editor_assets', array( $this, 'create_block_theme_enqueue' ) );

$this->theme = wp_get_theme();
}

function create_block_theme_enqueue() {
Expand All @@ -39,7 +42,7 @@ function create_block_theme_enqueue() {
return;
}

$asset_file = include( plugin_dir_path( dirname( __FILE__ ) ) . 'build/plugin-sidebar.asset.php' );
$asset_file = include plugin_dir_path( dirname( __FILE__ ) ) . 'build/plugin-sidebar.asset.php';

wp_register_script(
'create-block-theme-slot-fill',
Expand Down Expand Up @@ -75,6 +78,19 @@ function save_variation( $export_type, $theme ) {
Theme_Json::add_theme_json_variation_to_local( 'variation', $theme );
}

public function download_file( $file, $filename ) {
// Set headers.
header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename=' . $filename );
header( 'Content-Length: ' . filesize( $file ) );

// Send file.
readfile( $file );

// Delete file.
unlink( $file );
}

/**
* Export activated child theme
*/
Expand All @@ -97,12 +113,10 @@ function export_child_theme( $theme ) {

$zip->close();

header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename=' . $theme['slug'] . '.zip' );
header( 'Content-Length: ' . filesize( $filename ) );
flush();
echo readfile( $filename );
die();
// Download the ZIP file.
$this->download_file( $filename, $theme['slug'] . '.zip' );

return $filename;
}

/**
Expand Down Expand Up @@ -189,7 +203,7 @@ function clone_theme( $theme, $screenshot ) {

// Use previous theme's tags if custom tags are empty.
if ( empty( $theme['tags_custom'] ) ) {
$theme['tags_custom'] = implode( ', ', wp_get_theme()->get( 'Tags' ) );
$theme['tags_custom'] = implode( ', ', $this->theme->get( 'Tags' ) );
}

// Create ZIP file in the temporary directory.
Expand Down Expand Up @@ -241,8 +255,7 @@ function clone_theme( $theme, $screenshot ) {
* Create a child theme of the activated theme
*/
function create_child_theme( $theme, $screenshot ) {

$parent_theme_slug = Theme_Utils::get_theme_slug( wp_get_theme()->get( 'Name' ) );
$parent_theme_slug = Theme_Utils::get_theme_slug( $this->theme->get( 'Name' ) );
$child_theme_slug = Theme_Utils::get_theme_slug( $theme['name'] );

// Sanitize inputs.
Expand Down Expand Up @@ -300,7 +313,7 @@ function create_child_theme( $theme, $screenshot ) {
* Export activated parent theme
*/
function export_theme( $theme ) {
$theme['slug'] = wp_get_theme()->get( 'TextDomain' );
$theme['slug'] = $this->theme->get( 'TextDomain' );

// Create ZIP file in the temporary directory.
$filename = tempnam( get_temp_dir(), $theme['slug'] );
Expand Down Expand Up @@ -389,11 +402,9 @@ function create_blank_theme( $theme, $screenshot ) {
file_put_contents( $theme_json_path, $theme_json_string );
}
}

}

function blockbase_save_theme() {

if ( ! empty( $_GET['page'] ) && 'create-block-theme' === $_GET['page'] && ! empty( $_POST['theme'] ) ) {

// Check user capabilities.
Expand Down Expand Up @@ -422,7 +433,6 @@ function blockbase_save_theme() {

add_action( 'admin_notices', array( 'Form_Messages', 'admin_notice_save_success' ) );
} elseif ( 'variation' === $_POST['theme']['type'] ) {

if ( '' === $_POST['theme']['variation'] ) {
return add_action( 'admin_notices', array( 'Form_Messages', 'admin_notice_error_variation_name' ) );
}
Expand Down
11 changes: 5 additions & 6 deletions admin/create-theme/theme-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ public static function is_absolute_url( $url ) {
}

public static function get_theme_slug( $new_theme_name ) {
$theme = wp_get_theme();

// If the source theme has a single-word slug but the new theme has a multi-word slug
// then function will look like: function apple-bumpkin_support() and that won't work.
// There are no issues if it is multi-word>single-word or multi>multi or single>single.
// Due to the complexity of this situation (compared to the simplicity of the others)
// this will enforce the usage of a singleword slug for those themes.

$old_slug = wp_get_theme()->get( 'TextDomain' );
$old_slug = $theme->get( 'TextDomain' );
$new_slug = sanitize_title( $new_theme_name );
$new_slug = preg_replace( '/\s+/', '', $new_slug ); // Remove spaces

Expand All @@ -30,10 +31,11 @@ public static function get_file_extension_from_url( $url ) {
}

public static function replace_namespace( $content, $new_slug, $new_name ) {
$old_slug = wp_get_theme()->get( 'TextDomain' );
$theme = wp_get_theme();
$old_slug = $theme->get( 'TextDomain' );
$new_slug_underscore = str_replace( '-', '_', $new_slug );
$old_slug_underscore = str_replace( '-', '_', $old_slug );
$old_name = wp_get_theme()->get( 'Name' );
$old_name = $theme->get( 'Name' );

// Generate placeholders
$placeholder_slug = md5( $old_slug );
Expand Down Expand Up @@ -102,7 +104,6 @@ public static function clone_theme_to_folder( $location, $new_slug, $new_name )
// Add current file to target
file_put_contents( $location . DIRECTORY_SEPARATOR . $relative_path, $contents );
}

}

public static function add_templates_to_folder( $location, $export_type, $new_slug ) {
Expand Down Expand Up @@ -139,7 +140,6 @@ public static function add_templates_to_folder( $location, $export_type, $new_sl
// Add template to folder
$template_path = $location . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template->slug . '.html';
file_put_contents( $template_path, $template->content );

}

foreach ( $theme_templates->parts as $template_part ) {
Expand Down Expand Up @@ -200,7 +200,6 @@ public static function get_readme_data() {
$readme_file_details['recommendedPlugins'] = $matches[1][0] ?? '';

return $readme_file_details;

}

}
5 changes: 3 additions & 2 deletions admin/resolver_additions.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ class MY_Theme_JSON_Resolver extends WP_Theme_JSON_Resolver {
* 'variation' will include just the user custom styles and settings.
*/
public static function export_theme_data( $content, $extra_theme_data = null ) {
$current_theme = wp_get_theme();
if ( class_exists( 'WP_Theme_JSON_Gutenberg' ) ) {
$theme = new WP_Theme_JSON_Gutenberg();
} else {
$theme = new WP_Theme_JSON();
}

if ( 'all' === $content && wp_get_theme()->parent() ) {
if ( 'all' === $content && $current_theme->parent() ) {
// Get parent theme.json.
$parent_theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json', true ) );
$parent_theme_json_data = static::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) );
$parent_theme_json_data = static::translate( $parent_theme_json_data, $current_theme->parent()->get( 'TextDomain' ) );

// Get the schema from the parent JSON.
$schema = $parent_theme_json_data['$schema'];
Expand Down
Loading

0 comments on commit 1545d48

Please sign in to comment.