test,ci: 建立 phpunit 基建 + 移植 WC 測試 + CI workflow
- composer.json / phpunit.xml / tests/bootstrap.php(比照 HP AddOn, 直接 require 核心 plugin 的 unit bootstrap) - tests/unit/WooCommerceIntegrationTest.php(自 A 移植,10 tests) - .gitea/workflows/test.yml:lint + unit(unit job 會一併 checkout 核心 plugin, 因為測試 bootstrap 依賴它) 10 tests / 33 assertions GREEN Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
name: Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, master, develop ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main, master, develop ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: PHP Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check PHP syntax
|
||||||
|
run: |
|
||||||
|
find . -name "*.php" ! -path "./vendor/*" ! -path "./tests/*" -print0 | xargs -0 -n1 php -l
|
||||||
|
echo "PHP syntax OK"
|
||||||
|
|
||||||
|
unit:
|
||||||
|
name: Unit Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# The suite boots off the core plugin's test bootstrap, so the core must be
|
||||||
|
# checked out next to this AddOn under wp-content/plugins/.
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: 2meet-data-optimizer-woocommerce-addon
|
||||||
|
|
||||||
|
- name: Checkout core plugin
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: wpdev/2meet-data-optimizer
|
||||||
|
path: 2meet-data-optimizer
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
working-directory: 2meet-data-optimizer-woocommerce-addon
|
||||||
|
run: composer install --no-interaction --prefer-dist
|
||||||
|
|
||||||
|
- name: Install core dev dependencies (test bootstrap needs them)
|
||||||
|
working-directory: 2meet-data-optimizer
|
||||||
|
run: composer install --no-interaction --prefer-dist
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
working-directory: 2meet-data-optimizer-woocommerce-addon
|
||||||
|
run: php vendor/bin/phpunit --configuration phpunit.xml --testdox
|
||||||
@@ -14,3 +14,5 @@ Thumbs.db
|
|||||||
.playwright-mcp/
|
.playwright-mcp/
|
||||||
.claude/
|
.claude/
|
||||||
dist/
|
dist/
|
||||||
|
.phpunit.cache
|
||||||
|
.phpunit.result.cache
|
||||||
|
|||||||
+10
-4
@@ -1,18 +1,24 @@
|
|||||||
{
|
{
|
||||||
"name": "2meet/2meet-data-optimizer-woocommerce-addon",
|
"name": "2meet/2meet-data-optimizer-woocommerce-addon",
|
||||||
"description": "WooCommerce 整合:20 表 schema 註冊 + commission tracking + product/order zone + HPOS notice",
|
"description": "WooCommerce integration layer for 2meet Data Optimizer",
|
||||||
"type": "wordpress-plugin",
|
"type": "wordpress-plugin",
|
||||||
"license": "GPL-2.0-or-later",
|
"license": "GPL-2.0-or-later",
|
||||||
"keywords": ["wordpress", "2meet-data-optimizer", "addon", "woocommerce"],
|
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1"
|
"php": ">=8.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"brain/monkey": "^2.6",
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.2",
|
||||||
|
"phpcompatibility/phpcompatibility-wp": "^2.1",
|
||||||
|
"phpcsstandards/phpcsutils": "^1.2",
|
||||||
"phpunit/phpunit": "^10.5",
|
"phpunit/phpunit": "^10.5",
|
||||||
"wp-coding-standards/wpcs": "^3.0"
|
"squizlabs/php_codesniffer": "^3.13",
|
||||||
|
"wp-coding-standards/wpcs": "^3.0",
|
||||||
|
"yoast/phpunit-polyfills": "^2.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"phpcs": "phpcs --standard=WordPress includes/ 2meet-data-optimizer-woocommerce-addon.php"
|
"test": "phpunit --configuration phpunit.xml",
|
||||||
|
"phpcs": "phpcs --standard=WordPress includes/ admin/ cli/"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
|||||||
Generated
+565
-54
@@ -4,9 +4,127 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "cba6cd51d0a978057a719f3b0cf1a78d",
|
"content-hash": "6e6e5104586cd2b1a09c1e5c74ad35f9",
|
||||||
"packages": [],
|
"packages": [],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "antecedent/patchwork",
|
||||||
|
"version": "2.2.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/antecedent/patchwork.git",
|
||||||
|
"reference": "8b6b235f405af175259c8f56aea5fc23ab9f03ce"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/antecedent/patchwork/zipball/8b6b235f405af175259c8f56aea5fc23ab9f03ce",
|
||||||
|
"reference": "8b6b235f405af175259c8f56aea5fc23ab9f03ce",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": ">=4"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ignas Rudaitis",
|
||||||
|
"email": "ignas.rudaitis@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Method redefinition (monkey-patching) functionality for PHP.",
|
||||||
|
"homepage": "https://antecedent.github.io/patchwork/",
|
||||||
|
"keywords": [
|
||||||
|
"aop",
|
||||||
|
"aspect",
|
||||||
|
"interception",
|
||||||
|
"monkeypatching",
|
||||||
|
"redefinition",
|
||||||
|
"runkit",
|
||||||
|
"testing"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/antecedent/patchwork/issues",
|
||||||
|
"source": "https://github.com/antecedent/patchwork/tree/2.2.3"
|
||||||
|
},
|
||||||
|
"time": "2025-09-17T09:00:56+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "brain/monkey",
|
||||||
|
"version": "2.7.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Brain-WP/BrainMonkey.git",
|
||||||
|
"reference": "ea3aeb3d559ba3c0930b3f4d210b665a4c044d83"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/ea3aeb3d559ba3c0930b3f4d210b665a4c044d83",
|
||||||
|
"reference": "ea3aeb3d559ba3c0930b3f4d210b665a4c044d83",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"antecedent/patchwork": "^2.1.17",
|
||||||
|
"mockery/mockery": "~1.3.6 || ~1.4.4 || ~1.5.1 || ^1.6.10",
|
||||||
|
"php": ">=5.6.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.0.0",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3.0",
|
||||||
|
"phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.49 || ^9.6.30"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.x-dev",
|
||||||
|
"dev-version/1": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"inc/api.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Brain\\Monkey\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Giuseppe Mazzapica",
|
||||||
|
"email": "giuseppe.mazzapica@gmail.com",
|
||||||
|
"homepage": "https://gmazzap.me",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Mocking utility for PHP functions and WordPress plugin API",
|
||||||
|
"keywords": [
|
||||||
|
"Monkey Patching",
|
||||||
|
"interception",
|
||||||
|
"mock",
|
||||||
|
"mock functions",
|
||||||
|
"mockery",
|
||||||
|
"patchwork",
|
||||||
|
"redefinition",
|
||||||
|
"runkit",
|
||||||
|
"test",
|
||||||
|
"testing"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Brain-WP/BrainMonkey/issues",
|
||||||
|
"source": "https://github.com/Brain-WP/BrainMonkey"
|
||||||
|
},
|
||||||
|
"time": "2026-02-05T09:22:14+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dealerdirect/phpcodesniffer-composer-installer",
|
"name": "dealerdirect/phpcodesniffer-composer-installer",
|
||||||
"version": "v1.2.1",
|
"version": "v1.2.1",
|
||||||
@@ -103,6 +221,140 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-05-06T08:26:05+00:00"
|
"time": "2026-05-06T08:26:05+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "hamcrest/hamcrest-php",
|
||||||
|
"version": "v2.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/hamcrest/hamcrest-php.git",
|
||||||
|
"reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487",
|
||||||
|
"reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.4|^8.0"
|
||||||
|
},
|
||||||
|
"replace": {
|
||||||
|
"cordoval/hamcrest-php": "*",
|
||||||
|
"davedevelopment/hamcrest-php": "*",
|
||||||
|
"kodova/hamcrest-php": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0",
|
||||||
|
"phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"hamcrest"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"description": "This is the PHP port of Hamcrest Matchers",
|
||||||
|
"keywords": [
|
||||||
|
"test"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/hamcrest/hamcrest-php/issues",
|
||||||
|
"source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1"
|
||||||
|
},
|
||||||
|
"time": "2025-04-30T06:54:44+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mockery/mockery",
|
||||||
|
"version": "1.6.12",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mockery/mockery.git",
|
||||||
|
"reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699",
|
||||||
|
"reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"hamcrest/hamcrest-php": "^2.0.1",
|
||||||
|
"lib-pcre": ">=7.0",
|
||||||
|
"php": ">=7.3"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpunit/phpunit": "<8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^8.5 || ^9.6.17",
|
||||||
|
"symplify/easy-coding-standard": "^12.1.14"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"library/helpers.php",
|
||||||
|
"library/Mockery.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Mockery\\": "library/Mockery"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Pádraic Brady",
|
||||||
|
"email": "padraic.brady@gmail.com",
|
||||||
|
"homepage": "https://github.com/padraic",
|
||||||
|
"role": "Author"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dave Marshall",
|
||||||
|
"email": "dave.marshall@atstsolutions.co.uk",
|
||||||
|
"homepage": "https://davedevelopment.co.uk",
|
||||||
|
"role": "Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nathanael Esayeas",
|
||||||
|
"email": "nathanael.esayeas@protonmail.com",
|
||||||
|
"homepage": "https://github.com/ghostwriter",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Mockery is a simple yet flexible PHP mock object framework",
|
||||||
|
"homepage": "https://github.com/mockery/mockery",
|
||||||
|
"keywords": [
|
||||||
|
"BDD",
|
||||||
|
"TDD",
|
||||||
|
"library",
|
||||||
|
"mock",
|
||||||
|
"mock objects",
|
||||||
|
"mockery",
|
||||||
|
"stub",
|
||||||
|
"test",
|
||||||
|
"test double",
|
||||||
|
"testing"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"docs": "https://docs.mockery.io/",
|
||||||
|
"issues": "https://github.com/mockery/mockery/issues",
|
||||||
|
"rss": "https://github.com/mockery/mockery/releases.atom",
|
||||||
|
"security": "https://github.com/mockery/mockery/security/advisories",
|
||||||
|
"source": "https://github.com/mockery/mockery"
|
||||||
|
},
|
||||||
|
"time": "2024-05-16T03:13:13+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "myclabs/deep-copy",
|
"name": "myclabs/deep-copy",
|
||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
@@ -165,20 +417,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
"version": "v5.7.0",
|
"version": "v5.8.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||||
"reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
|
"reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
|
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/044a6a392ff8ad0d61f14370a5fbbd0a0107152f",
|
||||||
"reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
|
"reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-ctype": "*",
|
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-tokenizer": "*",
|
"ext-tokenizer": "*",
|
||||||
"php": ">=7.4"
|
"php": ">=7.4"
|
||||||
@@ -217,9 +468,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
|
"source": "https://github.com/nikic/PHP-Parser/tree/v5.8.0"
|
||||||
},
|
},
|
||||||
"time": "2025-12-06T11:56:16+00:00"
|
"time": "2026-07-04T14:30:18+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phar-io/manifest",
|
"name": "phar-io/manifest",
|
||||||
@@ -340,22 +591,235 @@
|
|||||||
"time": "2022-02-21T01:04:05+00:00"
|
"time": "2022-02-21T01:04:05+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpcsstandards/phpcsextra",
|
"name": "phpcompatibility/php-compatibility",
|
||||||
"version": "1.5.0",
|
"version": "9.3.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHPCSStandards/PHPCSExtra.git",
|
"url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
|
||||||
"reference": "b598aa890815b8df16363271b659d73280129101"
|
"reference": "9fb324479acf6f39452e0655d2429cc0d3914243"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/b598aa890815b8df16363271b659d73280129101",
|
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243",
|
||||||
"reference": "b598aa890815b8df16363271b659d73280129101",
|
"reference": "9fb324479acf6f39452e0655d2429cc0d3914243",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3",
|
||||||
|
"squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"squizlabs/php_codesniffer": "2.6.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
|
||||||
|
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
|
||||||
|
},
|
||||||
|
"type": "phpcodesniffer-standard",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Wim Godden",
|
||||||
|
"homepage": "https://github.com/wimg",
|
||||||
|
"role": "lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"homepage": "https://github.com/jrfnl",
|
||||||
|
"role": "lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
|
||||||
|
"homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"phpcs",
|
||||||
|
"standards"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues",
|
||||||
|
"source": "https://github.com/PHPCompatibility/PHPCompatibility"
|
||||||
|
},
|
||||||
|
"time": "2019-12-27T09:44:58+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpcompatibility/phpcompatibility-paragonie",
|
||||||
|
"version": "1.3.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
|
||||||
|
"reference": "244d7b04fc4bc2117c15f5abe23eb933b5f02bbf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/244d7b04fc4bc2117c15f5abe23eb933b5f02bbf",
|
||||||
|
"reference": "244d7b04fc4bc2117c15f5abe23eb933b5f02bbf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"phpcompatibility/php-compatibility": "^9.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||||
|
"paragonie/random_compat": "dev-master",
|
||||||
|
"paragonie/sodium_compat": "dev-master"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
|
||||||
|
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
|
||||||
|
},
|
||||||
|
"type": "phpcodesniffer-standard",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Wim Godden",
|
||||||
|
"role": "lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"role": "lead"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
|
||||||
|
"homepage": "http://phpcompatibility.com/",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"paragonie",
|
||||||
|
"phpcs",
|
||||||
|
"polyfill",
|
||||||
|
"standards",
|
||||||
|
"static analysis"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues",
|
||||||
|
"security": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/security/policy",
|
||||||
|
"source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/PHPCompatibility",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jrfnl",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "open_collective"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://thanks.dev/u/gh/phpcompatibility",
|
||||||
|
"type": "thanks_dev"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-09-19T17:43:28+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpcompatibility/phpcompatibility-wp",
|
||||||
|
"version": "2.1.8",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
|
||||||
|
"reference": "7c8d18b4d90dac9e86b0869a608fa09158e168fa"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/7c8d18b4d90dac9e86b0869a608fa09158e168fa",
|
||||||
|
"reference": "7c8d18b4d90dac9e86b0869a608fa09158e168fa",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"phpcompatibility/php-compatibility": "^9.0",
|
||||||
|
"phpcompatibility/phpcompatibility-paragonie": "^1.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
|
||||||
|
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
|
||||||
|
},
|
||||||
|
"type": "phpcodesniffer-standard",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Wim Godden",
|
||||||
|
"role": "lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"role": "lead"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
|
||||||
|
"homepage": "http://phpcompatibility.com/",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"phpcs",
|
||||||
|
"standards",
|
||||||
|
"static analysis",
|
||||||
|
"wordpress"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues",
|
||||||
|
"security": "https://github.com/PHPCompatibility/PHPCompatibilityWP/security/policy",
|
||||||
|
"source": "https://github.com/PHPCompatibility/PHPCompatibilityWP"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/PHPCompatibility",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jrfnl",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "open_collective"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://thanks.dev/u/gh/phpcompatibility",
|
||||||
|
"type": "thanks_dev"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-10-18T00:05:59+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpcsstandards/phpcsextra",
|
||||||
|
"version": "1.5.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCSStandards/PHPCSExtra.git",
|
||||||
|
"reference": "39467533fdb742446d68c1d10ac33d625ee0311c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/39467533fdb742446d68c1d10ac33d625ee0311c",
|
||||||
|
"reference": "39467533fdb742446d68c1d10ac33d625ee0311c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.4",
|
"php": ">=5.4",
|
||||||
"phpcsstandards/phpcsutils": "^1.2.0",
|
"phpcsstandards/phpcsutils": "^1.2.3",
|
||||||
"squizlabs/php_codesniffer": "^3.13.5 || ^4.0.1"
|
"squizlabs/php_codesniffer": "^3.13.5 || ^4.0.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@@ -419,20 +883,20 @@
|
|||||||
"type": "thanks_dev"
|
"type": "thanks_dev"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-11-12T23:06:57+00:00"
|
"time": "2026-07-27T11:13:17+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpcsstandards/phpcsutils",
|
"name": "phpcsstandards/phpcsutils",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHPCSStandards/PHPCSUtils.git",
|
"url": "https://github.com/PHPCSStandards/PHPCSUtils.git",
|
||||||
"reference": "c216317e96c8b3f5932808f9b0f1f7a14e3bbf55"
|
"reference": "5f35d9408c54d7b529501f3c688b6eae562aea1f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/c216317e96c8b3f5932808f9b0f1f7a14e3bbf55",
|
"url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/5f35d9408c54d7b529501f3c688b6eae562aea1f",
|
||||||
"reference": "c216317e96c8b3f5932808f9b0f1f7a14e3bbf55",
|
"reference": "5f35d9408c54d7b529501f3c688b6eae562aea1f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -512,7 +976,7 @@
|
|||||||
"type": "thanks_dev"
|
"type": "thanks_dev"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-12-08T14:27:58+00:00"
|
"time": "2026-07-27T10:28:41+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
@@ -837,24 +1301,24 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "10.5.63",
|
"version": "10.5.64",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "33198268dad71e926626b618f3ec3966661e4d90"
|
"reference": "0e8c1d19cea35ad97d4887f363d07c78e30fbf06"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0e8c1d19cea35ad97d4887f363d07c78e30fbf06",
|
||||||
"reference": "33198268dad71e926626b618f3ec3966661e4d90",
|
"reference": "0e8c1d19cea35ad97d4887f363d07c78e30fbf06",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
|
"ext-filter": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-libxml": "*",
|
"ext-libxml": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
"ext-xml": "*",
|
|
||||||
"ext-xmlwriter": "*",
|
"ext-xmlwriter": "*",
|
||||||
"myclabs/deep-copy": "^1.13.4",
|
"myclabs/deep-copy": "^1.13.4",
|
||||||
"phar-io/manifest": "^2.0.4",
|
"phar-io/manifest": "^2.0.4",
|
||||||
@@ -918,31 +1382,15 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63"
|
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.64"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"url": "https://phpunit.de/sponsors.html",
|
"url": "https://phpunit.de/sponsoring.html",
|
||||||
"type": "custom"
|
"type": "other"
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/sebastianbergmann",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://liberapay.com/sebastianbergmann",
|
|
||||||
"type": "liberapay"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://thanks.dev/u/gh/sebastianbergmann",
|
|
||||||
"type": "thanks_dev"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-01-27T05:48:37+00:00"
|
"time": "2026-07-06T14:50:35+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/cli-parser",
|
"name": "sebastian/cli-parser",
|
||||||
@@ -2028,16 +2476,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "wp-coding-standards/wpcs",
|
"name": "wp-coding-standards/wpcs",
|
||||||
"version": "3.3.0",
|
"version": "3.4.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
|
"url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
|
||||||
"reference": "7795ec6fa05663d716a549d0b44e47ffc8b0d4a6"
|
"reference": "ec2ff942335f33683a5957a85d138753876a05cf"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7795ec6fa05663d716a549d0b44e47ffc8b0d4a6",
|
"url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/ec2ff942335f33683a5957a85d138753876a05cf",
|
||||||
"reference": "7795ec6fa05663d716a549d0b44e47ffc8b0d4a6",
|
"reference": "ec2ff942335f33683a5957a85d138753876a05cf",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2046,9 +2494,9 @@
|
|||||||
"ext-tokenizer": "*",
|
"ext-tokenizer": "*",
|
||||||
"ext-xmlreader": "*",
|
"ext-xmlreader": "*",
|
||||||
"php": ">=7.2",
|
"php": ">=7.2",
|
||||||
"phpcsstandards/phpcsextra": "^1.5.0",
|
"phpcsstandards/phpcsextra": "^1.5.1",
|
||||||
"phpcsstandards/phpcsutils": "^1.1.0",
|
"phpcsstandards/phpcsutils": "^1.2.3",
|
||||||
"squizlabs/php_codesniffer": "^3.13.4"
|
"squizlabs/php_codesniffer": "^3.13.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||||
@@ -2090,7 +2538,70 @@
|
|||||||
"type": "custom"
|
"type": "custom"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-11-25T12:08:04+00:00"
|
"time": "2026-07-27T11:53:23+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yoast/phpunit-polyfills",
|
||||||
|
"version": "2.0.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Yoast/PHPUnit-Polyfills.git",
|
||||||
|
"reference": "1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27",
|
||||||
|
"reference": "1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.6",
|
||||||
|
"phpunit/phpunit": "^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.4.0",
|
||||||
|
"yoast/yoastcs": "^3.2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "4.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"phpunitpolyfills-autoload.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Team Yoast",
|
||||||
|
"email": "support@yoast.com",
|
||||||
|
"homepage": "https://yoast.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests",
|
||||||
|
"homepage": "https://github.com/Yoast/PHPUnit-Polyfills",
|
||||||
|
"keywords": [
|
||||||
|
"phpunit",
|
||||||
|
"polyfill",
|
||||||
|
"testing"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues",
|
||||||
|
"security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy",
|
||||||
|
"source": "https://github.com/Yoast/PHPUnit-Polyfills"
|
||||||
|
},
|
||||||
|
"time": "2025-08-10T05:13:49+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="tests/bootstrap.php"
|
||||||
|
colors="true"
|
||||||
|
failOnWarning="true"
|
||||||
|
beStrictAboutOutputDuringTests="true"
|
||||||
|
cacheDirectory=".phpunit.cache">
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="woocommerce-addon">
|
||||||
|
<directory>tests/unit</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<source>
|
||||||
|
<include>
|
||||||
|
<directory>includes</directory>
|
||||||
|
<directory>admin</directory>
|
||||||
|
<directory>cli</directory>
|
||||||
|
</include>
|
||||||
|
</source>
|
||||||
|
</phpunit>
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPUnit bootstrap for the WooCommerce AddOn.
|
||||||
|
*
|
||||||
|
* Reuses the core plugin's unit bootstrap (WP function stubs, $wpdb stub,
|
||||||
|
* constants, WPDO_* aliases) and loads this AddOn's classes on top.
|
||||||
|
*
|
||||||
|
* @package TMDO_WOOCOMMERCE
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$tmdo_core_bootstrap = dirname( __DIR__, 2 ) . '/2meet-data-optimizer/tests/bootstrap.php';
|
||||||
|
if ( ! file_exists( $tmdo_core_bootstrap ) ) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
'WooCommerce AddOn tests require the core plugin at ' . dirname( __DIR__, 2 ) . '/2meet-data-optimizer'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
require_once $tmdo_core_bootstrap;
|
||||||
|
|
||||||
|
define( 'TMDO_WOOCOMMERCE_PATH', dirname( __DIR__ ) . '/' );
|
||||||
|
define( 'TMDO_WOOCOMMERCE_URL', 'http://localhost/wp-content/plugins/2meet-data-optimizer-woocommerce-addon/' );
|
||||||
|
define( 'TMDO_WOOCOMMERCE_FILE', dirname( __DIR__ ) . '/2meet-data-optimizer-woocommerce-addon.php' );
|
||||||
|
define( 'TMDO_WOOCOMMERCE_VERSION', '0.1.0' );
|
||||||
|
|
||||||
|
foreach ( array(
|
||||||
|
'includes/class-tmdo-woocommerce.php',
|
||||||
|
'includes/class-tmdo-wc-orders-interceptor.php',
|
||||||
|
'includes/class-tmdo-wc-term-count-filter.php',
|
||||||
|
'admin/class-tmdo-admin-wc.php',
|
||||||
|
) as $tmdo_wc_file ) {
|
||||||
|
$tmdo_wc_path = TMDO_WOOCOMMERCE_PATH . $tmdo_wc_file;
|
||||||
|
if ( file_exists( $tmdo_wc_path ) ) {
|
||||||
|
require_once $tmdo_wc_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset( $tmdo_wc_file, $tmdo_wc_path, $tmdo_core_bootstrap );
|
||||||
|
|
||||||
|
// Mirrors includes/back-compat-aliases.php, which runs on plugins_loaded:7 and
|
||||||
|
// therefore never fires under PHPUnit.
|
||||||
|
foreach ( get_declared_classes() as $tmdo_declared ) {
|
||||||
|
if ( str_starts_with( $tmdo_declared, 'TMDO_' ) ) {
|
||||||
|
$tmdo_alias = 'WPDO_' . substr( $tmdo_declared, 5 );
|
||||||
|
if ( ! class_exists( $tmdo_alias, false ) ) {
|
||||||
|
class_alias( $tmdo_declared, $tmdo_alias );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset( $tmdo_declared, $tmdo_alias );
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for WPDO_WooCommerce + WPDO_WC_Orders_Interceptor + new CLI methods.
|
||||||
|
*
|
||||||
|
* v2.1.2 — covers the test-coverage gaps surfaced by the production audit
|
||||||
|
* (PRODUCTION_AUDIT_2026-04-26.md, test-automator section, 5 prioritized tests).
|
||||||
|
*/
|
||||||
|
class WooCommerceIntegrationTest extends TestCase {
|
||||||
|
|
||||||
|
protected function setUp(): void {
|
||||||
|
// Reset request-level state between tests.
|
||||||
|
$GLOBALS['_wp_options'] = array();
|
||||||
|
$GLOBALS['_wp_post_types'] = array();
|
||||||
|
$GLOBALS['_wp_current_user_can'] = array();
|
||||||
|
$GLOBALS['_wpdo_inserts'] = array();
|
||||||
|
$GLOBALS['_wpdo_upserts'] = array();
|
||||||
|
|
||||||
|
// Ensure $wpdb has a $queries property — other tests may have swapped
|
||||||
|
// $wpdb to a mock that doesn't define this property.
|
||||||
|
global $wpdb;
|
||||||
|
if ( ! property_exists( $wpdb, 'queries' ) ) {
|
||||||
|
$wpdb = $GLOBALS['_wpdo_orig_wpdb'] ?? new class {
|
||||||
|
public string $prefix = 'wp_';
|
||||||
|
public array $queries = [];
|
||||||
|
public function prepare( string $sql, ...$args ): string { return $sql; }
|
||||||
|
public function get_var( string $sql ): ?string { return null; }
|
||||||
|
public function get_row( string $sql, $output = OBJECT ) { return null; }
|
||||||
|
public function get_results( string $sql, $output = OBJECT ): array { return []; }
|
||||||
|
public function get_col( string $sql, int $x = 0 ): array { return []; }
|
||||||
|
public function query( string $sql ) { $this->queries[] = $sql; return 1; }
|
||||||
|
public function insert( string $t, array $d, $f = null ): int { $this->queries[] = "INSERT $t"; return 1; }
|
||||||
|
public function update( string $t, array $d, array $w, $df = null, $wf = null ): int { return 1; }
|
||||||
|
public function delete( string $t, array $w, $wf = null ): int { return 1; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test #5 — WPDO_WooCommerce::is_active() returns false without WC ──
|
||||||
|
|
||||||
|
public function test_is_active_returns_false_when_wc_not_installed(): void {
|
||||||
|
// In the test bootstrap WooCommerce class is NOT defined, WC_VERSION is NOT set,
|
||||||
|
// and the WC plugin file does not exist at the fake plugin dir.
|
||||||
|
// Conditions match a non-WC environment.
|
||||||
|
$this->assertFalse( class_exists( 'WooCommerce', false ) );
|
||||||
|
$this->assertFalse( defined( 'WC_VERSION' ) );
|
||||||
|
|
||||||
|
// All 3 detection paths should be false.
|
||||||
|
// is_active() is loose: returns true if ANY path is true. With all three false → false.
|
||||||
|
// We can't easily test without running the actual method, but we can verify
|
||||||
|
// each detection branch returns falsy:
|
||||||
|
$class_check = class_exists( 'WooCommerce' );
|
||||||
|
$const_check = defined( 'WC_VERSION' ) && WC_VERSION;
|
||||||
|
// In test env WP_PLUGIN_DIR may not be defined; that's a 4th sign of "no WP".
|
||||||
|
$file_check = defined( 'WP_PLUGIN_DIR' )
|
||||||
|
? file_exists( WP_PLUGIN_DIR . '/woocommerce/woocommerce.php' )
|
||||||
|
: false;
|
||||||
|
|
||||||
|
$this->assertFalse( $class_check );
|
||||||
|
$this->assertFalse( (bool) $const_check );
|
||||||
|
$this->assertFalse( $file_check );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test #1 — WC_Orders_Interceptor skips untracked statuses ──
|
||||||
|
|
||||||
|
public function test_action_order_status_changed_skips_untracked_status(): void {
|
||||||
|
$ic = new WPDO_WC_Orders_Interceptor();
|
||||||
|
|
||||||
|
// Stub feature flags so is_active() returns true (forces sync_commission to be reached).
|
||||||
|
WPDO_Feature_Flags::set( 'wc_orders', 'cutover' );
|
||||||
|
|
||||||
|
// Snapshot $wpdb query count BEFORE.
|
||||||
|
global $wpdb;
|
||||||
|
$before_query_count = count( $wpdb->queries );
|
||||||
|
|
||||||
|
// Untracked status — should early-return before sync_commission runs.
|
||||||
|
// If it reached sync_commission, the wc_get_order() call would either throw
|
||||||
|
// (function undefined in tests) or — if defined — eventually call $wpdb->query().
|
||||||
|
// Either way, the early-return path means $wpdb->queries does NOT grow.
|
||||||
|
$ic->action_order_status_changed( 999, 'pending', 'on-hold' );
|
||||||
|
|
||||||
|
$after_query_count = count( $wpdb->queries );
|
||||||
|
$this->assertSame(
|
||||||
|
$before_query_count,
|
||||||
|
$after_query_count,
|
||||||
|
'Untracked status must NOT trigger any $wpdb queries (no sync_commission)'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_action_order_status_changed_skips_when_inactive(): void {
|
||||||
|
$ic = new WPDO_WC_Orders_Interceptor();
|
||||||
|
// Module not in WRITE_ACTIVE_STATES → is_active() false.
|
||||||
|
WPDO_Feature_Flags::set( 'wc_orders', 'idle' );
|
||||||
|
|
||||||
|
global $wpdb;
|
||||||
|
$before_query_count = count( $wpdb->queries );
|
||||||
|
|
||||||
|
$ic->action_order_status_changed( 999, 'pending', 'completed' );
|
||||||
|
|
||||||
|
$after_query_count = count( $wpdb->queries );
|
||||||
|
$this->assertSame(
|
||||||
|
$before_query_count,
|
||||||
|
$after_query_count,
|
||||||
|
'Inactive module must NOT trigger any $wpdb queries'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test #2 — vendor_summary returns zeroed struct on null DB result ──
|
||||||
|
|
||||||
|
public function test_vendor_summary_returns_zeroed_struct_for_unknown_vendor(): void {
|
||||||
|
// Bootstrap $wpdb->get_row returns null by default.
|
||||||
|
$summary = WPDO_WC_Orders_Interceptor::vendor_summary( 99999 );
|
||||||
|
|
||||||
|
$this->assertIsArray( $summary );
|
||||||
|
$this->assertArrayHasKey( 'total_subtotal', $summary );
|
||||||
|
$this->assertArrayHasKey( 'total_commission', $summary );
|
||||||
|
$this->assertArrayHasKey( 'total_payout', $summary );
|
||||||
|
$this->assertArrayHasKey( 'order_count', $summary );
|
||||||
|
|
||||||
|
// Types matter for template rendering (number_format crashes on null).
|
||||||
|
$this->assertSame( 0.0, $summary['total_subtotal'] );
|
||||||
|
$this->assertSame( 0.0, $summary['total_commission'] );
|
||||||
|
$this->assertSame( 0.0, $summary['total_payout'] );
|
||||||
|
$this->assertSame( 0, $summary['order_count'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_vendor_summary_filters_by_status(): void {
|
||||||
|
// Same null DB scenario — we just verify status param doesn't throw.
|
||||||
|
$summary = WPDO_WC_Orders_Interceptor::vendor_summary( 1, 'completed' );
|
||||||
|
$this->assertSame( 0, $summary['order_count'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test #3 — WPDO_Core::render_health_alert_notice suppresses on empty ──
|
||||||
|
|
||||||
|
public function test_render_health_alert_notice_suppresses_when_option_empty(): void {
|
||||||
|
// $GLOBALS['_wp_options']['wpdo_health_alert'] is unset → get_option returns ''.
|
||||||
|
$core = new WPDO_Core();
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$core->render_health_alert_notice();
|
||||||
|
$output = ob_get_clean();
|
||||||
|
|
||||||
|
$this->assertSame( '', $output, 'No HTML when no alert option' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_render_health_alert_notice_suppresses_for_unprivileged(): void {
|
||||||
|
$GLOBALS['_wp_options']['wpdo_health_alert'] = 'DB grew 50%';
|
||||||
|
$GLOBALS['_wp_current_user_can']['manage_options'] = false;
|
||||||
|
|
||||||
|
$core = new WPDO_Core();
|
||||||
|
ob_start();
|
||||||
|
$core->render_health_alert_notice();
|
||||||
|
$output = ob_get_clean();
|
||||||
|
|
||||||
|
$this->assertSame( '', $output, 'No HTML for users without manage_options' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test #4 — CLI render_stub generates valid PHP ──
|
||||||
|
|
||||||
|
public function test_render_stub_generates_valid_php(): void {
|
||||||
|
$cli = new WPDO_CLI();
|
||||||
|
$ref = new ReflectionMethod( 'WPDO_CLI', 'render_stub' );
|
||||||
|
$ref->setAccessible( true );
|
||||||
|
|
||||||
|
$stub = $ref->invoke( $cli, '2meet-bookings', 'bk', 'TMEETIC_Bookings_WPDO' );
|
||||||
|
|
||||||
|
$this->assertStringContainsString( '<?php', $stub );
|
||||||
|
$this->assertStringContainsString( "if ( ! defined( 'ABSPATH' ) )", $stub );
|
||||||
|
$this->assertStringContainsString( 'class TMEETIC_Bookings_WPDO', $stub );
|
||||||
|
$this->assertStringContainsString( "'2meet-bookings'", $stub );
|
||||||
|
$this->assertStringContainsString( "'bk_example_one'", $stub );
|
||||||
|
$this->assertStringContainsString( "'bk_example_two'", $stub );
|
||||||
|
|
||||||
|
// Verify it parses as valid PHP.
|
||||||
|
$tmp = tempnam( sys_get_temp_dir(), 'wpdo_stub_' ) . '.php';
|
||||||
|
file_put_contents( $tmp, $stub );
|
||||||
|
exec( 'php -l ' . escapeshellarg( $tmp ) . ' 2>&1', $out, $rc );
|
||||||
|
unlink( $tmp );
|
||||||
|
|
||||||
|
$this->assertSame( 0, $rc, "Generated stub is not valid PHP:\n" . implode( "\n", $out ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_render_stub_with_different_slug_changes_class_name(): void {
|
||||||
|
$cli = new WPDO_CLI();
|
||||||
|
$ref = new ReflectionMethod( 'WPDO_CLI', 'render_stub' );
|
||||||
|
$ref->setAccessible( true );
|
||||||
|
|
||||||
|
$stub_a = $ref->invoke( $cli, 'plugin-a', 'pa', 'Plugin_A_WPDO' );
|
||||||
|
$stub_b = $ref->invoke( $cli, 'plugin-b', 'pb', 'Plugin_B_WPDO' );
|
||||||
|
|
||||||
|
$this->assertStringContainsString( 'class Plugin_A_WPDO', $stub_a );
|
||||||
|
$this->assertStringContainsString( 'class Plugin_B_WPDO', $stub_b );
|
||||||
|
$this->assertStringNotContainsString( 'Plugin_A_WPDO', $stub_b );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Bonus: H4 fix verification — Schema_Registry post_type/entity_type normalization ──
|
||||||
|
|
||||||
|
public function test_schema_registry_normalizes_entity_type_to_post_type(): void {
|
||||||
|
$registry = WPDO_Schema_Registry::instance();
|
||||||
|
|
||||||
|
// Snapshot current state to restore later (registry is a singleton).
|
||||||
|
$ref = new ReflectionClass( $registry );
|
||||||
|
$pp = $ref->getProperty( 'fields' );
|
||||||
|
$pp->setAccessible( true );
|
||||||
|
$original = $pp->getValue( $registry );
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Simulate a partner like 2meet-liff: entity_type='user', no post_type.
|
||||||
|
$registry->register( 'test-provider', array(
|
||||||
|
'entity_type' => 'user',
|
||||||
|
'meta_key' => '_test_user_meta',
|
||||||
|
'zone' => 'hot',
|
||||||
|
'data_type' => 'tinyint(1) NOT NULL DEFAULT 0',
|
||||||
|
) );
|
||||||
|
|
||||||
|
// Should be retrievable under post_type='user' (normalized).
|
||||||
|
$field = $registry->get_field( 'user', '_test_user_meta' );
|
||||||
|
$this->assertNotNull( $field, 'Field should be findable under normalized post_type=user' );
|
||||||
|
$this->assertSame( 'user', $field['post_type'] );
|
||||||
|
$this->assertSame( 'user', $field['entity_type'] );
|
||||||
|
|
||||||
|
// And NOT under empty-string post_type.
|
||||||
|
$bogus = $registry->get_field( '', '_test_user_meta' );
|
||||||
|
$this->assertNull( $bogus, 'Field should NOT be findable under empty-string post_type' );
|
||||||
|
} finally {
|
||||||
|
// Restore.
|
||||||
|
$pp->setValue( $registry, $original );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user