Skip to content

Commit

Permalink
Merge pull request #97 from woocommerce/23-11/add-theme-self-tests
Browse files Browse the repository at this point in the history
Added Theme self tests
  • Loading branch information
MrJnrman authored Dec 19, 2023
2 parents 18117c6 + 03a924b commit 0f70017
Show file tree
Hide file tree
Showing 88 changed files with 4,703 additions and 50 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/qit-self-test-malware.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: QIT Self-Tests - Malware

on:
# Every day at 11am and 11pm UTC (6am and 6pm ET)
schedule:
- cron: '0 11 * * *'
- cron: '0 23 * * *'
# Manually
workflow_dispatch:
# On push to trunk
push:
branches:
- trunk

jobs:
malware_tests:
uses: ./.github/workflows/self-test-template.yml
with:
test_type: malware
secrets:
QIT_USER: ${{ secrets.QIT_USER }}
QIT_ACCESS_TOKEN: ${{ secrets.QIT_ACCESS_TOKEN }}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![QIT Self-Tests - PHPStan](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-phpstan.yml/badge.svg)](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-phpstan.yml)
[![QIT Self-Tests - Security](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-security.yml/badge.svg)](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-security.yml)
[![QIT Self-Tests - PHPCompatibilityWP](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-phpcompatibility.yml/badge.svg)](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-phpcompatibility.yml)
[![QIT Self-Tests - Malware](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-malware.yml/badge.svg)](https://github.com/woocommerce/qit-cli/actions/workflows/qit-self-test-malware.yml)

<p align="center"><img src="https://woo.com/wp-content/themes/woo/images/logo-woocommerce-bubble.svg" alt="WooCommerce" style="width:100px;height:auto;"></p>

Expand Down Expand Up @@ -46,6 +47,7 @@ _(Pro Tip: Opting for the Composer installation method simplifies the process of
- `qit run:e2e my-extension --zip` - Runs the tests using an unreleased development build zip.
- `qit run:e2e my-extension --additional_wordpress_plugins=gutenberg` - Activates the "Gutenberg" feature plugin in the test environment as well.
- `qit run:e2e my-extension --optional_features=hpos` - Enables the [WooCommerce "High Performance Order Storage"](https://developer.woocommerce.com/roadmap/high-performance-order-storage/) feature in the test site.
-

You can use these parameters individually or in combination to create different scenarios for your tests. Run `qit run:<test-type> --help` to see all the available options. Different test types will have different options to choose from.

Expand All @@ -58,6 +60,8 @@ QIT currently supports the following types of tests:
- [Security Test](https://woocommerce.github.io/qit-documentation/#/test-types/security)
- [PHPStan Test](https://woocommerce.github.io/qit-documentation/#/test-types/phpstan)
- [API Test](https://woocommerce.github.io/qit-documentation/#/test-types/api)
- [PHP Compatibility](https://woocommerce.github.io/qit-documentation/#/test-types/phpcompatibility)
- [Malware Test](https://woocommerce.github.io/qit-documentation/#/test-types/malware)
- _PHP Minimum and Maximum Version Compatibility (Coming soon)_
- _Performance Test (Coming soon)_

Expand Down
31 changes: 20 additions & 11 deletions _tests/QITSelfTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ class Context {
public static $action;
public static $suite;
public static $test;
public static $sut_slug;

/*
* To run tests in QIT, we need to assign the results to a plugin in the Marketplace.
* We use the extension "woocommerce-product-feeds" and theme "storefront", because they're owned by the test user in Staging.
*/
public static $extension_slug = 'woocommerce-product-feeds';
public static $theme_slug = 'wporg-theme-storefront';
}

Context::$action = $GLOBALS['argv'][1] ?? 'run';
Context::$suite = $GLOBALS['argv'][2] ?? null;
Context::$test = $GLOBALS['argv'][3] ?? null;

/*
* To run tests in QIT, we need to assign the results to a plugin in the Marketplace.
* We use "woocommerce-product-feeds", because it's a plugin owned by the test user in Staging.
*/
Context::$sut_slug = 'woocommerce-product-feeds';

require_once __DIR__ . '/test-result-parser.php';
require_once __DIR__ . '/ParallelOutput.php';

Expand Down Expand Up @@ -146,6 +146,13 @@ function generate_test_runs( array $test_types ): array {

foreach ( $woo_versions as $woo_version ) {
foreach ( $php_versions as $php_version ) {

if ( file_exists( $test . '/' . Context::$extension_slug ) ) {
$sut_slug = Context::$extension_slug;
} else {
$sut_slug = Context::$theme_slug;
}

$tests_to_run[ basename( $test_type ) ][] = [
'type' => basename( $test_type ),
'slug' => basename( $test ),
Expand All @@ -156,6 +163,7 @@ function generate_test_runs( array $test_types ): array {
'remove_from_snapshot' => $env['remove_from_snapshot'] ?? '',
'params' => $env['params'] ?? [],
'path' => $test,
'sut_slug' => $sut_slug,
];
}
}
Expand Down Expand Up @@ -197,8 +205,9 @@ function run_test_runs( array $test_runs ) {
// Dispatch all tests in parallel using the qit binary.
foreach ( $test_runs as $test_type => &$test_type_test_runs ) {
foreach ( $test_type_test_runs as $t ) {
$php = ( new PhpExecutableFinder() )->find( false );
$qit = realpath( __DIR__ . '/../qit' );
$php = ( new PhpExecutableFinder() )->find( false );
$qit = realpath( __DIR__ . '/../qit' );
$sut_slug = $t['sut_slug'];

$args = [
$php,
Expand Down Expand Up @@ -235,7 +244,7 @@ function run_test_runs( array $test_runs ) {
}
}

$args[] = Context::$sut_slug;
$args[] = $sut_slug;

$qit_process = new Process( $args );
$qit_process->setTimeout( null ); // Let QIT CLI handle timeouts.
Expand Down Expand Up @@ -449,7 +458,7 @@ function generate_zips( array $test_type_test_runs ) {
$generated_zips = [];
foreach ( $test_type_test_runs as $t ) {
$path = $t['path'];
$slug = Context::$sut_slug;
$slug = $t['sut_slug'];

if ( in_array( md5( $path . $slug ), $generated_zips, true ) ) {
echo "[INFO] Skipping zip generation for test: {$t['test_function_name']} (Another test in same dir already zipped)\n";
Expand Down
6 changes: 6 additions & 0 deletions _tests/activation/childtheme/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
return [
'php' => '8.2',
'wp' => 'stable',
'woo' => 'stable',
];
13 changes: 13 additions & 0 deletions _tests/activation/childtheme/wporg-theme-storefront/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

add_action( 'wp', static function () {
if ( is_cart() ) {
call_to_undefined_function();
}

trigger_error( 'Warning on all requests - Child theme', E_USER_WARNING );
} );

add_action( 'init', static function() {
trigger_error( 'Notice on all requests - Child theme' );
} );
7 changes: 7 additions & 0 deletions _tests/activation/childtheme/wporg-theme-storefront/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
Theme Name: Storefront
Theme URI: https://woocommerce.com/products/storefront/
Description: Storefront Theme.
Template: twentytwentyfour
Version: 1.0.0
*/
6 changes: 6 additions & 0 deletions _tests/activation/parenttheme/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
return [
'php' => '8.2',
'wp' => 'stable',
'woo' => 'stable',
];
13 changes: 13 additions & 0 deletions _tests/activation/parenttheme/wporg-theme-storefront/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

add_action( 'wp', static function () {
if ( is_cart() ) {
call_to_undefined_function();
}

trigger_error( 'Warning on all requests - Parent Theme', E_USER_WARNING );
} );

add_action( 'init', static function() {
trigger_error( 'Notice on all requests - Parent Theme' );
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
/**
* The main template file.
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
*/

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
Theme Name: Storefront
Theme URI: https://woocommerce.com/products/storefront/
Description: Storefront Theme.
Version: 1.0.0
*/
6 changes: 6 additions & 0 deletions _tests/api/childtheme/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
return [
'php' => '8.2',
'wp' => 'stable',
'woo' => 'stable',
];
7 changes: 7 additions & 0 deletions _tests/api/childtheme/wporg-theme-storefront/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
Theme Name: Storefront
Theme URI: https://woocommerce.com/products/storefront/
Description: Storefront Theme.
Template: twentytwentyfour
Version: 1.0.0
*/
6 changes: 6 additions & 0 deletions _tests/api/parenttheme/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
return [
'php' => '8.2',
'wp' => 'stable',
'woo' => 'stable',
];
9 changes: 9 additions & 0 deletions _tests/api/parenttheme/wporg-theme-storefront/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
/**
* The main template file.
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
*/

6 changes: 6 additions & 0 deletions _tests/api/parenttheme/wporg-theme-storefront/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
Theme Name: Storefront
Theme URI: https://woocommerce.com/products/storefront/
Description: Storefront Theme.
Version: 1.0.0
*/
2 changes: 2 additions & 0 deletions _tests/malware/no_op/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
return [];
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

/*
* Plugin name: Malware - No-op.
*/

// No-op plugin.
2 changes: 2 additions & 0 deletions _tests/malware/violations/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
return [];
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* Plugin name: Malware Violations
* Description: This plugin contains multiple violations that should be flagged by the malware scanner
*/

function dangerous_method( $handle ) {
fpassthru( $handle );
}

$dodgy_php = "SetHandler application/x-httpd-php";
$dodgy_string = ".bash_history";

// Check password
if ( md5($_POST['password']) === 'd41d8cd98f00b204e9800998ecf8427e' ) {
echo "Gotchya!";
}

6 changes: 6 additions & 0 deletions _tests/phpcompatibility/childtheme/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
return [
'params' => [
'--min_php_version' => '7.2',
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

// Requires PHP 7.0.
$anonymousClass = new class {};

// Requires PHP 7.1.
function voidReturnType(): void {}

// Requires PHP 7.2.
$object = new class { public const A = 'a'; };
$objectType = $object::A ?? 'default'; // Null coalescing operator with class constant

// Requires PHP 7.3 (should be flagged since this plugin supports PHP 7.2).
$result = my_function(1, 2, 3,); // Trailing comma in function call

// Requires PHP 7.4 (should be flagged since this plugin supports PHP 7.2).
$arrowFunction = fn($x) => $x + 1;

// Requries PHP 8.0 (should not be flagged since this plugin does not support PHP 8.0).
str_contains('hello world', 'world');

// Requires PHP 8.1 (should not be flagged since this plugin does not support PHP 8.1).
class Bar {
readonly string $foo;
}

// Requires PHP 8.2 (should not be flagged since this plugin does not support PHP 8.2).
readonly class Foo {

}

// Deprecated in PHP 7.2
// The create_function() function is deprecated as of PHP 7.2.
$newfunc = create_function('$a', 'return $a * 2;');

// Deprecated in PHP 7.2
// The __autoload function is deprecated in favor of spl_autoload_register.
function __autoload($class) {
include 'classes/' . $class . '.class.php';
}

// Deprecated in PHP 7.3
// Deprecated flags for filter_var with FILTER_VALIDATE_URL.
filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED);

// Deprecated in PHP 7.3
// Using implode() with the parameters in a non-canonical order is deprecated.
implode($pieces, '');

// Deprecated in PHP 7.4
// Using curly braces for array and string offset access is deprecated.
$array = [1, 2, 3];
$element = $array{0};

// Deprecated in PHP 7.4
// This function is deprecated.
$magic_quotes = get_magic_quotes_gpc();

// PHP 8.0 Deprecations
// Deprecated: Required parameters after optional parameters
function exampleFunction($a = [], $b) {}

// Deprecated: ReflectionParameter methods
function deprecatedReflectionMethods(ReflectionParameter $param) {
$param->getClass();
}

// PHP 8.1 Deprecations
// Deprecated: Passing null to non-nullable internal function parameters
strlen(null);

// Deprecated: Serializable interface
class DeprecatedSerializable implements Serializable {
public function serialize() {}
public function unserialize($serialized) {}
}

// PHP 8.2 Deprecations
// Deprecated: Dynamic Properties
class ExampleClass {}
$example = new ExampleClass;
$example->dynamicProperty = 'Deprecated';

// Deprecated: utf8_encode and utf8_decode functions
utf8_encode('Deprecated');

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
Theme Name: Storefront
Theme URI: https://woocommerce.com/products/storefront/
Description: Storefront Theme.
Template: twentytwentyfour
Version: 1.0.0
*/
6 changes: 6 additions & 0 deletions _tests/phpcompatibility/parenttheme/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
return [
'params' => [
'--min_php_version' => '7.2',
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
/**
* The main template file.
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
*/

Loading

0 comments on commit 0f70017

Please sign in to comment.