From 7d6a93049399a5ea4d5aaf11417b775d63912afe Mon Sep 17 00:00:00 2001 From: Glynn Quelch Date: Wed, 10 Jun 2026 12:09:57 +0100 Subject: [PATCH] Add missing tests --- .github/workflows/phpunit.yml | 47 +++++ .gitignore | 3 + composer.lock | 189 +++++++++++------- tests/e2e/fixtures/seed-calendar.php | 82 ++++++++ .../frontend/calendar-start-of-week.spec.js | 151 ++++++++++++++ tests/phpunit/Calendar/CalendarGridTest.php | 173 ++++++++++++++++ 6 files changed, 568 insertions(+), 77 deletions(-) create mode 100644 .github/workflows/phpunit.yml create mode 100644 tests/e2e/fixtures/seed-calendar.php create mode 100644 tests/e2e/specs/frontend/calendar-start-of-week.spec.js create mode 100644 tests/phpunit/Calendar/CalendarGridTest.php diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..74fcf87 --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,47 @@ +name: PHPUnit Tests + +on: + pull_request: + branches: [ trunk, develop ] + +jobs: + phpunit: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + tools: composer + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + # Dev dependencies required: test:php runs vendor/bin/phpunit. + - name: Install Composer dependencies + run: composer install --no-progress --prefer-dist + + - name: Install npm dependencies + run: npm ci --force + + # Build so register_block_type finds build/blocks; phpunit.xml.dist sets + # convertWarningsToExceptions, so a missing build dir would fail activation. + - name: Build plugin assets + run: npm run build + + - name: Start wp-env + run: npx wp-env start + + - name: Run PHPUnit tests + run: npm run test:php + + - name: Stop wp-env + if: always() + run: npx wp-env stop diff --git a/.gitignore b/.gitignore index 6654761..3763620 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ build/* # wp-env local overrides (per-machine ports etc. — never commit) .wp-env.override.json +# Local manual WP-CLI test-data seeder (run by hand, never committed) +seed-test-events.php + # Playwright test-results/ playwright-report/ diff --git a/composer.lock b/composer.lock index eac18fa..24165ea 100644 --- a/composer.lock +++ b/composer.lock @@ -522,34 +522,34 @@ }, { "name": "johnbillion/wp-compat", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/johnbillion/wp-compat.git", - "reference": "32a2f2406daa5e620e50630e9d4b8b8065d084ab" + "reference": "2ccebedbbbc6b6eec3fba4a568cff0a4ec05bf6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/johnbillion/wp-compat/zipball/32a2f2406daa5e620e50630e9d4b8b8065d084ab", - "reference": "32a2f2406daa5e620e50630e9d4b8b8065d084ab", + "url": "https://api.github.com/repos/johnbillion/wp-compat/zipball/2ccebedbbbc6b6eec3fba4a568cff0a4ec05bf6e", + "reference": "2ccebedbbbc6b6eec3fba4a568cff0a4ec05bf6e", "shasum": "" }, "require": { "php": ">= 7.4", "phpstan/phpstan": "^2.0", - "wp-hooks/wordpress-core": "^1.11" + "wp-hooks/wordpress-core": "^1.12" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "johnbillion/plugin-infrastructure": "dev-trunk", "nikic/php-parser": "^5.1", - "php-stubs/wordpress-stubs": "^6.9", + "php-stubs/wordpress-stubs": "~7.0.0", "phpstan/phpstan-deprecation-rules": "2.0.0", "phpstan/phpstan-phpunit": "2.0.1", "phpstan/phpstan-strict-rules": "2.0.0", "phpunit/phpunit": "^9.0", "roots/wordpress-core-installer": "1.100.0", - "roots/wordpress-full": "*", + "roots/wordpress-full": "~7.0.0", "wp-coding-standards/wpcs": "3.1.0" }, "suggest": { @@ -596,7 +596,7 @@ "type": "github" } ], - "time": "2025-12-04T10:54:35+00:00" + "time": "2026-05-22T14:13:03+00:00" }, { "name": "myclabs/deep-copy", @@ -899,16 +899,16 @@ }, { "name": "php-stubs/wordpress-stubs", - "version": "v6.9.1", + "version": "v6.9.4", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "f12220f303e0d7c0844c0e5e957b0c3cee48d2f7" + "reference": "90a9412826b9944f93b10bf41d795b5fe68abcd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/f12220f303e0d7c0844c0e5e957b0c3cee48d2f7", - "reference": "f12220f303e0d7c0844c0e5e957b0c3cee48d2f7", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/90a9412826b9944f93b10bf41d795b5fe68abcd5", + "reference": "90a9412826b9944f93b10bf41d795b5fe68abcd5", "shasum": "" }, "conflict": { @@ -918,7 +918,7 @@ "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "nikic/php-parser": "^5.5", "php": "^7.4 || ^8.0", - "php-stubs/generator": "^0.8.3", + "php-stubs/generator": "^0.8.6", "phpdocumentor/reflection-docblock": "^6.0", "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^9.5", @@ -945,9 +945,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.9.1" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.9.4" }, - "time": "2026-02-03T19:29:21+00:00" + "time": "2026-05-01T20:36:01+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -1470,11 +1470,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.54", + "version": "2.2.0", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", - "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b4cd98348c809924f62bb9cc8c047f5e73bc9a58", + "reference": "b4cd98348c809924f62bb9cc8c047f5e73bc9a58", "shasum": "" }, "require": { @@ -1497,6 +1497,17 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ "dev", @@ -1519,7 +1530,7 @@ "type": "github" } ], - "time": "2026-04-29T13:31:09+00:00" + "time": "2026-05-28T08:22:43+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -2161,12 +2172,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "16706d82a6f250e56047a9e95791a92a8a29f791" + "reference": "d6992473ee5e901c44ba7e8c82b3445692d04794" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/16706d82a6f250e56047a9e95791a92a8a29f791", - "reference": "16706d82a6f250e56047a9e95791a92a8a29f791", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/d6992473ee5e901c44ba7e8c82b3445692d04794", + "reference": "d6992473ee5e901c44ba7e8c82b3445692d04794", "shasum": "" }, "conflict": { @@ -2221,7 +2232,7 @@ "auth0/login": "<=7.20", "auth0/symfony": "<=5.7", "auth0/wordpress": "<=5.5", - "automad/automad": "<2.0.0.0-alpha5", + "automad/automad": "<=2.0.0.0-beta27", "automattic/jetpack": "<9.8", "awesome-support/awesome-support": "<=6.0.7", "aws/aws-sdk-php": "<=3.371.3", @@ -2281,13 +2292,13 @@ "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "chriskacerguis/codeigniter-restserver": "<=2.7.1", "chrome-php/chrome": "<1.14", - "ci4-cms-erp/ci4ms": "<=0.31.7", + "ci4-cms-erp/ci4ms": "<=0.31.8", "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", "ckeditor/ckeditor": "<4.25", "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", "co-stack/fal_sftp": "<0.2.6", - "cockpit-hq/cockpit": "<2.14", - "code16/sharp": "<9.20", + "cockpit-hq/cockpit": "<=2.14", + "code16/sharp": "<9.22", "codeception/codeception": "<3.1.3|>=4,<4.1.22", "codeigniter/framework": "<3.1.10", "codeigniter4/framework": "<4.6.2", @@ -2412,6 +2423,7 @@ "erusev/parsedown": "<1.7.2", "ether/logs": "<3.0.4", "evolutioncms/evolution": "<=3.2.3", + "evoweb/sf-register": "<13.2.4|>=14,<14.0.2", "exceedone/exment": "<4.4.3|>=5,<5.0.3", "exceedone/laravel-admin": "<2.2.3|==3", "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev", @@ -2476,6 +2488,7 @@ "friendsofsymfony1/symfony1": ">=1.1,<1.5.19", "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", + "friendsoftypo3/tt-address": "<8.1.2|>=9,<9.1.1|>=10,<10.0.1", "froala/wysiwyg-editor": "<=4.3", "frosh/adminer-platform": "<2.2.1", "froxlor/froxlor": "<2.3.6", @@ -2484,13 +2497,13 @@ "funadmin/funadmin": "<=7.1.0.0-RC6", "gaoming13/wechat-php-sdk": "<=1.10.2", "genix/cms": "<=1.1.11", - "georgringer/news": "<1.3.3", + "georgringer/news": "<11.4.4|>=12,<12.3.2|>=13,<13.0.2|>=14,<14.0.3", "geshi/geshi": "<=1.0.9.1", "getformwork/formwork": "<=2.3.3", "getgrav/grav": "<=2.0.0.0-RC1", "getgrav/grav-plugin-api": "<1.0.0.0-beta15", "getgrav/grav-plugin-form": "<9.1", - "getkirby/cms": "<4.9|>=5,<5.4", + "getkirby/cms": "<=4.9|>=5,<=5.4", "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", @@ -2592,13 +2605,14 @@ "kimai/kimai": "<=2.55", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", - "knplabs/knp-snappy": "<=1.4.2", + "knplabs/knp-snappy": "<=1.7", "kohana/core": "<3.3.3", "koillection/koillection": "<1.6.12", "krayin/laravel-crm": "<=2.2", "kreait/firebase-php": ">=3.2,<3.8.1", "kumbiaphp/kumbiapp": "<=1.1.1", "la-haute-societe/tcpdf": "<6.2.22", + "laktak/hjson": "<2.3", "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2", "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", "laminas/laminas-http": "<2.14.2", @@ -2683,6 +2697,7 @@ "miraheze/ts-portal": "<=33", "mittwald/typo3_forum": "<1.2.1", "mix/mix": ">=2,<=2.2.17", + "mmc/ceselector": "<3.0.3|>=4,<4.0.2|>=5,<5.0.1|>=6,<6.0.1", "mobiledetect/mobiledetectlib": "<2.8.32", "modx/revolution": "<=3.1", "mojo42/jirafeau": "<4.4", @@ -2786,7 +2801,7 @@ "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.2", - "phpmyfaq/phpmyfaq": "<=4.1.1", + "phpmyfaq/phpmyfaq": "<4.1.3", "phpoffice/common": "<0.2.9", "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", @@ -2801,14 +2816,14 @@ "phpxmlrpc/phpxmlrpc": "<4.9.2", "phraseanet/phraseanet": "==4.0.3", "pi/pi": "<=2.5", - "pimcore/admin-ui-classic-bundle": "<=1.7.15|>=2.0.0.0-RC1-dev,<=2.2.2", + "pimcore/admin-ui-classic-bundle": "<=2.3.5", "pimcore/customer-management-framework-bundle": "<4.2.1", "pimcore/data-hub": "<1.2.4", "pimcore/data-importer": "<1.8.9|>=1.9,<1.9.3", "pimcore/demo": "<10.3", "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<=11.5.14.1|>=12,<12.3.3|==12.3.3", + "pimcore/pimcore": "<=12.3.6", "pimcore/web2print-tools-bundle": "<=5.2.1|>=6.0.0.0-RC1-dev,<=6.1", "piwik/piwik": "<1.11", "pixelfed/pixelfed": "<0.12.5", @@ -2834,7 +2849,7 @@ "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", "propel/propel1": ">=1,<=1.7.1", "psy/psysh": "<=0.11.22|>=0.12,<=0.12.18", - "pterodactyl/panel": "<1.12.1", + "pterodactyl/panel": "<1.12.3", "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", "ptrofimov/beanstalk_console": "<1.7.14", "pubnub/pubnub": "<6.1", @@ -2877,9 +2892,11 @@ "scheb/two-factor-bundle": "<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", - "setasign/fpdi": "<2.6.4", + "setasign/fpdi": "<2.6.7", "sfroemken/url_redirect": "<=1.2.1", "sheng/yiicms": "<1.2.1", + "shopper/cart": "<2.8", + "shopper/framework": "<2.8", "shopware/core": "<6.6.10.15-dev|>=6.7,<6.7.8.1-dev", "shopware/platform": "<6.6.10.15-dev|>=6.7,<6.7.8.1-dev", "shopware/production": "<=6.3.5.2", @@ -2911,6 +2928,7 @@ "simplesamlphp/saml2": "<=4.16.15|>=5.0.0.0-alpha1,<=5.0.0.0-alpha19", "simplesamlphp/saml2-legacy": "<=4.16.15", "simplesamlphp/simplesamlphp": "<1.18.6", + "simplesamlphp/simplesamlphp-module-casserver": "<=7.0.2", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "simplesamlphp/simplesamlphp-module-openid": "<1", "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", @@ -2932,6 +2950,7 @@ "soosyze/soosyze": "<=2", "spatie/browsershot": "<5.0.5", "spatie/image-optimizer": "<1.7.3", + "spatie/schema-org": ">=3.23.1,<4.0.2", "spencer14420/sp-php-email-handler": "<1", "spipu/html2pdf": "<5.2.8", "spiral/roadrunner": "<2025.1", @@ -2943,14 +2962,14 @@ "starcitizentools/short-description": ">=4,<4.0.1", "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", "starcitizenwiki/embedvideo": "<=4", - "statamic/cms": "<5.73.21|>=6,<6.15", + "statamic/cms": "<5.73.22|>=6,<6.18.1", "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<=2.1.67", "studiomitte/friendlycaptcha": "<0.1.4", "subhh/libconnect": "<7.0.8|>=8,<8.1", "sukohi/surpass": "<1", "sulu/form-bundle": ">=2,<2.5.3", - "sulu/sulu": "<2.6.22|>=3,<3.0.5", + "sulu/sulu": "<=2.6.22|>=3,<=3.0.5", "sumocoders/framework-user-bundle": "<1.4", "superbig/craft-audit": "<3.0.2", "svewap/a21glossary": "<=0.4.10", @@ -2968,42 +2987,53 @@ "symbiote/silverstripe-seed": "<6.0.3", "symbiote/silverstripe-versionedfiles": "<=2.0.3", "symfont/process": ">=0", - "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", + "symfony/cache": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/dom-crawler": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", - "symfony/http-client": ">=4.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", - "symfony/http-foundation": "<5.4.50|>=6,<6.4.29|>=7,<7.3.7", - "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/html-sanitizer": ">=6.1,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", + "symfony/http-client": ">=4.3,<5.4.53|>=6,<6.4.15|>=7,<7.1.8", + "symfony/http-foundation": "<5.4.50|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", + "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6|>=7.4,<7.4.12|>=8,<8.0.12", "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/json-path": ">=7.3,<7.4.12|>=8,<8.0.12", + "symfony/lox24-notifier": ">=7.1,<7.4.12|>=8,<8.0.12", + "symfony/mailer": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/mailjet-mailer": ">=6.4,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/mailomat-mailer": ">=7.2,<7.4.13|>=8,<8.0.13", + "symfony/mailtrap-mailer": ">=7.2,<7.4.12|>=8,<8.0.12", "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", - "symfony/mime": ">=4.3,<4.3.8", + "symfony/mime": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/monolog-bridge": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/polyfill": ">=1,<1.10", + "symfony/polyfill": ">=1,<1.10|>=1.17.1,<1.38.1", + "symfony/polyfill-intl-idn": ">=1.17.1,<1.38.1", "symfony/polyfill-php55": ">=1,<1.10", "symfony/process": "<5.4.51|>=6,<6.4.33|>=7,<7.1.7|>=7.3,<7.3.11|>=7.4,<7.4.5|>=8,<8.0.5", "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/routing": ">=2,<2.0.19", - "symfony/runtime": ">=5.3,<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/routing": "<5.4.53|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", + "symfony/runtime": ">=5.3,<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.4.10|>=7,<7.0.10|>=7.1,<7.1.3", "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/security-http": "<5.4.53|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", - "symfony/symfony": "<5.4.51|>=6,<6.4.33|>=7,<7.3.11|>=7.4,<7.4.5|>=8,<8.0.5", + "symfony/symfony": "<5.4.53|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", "symfony/translation": ">=2,<2.0.17", - "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8|>=6.4.24,<6.4.40", + "symfony/twilio-notifier": ">=6.4,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/ux-autocomplete": "<2.11.2", "symfony/ux-live-component": "<2.25.1", "symfony/ux-twig-component": "<2.25.1", "symfony/validator": "<5.4.43|>=6,<6.4.11|>=7,<7.1.4", "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", - "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", + "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4|>=7.2.9,<7.4.12|>=8,<8.0.12", "symfony/webhook": ">=6.3,<6.3.8", - "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2", + "symfony/yaml": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symphonycms/symphony-2": "<2.6.4", "t3/dce": "<0.11.5|>=2.2,<2.6.2", "t3g/svg-sanitizer": "<1.0.3", @@ -3017,7 +3047,7 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", - "thorsten/phpmyfaq": "<=4.1.1", + "thorsten/phpmyfaq": "<4.1.3", "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -3025,16 +3055,20 @@ "titon/framework": "<9.9.99", "tltneon/lgsl": "<7", "tobiasbg/tablepress": "<=2.0.0.0-RC1", + "tomasnorre/crawler": "<11.0.13|>=12,<12.0.11", "topthink/framework": "<6.0.17|>=6.1,<=8.0.4", "topthink/think": "<=6.1.1", "topthink/thinkphp": "<=3.2.3|>=6.1.3,<=8.0.4", "torrentpier/torrentpier": "<=2.8.8", - "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", + "tpwd/ke_search": "<5.6.2|>=6,<6.6.1|>=7,<7.0.1", "tribalsystems/zenario": "<=9.7.61188", "truckersmp/phpwhois": "<=4.3.1", "ttskch/pagination-service-provider": "<1", "twbs/bootstrap": "<3.4.1|>=4,<4.3.1", - "twig/twig": "<3.11.2|>=3.12,<3.14.1|>=3.16,<3.19", + "twig/cssinliner-extra": "<3.26", + "twig/intl-extra": "<3.26", + "twig/markdown-extra": "<3.26", + "twig/twig": "<3.27", "typicms/core": "<16.1.7", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1|==14.2", @@ -3076,7 +3110,7 @@ "uvdesk/core-framework": "<=1.1.1", "vanilla/safecurl": "<0.9.2", "verbb/comments": "<1.5.5", - "verbb/formie": "<=2.1.43", + "verbb/formie": "<2.2.20|>=3.0.0.0-beta1,<3.1.24", "verbb/image-resizer": "<2.0.9", "verbb/knock-knock": "<1.2.8", "verot/class.upload.php": "<=2.1.6", @@ -3124,7 +3158,7 @@ "xpressengine/xpressengine": "<3.0.15", "yab/quarx": "<2.4.5", "yansongda/pay": "<=3.7.19", - "yeswiki/yeswiki": "<=4.6", + "yeswiki/yeswiki": "<4.6.4", "yetiforce/yetiforce-crm": "<6.5", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", @@ -3219,7 +3253,7 @@ "type": "tidelift" } ], - "time": "2026-05-14T13:38:25+00:00" + "time": "2026-05-27T21:36:42+00:00" }, { "name": "sebastian/cli-parser", @@ -4444,16 +4478,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v7.4.10", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "4eb0d9dfa9d4f7c59216baf49b3ed6b1fb72293d" + "reference": "f299e20ce983be6c0744952533c6dfeaaa1448e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4eb0d9dfa9d4f7c59216baf49b3ed6b1fb72293d", - "reference": "4eb0d9dfa9d4f7c59216baf49b3ed6b1fb72293d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f299e20ce983be6c0744952533c6dfeaaa1448e2", + "reference": "f299e20ce983be6c0744952533c6dfeaaa1448e2", "shasum": "" }, "require": { @@ -4504,7 +4538,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.10" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.13" }, "funding": [ { @@ -4524,7 +4558,7 @@ "type": "tidelift" } ], - "time": "2026-05-06T11:55:30+00:00" + "time": "2026-05-20T14:07:29+00:00" }, { "name": "symfony/filesystem", @@ -4681,16 +4715,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", "shasum": "" }, "require": { @@ -4742,7 +4776,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" }, "funding": [ { @@ -4762,7 +4796,7 @@ "type": "tidelift" } ], - "time": "2026-04-10T17:25:58+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/service-contracts", @@ -5113,16 +5147,16 @@ }, { "name": "wp-hooks/wordpress-core", - "version": "1.11.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/wp-hooks/wordpress-core-hooks.git", - "reference": "610a3721216797daa72a16044c40938ac040551a" + "reference": "0ba438bdd4c99b6613eb8459feb0a4f6d2d7082c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-hooks/wordpress-core-hooks/zipball/610a3721216797daa72a16044c40938ac040551a", - "reference": "610a3721216797daa72a16044c40938ac040551a", + "url": "https://api.github.com/repos/wp-hooks/wordpress-core-hooks/zipball/0ba438bdd4c99b6613eb8459feb0a4f6d2d7082c", + "reference": "0ba438bdd4c99b6613eb8459feb0a4f6d2d7082c", "shasum": "" }, "replace": { @@ -5132,7 +5166,7 @@ "erusev/parsedown": "1.8.0-beta-7", "oomphinc/composer-installers-extender": "^2", "roots/wordpress-core-installer": "^1.0.0", - "roots/wordpress-full": "6.9", + "roots/wordpress-full": "7.0", "wp-hooks/generator": "1.0.0" }, "type": "library", @@ -5142,6 +5176,7 @@ "wp-admin/includes/deprecated.php", "wp-admin/includes/ms-deprecated.php", "wp-content/", + "wp-includes/build/pages/", "wp-includes/deprecated.php", "wp-includes/ID3/", "wp-includes/ms-deprecated.php", @@ -5183,7 +5218,7 @@ "description": "All the actions and filters from WordPress core in machine-readable JSON format.", "support": { "issues": "https://github.com/wp-hooks/wordpress-core-hooks/issues", - "source": "https://github.com/wp-hooks/wordpress-core-hooks/tree/1.11.0" + "source": "https://github.com/wp-hooks/wordpress-core-hooks/tree/1.12.0" }, "funding": [ { @@ -5191,7 +5226,7 @@ "type": "github" } ], - "time": "2025-12-03T22:11:59+00:00" + "time": "2026-05-22T10:28:41+00:00" }, { "name": "yoast/phpunit-polyfills", @@ -5265,10 +5300,10 @@ }, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], + "platform": {}, + "platform-dev": {}, "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } diff --git a/tests/e2e/fixtures/seed-calendar.php b/tests/e2e/fixtures/seed-calendar.php new file mode 100644 index 0000000..8e1fbbb --- /dev/null +++ b/tests/e2e/fixtures/seed-calendar.php @@ -0,0 +1,82 @@ + + * + * Sets the WordPress `start_of_week` option to the value passed as the first + * positional argument (default 1 = Monday), then seeds a single published + * se-event with a child se-event-date dated *today* so the current month has + * an event and the calendar renders that month's grid (rather than the + * "No Events Scheduled" state or jumping to another month). Creates a page + * holding the real calendar block and echoes its ID for the spec to navigate + * to. Idempotent — wipes prior run first. + * + * @package Simple_Events + */ + +$prefix = 'E2ECAL'; + +// First positional arg from `wp eval-file` is the start_of_week to set. +$start_of_week = isset( $args[0] ) && '' !== $args[0] ? (int) $args[0] : 1; +$start_of_week = max( 0, min( 6, $start_of_week ) ); + +update_option( 'start_of_week', $start_of_week ); + +// Full clean slate: delete EVERY se-event and se-event-date (any status) so the +// calendar only ever sees this seeder's data, plus a prior run's page. +$wipe = get_posts( + array( + 'post_type' => array( 'se-event', 'se-event-date' ), + 'post_status' => 'any', + 'numberposts' => -1, + ) +); +foreach ( $wipe as $p ) { + wp_delete_post( $p->ID, true ); +} +foreach ( get_posts( + array( + 'post_type' => 'page', + 'post_status' => 'any', + 'numberposts' => -1, + 's' => $prefix, + ) +) as $p ) { + wp_delete_post( $p->ID, true ); +} + +// Event-info block in content so the save_post cleanup hook keeps child dates. +$event_content = ''; + +$event_id = wp_insert_post( + array( + 'post_type' => 'se-event', + 'post_status' => 'publish', + 'post_title' => $prefix . ' EVENT', + 'post_content' => $event_content, + ) +); + +// Date today (noon, to stay safely inside the current month) so the current +// month has an event and the grid renders. +$ts = strtotime( 'today noon' ); +se_event_create_event_date( + $event_id, + array( + 'start_date' => $ts, + 'end_date' => $ts + 7200, + 'all_day' => false, + ) +); + +$page_id = wp_insert_post( + array( + 'post_type' => 'page', + 'post_status' => 'publish', + 'post_title' => $prefix . ' PAGE', + 'post_content' => '', + ) +); + +echo (int) $page_id; diff --git a/tests/e2e/specs/frontend/calendar-start-of-week.spec.js b/tests/e2e/specs/frontend/calendar-start-of-week.spec.js new file mode 100644 index 0000000..38de521 --- /dev/null +++ b/tests/e2e/specs/frontend/calendar-start-of-week.spec.js @@ -0,0 +1,151 @@ +const { test, expect } = require( '@playwright/test' ); +const { execSync } = require( 'child_process' ); +const path = require( 'path' ); + +const BASE_URL = process.env.WP_BASE_URL || 'http://localhost:8888'; + +const WEEKDAYS = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', +]; + +// Regression cases for the calendar day-of-week fix (PR #76). The old +// Monday-only offset maths broke Sunday- and Saturday-start weeks, so those are +// the representative values exercised here alongside the Monday default. +const START_OF_WEEKS = [ 0, 1, 6 ]; // Sunday, Monday, Saturday. + +/** + * Seed the calendar page for a given start_of_week and return its page ID. + * + * @param {number} startOfWeek 0 (Sunday) through 6 (Saturday). + * @return {string} The seeded page ID. + */ +function seedCalendar( startOfWeek ) { + const out = execSync( + `npx wp-env run cli --env-cwd='wp-content/plugins/simple-events' -- wp eval-file tests/e2e/fixtures/seed-calendar.php ${ startOfWeek }`, + { encoding: 'utf8' } + ); + const m = out.match( /(\d+)\s*$/m ); + if ( ! m ) { + throw new Error( 'Seeder did not return a page ID. Output:\n' + out ); + } + return m[ 1 ]; +} + +/** + * Weekday (0=Sun..6=Sat) for a yyyy-mm-dd datetime attribute, read in UTC so + * the test machine's timezone can't shift the day. + * + * @param {string} datetime A `Y-m-d` string from a