diff --git a/.distignore b/.distignore index aa51614..183ddca 100644 --- a/.distignore +++ b/.distignore @@ -2,6 +2,8 @@ /.git /.github /.wordpress-org +/bin +/tests .distignore .gitignore diff --git a/.github/workflows/lint_phpcs.yml b/.github/workflows/lint_phpcs.yml new file mode 100644 index 0000000..92597a8 --- /dev/null +++ b/.github/workflows/lint_phpcs.yml @@ -0,0 +1,39 @@ +name: PHP CodeSniffer lint + +on: + pull_request: + branches: + - trunk + - develop + - branch-* + - feature/* + +jobs: + run: + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: false + matrix: + operating-system: [ubuntu-latest] + php-versions: ['7.4'] + + name: RocketCDN lint with PHPCS. PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}. + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none # XDebug can be enabled here 'coverage: xdebug' + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-scripts + + - name: Lint with phpcs + run: | + vendor/bin/phpcs --config-set installed_paths ../../phpcompatibility/phpcompatibility-paragonie,../../phpcompatibility/phpcompatibility-wp,../../wp-coding-standards/wpcs,../../phpcompatibility/php-compatibility + composer phpcs diff --git a/.github/workflows/test_php8.yml b/.github/workflows/test_php8.yml new file mode 100644 index 0000000..2a82dc9 --- /dev/null +++ b/.github/workflows/test_php8.yml @@ -0,0 +1,73 @@ +name: Unit/Integration tests - PHP 8 + +on: + pull_request: + branches: + - trunk + - develop + - branch-* + - feature/* + +jobs: + run: + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: false + matrix: + operating-system: [ubuntu-latest] + php-versions: ['8.0'] + wp-versions: ['latest'] + + name: WP ${{ matrix.wp-versions }} with PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}. + + env: + WP_TESTS_DIR: "/tmp/tests/phpunit" + WP_CORE_DIR: "/tmp/wordpress-develop" + ROCKETCDN_EMAIL: ${{ secrets.ROCKETCDN_EMAIL }} + ROCKETCDN_PWD: ${{ secrets.ROCKETCDN_PWD }} + ROCKETCDN_TOKEN: ${{ secrets.ROCKETCDN_TOKEN }} + ROCKETCDN_URL: ${{ secrets.ROCKETCDN_URL }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none # XDebug can be enabled here 'coverage: xdebug' + tools: composer:v2, phpunit + + - name: Start mysql service + run: sudo /etc/init.d/mysql start + + - name: Setup problem matchers for PHP + run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-scripts --ignore-platform-reqs + + - name: Install tests + run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:3306 ${{ matrix.wp-versions }} + + - name: Mysql8 auth plugin workaround + run: sudo mysql -u root -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';" + + - name: Test + run: composer run-tests diff --git a/.github/workflows/test_rocketcdn.yml b/.github/workflows/test_rocketcdn.yml new file mode 100644 index 0000000..2523778 --- /dev/null +++ b/.github/workflows/test_rocketcdn.yml @@ -0,0 +1,74 @@ +name: Unit/Integration tests + +on: + pull_request: + branches: + - trunk + - develop + - branch-* + - feature/* + +jobs: + run: + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: false + matrix: + operating-system: [ubuntu-latest] + php-versions: ['7.3', '7.4'] + wp-versions: ['latest'] + + name: WP ${{ matrix.wp-versions }} with PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}. + + env: + WP_TESTS_DIR: "/tmp/tests/phpunit" + WP_CORE_DIR: "/tmp/wordpress-develop" + ROCKETCDN_EMAIL: ${{ secrets.ROCKETCDN_EMAIL }} + ROCKETCDN_PWD: ${{ secrets.ROCKETCDN_PWD }} + ROCKETCDN_TOKEN: ${{ secrets.ROCKETCDN_TOKEN }} + ROCKETCDN_URL: ${{ secrets.ROCKETCDN_URL }} + ROCKETCDN_WEBSITE_ID: ${{ secrets.ROCKETCDN_WEBSITE_ID }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none # XDebug can be enabled here 'coverage: xdebug' + tools: composer:v2, phpunit + + - name: Start mysql service + run: sudo /etc/init.d/mysql start + + - name: Setup problem matchers for PHP + run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-scripts + + - name: Install tests + run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:3306 ${{ matrix.wp-versions }} + + - name: Mysql8 auth plugin workaround + run: sudo mysql -u root -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';" + + - name: Test + run: composer run-tests diff --git a/bin/browserstack.png b/bin/browserstack.png new file mode 100644 index 0000000..2e1a555 Binary files /dev/null and b/bin/browserstack.png differ diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh new file mode 100755 index 0000000..878881f --- /dev/null +++ b/bin/install-wp-tests.sh @@ -0,0 +1,152 @@ +#!/usr/bin/env bash + +if [ $# -lt 3 ]; then + echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" + exit 1 +fi + +DB_NAME=$1 +DB_USER=$2 +DB_PASS=$3 +DB_HOST=${4-localhost} +WP_VERSION=${5-latest} +SKIP_DB_CREATE=${6-false} + +TMPDIR=${TMPDIR-/tmp} +TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//") +WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib} +WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/} + +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + +if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then + WP_TESTS_TAG="branches/$WP_VERSION" +elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then + if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then + # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x + WP_TESTS_TAG="tags/${WP_VERSION%??}" + else + WP_TESTS_TAG="tags/$WP_VERSION" + fi +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" +else + # http serves a single offer, whereas https serves multiple. we only want one + download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json + grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json + LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') + if [[ -z "$LATEST_VERSION" ]]; then + echo "Latest WordPress version could not be found" + exit 1 + fi + WP_TESTS_TAG="tags/$LATEST_VERSION" +fi + +set -ex + +install_wp() { + + if [ -d $WP_CORE_DIR ]; then + return; + fi + + mkdir -p $WP_CORE_DIR + + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p $TMPDIR/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip + unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/ + mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR + else + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then + # https serves multiple offers, whereas http serves single. + download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json + if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then + # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x + LATEST_VERSION=${WP_VERSION%??} + else + # otherwise, scan the releases and get the most up to date minor version of the major release + local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'` + LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1) + fi + if [[ -z "$LATEST_VERSION" ]]; then + local ARCHIVE_NAME="wordpress-$WP_VERSION" + else + local ARCHIVE_NAME="wordpress-$LATEST_VERSION" + fi + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz + tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR + fi + + download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php +} + +install_test_suite() { + # portable in-place argument for both GNU sed and Mac OSX sed + if [[ $(uname -s) == 'Darwin' ]]; then + local ioption='-i .bak' + else + local ioption='-i' + fi + + # set up testing suite if it doesn't yet exist + if [ ! -d $WP_TESTS_DIR ]; then + # set up testing suite + mkdir -p $WP_TESTS_DIR + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data + fi + + if [ ! -f wp-tests-config.php ]; then + download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + # remove all forward slashes in the end + WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php + fi + +} + +install_db() { + + if [ ${SKIP_DB_CREATE} = "true" ]; then + return 0 + fi + + # parse DB_HOST for port or socket references + local PARTS=(${DB_HOST//\:/ }) + local DB_HOSTNAME=${PARTS[0]}; + local DB_SOCK_OR_PORT=${PARTS[1]}; + local EXTRA="" + + if ! [ -z $DB_HOSTNAME ] ; then + if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi + fi + + # create database + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + +install_wp +install_test_suite +install_db diff --git a/bin/makemo.sh b/bin/makemo.sh new file mode 100755 index 0000000..455dc92 --- /dev/null +++ b/bin/makemo.sh @@ -0,0 +1,4 @@ +#! /bin/sh +# Create .mo files from .po files. +# Twisted by WP-Translations.org, created by grappler. +for file in `find . -name "*.po"` ; do /usr/local/opt/gettext/bin/msgfmt -o ${file/.po/.mo} $file ; done \ No newline at end of file diff --git a/bin/phpcs-changed.sh b/bin/phpcs-changed.sh new file mode 100644 index 0000000..5980fbd --- /dev/null +++ b/bin/phpcs-changed.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +FILES=$(git ls-files -om --exclude-standard); +if [ -n "$FILES" ]; then + phpcs "$FILES" +fi diff --git a/composer.json b/composer.json index b40ace3..d3482ce 100644 --- a/composer.json +++ b/composer.json @@ -34,13 +34,13 @@ "league/container": "^3.3", "phpcompatibility/phpcompatibility-wp": "^2.0", "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5", + "phpunit/phpunit": "^7.5 || ^8 || ^9", "phpunit/php-file-iterator": "2.0.3", "psr/container": "1.0.0", "roave/security-advisories": "dev-master", "szepeviktor/phpstan-wordpress": "^0.7.0", "wp-coding-standards/wpcs": "^2", - "wp-media/phpunit": "^2.0" + "wp-media/phpunit": "^3.0" }, "autoload": { "psr-4": { @@ -65,12 +65,10 @@ }, "scripts": { "test-unit": "\"vendor/bin/phpunit\" --testsuite unit --colors=always --configuration tests/Unit/phpunit.xml.dist", - "test-integration": "\"vendor/bin/phpunit\" --testsuite integration --colors=always --configuration tests/Integration/phpunit.xml.dist --exclude-group AdminOnly", - "test-integration-adminonly": "\"vendor/bin/phpunit\" --testsuite integration --colors=always --configuration tests/Integration/phpunit.xml.dist --group AdminOnly", + "test-integration": "\"vendor/bin/phpunit\" --testsuite integration --colors=always --configuration tests/Integration/phpunit.xml.dist", "run-tests": [ "@test-unit", - "@test-integration", - "@test-integration-adminonly" + "@test-integration" ], "run-stan":"vendor/bin/phpstan analyze --memory-limit=2G --no-progress", "phpcs": "phpcs --basepath=.", diff --git a/composer.lock b/composer.lock index 2044268..e238e2a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "935f73171d0cfee36cdc863ebd8d177e", + "content-hash": "de9e8a22f5284ea08ba9f758fbdda55c", "packages": [ { "name": "composer/installers", @@ -161,16 +161,16 @@ "packages-dev": [ { "name": "antecedent/patchwork", - "version": "2.1.21", + "version": "2.1.28", "source": { "type": "git", "url": "https://github.com/antecedent/patchwork.git", - "reference": "25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d" + "reference": "6b30aff81ebadf0f2feb9268d3e08385cebcc08d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antecedent/patchwork/zipball/25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d", - "reference": "25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/6b30aff81ebadf0f2feb9268d3e08385cebcc08d", + "reference": "6b30aff81ebadf0f2feb9268d3e08385cebcc08d", "shasum": "" }, "require": { @@ -191,7 +191,7 @@ } ], "description": "Method redefinition (monkey-patching) functionality for PHP.", - "homepage": "http://patchwork2.org/", + "homepage": "https://antecedent.github.io/patchwork/", "keywords": [ "aop", "aspect", @@ -203,9 +203,9 @@ ], "support": { "issues": "https://github.com/antecedent/patchwork/issues", - "source": "https://github.com/antecedent/patchwork/tree/2.1.21" + "source": "https://github.com/antecedent/patchwork/tree/2.1.28" }, - "time": "2022-02-07T07:28:34+00:00" + "time": "2024-02-06T09:26:11+00:00" }, { "name": "brain/monkey", @@ -239,12 +239,12 @@ } }, "autoload": { - "psr-4": { - "Brain\\Monkey\\": "src/" - }, "files": [ "inc/api.php" - ] + ], + "psr-4": { + "Brain\\Monkey\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -410,31 +410,79 @@ }, "time": "2022-02-04T12:51:07+00:00" }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -461,7 +509,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -477,7 +525,7 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -611,16 +659,16 @@ }, { "name": "league/flysystem", - "version": "1.1.9", + "version": "1.1.10", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99" + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", "shasum": "" }, "require": { @@ -693,7 +741,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.9" + "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" }, "funding": [ { @@ -701,30 +749,30 @@ "type": "other" } ], - "time": "2021-12-09T09:40:50+00:00" + "time": "2022-10-04T09:16:37+00:00" }, { "name": "league/mime-type-detection", - "version": "1.9.0", + "version": "1.15.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69" + "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69", - "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", "shasum": "" }, "require": { "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, "type": "library", "autoload": { @@ -745,7 +793,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.9.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0" }, "funding": [ { @@ -757,20 +805,20 @@ "type": "tidelift" } ], - "time": "2021-11-21T11:48:40+00:00" + "time": "2024-01-28T23:22:08+00:00" }, { "name": "mikey179/vfsstream", - "version": "v1.6.10", + "version": "v1.6.11", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", - "reference": "250c0825537d501e327df879fb3d4cd751933b85" + "reference": "17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/250c0825537d501e327df879fb3d4cd751933b85", - "reference": "250c0825537d501e327df879fb3d4cd751933b85", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f", + "reference": "17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f", "shasum": "" }, "require": { @@ -808,39 +856,42 @@ "source": "https://github.com/bovigo/vfsStream/tree/master", "wiki": "https://github.com/bovigo/vfsStream/wiki" }, - "time": "2021-09-25T08:05:01+00:00" + "time": "2022-02-23T02:02:42+00:00" }, { "name": "mockery/mockery", - "version": "1.3.5", + "version": "1.6.11", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d" + "reference": "81a161d0b135df89951abd52296adf97deb0723d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/472fa8ca4e55483d55ee1e73c963718c4393791d", - "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d", + "url": "https://api.github.com/repos/mockery/mockery/zipball/81a161d0b135df89951abd52296adf97deb0723d", + "reference": "81a161d0b135df89951abd52296adf97deb0723d", "shasum": "" }, "require": { "hamcrest/hamcrest-php": "^2.0.1", "lib-pcre": ">=7.0", - "php": ">=5.6.0" + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3" + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, "autoload": { - "psr-0": { - "Mockery": "library/" + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" } }, "notification-url": "https://packagist.org/downloads/", @@ -851,12 +902,20 @@ { "name": "Pádraic Brady", "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" + "homepage": "https://github.com/padraic", + "role": "Author" }, { "name": "Dave Marshall", "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "http://davedevelopment.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", @@ -874,35 +933,39 @@ "testing" ], "support": { + "docs": "https://docs.mockery.io/", "issues": "https://github.com/mockery/mockery/issues", - "source": "https://github.com/mockery/mockery/tree/1.3.5" + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" }, - "time": "2021-09-13T15:33:03+00:00" + "time": "2024-03-21T18:34:15+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { @@ -927,7 +990,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -935,32 +998,34 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -992,26 +1057,32 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2018-07-08T19:23:20+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1043,37 +1114,37 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/master" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2018-07-08T19:19:57+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "php-stubs/wordpress-stubs", - "version": "v5.9.0", + "version": "v5.9.9", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b" + "reference": "06c51c4863659ea9e9f4c2a23293728a677cb059" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", - "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/06c51c4863659ea9e9f4c2a23293728a677cb059", + "reference": "06c51c4863659ea9e9f4c2a23293728a677cb059", "shasum": "" }, - "replace": { - "giacocorsiglia/wordpress-stubs": "*" - }, "require-dev": { - "nikic/php-parser": "< 4.12.0", - "php": "~7.3 || ~8.0", - "php-stubs/generator": "^0.8.0", - "phpdocumentor/reflection-docblock": "^5.3", - "phpstan/phpstan": "^1.2" + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "nikic/php-parser": "^4.13", + "php": "^7.4 || ~8.0.0", + "php-stubs/generator": "^0.8.3", + "phpdocumentor/reflection-docblock": "5.3", + "phpstan/phpstan": "^1.10.49", + "phpunit/phpunit": "^9.5", + "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.11" }, "suggest": { "paragonie/sodium_compat": "Pure PHP implementation of libsodium", - "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" }, "type": "library", @@ -1090,9 +1161,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.9.0" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.9.9" }, - "time": "2022-01-26T00:27:45+00:00" + "time": "2024-04-14T17:16:00+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -1158,28 +1229,28 @@ }, { "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.1", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "ddabec839cc003651f2ce695c938686d1086cf43" + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/ddabec839cc003651f2ce695c938686d1086cf43", - "reference": "ddabec839cc003651f2ce695c938686d1086cf43", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/293975b465e0e709b571cbf0c957c6c0a7b9a2ac", + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac", "shasum": "" }, "require": { "phpcompatibility/php-compatibility": "^9.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "paragonie/random_compat": "dev-master", "paragonie/sodium_compat": "dev-master" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "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", @@ -1204,26 +1275,42 @@ "paragonie", "phpcs", "polyfill", - "standards" + "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" }, - "time": "2021-02-15T10:24:51+00:00" + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:30:46+00:00" }, { "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.3", + "version": "2.1.5", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "d55de55f88697b9cdb94bccf04f14eb3b11cf308" + "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/d55de55f88697b9cdb94bccf04f14eb3b11cf308", - "reference": "d55de55f88697b9cdb94bccf04f14eb3b11cf308", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082", "shasum": "" }, "require": { @@ -1231,10 +1318,10 @@ "phpcompatibility/phpcompatibility-paragonie": "^1.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7" + "dealerdirect/phpcodesniffer-composer-installer": "^1.0" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "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", @@ -1258,13 +1345,29 @@ "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" }, - "time": "2021-12-30T16:37:40+00:00" + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:37:59+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1321,28 +1424,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "version": "5.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "reference": "298d2febfe79d03fe714eb871d5538da55205b1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/298d2febfe79d03fe714eb871d5538da55205b1a", + "reference": "298d2febfe79d03fe714eb871d5538da55205b1a", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "mockery/mockery": "~1.3.5", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.13" }, "type": "library", "extra": { @@ -1366,37 +1476,45 @@ }, { "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "email": "opensource@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.0" }, - "time": "2021-10-19T17:43:47+00:00" + "time": "2024-04-09T21:13:58+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.0", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" + "reference": "153ae662783729388a584b4361f2545e4d841e3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { @@ -1422,34 +1540,35 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" }, - "time": "2022-01-04T19:58:01+00:00" + "time": "2024-02-23T11:10:43+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.15.0", + "version": "v1.19.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + "reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/67a759e7d8746d501c41536ba40cd9c0a07d6a87", + "reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", + "doctrine/instantiator": "^1.2 || ^2.0", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*", "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0" }, "type": "library", "extra": { @@ -1482,6 +1601,7 @@ "keywords": [ "Double", "Dummy", + "dev", "fake", "mock", "spy", @@ -1489,22 +1609,69 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.19.0" }, - "time": "2021-12-08T12:19:24+00:00" + "time": "2024-02-29T11:52:51+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.29.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", + "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" + }, + "time": "2024-05-06T12:04:23+00:00" }, { "name": "phpstan/phpstan", - "version": "0.12.99", + "version": "0.12.100", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7" + "reference": "48236ddf823547081b2b153d1cd2994b784328c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b4d40f1d759942f523be267a1bab6884f46ca3f7", - "reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/48236ddf823547081b2b153d1cd2994b784328c3", + "reference": "48236ddf823547081b2b153d1cd2994b784328c3", "shasum": "" }, "require": { @@ -1535,7 +1702,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.99" + "source": "https://github.com/phpstan/phpstan/tree/0.12.100" }, "funding": [ { @@ -1546,53 +1713,49 @@ "url": "https://github.com/phpstan", "type": "github" }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", "type": "tidelift" } ], - "time": "2021-09-12T20:09:55+00:00" + "time": "2022-11-01T09:52:08+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "6.1.4", + "version": "7.0.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", + "php": ">=7.2", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", + "phpunit/php-token-stream": "^3.1.3 || ^4.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", + "sebastian/environment": "^4.2.2", "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "theseer/tokenizer": "^1.1.3" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.2.2" }, "suggest": { - "ext-xdebug": "^2.6.0" + "ext-xdebug": "^2.7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.1-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -1620,9 +1783,15 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.17" }, - "time": "2018-10-31T16:06:48+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:09:37+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1731,16 +1900,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.1.3", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a691211e94ff39a34811abd521c31bd5b305b0bb", + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb", "shasum": "" }, "require": { @@ -1778,7 +1947,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.4" }, "funding": [ { @@ -1786,33 +1955,33 @@ "type": "github" } ], - "time": "2020-11-30T08:20:02+00:00" + "time": "2024-03-01T13:42:41+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.1.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.1" + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1837,7 +2006,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" }, "funding": [ { @@ -1846,57 +2015,56 @@ } ], "abandoned": true, - "time": "2021-07-26T12:15:06+00:00" + "time": "2020-08-04T08:28:15+00:00" }, { "name": "phpunit/phpunit", - "version": "7.5.20", + "version": "8.5.18", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" + "reference": "bd5fc77c869e8dd65040dacbad170f074c13796c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd5fc77c869e8dd65040dacbad170f074c13796c", + "reference": "bd5fc77c869e8dd65040dacbad170f074c13796c", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.1", + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.0", + "phar-io/manifest": "^2.0.1", + "phar-io/version": "^3.0.2", + "php": ">=7.2", + "phpspec/prophecy": "^1.10.3", + "phpunit/php-code-coverage": "^7.0.12", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.3", + "sebastian/exporter": "^3.1.2", + "sebastian/global-state": "^3.0.0", "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", "sebastian/version": "^2.0.1" }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" + "phpunit/php-invoker": "^2.0.0" }, "bin": [ "phpunit" @@ -1904,7 +2072,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.5-dev" + "dev-master": "8.5-dev" } }, "autoload": { @@ -1932,9 +2100,19 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.18" }, - "time": "2020-01-08T08:45:45+00:00" + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-07-19T06:13:17+00:00" }, { "name": "psr/container", @@ -1995,313 +2173,588 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "2ec9ad634c459ee60c42d99390be37c8a3c6e8e5" + "reference": "386924e51b2e98d13dcc88bb530807046edbda90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/2ec9ad634c459ee60c42d99390be37c8a3c6e8e5", - "reference": "2ec9ad634c459ee60c42d99390be37c8a3c6e8e5", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/386924e51b2e98d13dcc88bb530807046edbda90", + "reference": "386924e51b2e98d13dcc88bb530807046edbda90", "shasum": "" }, "conflict": { "3f/pygmentize": "<1.2", + "admidio/admidio": "<4.2.13", "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3", + "aheinze/cockpit": "<2.2", + "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", + "airesvsg/acf-to-rest-api": "<=3.1", "akaunting/akaunting": "<2.1.13", + "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", + "alextselegidis/easyappointments": "<1.5", "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amazing/media2click": ">=1,<1.3.3", "amphp/artax": "<1.0.6|>=2,<2.0.6", - "amphp/http": "<1.0.1", + "amphp/http": "<=1.7.2|>=2,<=2.1", "amphp/http-client": ">=4,<4.4", "anchorcms/anchor-cms": "<=0.12.7", - "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6", + "andreapollastri/cipi": "<=3.1.15", + "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", + "apache-solr-for-typo3/solr": "<2.8.3", + "apereo/phpcas": "<1.6", + "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3", + "appwrite/server-ce": "<=1.2.1", + "arc/web": "<3", "area17/twill": "<1.2.5|>=2,<2.5.3", - "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", - "aws/aws-sdk-php": ">=3,<3.2.1", - "bagisto/bagisto": "<0.1.5", + "artesaos/seotools": "<0.17.2", + "asymmetricrypt/asymmetricrypt": "<9.9.99", + "athlon1600/php-proxy": "<=5.1", + "athlon1600/php-proxy-app": "<=3", + "austintoddj/canvas": "<=3.4.2", + "automad/automad": "<=1.10.9", + "automattic/jetpack": "<9.8", + "awesome-support/awesome-support": "<=6.0.7", + "aws/aws-sdk-php": "<3.288.1", + "azuracast/azuracast": "<0.18.3", + "backdrop/backdrop": "<1.24.2", + "backpack/crud": "<3.4.9", + "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", + "badaso/core": "<2.7", + "bagisto/bagisto": "<2.1", "barrelstrength/sprout-base-email": "<1.2.7", "barrelstrength/sprout-forms": "<3.9", - "baserproject/basercms": "<4.5.4", - "billz/raspap-webgui": "<=2.6.6", + "barryvdh/laravel-translation-manager": "<0.6.2", + "barzahlen/barzahlen-php": "<2.0.1", + "baserproject/basercms": "<5.0.9", + "bassjobsen/bootstrap-3-typeahead": ">4.0.2", + "bbpress/bbpress": "<2.6.5", + "bcosca/fatfree": "<3.7.2", + "bedita/bedita": "<4", + "bigfork/silverstripe-form-capture": ">=3,<3.1.1", + "billz/raspap-webgui": "<2.9.5", "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", + "blueimp/jquery-file-upload": "==6.4.4", + "bmarshall511/wordpress_zero_spam": "<5.2.13", "bolt/bolt": "<3.7.2", - "bolt/core": "<4.1.13", + "bolt/core": "<=4.2", "bottelet/flarepoint": "<2.2.1", + "bref/bref": "<2.1.17", "brightlocal/phpwhois": "<=4.2.5", + "brotkrueml/codehighlight": "<2.7", + "brotkrueml/schema": "<1.13.1|>=2,<2.5.1", + "brotkrueml/typo3-matomo-integration": "<1.3.2", "buddypress/buddypress": "<7.2.1", "bugsnag/bugsnag-laravel": ">=2,<2.0.2", - "bytefury/crater": "<6", + "bytefury/crater": "<6.0.2", "cachethq/cachet": "<2.5.1", - "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.5.18|>=3.6,<3.6.15|>=3.7,<3.7.7", + "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", "cardgate/magento2": "<2.0.33", + "cardgate/woocommerce": "<=3.1.15", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cartalyst/sentry": "<=2.1.6", "catfan/medoo": "<1.7.5", - "centreon/centreon": "<20.10.7", + "causal/oidc": "<2.1", + "cecil/cecil": "<7.47.1", + "centreon/centreon": "<22.10.15", "cesnet/simplesamlphp-module-proxystatistics": "<3.1", + "chriskacerguis/codeigniter-restserver": "<=2.7.1", + "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", + "ckeditor/ckeditor": "<4.24", + "cockpit-hq/cockpit": "<=2.6.3|==2.7", "codeception/codeception": "<3.1.3|>=4,<4.1.22", - "codeigniter/framework": "<=3.0.6", - "codeigniter4/framework": "<4.1.8", + "codeigniter/framework": "<3.1.9", + "codeigniter4/framework": "<4.4.7", + "codeigniter4/shield": "<1.0.0.0-beta8", "codiad/codiad": "<=2.8.4", - "composer/composer": "<1.10.23|>=2-alpha.1,<2.1.9", - "concrete5/concrete5": "<8.5.5", - "concrete5/core": "<8.5.7", + "composer/composer": "<1.10.27|>=2,<2.2.23|>=2.3,<2.7", + "concrete5/concrete5": "<9.2.8", + "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", - "contao/core": ">=2,<3.5.39", - "contao/core-bundle": ">=4,<4.4.56|>=4.5,<4.9.18|>=4.10,<4.11.7|= 4.10.0", - "contao/listing-bundle": ">=4,<4.4.8", - "craftcms/cms": "<3.7.14", - "croogo/croogo": "<3.0.7", + "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", + "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", + "contao/core": "<3.5.39", + "contao/core-bundle": "<4.13.40|>=5,<5.3.4", + "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8", + "contao/managed-edition": "<=1.5", + "corveda/phpsandbox": "<1.3.5", + "cosenary/instagram": "<=2.3", + "craftcms/cms": "<4.6.2", + "croogo/croogo": "<4", + "cuyz/valinor": "<0.12", + "czproject/git-php": "<4.0.3", + "dapphp/securimage": "<3.6.6", + "darylldoyle/safe-svg": "<1.9.10", "datadog/dd-trace": ">=0.30,<0.30.2", + "datatables/datatables": "<1.10.10", "david-garcia/phpwhois": "<=4.3.1", - "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1", - "directmailteam/direct-mail": "<5.2.4", - "doctrine/annotations": ">=1,<1.2.7", + "dbrisinajumi/d2files": "<1", + "dcat/laravel-admin": "<=2.1.3.0-beta", + "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", + "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", + "desperado/xml-bundle": "<=0.1.7", + "devgroup/dotplant": "<2020.09.14-dev", + "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2", + "doctrine/annotations": "<1.2.7", "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", - "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1", + "doctrine/common": "<2.4.3|>=2.5,<2.5.1", "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4", "doctrine/doctrine-bundle": "<1.5.2", "doctrine/doctrine-module": "<=0.7.1", - "doctrine/mongodb-odm": ">=1,<1.0.2", - "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", + "doctrine/mongodb-odm": "<1.0.2", + "doctrine/mongodb-odm-bundle": "<3.0.1", "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", - "dolibarr/dolibarr": "<=14.0.5|>= 3.3.beta1, < 13.0.2", - "dompdf/dompdf": ">=0.6,<0.6.2", - "drupal/core": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", - "drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", + "dolibarr/dolibarr": "<=19", + "dompdf/dompdf": "<2.0.4", + "doublethreedigital/guest-entries": "<3.1.2", + "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2", + "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", + "duncanmcclean/guest-entries": "<3.1.2", "dweeves/magmi": "<=0.7.24", + "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2", "ecodev/newsletter": "<=4", + "ectouch/ectouch": "<=2.7.2", + "egroupware/egroupware": "<16.1.20170922", + "elefant/cms": "<2.0.7", "elgg/elgg": "<3.3.24|>=4,<4.0.5", + "elijaa/phpmemcacheadmin": "<=1.3", + "encore/laravel-admin": "<=1.8.19", "endroid/qr-code-bundle": "<3.4.2", - "enshrined/svg-sanitize": "<0.13.1", + "enhavo/enhavo-app": "<=0.13.1", + "enshrined/svg-sanitize": "<0.15", "erusev/parsedown": "<1.7.2", "ether/logs": "<3.0.4", - "ezsystems/demobundle": ">=5.4,<5.4.6.1", + "evolutioncms/evolution": "<=3.2.3", + "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", "ezsystems/ez-support-tools": ">=2.2,<2.2.3", - "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1", - "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1", + "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev", + "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev", "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24", - "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<=1.5.25", + "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26", "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", - "ezsystems/ezplatform-kernel": "<=1.2.5|>=1.3,<=1.3.1", + "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", + "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35", "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", - "ezsystems/ezplatform-richtext": ">=2.3,<=2.3.7", + "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev", + "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15", "ezsystems/ezplatform-user": ">=1,<1.0.1", - "ezsystems/ezpublish-kernel": "<=6.13.8.1|>=7,<7.5.26", - "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.3.5.1", + "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31", + "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.06,<=2019.03.5.1", "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", - "ezsystems/repository-forms": ">=2.3,<2.3.2.1", + "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", "ezyang/htmlpurifier": "<4.1.1", "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", + "facturascripts/facturascripts": "<=2022.08", + "fastly/magento2": "<1.2.26", "feehi/cms": "<=2.1.1", - "feehi/feehicms": "<=0.1.3", - "firebase/php-jwt": "<2", - "flarum/core": ">=1,<=1.0.1", - "flarum/sticky": ">=0.1-beta.14,<=0.1-beta.15", - "flarum/tags": "<=0.1-beta.13", + "feehi/feehicms": "<=2.1.1", + "fenom/fenom": "<=2.12.1", + "filegator/filegator": "<7.8", + "filp/whoops": "<2.1.13", + "fineuploader/php-traditional-server": "<=1.2.2", + "firebase/php-jwt": "<6", + "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", + "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6", + "flarum/core": "<1.8.5", + "flarum/flarum": "<0.1.0.0-beta8", + "flarum/framework": "<1.8.5", + "flarum/mentions": "<1.6.3", + "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15", + "flarum/tags": "<=0.1.0.0-beta13", + "floriangaerber/magnesium": "<0.3.1", "fluidtypo3/vhs": "<5.1.1", + "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", + "fof/upload": "<1.2.3", + "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", "fooman/tcpdf": "<6.2.22", - "forkcms/forkcms": "<=5.9.2", + "forkcms/forkcms": "<5.11.1", "fossar/tcpdf-parser": "<6.2.22", - "francoisjacquet/rosariosis": "<8.1.1", + "francoisjacquet/rosariosis": "<=11.5.1", + "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2", "friendsofsymfony/oauth2-php": "<1.3", "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", + "friendsofsymfony1/swiftmailer": ">=4,<5.4.13|>=6,<6.2.5", + "friendsofsymfony1/symfony1": ">=1.1,<1.15.19", "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", - "froala/wysiwyg-editor": "<3.2.7", + "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", + "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.3", + "froxlor/froxlor": "<=2.1.1", + "frozennode/administrator": "<=5.0.12", "fuel/core": "<1.8.1", + "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3", "gaoming13/wechat-php-sdk": "<=1.10.2", - "getgrav/grav": "<1.7.28", - "getkirby/cms": "<3.5.8", + "genix/cms": "<=1.1.11", + "getgrav/grav": "<1.7.45", + "getkirby/cms": "<4.1.1", + "getkirby/kirby": "<=2.5.12", "getkirby/panel": "<2.5.14", - "gilacms/gila": "<=1.11.4", + "getkirby/starterkit": "<=3.7.0.2", + "gilacms/gila": "<=1.15.4", + "gleez/cms": "<=1.3|==2", "globalpayments/php-sdk": "<2", + "gogentooss/samlbase": "<1.2.7", + "google/protobuf": "<3.15", "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", - "gree/jose": "<=2.2", + "gree/jose": "<2.2.1", "gregwar/rst": "<1.0.3", - "grumpydictator/firefly-iii": "<5.6.5", - "guzzlehttp/guzzle": ">=4-rc.2,<4.2.4|>=5,<5.3.1|>=6,<6.2.1", + "grumpydictator/firefly-iii": "<6.1.7", + "gugoan/economizzer": "<=0.9.0.0-beta1", + "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", + "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", + "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", + "harvesthq/chosen": "<1.8.7", "helloxz/imgurl": "<=2.31", + "hhxsv5/laravel-s": "<3.7.36", "hillelcoren/invoice-ninja": "<5.3.35", + "himiklab/yii2-jqgrid-widget": "<1.0.8", "hjue/justwriting": "<=1", "hov/jobfair": "<1.0.13|>=2,<2.0.2", + "httpsoft/http-message": "<1.0.12", + "hyn/multi-tenant": ">=5.6,<5.7.2", + "ibexa/admin-ui": ">=4.2,<4.2.3", + "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2", + "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", "ibexa/post-install": "<=1.0.4", + "ibexa/solr": ">=4.5,<4.5.4", + "ibexa/user": ">=4,<4.4.3", "icecoder/icecoder": "<=8.1", - "illuminate/auth": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10", + "idno/known": "<=1.3.1", + "ilicmiljan/secure-props": ">=1.2,<1.2.2", + "illuminate/auth": "<5.5.10", "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4", "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", - "impresscms/impresscms": "<=1.4.2", - "in2code/femanager": "<5.5.1|>=6,<6.3.1", - "intelliants/subrion": "<=4.2.1", + "imdbphp/imdbphp": "<=5.1.1", + "impresscms/impresscms": "<=1.4.5", + "impresspages/impresspages": "<=1.0.12", + "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3", + "in2code/ipandlanguageredirect": "<5.1.2", + "in2code/lux": "<17.6.1|>=18,<24.0.2", + "innologi/typo3-appointments": "<2.0.6", + "intelliants/subrion": "<4.2.2", + "inter-mediator/inter-mediator": "==5.5", + "islandora/islandora": ">=2,<2.4.1", "ivankristianto/phpwhois": "<=4.3", "jackalope/jackalope-doctrine-dbal": "<1.7.4", "james-heinrich/getid3": "<1.9.21", - "joomla/archive": "<1.1.10", + "james-heinrich/phpthumb": "<1.7.12", + "jasig/phpcas": "<1.3.3", + "jcbrand/converse.js": "<3.3.3", + "johnbillion/wp-crontrol": "<1.16.2", + "joomla/application": "<1.0.13", + "joomla/archive": "<1.1.12|>=2,<2.0.1", + "joomla/filesystem": "<1.6.2|>=2,<2.0.1", + "joomla/filter": "<1.4.4|>=2,<2.0.1", + "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12", + "joomla/input": ">=2,<2.0.2", + "joomla/joomla-cms": ">=2.5,<3.9.12", "joomla/session": "<1.3.1", + "joyqi/hyper-down": "<=2.4.27", + "jsdecena/laracom": "<2.0.9", "jsmitty12/phpwhois": "<5.1", + "juzaweb/cms": "<=3.4", "kazist/phpwhois": "<=4.2.6", + "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", - "kitodo/presentation": "<3.1.2", + "khodakhah/nodcms": "<=3", + "kimai/kimai": "<2.13", + "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", + "knplabs/knp-snappy": "<=1.4.2", + "kohana/core": "<3.3.3", + "krayin/laravel-crm": "<1.2.2", "kreait/firebase-php": ">=3.2,<3.8.1", + "kumbiaphp/kumbiapp": "<=1.1.1", "la-haute-societe/tcpdf": "<6.2.22", + "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", - "laravel/framework": "<6.20.42|>=7,<7.30.6|>=8,<8.75", + "laravel/fortify": "<1.11.1", + "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", + "laravel/laravel": ">=5.4,<5.4.22", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", "latte/latte": "<2.10.8", - "lavalite/cms": "<=5.8", + "lavalite/cms": "<=9|==10.1", "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", "league/commonmark": "<0.18.3", "league/flysystem": "<1.1.4|>=2,<2.1.1", + "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", - "librenms/librenms": "<=21.11", + "libreform/libreform": ">=2,<=2.0.8", + "librenms/librenms": "<2017.08.18", + "liftkit/database": "<2.13.2", + "lightsaml/lightsaml": "<1.3.5", "limesurvey/limesurvey": "<3.27.19", "livehelperchat/livehelperchat": "<=3.91", - "livewire/livewire": ">2.2.4,<2.2.6", + "livewire/livewire": ">2.2.4,<2.2.6|>=3.3.5,<3.4.9", "lms/routes": "<2.1.1", "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", - "magento/community-edition": ">=2,<2.2.10|>=2.3,<2.3.3", - "magento/magento1ce": "<1.9.4.3", - "magento/magento1ee": ">=1,<1.14.4.3", - "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2", + "luyadev/yii-helpers": "<1.2.1", + "magento/community-edition": "<2.4.3.0-patch3|>=2.4.4,<2.4.5", + "magento/core": "<=1.9.4.5", + "magento/magento1ce": "<1.9.4.3-dev", + "magento/magento1ee": ">=1,<1.14.4.3-dev", + "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2.0-patch2", + "magneto/core": "<1.9.4.4-dev", + "maikuolan/phpmussel": ">=1,<1.6", + "mainwp/mainwp": "<=4.4.3.3", + "mantisbt/mantisbt": "<2.26.1", "marcwillmann/turn": "<0.3.3", - "mautic/core": "<4|= 2.13.1", - "mediawiki/core": ">=1.27,<1.27.6|>=1.29,<1.29.3|>=1.30,<1.30.2|>=1.31,<1.31.9|>=1.32,<1.32.6|>=1.32.99,<1.33.3|>=1.33.99,<1.34.3|>=1.34.99,<1.35", - "microweber/microweber": "<1.2.11", + "matyhtf/framework": "<3.0.6", + "mautic/core": "<4.4.12|>=5.0.0.0-alpha,<5.0.4", + "mdanter/ecc": "<2", + "mediawiki/core": "<1.36.2", + "mediawiki/matomo": "<2.4.3", + "mediawiki/semantic-media-wiki": "<4.0.2", + "melisplatform/melis-asset-manager": "<5.0.1", + "melisplatform/melis-cms": "<5.0.1", + "melisplatform/melis-front": "<5.0.1", + "mezzio/mezzio-swoole": "<3.7|>=4,<4.3", + "mgallegos/laravel-jqgrid": "<=1.3", + "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1", + "microsoft/microsoft-graph-beta": "<2.0.1", + "microsoft/microsoft-graph-core": "<2.0.2", + "microweber/microweber": "<=2.0.4", + "mikehaertl/php-shellcommand": "<1.6.1", "miniorange/miniorange-saml": "<1.4.3", "mittwald/typo3_forum": "<1.2.1", - "modx/revolution": "<2.8", + "mobiledetect/mobiledetectlib": "<2.8.32", + "modx/revolution": "<=2.8.3.0-patch", + "mojo42/jirafeau": "<4.4", + "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<3.9.11|>=3.10-beta,<3.10.8|>=3.11,<3.11.5", + "moodle/moodle": "<=4.3.3", + "mos/cimage": "<0.7.19", + "movim/moxl": ">=0.8,<=0.10", + "movingbytes/social-network": "<=1.2.1", + "mpdf/mpdf": "<=7.1.7", + "munkireport/comment": "<4.1", + "munkireport/managedinstalls": "<2.6", + "munkireport/munki_facts": "<1.5", + "munkireport/munkireport": ">=2.5.3,<5.6.3", + "munkireport/reportdata": "<3.5", + "munkireport/softwareupdate": "<1.6", "mustache/mustache": ">=2,<2.14.1", "namshi/jose": "<2.2", "neoan3-apps/template": "<1.1.1", + "neorazorx/facturascripts": "<2022.04", "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3", - "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", + "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9", + "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", - "nilsteampassnet/teampass": "<=2.1.27.36", - "nukeviet/nukeviet": "<4.3.4", - "nystudio107/craft-seomatic": "<3.3", + "nilsteampassnet/teampass": "<3.0.10", + "nonfiction/nterchange": "<4.1.1", + "notrinos/notrinos-erp": "<=0.7", + "noumo/easyii": "<=0.9", + "novaksolutions/infusionsoft-php-sdk": "<1", + "nukeviet/nukeviet": "<4.5.02", + "nyholm/psr7": "<1.6.1", + "nystudio107/craft-seomatic": "<3.4.12", + "nzedb/nzedb": "<0.8", "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", "october/backend": "<1.1.2", - "october/cms": "= 1.1.1|= 1.0.471|= 1.0.469|>=1.0.319,<1.0.469", - "october/october": ">=1.0.319,<1.0.466|>=2.1,<2.1.12", + "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", + "october/october": "<=3.4.4", "october/rain": "<1.0.472|>=1.1,<1.1.2", - "october/system": "<1.0.473|>=1.1,<1.1.6|>=2.1,<2.1.12", + "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.2", + "omeka/omeka-s": "<4.0.3", "onelogin/php-saml": "<2.10.4", - "oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5", - "opencart/opencart": "<=3.0.3.2", + "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", + "open-web-analytics/open-web-analytics": "<1.7.4", + "opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev", "openid/php-openid": "<2.3", - "openmage/magento-lts": "<19.4.15|>=20,<20.0.13", - "orchid/platform": ">=9,<9.4.4", + "openmage/magento-lts": "<20.5", + "opensolutions/vimbadmin": "<=3.0.15", + "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2", + "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5", + "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", + "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", - "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<4.2.8", + "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1", + "oro/customer-portal": ">=4.1,<=4.1.13|>=4.2,<=4.2.10|>=5,<=5.0.11|>=5.1,<=5.1.3", + "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<=5.0.12|>=5.1,<=5.1.3", + "oxid-esales/oxideshop-ce": "<4.5", + "oxid-esales/paymorrow-module": ">=1,<1.0.2|>=2,<2.0.1", + "packbackbooks/lti-1-3-php-library": "<5", "padraic/humbug_get_contents": "<1.1.2", - "pagarme/pagarme-php": ">=0,<3", + "pagarme/pagarme-php": "<3", "pagekit/pagekit": "<=1.0.18", "paragonie/random_compat": "<2", - "passbolt/passbolt_api": "<2.11", + "passbolt/passbolt_api": "<4.6.2", + "paypal/adaptivepayments-sdk-php": "<=3.9.2", + "paypal/invoice-sdk-php": "<=3.9", "paypal/merchant-sdk-php": "<3.12", + "paypal/permissions-sdk-php": "<=3.9.1", "pear/archive_tar": "<1.4.14", + "pear/auth": "<1.2.4", + "pear/crypt_gpg": "<1.6.7", + "pear/pear": "<=1.10.1", "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1", "personnummer/personnummer": "<3.0.2", "phanan/koel": "<5.1.4", + "phenx/php-svg-lib": "<0.5.2", + "php-mod/curl": "<2.3.2", + "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1", + "phpems/phpems": ">=6,<=6.1.3", "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", - "phpmyadmin/phpmyadmin": "<4.9.8|>=5,<5.0.3|>=5.1,<5.1.2", - "phpoffice/phpexcel": "<1.8.2", + "phpmyadmin/phpmyadmin": "<5.2.1", + "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5", + "phpoffice/common": "<0.2.9", + "phpoffice/phpexcel": "<1.8", "phpoffice/phpspreadsheet": "<1.16", - "phpseclib/phpseclib": "<2.0.31|>=3,<3.0.7", - "phpservermon/phpservermon": "<=3.5.2", + "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", + "phpservermon/phpservermon": "<3.6", + "phpsysinfo/phpsysinfo": "<3.4.3", "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", - "pimcore/pimcore": "<=10.2.9", - "pocketmine/pocketmine-mp": "<4.0.7", + "phpxmlrpc/phpxmlrpc": "<4.9.2", + "pi/pi": "<=2.5", + "pimcore/admin-ui-classic-bundle": "<1.3.4", + "pimcore/customer-management-framework-bundle": "<4.0.6", + "pimcore/data-hub": "<1.2.4", + "pimcore/demo": "<10.3", + "pimcore/ecommerce-framework-bundle": "<1.0.10", + "pimcore/perspective-editor": "<1.5.1", + "pimcore/pimcore": "<11.2.3", + "pixelfed/pixelfed": "<0.11.11", + "plotly/plotly.js": "<2.25.2", + "pocketmine/bedrock-protocol": "<8.0.2", + "pocketmine/pocketmine-mp": "<5.11.2", + "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", "pressbooks/pressbooks": "<5.18", "prestashop/autoupgrade": ">=4,<4.10.1", - "prestashop/contactform": ">1.0.1,<4.3", + "prestashop/blockreassurance": "<=5.1.3", + "prestashop/blockwishlist": ">=2,<2.1.1", + "prestashop/contactform": ">=1.0.1,<4.3", "prestashop/gamification": "<2.3.2", - "prestashop/prestashop": ">=1.7,<=1.7.8.2", - "prestashop/productcomments": ">=4,<4.2.1", + "prestashop/prestashop": "<8.1.4", + "prestashop/productcomments": "<5.0.2", "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<3.4.1", "prestashop/ps_linklist": "<3.1", - "privatebin/privatebin": "<1.2.2|>=1.3,<1.3.2", - "propel/propel": ">=2-alpha.1,<=2-alpha.7", + "privatebin/privatebin": "<1.4", + "processwire/processwire": "<=3.0.210", + "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", "propel/propel1": ">=1,<=1.7.1", - "pterodactyl/panel": "<1.7", + "pterodactyl/panel": "<1.11.6", + "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", + "ptrofimov/beanstalk_console": "<1.7.14", + "pubnub/pubnub": "<6.1", "pusher/pusher-php-server": "<2.2.1", - "pwweb/laravel-core": "<=0.3.6-beta", + "pwweb/laravel-core": "<=0.3.6.0-beta", + "pyrocms/pyrocms": "<=3.9.1", + "qcubed/qcubed": "<=3.1.1", + "quickapps/cms": "<=2.0.0.0-beta2", + "rainlab/blog-plugin": "<1.4.1", "rainlab/debugbar-plugin": "<3.1", - "remdex/livehelperchat": "<3.93", + "rainlab/user-plugin": "<=1.4.5", + "rankmath/seo-by-rank-math": "<=1.0.95", + "rap2hpoutre/laravel-log-viewer": "<0.13", + "react/http": ">=0.7,<1.9", + "really-simple-plugins/complianz-gdpr": "<6.4.2", + "redaxo/source": "<=5.15.1", + "remdex/livehelperchat": "<4.29", + "reportico-web/reportico": "<=8.1", + "rhukster/dom-sanitizer": "<1.0.7", "rmccue/requests": ">=1.6,<1.8", - "robrichards/xmlseclibs": "<3.0.4", + "robrichards/xmlseclibs": ">=1,<3.0.4", + "roots/soil": "<4.1", + "rudloff/alltube": "<3.0.3", + "s-cart/core": "<6.9", + "s-cart/s-cart": "<6.9", "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", - "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9", - "scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11", + "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", + "scheb/two-factor-bundle": "<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", - "shopware/core": "<=6.4.6", - "shopware/platform": "<=6.4.6", + "sfroemken/url_redirect": "<=1.2.1", + "sheng/yiicms": "<=1.2", + "shopware/core": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", + "shopware/platform": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", "shopware/production": "<=6.3.5.2", - "shopware/shopware": "<5.7.7", - "showdoc/showdoc": "<2.10.2", - "silverstripe/admin": ">=1,<1.8.1", - "silverstripe/assets": ">=1,<1.4.7|>=1.5,<1.5.2", - "silverstripe/cms": "<4.3.6|>=4.4,<4.4.4", + "shopware/shopware": "<6.2.3", + "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", + "shopxo/shopxo": "<2.2.6", + "showdoc/showdoc": "<2.10.4", + "silverstripe-australia/advancedreports": ">=1,<=2", + "silverstripe/admin": "<1.13.19|>=2,<2.1.8", + "silverstripe/assets": ">=1,<1.11.1", + "silverstripe/cms": "<4.11.3", "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", - "silverstripe/framework": "<4.7.4", - "silverstripe/graphql": "<3.5.2|>=4-alpha.1,<4-alpha.2", + "silverstripe/framework": "<4.13.39|>=5,<5.1.11", + "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3", + "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", + "silverstripe/recipe-cms": ">=4.5,<4.5.3", "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", - "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", - "silverstripe/subsites": ">=2,<2.1.1", + "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4|>=2.1,<2.1.2", + "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", + "silverstripe/subsites": ">=2,<2.6.1", "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", - "silverstripe/userforms": "<3", + "silverstripe/userforms": "<3|>=5,<5.4.2", + "silverstripe/versioned-admin": ">=1,<1.11.1", "simple-updates/phpwhois": "<=1", - "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", + "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12", "simplesamlphp/simplesamlphp": "<1.18.6", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "simplesamlphp/simplesamlphp-module-openid": "<1", + "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", + "simplesamlphp/xml-security": "==1.6.11", "simplito/elliptic-php": "<1.0.6", + "sitegeist/fluid-components": "<3.5", + "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", + "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", "slim/slim": "<2.6", - "smarty/smarty": "<3.1.43|>=4,<4.0.3", - "snipe/snipe-it": "<=5.3.7", + "slub/slub-events": "<3.0.3", + "smarty/smarty": "<3.1.48|>=4,<4.3.1", + "snipe/snipe-it": "<=6.2.2", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", - "spipu/html2pdf": "<5.2.4", + "spatie/browsershot": "<3.57.4", + "spipu/html2pdf": "<5.2.8", + "spoon/library": "<1.4.1", "spoonity/tcpdf": "<6.2.22", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", - "ssddanbrown/bookstack": "<21.12.1", - "stormpath/sdk": ">=0,<9.9.99", - "studio-42/elfinder": "<2.1.59", - "subrion/cms": "<=4.2.1", - "sulu/sulu": "= 2.4.0-RC1|<1.6.44|>=2,<2.2.18|>=2.3,<2.3.8", - "swiftmailer/swiftmailer": ">=4,<5.4.5", + "ssddanbrown/bookstack": "<22.02.3", + "statamic/cms": "<4.46", + "stormpath/sdk": "<9.9.99", + "studio-42/elfinder": "<2.1.62", + "subhh/libconnect": "<7.0.8|>=8,<8.1", + "sukohi/surpass": "<1", + "sulu/sulu": "<1.6.44|>=2,<2.4.17|>=2.5,<2.5.13", + "sumocoders/framework-user-bundle": "<1.4", + "superbig/craft-audit": "<3.0.2", + "swag/paypal": "<5.4.4", + "swiftmailer/swiftmailer": "<6.2.5", + "swiftyedit/swiftyedit": "<1.2", "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", - "sylius/grid-bundle": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", + "sylius/grid-bundle": "<1.10.1", "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1", - "sylius/resource-bundle": "<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", - "sylius/sylius": "<1.6.9|>=1.7,<1.7.9|>=1.8,<1.8.3|>=1.9,<1.9.5", + "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", + "sylius/sylius": "<=1.12.13", "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", + "symbiote/silverstripe-seed": "<6.0.3", "symbiote/silverstripe-versionedfiles": "<=2.0.3", - "symfont/process": ">=0,<4", + "symfont/process": ">=0", "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", "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/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.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3|= 6.0.3|= 5.4.3|= 5.3.14", + "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-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7", - "symfony/http-kernel": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.4.13|>=5,<5.1.5|>=5.2,<5.3.12", + "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/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", "symfony/mime": ">=4.3,<4.3.8", @@ -2311,82 +2764,139 @@ "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/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", - "symfony/security-bundle": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11|>=5.3,<5.3.12", + "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", "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,<3.4.48|>=4,<4.4.23|>=5,<5.2.8|>=5.3,<5.3.2", + "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.3.2|>=5.4,<5.4.31|>=6,<6.3.8", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", - "symfony/symfony": ">=2,<3.4.49|>=4,<4.4.35|>=5,<5.3.12|>=5.3.14,<=5.3.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3", + "symfony/symfony": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", "symfony/translation": ">=2,<2.0.17", + "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/ux-autocomplete": "<2.11.2", "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", "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/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", - "t3/dce": ">=2.2,<2.6.2", + "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", + "symphonycms/symphony-2": "<2.6.4", + "t3/dce": "<0.11.5|>=2.2,<2.6.2", "t3g/svg-sanitizer": "<1.0.3", - "tecnickcom/tcpdf": "<6.2.22", - "terminal42/contao-tablelookupwizard": ">=1,<3.3.5", + "t3s/content-consent": "<1.0.3|>=2,<2.0.2", + "tastyigniter/tastyigniter": "<3.3", + "tcg/voyager": "<=1.4", + "tecnickcom/tcpdf": "<=6.7.4", + "terminal42/contao-tablelookupwizard": "<3.3.5", "thelia/backoffice-default-template": ">=2.1,<2.1.2", - "thelia/thelia": ">=2.1-beta.1,<2.1.3", + "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", - "tinymce/tinymce": "<5.10", - "titon/framework": ">=0,<9.9.99", - "topthink/framework": "<6.0.9", - "topthink/think": "<=6.0.9", + "thinkcmf/thinkcmf": "<6.0.8", + "thorsten/phpmyfaq": "<3.2.2", + "tikiwiki/tiki-manager": "<=17.1", + "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", + "tinymce/tinymce": "<7", + "tinymighty/wiki-seo": "<1.2.2", + "titon/framework": "<9.9.99", + "tobiasbg/tablepress": "<=2.0.0.0-RC1", + "topthink/framework": "<6.0.14", + "topthink/think": "<=6.1.1", "topthink/thinkphp": "<=3.2.3", - "tribalsystems/zenario": "<8.8.53370", + "torrentpier/torrentpier": "<=2.4.1", + "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", + "tribalsystems/zenario": "<9.5.60602", "truckersmp/phpwhois": "<=4.3.1", - "twig/twig": "<1.38|>=2,<2.7", - "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.19|>=11,<11.5", - "typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", - "typo3/cms-core": ">=6.2,<=6.2.56|>=7,<=7.6.52|>=8,<=8.7.41|>=9,<9.5.29|>=10,<10.4.19|>=11,<11.5", + "ttskch/pagination-service-provider": "<1", + "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", + "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.24|>=10,<=10.4.13|>=11,<=11.1", + "typo3/cms-core": "<=8.7.56|>=9,<=9.5.45|>=10,<=10.4.42|>=11,<=11.5.34|>=12,<=12.4.10|==13", + "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", + "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1", "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", + "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5", + "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8", + "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30", "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", + "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3", "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10", "ua-parser/uap-php": "<3.8", - "unisharp/laravel-filemanager": "<=2.3", + "uasoft-indonesia/badaso": "<=2.9.7", + "unisharp/laravel-filemanager": "<2.6.4", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", + "uvdesk/community-skeleton": "<=1.1.1", + "uvdesk/core-framework": "<=1.1.1", "vanilla/safecurl": "<0.9.2", - "verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4", - "vrana/adminer": "<4.7.9", + "verbb/comments": "<1.5.5", + "verbb/image-resizer": "<2.0.9", + "verbb/knock-knock": "<1.2.8", + "verot/class.upload.php": "<=2.1.6", + "villagedefrance/opencart-overclocked": "<=1.11.1", + "vova07/yii2-fileapi-widget": "<0.1.9", + "vrana/adminer": "<4.8.1", + "waldhacker/hcaptcha": "<2.1.2", "wallabag/tcpdf": "<6.2.22", + "wallabag/wallabag": "<2.6.7", "wanglelecc/laracms": "<=1.0.3", "web-auth/webauthn-framework": ">=3.3,<3.3.4", + "web-feet/coastercms": "==5.5", + "webbuilders-group/silverstripe-kapost-bridge": "<0.4", "webcoast/deferred-image-processing": "<1.0.2", + "webklex/laravel-imap": "<5.3", + "webklex/php-imap": "<5.3", + "webpa/webpa": "<3.1.2", + "wikibase/wikibase": "<=1.39.3", "wikimedia/parsoid": "<0.12.2", "willdurand/js-translation-bundle": "<2.1.1", - "wp-cli/wp-cli": "<2.5", - "yetiforce/yetiforce-crm": "<=6.3", + "winter/wn-backend-module": "<1.2.4", + "winter/wn-dusk-plugin": "<2.1", + "winter/wn-system-module": "<1.2.4", + "wintercms/winter": "<=1.2.3", + "woocommerce/woocommerce": "<6.6", + "wp-cli/wp-cli": ">=0.12,<2.5", + "wp-graphql/wp-graphql": "<=1.14.5", + "wp-premium/gravityforms": "<2.4.21", + "wpanel/wpanel4-cms": "<=4.3.1", + "wpcloud/wp-stateless": "<3.2", + "wpglobus/wpglobus": "<=1.9.6", + "wwbn/avideo": "<=12.4", + "xataface/xataface": "<3", + "xpressengine/xpressengine": "<3.0.15", + "yab/quarx": "<2.4.5", + "yeswiki/yeswiki": "<4.1", + "yetiforce/yetiforce-crm": "<=6.4", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", - "yiisoft/yii": ">=1.1.14,<1.1.15", + "yiisoft/yii": "<1.1.29", "yiisoft/yii2": "<2.0.38", + "yiisoft/yii2-authclient": "<2.2.15", "yiisoft/yii2-bootstrap": "<2.0.4", "yiisoft/yii2-dev": "<2.0.43", "yiisoft/yii2-elasticsearch": "<2.0.5", - "yiisoft/yii2-gii": "<2.0.4", + "yiisoft/yii2-gii": "<=2.2.4", "yiisoft/yii2-jui": "<2.0.4", "yiisoft/yii2-redis": "<2.0.8", + "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", "yoast-seo-for-typo3/yoast_seo": "<7.2.3", "yourls/yourls": "<=1.8.2", + "yuan1994/tpadmin": "<=1.3.12", + "zencart/zencart": "<=1.5.7.0-beta", "zendesk/zendesk_api_client_php": "<2.2.11", "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", - "zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5", + "zendframework/zend-db": "<2.2.10|>=2.3,<2.3.5", "zendframework/zend-developer-tools": ">=1.2.2,<1.2.3", - "zendframework/zend-diactoros": ">=1,<1.8.4", - "zendframework/zend-feed": ">=1,<2.10.3", + "zendframework/zend-diactoros": "<1.8.4", + "zendframework/zend-feed": "<2.10.3", "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1", - "zendframework/zend-http": ">=1,<2.8.1", + "zendframework/zend-http": "<2.8.1", "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", - "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-mail": "<2.4.11|>=2.5,<2.7.2", "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", "zendframework/zend-validator": ">=2.3,<2.3.6", @@ -2394,13 +2904,22 @@ "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", "zendframework/zendframework": "<=3", "zendframework/zendframework1": "<1.12.20", - "zendframework/zendopenid": ">=2,<2.0.2", + "zendframework/zendopenid": "<2.0.2", + "zendframework/zendrest": "<2.0.2", + "zendframework/zendservice-amazon": "<2.0.3", + "zendframework/zendservice-api": "<1", + "zendframework/zendservice-audioscrobbler": "<2.0.2", + "zendframework/zendservice-nirvanix": "<2.0.2", + "zendframework/zendservice-slideshare": "<2.0.2", + "zendframework/zendservice-technorati": "<2.0.2", + "zendframework/zendservice-windowsazure": "<2.0.2", "zendframework/zendxml": ">=1,<1.0.1", + "zenstruck/collection": "<0.2.1", "zetacomponents/mail": "<1.8.2", "zf-commons/zfc-user": "<1.2.2", "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", "zfr/zfr-oauth2-server-module": "<0.1.2", - "zoujingli/thinkadmin": "<6.0.22" + "zoujingli/thinkadmin": "<=6.1.53" }, "type": "metapackage", "notification-url": "https://packagist.org/downloads/", @@ -2420,6 +2939,9 @@ } ], "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", + "keywords": [ + "dev" + ], "support": { "issues": "https://github.com/Roave/SecurityAdvisories/issues", "source": "https://github.com/Roave/SecurityAdvisories/tree/latest" @@ -2434,20 +2956,20 @@ "type": "tidelift" } ], - "time": "2022-02-05T03:12:57+00:00" + "time": "2024-05-06T15:04:21+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", "shasum": "" }, "require": { @@ -2481,7 +3003,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.3" }, "funding": [ { @@ -2489,20 +3011,20 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2024-03-01T13:45:45+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" + "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770", + "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770", "shasum": "" }, "require": { @@ -2555,7 +3077,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5" }, "funding": [ { @@ -2563,20 +3085,20 @@ "type": "github" } ], - "time": "2020-11-30T08:04:30+00:00" + "time": "2022-09-14T12:31:48+00:00" }, { "name": "sebastian/diff", - "version": "3.0.3", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/98ff311ca519c3aa73ccd3de053bdb377171d7b6", + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6", "shasum": "" }, "require": { @@ -2621,7 +3143,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.6" }, "funding": [ { @@ -2629,20 +3151,20 @@ "type": "github" } ], - "time": "2020-11-30T07:59:04+00:00" + "time": "2024-03-02T06:16:36+00:00" }, { "name": "sebastian/environment", - "version": "4.2.4", + "version": "4.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + "reference": "56932f6049a0482853056ffd617c91ffcc754205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/56932f6049a0482853056ffd617c91ffcc754205", + "reference": "56932f6049a0482853056ffd617c91ffcc754205", "shasum": "" }, "require": { @@ -2684,7 +3206,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.5" }, "funding": [ { @@ -2692,24 +3214,24 @@ "type": "github" } ], - "time": "2020-11-30T07:53:42+00:00" + "time": "2024-03-01T13:49:59+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.4", + "version": "3.1.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1939bc8fd1d39adcfa88c5b35335910869214c56", + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56", "shasum": "" }, "require": { - "php": ">=7.0", + "php": ">=7.2", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -2761,7 +3283,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.6" }, "funding": [ { @@ -2769,27 +3291,30 @@ "type": "github" } ], - "time": "2021-11-11T13:51:24+00:00" + "time": "2024-03-02T06:21:38+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/91c7c47047a971f02de57ed6f040087ef110c5d9", + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^8.0" }, "suggest": { "ext-uopz": "*" @@ -2797,7 +3322,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2822,22 +3347,28 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.5" }, - "time": "2017-04-27T15:39:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:13:16+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "ac5b293dba925751b808e02923399fb44ff0d541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ac5b293dba925751b808e02923399fb44ff0d541", + "reference": "ac5b293dba925751b808e02923399fb44ff0d541", "shasum": "" }, "require": { @@ -2873,7 +3404,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.5" }, "funding": [ { @@ -2881,20 +3412,20 @@ "type": "github" } ], - "time": "2020-11-30T07:40:27+00:00" + "time": "2024-03-01T13:54:02+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d439c229e61f244ff1f211e5c99737f90c67def", + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def", "shasum": "" }, "require": { @@ -2928,7 +3459,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.3" }, "funding": [ { @@ -2936,20 +3467,20 @@ "type": "github" } ], - "time": "2020-11-30T07:37:18+00:00" + "time": "2024-03-01T13:56:04+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/9bfd3c6f1f08c026f542032dfb42813544f7d64c", + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c", "shasum": "" }, "require": { @@ -2991,7 +3522,7 @@ "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.2" }, "funding": [ { @@ -2999,20 +3530,20 @@ "type": "github" } ], - "time": "2020-11-30T07:34:24+00:00" + "time": "2024-03-01T14:07:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/72a7f7674d053d548003b16ff5a106e7e0e06eee", + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee", "shasum": "" }, "require": { @@ -3042,8 +3573,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.3" }, "funding": [ { @@ -3051,7 +3581,63 @@ "type": "github" } ], - "time": "2020-11-30T07:30:19+00:00" + "time": "2024-03-01T13:59:09+00:00" + }, + { + "name": "sebastian/type", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/18f071c3a29892b037d35e6b20ddf3ea39b42874", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/1.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-01T14:04:07+00:00" }, { "name": "sebastian/version", @@ -3102,16 +3688,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.2", + "version": "3.9.2", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480", + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480", "shasum": "" }, "require": { @@ -3121,11 +3707,11 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "bin/phpcbf", + "bin/phpcs" ], "type": "library", "extra": { @@ -3140,34 +3726,58 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", - "standards" + "standards", + "static analysis" ], "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, - "time": "2021-12-12T21:44:58+00:00" + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-23T20:25:34+00:00" }, { "name": "symfony/console", - "version": "v5.4.3", + "version": "v5.4.39", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8" + "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2a86ec353d825c75856c6fd14fac416a7bdb6b8", - "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8", + "url": "https://api.github.com/repos/symfony/console/zipball/f3e591c48688a0cfa1a3296205926c05e84b22b1", + "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1", "shasum": "" }, "require": { @@ -3232,12 +3842,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.3" + "source": "https://github.com/symfony/console/tree/v5.4.39" }, "funding": [ { @@ -3253,29 +3863,29 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:28:35+00:00" + "time": "2024-04-18T08:26:06+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3304,7 +3914,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -3320,20 +3930,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/finder", - "version": "v5.4.3", + "version": "v5.4.39", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d" + "reference": "f6a96e4fcd468a25fede16ee665f50ced856bd0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d", - "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d", + "url": "https://api.github.com/repos/symfony/finder/zipball/f6a96e4fcd468a25fede16ee665f50ced856bd0a", + "reference": "f6a96e4fcd468a25fede16ee665f50ced856bd0a", "shasum": "" }, "require": { @@ -3367,7 +3977,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.3" + "source": "https://github.com/symfony/finder/tree/v5.4.39" }, "funding": [ { @@ -3383,20 +3993,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:34:36+00:00" + "time": "2024-04-18T08:26:06+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.24.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", "shasum": "" }, "require": { @@ -3410,21 +4020,18 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3449,7 +4056,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" }, "funding": [ { @@ -3465,20 +4072,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.24.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", "shasum": "" }, "require": { @@ -3489,9 +4096,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -3530,7 +4134,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" }, "funding": [ { @@ -3546,20 +4150,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.24.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { @@ -3570,9 +4174,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -3614,7 +4215,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -3630,20 +4231,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", "shasum": "" }, "require": { @@ -3657,21 +4258,18 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3697,7 +4295,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" }, "funding": [ { @@ -3713,20 +4311,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.24.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", "shasum": "" }, "require": { @@ -3734,9 +4332,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -3776,7 +4371,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" }, "funding": [ { @@ -3792,20 +4387,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.24.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", "shasum": "" }, "require": { @@ -3813,9 +4408,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -3859,7 +4451,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" }, "funding": [ { @@ -3875,7 +4467,7 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:33+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/service-contracts", @@ -3958,43 +4550,43 @@ }, { "name": "symfony/string", - "version": "v5.4.3", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10" + "reference": "ffeb9591c61f65a68d47f77d12b83fa530227a69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10", + "url": "https://api.github.com/repos/symfony/string/zipball/ffeb9591c61f65a68d47f77d12b83fa530227a69", + "reference": "ffeb9591c61f65a68d47f77d12b83fa530227a69", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, "files": [ "Resources/functions.php" ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -4024,7 +4616,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.3" + "source": "https://github.com/symfony/string/tree/v6.4.7" }, "funding": [ { @@ -4040,7 +4632,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "szepeviktor/phpstan-wordpress", @@ -4108,16 +4700,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -4146,7 +4738,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -4154,25 +4746,25 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2024-03-03T12:36:25+00:00" }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -4210,9 +4802,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" }, { "name": "wp-coding-standards/wpcs", @@ -4267,16 +4859,16 @@ }, { "name": "wp-media/phpunit", - "version": "v2.1", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/wp-media/phpunit.git", - "reference": "f832eebe3906fc2fae2ad936b4c4a2acf5d697b5" + "reference": "29a596a83c4d3893f63ea6ae21301bee8be41251" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-media/phpunit/zipball/f832eebe3906fc2fae2ad936b4c4a2acf5d697b5", - "reference": "f832eebe3906fc2fae2ad936b4c4a2acf5d697b5", + "url": "https://api.github.com/repos/wp-media/phpunit/zipball/29a596a83c4d3893f63ea6ae21301bee8be41251", + "reference": "29a596a83c4d3893f63ea6ae21301bee8be41251", "shasum": "" }, "require": { @@ -4310,20 +4902,20 @@ "issues": "https://github.com/wp-media/phpunit/issues", "source": "https://github.com/wp-media/phpunit" }, - "time": "2021-09-30T19:36:23+00:00" + "time": "2023-05-10T15:56:16+00:00" }, { "name": "yoast/phpunit-polyfills", - "version": "1.0.3", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "5ea3536428944955f969bc764bbe09738e151ada" + "reference": "a0f7d708794a738f328d7b6c94380fd1d6c40446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/5ea3536428944955f969bc764bbe09738e151ada", - "reference": "5ea3536428944955f969bc764bbe09738e151ada", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/a0f7d708794a738f328d7b6c94380fd1d6c40446", + "reference": "a0f7d708794a738f328d7b6c94380fd1d6c40446", "shasum": "" }, "require": { @@ -4331,13 +4923,14 @@ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { - "yoast/yoastcs": "^2.2.0" + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "yoast/yoastcs": "^3.1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -4369,37 +4962,38 @@ ], "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": "2021-11-23T01:37:03+00:00" + "time": "2024-04-05T16:01:51+00:00" }, { "name": "yoast/wp-test-utils", - "version": "1.0.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/Yoast/wp-test-utils.git", - "reference": "21df3a08974ee62f489f64e34be7f26a32ec872c" + "reference": "2e0f62e0281e4859707c5f13b7da1422aa1c8f7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/wp-test-utils/zipball/21df3a08974ee62f489f64e34be7f26a32ec872c", - "reference": "21df3a08974ee62f489f64e34be7f26a32ec872c", + "url": "https://api.github.com/repos/Yoast/wp-test-utils/zipball/2e0f62e0281e4859707c5f13b7da1422aa1c8f7b", + "reference": "2e0f62e0281e4859707c5f13b7da1422aa1c8f7b", "shasum": "" }, "require": { - "brain/monkey": "^2.6.0", + "brain/monkey": "^2.6.1", "php": ">=5.6", - "yoast/phpunit-polyfills": "^1.0.1" + "yoast/phpunit-polyfills": "^1.1.0" }, "require-dev": { - "yoast/yoastcs": "^2.2.0" + "yoast/yoastcs": "^2.3.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-develop": "1.x-dev", + "dev-main": "1.x-dev" } }, "autoload": { @@ -4432,6 +5026,7 @@ "brainmonkey", "integration-testing", "phpunit", + "testing", "unit-testing", "wordpress" ], @@ -4439,7 +5034,7 @@ "issues": "https://github.com/Yoast/wp-test-utils/issues", "source": "https://github.com/Yoast/wp-test-utils" }, - "time": "2021-09-27T05:50:36+00:00" + "time": "2023-09-27T10:25:08+00:00" } ], "aliases": [], @@ -4455,5 +5050,5 @@ "platform-dev": { "php": "^7 || ^8" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } diff --git a/phpcs.xml b/phpcs.xml index 0dfab9e..3fb62a1 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -10,6 +10,7 @@ . /vendor/* + /tests/* /src/Dependencies/* diff --git a/src/API/Client.php b/src/API/Client.php index 8e258b3..8976c00 100644 --- a/src/API/Client.php +++ b/src/API/Client.php @@ -99,7 +99,6 @@ public function is_website_sync( $api_key = '' ): bool { } $hostname = $this->extract_hostname( home_url() ); - foreach ( $customer_data['websites'] as $website ) { if ( ! isset( $website['hostname'] ) ) { continue; diff --git a/src/Admin/AdminBar/AdminBar.php b/src/Admin/AdminBar/AdminBar.php index ef3f8dd..8510908 100644 --- a/src/Admin/AdminBar/AdminBar.php +++ b/src/Admin/AdminBar/AdminBar.php @@ -151,16 +151,27 @@ public function add_admin_bar_menu( $wp_admin_bar ) { public function purge_cache() { if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'rocketcdn_purge_cache' ) ) { wp_nonce_ays( '' ); + return; } if ( ! current_user_can( 'manage_options' ) ) { + wp_die(); return; } $this->api_client->purge_cache(); wp_safe_redirect( esc_url_raw( wp_get_referer() ) ); - exit; + $this->exit(); + } + + /** + * Wrapped exit function to test + * + * @return void + */ + protected function exit() { + WP_ROCKET_CDN_IS_TESTING ? wp_die() : exit; } /** diff --git a/src/Admin/Settings/Page.php b/src/Admin/Settings/Page.php index 2f42bfe..1ce0390 100644 --- a/src/Admin/Settings/Page.php +++ b/src/Admin/Settings/Page.php @@ -110,10 +110,12 @@ public function validate_api_key() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You do not have permissions to perform this action.', 'rocketcdn' ) ); + return; } if ( ! isset( $_POST['api_key'] ) ) { wp_send_json_error( __( 'They API key field is not set', 'rocketcdn' ) ); + return; } $api_key = sanitize_key( $_POST['api_key'] ); @@ -122,6 +124,7 @@ public function validate_api_key() { if ( empty( $valid_key ) ) { wp_send_json_error( __( 'Invalid API key', 'rocketcdn' ) ); + return; } $is_sync = $this->api_client->is_website_sync( $api_key ); @@ -135,6 +138,7 @@ public function validate_api_key() { ); wp_send_json_error( $message ); + return; } wp_send_json_success(); @@ -150,16 +154,19 @@ public function update_api_key() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You do not have permissions to perform this action.', 'rocketcdn' ) ); + return; } if ( ! isset( $_POST['api_key'] ) ) { wp_send_json_error( __( 'They API key field is not set', 'rocketcdn' ) ); + return; } $api_key = sanitize_key( $_POST['api_key'] ); if ( empty( $api_key ) ) { wp_send_json_error( __( 'The API key field is empty', 'rocketcdn' ) ); + return; } delete_transient( 'rocketcdn_customer_data' ); @@ -168,6 +175,7 @@ public function update_api_key() { if ( empty( $valid_key ) ) { wp_send_json_error( __( 'Invalid API key', 'rocketcdn' ) ); + return; } $is_sync = $this->api_client->is_website_sync( $api_key ); @@ -181,6 +189,7 @@ public function update_api_key() { ); wp_send_json_error( $message ); + return; } $this->options->set( 'api_key', $api_key ); @@ -213,12 +222,14 @@ public function purge_cache() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You do not have permissions to perform this action.', 'rocketcdn' ) ); + return; } $result = $this->api_client->purge_cache(); if ( ! $result['success'] ) { wp_send_json_error( $result['message'] ); + return; } wp_send_json_success( __( 'Done! Your cache has been cleared', 'rocketcdn' ) ); diff --git a/src/EventManagement/EventManager.php b/src/EventManagement/EventManager.php index 7d161a0..b062b13 100644 --- a/src/EventManagement/EventManager.php +++ b/src/EventManagement/EventManager.php @@ -97,8 +97,8 @@ public function remove_subscriber( SubscriberInterface $subscriber ) { * of the WordPress plugin API. * * @param SubscriberInterface $subscriber SubscriberInterface implementation. - * @param string $hook_name Hook name. - * @param mixed $parameters Parameters, can be a string, an array or a multidimensional array. + * @param string $hook_name Hook name. + * @param mixed $parameters Parameters, can be a string, an array or a multidimensional array. */ private function add_subscriber_callback( SubscriberInterface $subscriber, $hook_name, $parameters ) { if ( is_string( $parameters ) ) { @@ -117,8 +117,8 @@ private function add_subscriber_callback( SubscriberInterface $subscriber, $hook * of the WordPress plugin API. * * @param SubscriberInterface $subscriber SubscriberInterface implementation. - * @param string $hook_name Hook name. - * @param mixed $parameters Parameters, can be a string, an array or a multidimensional array. + * @param string $hook_name Hook name. + * @param mixed $parameters Parameters, can be a string, an array or a multidimensional array. */ private function remove_subscriber_callback( SubscriberInterface $subscriber, $hook_name, $parameters ) { if ( is_string( $parameters ) ) { diff --git a/src/Front/CDN.php b/src/Front/CDN.php index ede2c04..77b5a4a 100644 --- a/src/Front/CDN.php +++ b/src/Front/CDN.php @@ -61,7 +61,7 @@ public function end_buffering( $html ): string { * * @return bool */ - private function should_rewrite(): bool { + protected function should_rewrite(): bool { if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || @@ -91,6 +91,7 @@ private function should_rewrite(): bool { */ private function rewrite( string $html ): string { $pattern = '#[("\']\s*(?(?:(?:https?:|)' . preg_quote( $this->get_base_url(), '#' ) . ')\/(?:(?:(?:' . $this->get_allowed_paths() . ')[^"\',)]+))|\/[^/](?:[^"\')\s>]+\.[[:alnum:]]+))\s*["\')]#i'; + return preg_replace_callback( $pattern, function( $matches ) { diff --git a/tests/CallbackTrait.php b/tests/CallbackTrait.php new file mode 100644 index 0000000..ed5be65 --- /dev/null +++ b/tests/CallbackTrait.php @@ -0,0 +1,16 @@ +assertTrue( has_action( $event ) ); + + global $wp_filter; + $callbacks = $wp_filter[ $event ]->callbacks; + + $registration = current( $callbacks[ $priority ] ); + $this->assertEquals( $method, $registration['function'][1] ); + } +} diff --git a/tests/Fixtures/WPDieException.php b/tests/Fixtures/WPDieException.php new file mode 100644 index 0000000..7d4c55b --- /dev/null +++ b/tests/Fixtures/WPDieException.php @@ -0,0 +1,7 @@ + [ + 'config' => [ + 'cache' => false, + 'api' => 'api', + 'baseurl' => 'url', + 'url' => 'urlcustomer/me', + 'headers' => [ + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'response' => 'response', + 'body' => '{"data":1}', + 'code' => 200, + 'requestsucceed' => true, + ], + 'expected' => [ + 'data' => 1, + ], + ], + 'testShouldReturnNothingWhenRequestFailed' => [ + 'config' => [ + 'cache' => false, + 'api' => 'api', + 'baseurl' => 'url', + 'url' => 'urlcustomer/me', + 'headers' => [ + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'response' => 'response', + 'body' => '{"data":1}', + 'code' => 400, + 'requestsucceed' => false, + ], + 'expected' => [], + ], + 'testShouldReturnNothingWhenBodyEmpty' => [ + 'config' => [ + 'cache' => false, + 'api' => 'api', + 'baseurl' => 'url', + 'url' => 'urlcustomer/me', + 'headers' => [ + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'response' => 'response', + 'body' => '', + 'code' => 200, + 'requestsucceed' => true, + ], + 'expected' => [], + ], + 'testShouldReturnNothingWhenNoAPIKey' => [ + 'config' => [ + 'cache' => false, + 'api' => '', + 'baseurl' => 'url', + 'url' => 'urlcustomer/me', + 'headers' => [ + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'response' => 'response', + 'body' => '{"data":1}', + 'code' => 200, + 'requestsucceed' => false, + ], + 'expected' => [], + ], + 'testShouldReturnCacheWhenAvailable' => [ + 'config' => [ + 'cache' => [ + 'data', + ], + 'api' => 'api', + 'baseurl' => 'url', + 'url' => 'urlcustomer/me', + 'headers' => [ + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'response' => 'response', + 'body' => '{"data":1}', + 'code' => 200, + 'requestsucceed' => false, + ], + 'expected' => [ + 'data', + ], + ], +]; diff --git a/tests/Fixtures/src/API/Client/getWebsiteCdnUrl.php b/tests/Fixtures/src/API/Client/getWebsiteCdnUrl.php new file mode 100644 index 0000000..d483a04 --- /dev/null +++ b/tests/Fixtures/src/API/Client/getWebsiteCdnUrl.php @@ -0,0 +1,65 @@ + [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [ + [ + 'hostname' => 'hostname', + 'cdn_url' => 'cdn_url', + ], + ], + ], + ], + 'expected' => 'cdn_url', + ], + 'testShouldReturnEmptyWhenNoWebsiteOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [], + ], + 'expected' => '', + ], + 'testShouldReturnEmptyWhenNoElementsWebsiteOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [], + ], + ], + 'expected' => '', + ], + 'testShouldReturnEmptyWhenNoHostnameOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [], + ], + ], + 'expected' => '', + ], + 'testShouldReturnEmptyWhenWrongHostnameOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [ + [ + 'hostname' => 'wrongname', + ], + ], + ], + ], + 'expected' => '', + ], +]; diff --git a/tests/Fixtures/src/API/Client/isWebsiteSync.php b/tests/Fixtures/src/API/Client/isWebsiteSync.php new file mode 100644 index 0000000..68233c5 --- /dev/null +++ b/tests/Fixtures/src/API/Client/isWebsiteSync.php @@ -0,0 +1,68 @@ + [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [ + [ + 'hostname' => 'hostname', + 'cdn_url' => 'cdn_url', + ], + ], + ], + ], + 'expected' => true, + ], + 'testShouldReturnFalseWhenNoWebsiteOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [], + ], + 'expected' => false, + ], + + 'testShouldReturnFalseWhenNoElementsWebsiteOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [], + ], + ], + 'expected' => false, + ], + + 'testShouldReturnFalseWhenNoHostnameOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [], + ], + ], + 'expected' => false, + ], + + 'testShouldReturnFalseWhenWrongHostnameOffset' => [ + 'config' => [ + 'api' => 'api', + 'homeurl' => 'https://hostname', + 'hostname' => 'hostname', + 'customerdata' => [ + 'websites' => [ + [ + 'hostname' => 'wrongname', + ], + ], + ], + ], + 'expected' => false, + ], +]; diff --git a/tests/Fixtures/src/API/Client/purgeCache.php b/tests/Fixtures/src/API/Client/purgeCache.php new file mode 100644 index 0000000..21947b9 --- /dev/null +++ b/tests/Fixtures/src/API/Client/purgeCache.php @@ -0,0 +1,112 @@ + [ + 'config' => [ + 'api' => 'api', + 'cdn' => 'https://cdn', + 'response' => 'response', + 'code' => 200, + 'body' => '{"data":1}', + 'baseurl' => 'url', + 'url' => 'urlwebsite/cdn/purge', + 'headers' => [ + 'method' => 'DELETE', + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'requestsucceed' => true, + ], + 'expected' => [ + 'data' => 1, + ], + ], + 'testShouldReturnFailureMessageWhenRequestFailed' => [ + 'config' => [ + 'api' => 'api', + 'cdn' => 'https://cdn', + 'response' => 'response', + 'code' => 400, + 'body' => '', + 'baseurl' => 'url', + 'url' => 'urlwebsite/cdn/purge', + 'headers' => [ + 'method' => 'DELETE', + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'requestsucceed' => false, + ], + 'expected' => [ + 'success' => false, + 'message' => 'The purge cache request failed.', + ], + ], + 'testShouldReturnFailureMessageWhenBodyEmpty' => [ + 'config' => [ + 'api' => 'api', + 'cdn' => 'https://cdn', + 'response' => 'response', + 'code' => 200, + 'body' => '', + 'baseurl' => 'url', + 'url' => 'urlwebsite/cdn/purge', + 'headers' => [ + 'method' => 'DELETE', + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'requestsucceed' => true, + ], + 'expected' => [ + 'success' => false, + 'message' => 'The purge cache request failed.', + ], + ], + 'testShouldReturnFailureMessageWhenNoAPIKey' => [ + 'config' => [ + 'api' => '', + 'cdn' => '', + 'response' => 'response', + 'code' => 200, + 'body' => '', + 'baseurl' => 'url', + 'url' => 'urlwebsite/cdn/purge', + 'headers' => [ + 'method' => 'DELETE', + 'headers' => [ + 'Authorization' => 'token ', + ], + ], + 'requestsucceed' => false, + ], + 'expected' => [ + 'success' => false, + 'message' => 'Your API key is empty.', + ], + ], + 'testShouldReturnFailureMessageWhenNoCDN' => [ + 'config' => [ + 'api' => 'api', + 'cdn' => '', + 'response' => 'response', + 'code' => 200, + 'body' => '', + 'baseurl' => 'url', + 'url' => 'urlwebsite/cdn/purge', + 'headers' => [ + 'method' => 'DELETE', + 'headers' => [ + 'Authorization' => 'token api', + ], + ], + 'requestsucceed' => false, + ], + 'expected' => [ + 'success' => false, + 'message' => 'Your CDN URL is empty.', + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/AdminBar/AdminBar/WPAdminBar.php b/tests/Fixtures/src/Admin/AdminBar/AdminBar/WPAdminBar.php new file mode 100644 index 0000000..4470fa4 --- /dev/null +++ b/tests/Fixtures/src/Admin/AdminBar/AdminBar/WPAdminBar.php @@ -0,0 +1,6 @@ + [ + 'config' => [ + 'is_admin' => false, + 'has_right' => false, + 'api' => '', + 'data' => [ 'data' ], + 'request_uri' => 'uri', + ], + 'expected' => [], + ], + 'testNoRightShouldNotAdd' => [ + 'config' => [ + 'is_admin' => true, + 'has_right' => false, + 'api' => '', + 'data' => [ 'data' ], + 'request_uri' => 'uri', + ], + 'expected' => [], + ], + 'testNoApiKeyShouldAddNoConnection' => [ + 'config' => [ + 'is_admin' => true, + 'has_right' => true, + 'api' => '', + 'data' => [ 'data' ], + 'request_uri' => 'uri', + ], + 'expected' => [ + [ + 'id' => 'rocketcdn', + 'title' => 'RocketCDN is disconnected', + ], + [ + 'id' => 'rocketcdn-connect', + 'title' => 'Connect RocketCDN', + 'href' => 'options-general.php?page=rocketcdn', + 'parent' => 'rocketcdn', + ], + ], + ], + 'testNoDataShouldAddNoConnection' => [ + 'config' => [ + 'is_admin' => true, + 'has_right' => true, + 'api' => 'api', + 'data' => [], + 'request_uri' => 'uri', + ], + 'expected' => [ + [ + 'id' => 'rocketcdn', + 'title' => 'RocketCDN is disconnected', + ], + [ + 'id' => 'rocketcdn-connect', + 'title' => 'Connect RocketCDN', + 'href' => 'options-general.php?page=rocketcdn', + 'parent' => 'rocketcdn', + ], + ], + ], + 'testRequestURINotEmptyShouldRightReferrer' => [ + 'config' => [ + 'is_admin' => true, + 'has_right' => true, + 'api' => 'api', + 'data' => [ 'data' ], + 'request_uri' => 'uri', + ], + 'expected' => [ + [ + 'id' => 'rocketcdn', + 'title' => 'RocketCDN', + ], + [ + 'id' => 'rocketcdn-settings', + 'title' => 'Settings', + 'href' => 'options-general.php?page=rocketcdn', + 'parent' => 'rocketcdn', + ], + [ + 'id' => 'rocketcdn-purge-cache', + 'title' => 'Purge cache', + 'href' => 'admin-post.php?action=rocketcdn-purge-cache&_wp_http_referer=uri', + 'parent' => 'rocketcdn', + ], + [ + 'id' => 'rocketcdn-faq', + 'title' => 'FAQ', + 'href' => 'https://rocketcdn.me/faq/', + 'parent' => 'rocketcdn', + 'meta' => [ + 'rel' => 'noopener', + 'target' => '_blank', + ], + ], + [ + 'id' => 'rocketcdn-support', + 'title' => 'Support', + 'href' => 'https://rocketcdn.me/contact/', + 'parent' => 'rocketcdn', + 'meta' => [ + 'rel' => 'noopener', + 'target' => '_blank', + 'html' => '', + ], + ], + ], + ], + 'testRequestURIEmptyShouldDefaultReferrer' => [ + 'config' => [ + 'is_admin' => true, + 'has_right' => true, + 'api' => 'api', + 'data' => [ 'data' ], + 'request_uri' => '', + ], + 'expected' => [ + [ + 'id' => 'rocketcdn', + 'title' => 'RocketCDN', + ], + [ + 'id' => 'rocketcdn-settings', + 'title' => 'Settings', + 'href' => 'options-general.php?page=rocketcdn', + 'parent' => 'rocketcdn', + ], + [ + 'id' => 'rocketcdn-purge-cache', + 'title' => 'Purge cache', + 'href' => 'admin-post.php?action=rocketcdn-purge-cache', + 'parent' => 'rocketcdn', + ], + [ + 'id' => 'rocketcdn-faq', + 'title' => 'FAQ', + 'href' => 'https://rocketcdn.me/faq/', + 'parent' => 'rocketcdn', + 'meta' => [ + 'rel' => 'noopener', + 'target' => '_blank', + ], + ], + [ + 'id' => 'rocketcdn-support', + 'title' => 'Support', + 'href' => 'https://rocketcdn.me/contact/', + 'parent' => 'rocketcdn', + 'meta' => [ + 'rel' => 'noopener', + 'target' => '_blank', + 'html' => '', + ], + ], + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/AdminBar/AdminBar/enqueueStyle.php b/tests/Fixtures/src/Admin/AdminBar/AdminBar/enqueueStyle.php new file mode 100644 index 0000000..1943265 --- /dev/null +++ b/tests/Fixtures/src/Admin/AdminBar/AdminBar/enqueueStyle.php @@ -0,0 +1,25 @@ + [ + 'config' => [ + 'base' => '/', + ], + 'expected' => [ + 'id' => 'rocketcdn-admin-bar', + 'path' => '/css/admin-bar.css', + 'options' => [], + 'version' => ROCKETCDN_VERSION, + ], + ], + 'testSiteURLWithPathShouldEnqueue' => [ + 'config' => [ + 'base' => '/test/', + ], + 'expected' => [ + 'id' => 'rocketcdn-admin-bar', + 'path' => '/test/css/admin-bar.css', + 'options' => [], + 'version' => ROCKETCDN_VERSION, + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/AdminBar/AdminBar/purgeCache.php b/tests/Fixtures/src/Admin/AdminBar/AdminBar/purgeCache.php new file mode 100644 index 0000000..eae22ae --- /dev/null +++ b/tests/Fixtures/src/Admin/AdminBar/AdminBar/purgeCache.php @@ -0,0 +1,39 @@ + [ + 'config' => [ + 'nonce' => null, + 'is_nonce_valid' => false, + 'has_right' => false, + 'referer' => '', + ], + 'expected' => '', + ], + 'testInvalidNonceShouldStop' => [ + 'config' => [ + 'nonce' => 'nonce', + 'is_nonce_valid' => false, + 'has_right' => false, + 'referer' => '', + ], + 'expected' => '', + ], + 'testNoRightShouldStop' => [ + 'config' => [ + 'nonce' => 'nonce', + 'is_nonce_valid' => true, + 'has_right' => false, + 'referer' => '', + ], + 'expected' => '', + ], + 'testShouldRedirect' => [ + 'config' => [ + 'nonce' => 'nonce', + 'is_nonce_valid' => true, + 'has_right' => true, + 'referer' => 'ref', + ], + 'expected' => 'ref', + ], +]; diff --git a/tests/Fixtures/src/Admin/AdminBar/Subscriber/addAdminBarMenu.php b/tests/Fixtures/src/Admin/AdminBar/Subscriber/addAdminBarMenu.php new file mode 100644 index 0000000..3fda5c0 --- /dev/null +++ b/tests/Fixtures/src/Admin/AdminBar/Subscriber/addAdminBarMenu.php @@ -0,0 +1,126 @@ + [ + 'config' => [ + 'option' => [ + 'api_key' => 'api_key_right', + ], + 'process_generate' => [ + 'response' => [ + 'body' => '{"websites":["test"]}', + 'response' => [ + 'code' => 200, + 'message' => "Success", + ], + ], + ], + 'request' => 'uri', + 'admin' => true, + 'cap' => true, + ], + 'expected' => [ + 'base' => (object) [ + 'id' => 'rocketcdn', + 'title' => 'RocketCDN', + 'parent' => false, + 'href' => false, + 'group' => false, + 'meta' => [], + ], + 'connect' => null, + 'settings' => (object) [ + 'id' => 'rocketcdn-settings', + 'title' => 'Settings', + 'parent' => 'rocketcdn', + 'href' => 'http://example.org/wp-admin/options-general.php?page=rocketcdn', + 'group' => false, + 'meta' => [], + ], + 'cache' => (object) [ + 'id' => 'rocketcdn-purge-cache', + 'title' => 'Purge cache', + 'href' => 'http://example.org/wp-admin/admin-post.php?action=rocketcdn-purge-cache&_wp_http_referer=uri&_wpnonce=wp_rocket_nonce', + 'parent' => 'rocketcdn', + 'group' => false, + 'meta' => [], + ], + 'faq' => (object) [ + 'id' => 'rocketcdn-faq', + 'title' => 'FAQ', + 'href' => 'https://rocketcdn.me/faq/', + 'parent' => 'rocketcdn', + 'group' => false, + 'meta' => [ + 'rel' => 'noopener', + 'target' => '_blank', + ], + ], + 'support' => (object) [ + 'id' => 'rocketcdn-support', + 'title' => 'Support', + 'href' => 'https://rocketcdn.me/contact/', + 'parent' => 'rocketcdn', + 'group' => false, + 'meta' => [ + 'rel' => 'noopener', + 'target' => '_blank', + 'html' => '', + ], + ], + ], + ], + 'testNoApiShouldDisplayConnect' => [ + 'config' => [ + 'option' => [ + 'api_key' => null, + ], + 'request' => 'uri', + 'admin' => true, + 'cap' => true, + ], + 'expected' => [ + 'base' => (object) [ + 'id' => 'rocketcdn', + 'title' => 'RocketCDN is disconnected', + 'parent' => false, + 'href' => false, + 'group' => false, + 'meta' => [], + ], + 'connect' => (object) [ + 'id' => 'rocketcdn-connect', + 'title' => 'Connect RocketCDN', + 'parent' => 'rocketcdn', + 'href' => 'http://example.org/wp-admin/options-general.php?page=rocketcdn', + 'group' => false, + 'meta' => [], + ], + 'settings' => null, + 'cache' => null, + 'faq' => null, + 'support' => null, + ], + ], + 'testFrontShouldDisplayNothing' => [ + 'config' => [ + 'option' => [ + 'api_key' => null, + ], + 'request' => 'uri', + 'admin' => false, + 'cap' => false, + ], + 'expected' => [], + ], + 'testEditorShouldDisplayNothing' => [ + 'config' => [ + 'option' => [ + 'api_key' => null, + ], + 'request' => 'uri', + 'admin' => true, + 'cap' => false, + ], + 'expected' => [], + ], +]; diff --git a/tests/Fixtures/src/Admin/AdminBar/Subscriber/enqueueStyle.php b/tests/Fixtures/src/Admin/AdminBar/Subscriber/enqueueStyle.php new file mode 100644 index 0000000..c55f67e --- /dev/null +++ b/tests/Fixtures/src/Admin/AdminBar/Subscriber/enqueueStyle.php @@ -0,0 +1,8 @@ + [ + 'config' => [ + 'hook' => 'edit.php', + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html b/tests/Fixtures/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html new file mode 100644 index 0000000..01602d9 --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html @@ -0,0 +1 @@ +

RocketCDN: Your API key is wrong. You can find your API key in your RocketCDN account.

diff --git a/tests/Fixtures/src/Admin/Notices/Notices/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html b/tests/Fixtures/src/Admin/Notices/Notices/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html new file mode 100644 index 0000000..57eab39 --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Notices/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html @@ -0,0 +1 @@ +

RocketCDN: You are almost done. Add your API key to deliver your content at the speed of light!

diff --git a/tests/Fixtures/src/Admin/Notices/Notices/emptyApiKeyNotice.php b/tests/Fixtures/src/Admin/Notices/Notices/emptyApiKeyNotice.php new file mode 100644 index 0000000..8bef73d --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Notices/emptyApiKeyNotice.php @@ -0,0 +1,27 @@ + [ + 'config' => [ + 'api' => 'api', + 'has_rights' => false, + 'admin_url' => 'admin_url', + ], + 'expected' => '', + ], + 'testAPIKeyExistShouldNoPrintAPINotice' => [ + 'config' => [ + 'api' => 'api', + 'has_rights' => true, + 'admin_url' => 'admin_url', + ], + 'expected' => '', + ], + 'testNoAPIAndHasRightShouldPrintAPINotice' => [ + 'config' => [ + 'api' => '', + 'has_rights' => true, + 'admin_url' => 'admin_url', + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Notices/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html' ), + ], +]; diff --git a/tests/Fixtures/src/Admin/Notices/Notices/wrongApiKeyNotice.php b/tests/Fixtures/src/Admin/Notices/Notices/wrongApiKeyNotice.php new file mode 100644 index 0000000..56ae1b3 --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Notices/wrongApiKeyNotice.php @@ -0,0 +1,41 @@ + [ + 'config' => [ + 'api' => '', + 'has_rights' => false, + 'data' => [ + 'data', + ], + ], + 'expected' => '', + ], + 'testAPIKeyNotExistShouldNoPrintWarning' => [ + 'config' => [ + 'api' => '', + 'has_rights' => true, + 'data' => [ + 'data', + ], + ], + 'expected' => '', + ], + 'testNoUserdataShouldNoPrintWarning' => [ + 'config' => [ + 'api' => 'api', + 'has_rights' => true, + 'data' => [ + 'data', + ], + ], + 'expected' => '', + ], + 'testAPIKeyUserdataHasRightsShouldPrintWarning' => [ + 'config' => [ + 'api' => 'api', + 'has_rights' => true, + 'data' => [], + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html' ), + ], +]; diff --git a/tests/Fixtures/src/Admin/Notices/Subscriber/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html b/tests/Fixtures/src/Admin/Notices/Subscriber/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html new file mode 100644 index 0000000..01602d9 --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Subscriber/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html @@ -0,0 +1 @@ +

RocketCDN: Your API key is wrong. You can find your API key in your RocketCDN account.

diff --git a/tests/Fixtures/src/Admin/Notices/Subscriber/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html b/tests/Fixtures/src/Admin/Notices/Subscriber/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html new file mode 100644 index 0000000..57eab39 --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Subscriber/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html @@ -0,0 +1 @@ +

RocketCDN: You are almost done. Add your API key to deliver your content at the speed of light!

diff --git a/tests/Fixtures/src/Admin/Notices/Subscriber/emptyApiKeyNotice.php b/tests/Fixtures/src/Admin/Notices/Subscriber/emptyApiKeyNotice.php new file mode 100644 index 0000000..4b7d586 --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Subscriber/emptyApiKeyNotice.php @@ -0,0 +1,39 @@ + [ + 'config' => [ + 'admin' => false, + 'option' => [ + 'api_key' => null, + ], + ], + 'expected' => [ + 'contains' => false, + 'html' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Subscriber/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html' ), + ], + ], + 'testApiKeyShouldDisplayNothing' => [ + 'config' => [ + 'admin' => true, + 'option' => [ + 'api_key' => 'api_key', + ], + ], + 'expected' => [ + 'contains' => false, + 'html' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Subscriber/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html' ), + ], + ], + 'testShouldDisplayNotification' => [ + 'config' => [ + 'admin' => true, + 'option' => [ + 'api_key' => null, + ], + ], + 'expected' => [ + 'contains' => true, + 'html' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Subscriber/HTML/testNoAPIAndHasRightShouldPrintAPINotice.html' ), + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Notices/Subscriber/wrongApiKeyNotice.php b/tests/Fixtures/src/Admin/Notices/Subscriber/wrongApiKeyNotice.php new file mode 100644 index 0000000..26b1c7c --- /dev/null +++ b/tests/Fixtures/src/Admin/Notices/Subscriber/wrongApiKeyNotice.php @@ -0,0 +1,45 @@ + [ + 'config' => [ + 'option' => [ + 'api_key' => '', + ], + ], + 'expected' => [ + 'contains' => false, + 'html' => str_replace( "\n", '', file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html' ) ), + ], + ], + 'testNoUserdataShouldPrintWarning' => [ + 'config' => [ + 'option' => [ + 'api_key' => 'api_key', + ], + ], + 'expected' => [ + 'contains' => true, + 'html' => str_replace( "\n", '', file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html' ) ), + ], + ], + 'testAPIKeyUserdataHasRightsShouldNotPrintWarning' => [ + 'config' => [ + 'option' => [ + 'api_key' => 'api_key_right', + ], + 'process_generate' => [ + 'response' => [ + 'body' => '{"websites":["test"]}', + 'response' => [ + 'code' => 200, + 'message' => "Success", + ], + ], + ], + ], + 'expected' => [ + 'contains' => false, + 'html' => str_replace( "\n", '', file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Notices/Notices/HTML/testAPIKeyUserdataHasRightsShouldPrintWarning.html' ) ), + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Page/HTML/testInvalidAPIShouldPrintNoKey.php b/tests/Fixtures/src/Admin/Settings/Page/HTML/testInvalidAPIShouldPrintNoKey.php new file mode 100644 index 0000000..7d70c02 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/HTML/testInvalidAPIShouldPrintNoKey.php @@ -0,0 +1,42 @@ +
+
+
+
+

+

+
+
+

+ +
+
+
+
+

+

+

+

+
+ +

+ +

+
+
+
+

+
+
+

+

+

+

+
+
+
+
+
diff --git a/tests/Fixtures/src/Admin/Settings/Page/HTML/testNoAPIShouldPrintNoKey.php b/tests/Fixtures/src/Admin/Settings/Page/HTML/testNoAPIShouldPrintNoKey.php new file mode 100644 index 0000000..1ba153d --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/HTML/testNoAPIShouldPrintNoKey.php @@ -0,0 +1,42 @@ +
+
+
+
+

+

+
+
+

+ +
+
+
+
+

+

+

+

+
+ +

+ +

+
+
+
+

+
+
+

+

+

+

+
+
+
+
+
diff --git a/tests/Fixtures/src/Admin/Settings/Page/HTML/testValidAPIShouldPrintKey.php b/tests/Fixtures/src/Admin/Settings/Page/HTML/testValidAPIShouldPrintKey.php new file mode 100644 index 0000000..20d3cc7 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/HTML/testValidAPIShouldPrintKey.php @@ -0,0 +1,42 @@ +
+
+
+
+

+

+
+
+

+ +
+
+
+

+
+


+

+ +
+
+
+

+
+

+ +
+
+

+
+
+
+ +
+

+
+
+
+
+
+
diff --git a/tests/Fixtures/src/Admin/Settings/Page/enqueueAssets.php b/tests/Fixtures/src/Admin/Settings/Page/enqueueAssets.php new file mode 100644 index 0000000..36d0128 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/enqueueAssets.php @@ -0,0 +1,33 @@ + [ + 'config' => [ + 'hook' => 'settings_page_rocketcdn', + 'should_register' => true, + ], + 'expected' => [ + 'version' => ROCKETCDN_VERSION, + 'style' => [ + 'id' => 'rocketcdn-settings', + 'url' => '/css/settings.css', + 'dependencies' => [], + ], + 'script' => [ + 'id' => 'rocketcdn_ajax', + 'url' => '/js/ajax.js', + 'dependencies' => [], + ], + 'localize' => [ + 'handle' => 'rocketcdn_ajax', + 'object' => 'rocketcdn_ajax_data', + ], + ], + ], + 'testShouldNotRegister' => [ + 'config' => [ + 'hook' => 'wrong', + 'should_register' => false, + ], + 'expected' => [], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Page/purgeCache.php b/tests/Fixtures/src/Admin/Settings/Page/purgeCache.php new file mode 100644 index 0000000..3edbfe9 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/purgeCache.php @@ -0,0 +1,42 @@ + [ + 'config' => [ + 'has_right' => false, + 'response' => [ + 'success' => false, + 'message' => 'Message', + ], + ], + 'expected' => [ + 'success' => false, + 'message' => 'You do not have permissions to perform this action.', + ], + ], + 'testFailedShouldReturnError' => [ + 'config' => [ + 'has_right' => true, + 'response' => [ + 'success' => false, + 'message' => 'Message', + ], + ], + 'expected' => [ + 'success' => false, + 'message' => 'Message', + ], + ], + 'testSuccessShouldReturnSuccess' => [ + 'config' => [ + 'has_right' => true, + 'response' => [ + 'success' => true, + 'message' => 'Message', + ], + ], + 'expected' => [ + 'success' => true, + 'message' => 'Done! Your cache has been cleared', + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Page/renderPage.php b/tests/Fixtures/src/Admin/Settings/Page/renderPage.php new file mode 100644 index 0000000..f25af4d --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/renderPage.php @@ -0,0 +1,33 @@ + [ + 'config' => [ + 'api' => null, + 'cdn_url' => 'cdn_url', + 'is_sync' => false, + 'title' => 'title', + 'configs' => 'configs', + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Settings/Page/HTML/testNoAPIShouldPrintNoKey.php' ), + ], + 'testInvalidAPIShouldPrintNoKey' => [ + 'config' => [ + 'api' => 'api', + 'cdn_url' => 'cdn_url', + 'is_sync' => false, + 'title' => 'title', + 'configs' => 'configs', + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Settings/Page/HTML/testInvalidAPIShouldPrintNoKey.php' ), + ], + 'testValidAPIShouldPrintKey' => [ + 'config' => [ + 'api' => 'api', + 'cdn_url' => 'cdn_url', + 'is_sync' => true, + 'title' => 'title', + 'configs' => 'configs', + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Admin/Settings/Page/HTML/testValidAPIShouldPrintKey.php' ), + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Page/saveCdnUrl.php b/tests/Fixtures/src/Admin/Settings/Page/saveCdnUrl.php new file mode 100644 index 0000000..9f569fe --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/saveCdnUrl.php @@ -0,0 +1,14 @@ + [ + 'config' => [ + 'cdn' => 'cdn', + ], + ], + 'testNoCdnShouldNoSave' => [ + 'config' => [ + 'cdn' => '', + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Page/updateApiKey.php b/tests/Fixtures/src/Admin/Settings/Page/updateApiKey.php new file mode 100644 index 0000000..d054c8d --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/updateApiKey.php @@ -0,0 +1,70 @@ + [ + 'config' => [ + 'api' => null, + 'has_right' => false, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'You do not have permissions to perform this action.', + ], + ], + 'testHasNoAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => null, + 'has_right' => true, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'They API key field is not set', + ], + ], + 'testHasInvalidAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => null, + 'has_right' => true, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'They API key field is not set', + ], + ], + 'testHasInvalidDataShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'has_right' => true, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'Invalid API key', + ], + ], + 'testHasNotSyncShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'has_right' => true, + 'is_valid' => [ 'data' ], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'Your website is not yet synchronized with your subscription. Please add your website from your RocketCDN account page.', + ], + ], + 'testShouldCallJsonSuccess' => [ + 'config' => [ + 'api' => 'api', + 'has_right' => true, + 'is_valid' => [ 'data' ], + 'is_sync' => true, + ], + 'expected' => [ + 'message' => 'Your API key is valid.', + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Page/validateApiKey.php b/tests/Fixtures/src/Admin/Settings/Page/validateApiKey.php new file mode 100644 index 0000000..7041000 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Page/validateApiKey.php @@ -0,0 +1,67 @@ + [ + 'config' => [ + 'api' => null, + 'has_right' => false, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'You do not have permissions to perform this action.', + ], + ], + 'testHasNoAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => null, + 'has_right' => true, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'They API key field is not set', + ], + ], + 'testHasInvalidAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => null, + 'has_right' => true, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'They API key field is not set', + ], + ], + 'testHasInvalidDataShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'has_right' => true, + 'is_valid' => [], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'Invalid API key', + ], + ], + 'testHasNotSyncShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'has_right' => true, + 'is_valid' => [ 'data' ], + 'is_sync' => false, + ], + 'expected' => [ + 'message' => 'Your website is not yet synchronized with your subscription. Please add your website from your RocketCDN account page.', + ], + ], + 'testShouldCallJsonSuccess' => [ + 'config' => [ + 'api' => 'api', + 'has_right' => true, + 'is_valid' => [ 'data' ], + 'is_sync' => true, + ], + 'expected' => [], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Subscriber/enqueueAssets.php b/tests/Fixtures/src/Admin/Settings/Subscriber/enqueueAssets.php new file mode 100644 index 0000000..2c8637e --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Subscriber/enqueueAssets.php @@ -0,0 +1,15 @@ + [ + 'config' => [ + 'hook' => 'edit.php', + ], + 'expected' => false, + ], + 'shouldEnqueueAssets' => [ + 'config' => [ + 'hook' => 'settings_page_rocketcdn', + ], + 'expected' => true, + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Subscriber/purgeCache.php b/tests/Fixtures/src/Admin/Settings/Subscriber/purgeCache.php new file mode 100644 index 0000000..2ae2ce5 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Subscriber/purgeCache.php @@ -0,0 +1,42 @@ + [ + 'config' => [ + 'can_manage_options' => false, + 'api' => 'api', + 'cdn' => 'cdn', + ], + 'expected' => [ + 'bailout' => true, + ], + ], + 'testFailedShouldReturnError' => [ + 'config' => [ + 'can_manage_options' => true, + 'api' => 'api', + 'cdn' => 'cdn', + 'process_generate' => [ + 'is_wp_error' => true, + 'message' => 'error', + ], + ], + 'expected' => [ + 'bailout' => true, + ], + ], + 'testSuccessShouldReturnSuccess' => [ + 'config' => [ + 'can_manage_options' => true, + 'api' => 'api', + 'cdn' => 'cdn', + 'process_generate' => [ + 'is_wp_error' => true, + 'response' => '{"status":200,"success":true,"message":"success"}', + ], + ], + 'expected' => [ + 'bailout' => true, + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Subscriber/saveCdnUrl.php b/tests/Fixtures/src/Admin/Settings/Subscriber/saveCdnUrl.php new file mode 100644 index 0000000..3c29ec8 --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Subscriber/saveCdnUrl.php @@ -0,0 +1,4 @@ + [ + 'config' => [ + 'api' => '', + 'check_ajax_referer' => true, + 'can_manage_options' => false, + ], + 'expected' => [ + 'bailout' => true, + 'json' => 'wp_send_json_error', + ], + ], + 'testHasNoAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => '', + 'can_manage_options' => true, + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], + 'testHasInvalidAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'can_manage_options' => true, + 'process_generate' => [ + 'is_wp_error' => true, + 'message' => 'error', + ], + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], + 'testHasNotSyncShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'can_manage_options' => true, + 'process_generate' => [ + 'is_wp_error' => true, + 'response' => '{"status":200,"success":true,"message":"succes","websites":["test"]}', + ], + ], + 'expected' => [ + 'bailout' => true, + ], + ], + 'testShouldCallJsonSuccess' => [ + 'config' => [ + 'can_manage_options' => true, + 'api' => 'api', + 'process_generate' => [ + 'response' => '{"status":200,"success":true,"message":"succes","websites":["test"]}', + ], + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], + 'testCacheShouldReturnCacheShouldReturnCache' => [ + 'config' => [ + 'api' => 'api', + 'can_manage_options' => true, + 'rocketcdn_customer_data' => [ + 'success' => true, + 'message' => 'success', + 'websites' => [ 'hostname' => 'example.org' ], + ], + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], +]; diff --git a/tests/Fixtures/src/Admin/Settings/Subscriber/validateApiKey.php b/tests/Fixtures/src/Admin/Settings/Subscriber/validateApiKey.php new file mode 100644 index 0000000..c3010ad --- /dev/null +++ b/tests/Fixtures/src/Admin/Settings/Subscriber/validateApiKey.php @@ -0,0 +1,87 @@ + [ + 'config' => [ + 'api' => '', + 'check_ajax_referer' => true, + 'can_manage_options' => false, + ], + 'expected' => [ + 'bailout' => true, + 'json' => 'wp_send_json_error', + ], + ], + 'testHasNoAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => '', + 'can_manage_options' => true, + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], + 'testHasInvalidAPIShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'can_manage_options' => true, + 'process_generate' => [ + 'is_wp_error' => true, + 'message' => 'error', + ], + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], + 'testHasNotSyncShouldCallJsonError' => [ + 'config' => [ + 'api' => 'api', + 'can_manage_options' => true, + 'process_generate' => [ + 'is_wp_error' => true, + 'response' => '{"status":200,"success":true,"message":"succes","websites":["test"]}', + ], + ], + 'expected' => [ + 'bailout' => true, + ], + ], + 'testShouldCallJsonSuccess' => [ + 'config' => [ + 'can_manage_options' => true, + 'api' => 'api', + 'process_generate' => [ + 'response' => '{"status":200,"success":true,"message":"succes","websites":["test"]}', + ], + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], + 'testCacheShouldReturnCacheShouldReturnCache' => [ + 'config' => [ + 'api' => 'api', + 'can_manage_options' => true, + 'rocketcdn_customer_data' => [ + 'success' => true, + 'message' => 'success', + 'websites' => [ 'hostname' => 'example.org' ], + ], + ], + 'expected' => [ + 'bailout' => true, + 'data' => [ + 'status' => 200, + ], + ], + ], +]; diff --git a/tests/Fixtures/src/Front/CDN/HTML/siteURL/original.html b/tests/Fixtures/src/Front/CDN/HTML/siteURL/original.html new file mode 100644 index 0000000..fe6b1b0 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/HTML/siteURL/original.html @@ -0,0 +1,1034 @@ + + + + + + + + + + + + + + Page Image Alignment – tests + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + +
+
+ + +
+
+

Page Image Alignment

+
+

Welcome to image alignment! The best way to demonstrate the ebb and flow of the various image positioning options is to nestle them snuggly among an ocean of words. Grab a paddle and let’s get started.

+

On the topic of alignment, it should be noted that users can choose from the options of None, Left, Right, and Center. In addition, they also get the options of Thumbnail, Medium, Large & Fullsize.

+ Test link + +

Image Alignment 580x300

+

The image above happens to be centered.

+

Image Alignment 150x150The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+

Image Alignment 1200x400

+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+

Image Alignment 300x200

+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And just when you thought we were done, we’re going to do them all over again with captions!

+
Image Alignment 580x300
Look at 580×300 getting some caption love.
+

The image above happens to be centered. The caption also has a link in it, just to see if it does anything funky.

+
Image Alignment 150x150
Itty-bitty caption.
+

The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+
Image Alignment 1200x400
Massive image comment for your eyeballs.
+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+
Image Alignment 300x200
Feels good to be right all the time.
+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And that’s a wrap, yo! You survived the tumultuous waters of alignment. Image alignment achievement unlocked!

+
+ +
+
+ +
+ + + + logo d'acommeassure + +
+
+ +
+ +
+ Laisser un commentaire
+

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

+ +

+

+ +

+
+ +
+ +
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + diff --git a/tests/Fixtures/src/Front/CDN/HTML/siteURL/rewrite.html b/tests/Fixtures/src/Front/CDN/HTML/siteURL/rewrite.html new file mode 100644 index 0000000..c87e0a4 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/HTML/siteURL/rewrite.html @@ -0,0 +1,1034 @@ + + + + + + + + + + + + + + Page Image Alignment – tests + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + +
+
+ + +
+
+

Page Image Alignment

+
+

Welcome to image alignment! The best way to demonstrate the ebb and flow of the various image positioning options is to nestle them snuggly among an ocean of words. Grab a paddle and let’s get started.

+

On the topic of alignment, it should be noted that users can choose from the options of None, Left, Right, and Center. In addition, they also get the options of Thumbnail, Medium, Large & Fullsize.

+ Test link + +

Image Alignment 580x300

+

The image above happens to be centered.

+

Image Alignment 150x150The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+

Image Alignment 1200x400

+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+

Image Alignment 300x200

+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And just when you thought we were done, we’re going to do them all over again with captions!

+
Image Alignment 580x300
Look at 580×300 getting some caption love.
+

The image above happens to be centered. The caption also has a link in it, just to see if it does anything funky.

+
Image Alignment 150x150
Itty-bitty caption.
+

The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+
Image Alignment 1200x400
Massive image comment for your eyeballs.
+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+
Image Alignment 300x200
Feels good to be right all the time.
+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And that’s a wrap, yo! You survived the tumultuous waters of alignment. Image alignment achievement unlocked!

+
+ +
+
+ +
+ + + + logo d'acommeassure + +
+
+ +
+ +
+ Laisser un commentaire
+

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

+ +

+

+ +

+
+ +
+ +
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + diff --git a/tests/Fixtures/src/Front/CDN/HTML/siteURLWithPath/original.html b/tests/Fixtures/src/Front/CDN/HTML/siteURLWithPath/original.html new file mode 100644 index 0000000..5da5300 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/HTML/siteURLWithPath/original.html @@ -0,0 +1,723 @@ + + + + + + + + + Page Image Alignment – tests + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + +
+
+ + +
+
+

Page Image Alignment

+
+

Welcome to image alignment! The best way to demonstrate the ebb and flow of the various image positioning options is to nestle them snuggly among an ocean of words. Grab a paddle and let’s get started.

+

On the topic of alignment, it should be noted that users can choose from the options of None, Left, Right, and Center. In addition, they also get the options of Thumbnail, Medium, Large & Fullsize.

+

Image Alignment 580x300

+

The image above happens to be centered.

+

Image Alignment 150x150The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+

Image Alignment 1200x400

+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+

Image Alignment 300x200

+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And just when you thought we were done, we’re going to do them all over again with captions!

+
Image Alignment 580x300
Look at 580×300 getting some caption love.
+

The image above happens to be centered. The caption also has a link in it, just to see if it does anything funky.

+
Image Alignment 150x150
Itty-bitty caption.
+

The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+
Image Alignment 1200x400
Massive image comment for your eyeballs.
+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+
Image Alignment 300x200
Feels good to be right all the time.
+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And that’s a wrap, yo! You survived the tumultuous waters of alignment. Image alignment achievement unlocked!

+
+
+ +
+ +
+ Laisser un commentaire
+

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

+ +

+

+ +

+
+ +
+ +
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + diff --git a/tests/Fixtures/src/Front/CDN/HTML/siteURLWithPath/rewrite.html b/tests/Fixtures/src/Front/CDN/HTML/siteURLWithPath/rewrite.html new file mode 100644 index 0000000..f9190bc --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/HTML/siteURLWithPath/rewrite.html @@ -0,0 +1,723 @@ + + + + + + + + + Page Image Alignment – tests + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + +
+
+ + +
+
+

Page Image Alignment

+
+

Welcome to image alignment! The best way to demonstrate the ebb and flow of the various image positioning options is to nestle them snuggly among an ocean of words. Grab a paddle and let’s get started.

+

On the topic of alignment, it should be noted that users can choose from the options of None, Left, Right, and Center. In addition, they also get the options of Thumbnail, Medium, Large & Fullsize.

+

Image Alignment 580x300

+

The image above happens to be centered.

+

Image Alignment 150x150The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+

Image Alignment 1200x400

+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+

Image Alignment 300x200

+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And just when you thought we were done, we’re going to do them all over again with captions!

+
Image Alignment 580x300
Look at 580×300 getting some caption love.
+

The image above happens to be centered. The caption also has a link in it, just to see if it does anything funky.

+
Image Alignment 150x150
Itty-bitty caption.
+

The rest of this paragraph is filler for the sake of seeing the text wrap around the 150×150 image, which is left aligned.

+

As you can see the should be some space above, below, and to the right of the image. The text should not be creeping on the image. Creeping is just not right. Images need breathing room too. Let them speak like you words. Let them do their jobs without any hassle from the text. In about one more sentence here, we’ll see that the text moves from the right of the image down below the image in seamless transition. Again, letting the do it’s thang. Mission accomplished!

+

And now for a massively large image. It also has no alignment.

+
Image Alignment 1200x400
Massive image comment for your eyeballs.
+

The image above, though 1200px wide, should not overflow the content area. It should remain contained with no visible disruption to the flow of content.

+
Image Alignment 300x200
Feels good to be right all the time.
+

And now we’re going to shift things to the right align. Again, there should be plenty of room above, below, and to the left of the image. Just look at him there… Hey guy! Way to rock that right side. I don’t care what the left aligned image says, you look great. Don’t let anyone else tell you differently.

+

In just a bit here, you should see the text start to wrap below the right aligned image and settle in nicely. There should still be plenty of room and everything should be sitting pretty. Yeah… Just like that. It never felt so good to be right.

+

And that’s a wrap, yo! You survived the tumultuous waters of alignment. Image alignment achievement unlocked!

+
+
+ +
+ +
+ Laisser un commentaire
+

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

+ +

+

+ +

+
+ +
+ +
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + diff --git a/tests/Fixtures/src/Front/CDN/Subscriber/addPreconnectCdn.php b/tests/Fixtures/src/Front/CDN/Subscriber/addPreconnectCdn.php new file mode 100644 index 0000000..2361be0 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/Subscriber/addPreconnectCdn.php @@ -0,0 +1,14 @@ + [ + 'config' => [ + 'cdn_url' => '123456.rocketcdn.me', + ], + 'expected' => [ + 'html' => << +HTML, + ], + ], +]; diff --git a/tests/Fixtures/src/Front/CDN/addPreconnectCdn.php b/tests/Fixtures/src/Front/CDN/addPreconnectCdn.php new file mode 100644 index 0000000..50aa2b7 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/addPreconnectCdn.php @@ -0,0 +1,79 @@ + [ + 'config' => [ + 'urls' => [ + 'url1', + 'url2', + 'url3', + ], + 'rewrite' => true, + 'relation_type' => 'prerender', + 'cdn' => 'cdn', + ], + 'expected' => [ + 'url1', + 'url2', + 'url3', + ], + 'cdn' => 'cdn', + ], + 'testShouldNotRewriteShouldReturnOriginalUrls' => [ + 'config' => [ + 'urls' => [ + 'url1', + 'url2', + 'url3', + ], + 'rewrite' => false, + 'relation_type' => 'preconnect', + 'cdn' => 'cdn', + ], + 'expected' => [ + 'url1', + 'url2', + 'url3', + ], + ], + 'testEmptyCdnShouldReturnOriginalUrls' => [ + 'config' => [ + 'urls' => [ + 'url1', + 'url2', + 'url3', + ], + 'rewrite' => true, + 'relation_type' => 'preconnect', + 'cdn' => null, + ], + 'expected' => [ + 'url1', + 'url2', + 'url3', + ], + ], + 'testCdnPreconnectRelationTypeRewriteShouldReturnCdn' => [ + 'config' => [ + 'urls' => [ + 'url1', + 'url2', + 'url3', + ], + 'rewrite' => true, + 'relation_type' => 'preconnect', + 'cdn' => 'cdn', + ], + 'expected' => [ + 'url1', + 'url2', + 'url3', + [ + 'href' => 'cdn', + ], + [ + 'href' => 'cdn', + 'crossorigin' => 'anonymous', + ], + ], + ], +]; diff --git a/tests/Fixtures/src/Front/CDN/endBuffering.php b/tests/Fixtures/src/Front/CDN/endBuffering.php new file mode 100644 index 0000000..3bdf21e --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/endBuffering.php @@ -0,0 +1,28 @@ + [ + 'config' => [ + 'homeurl' => 'http://example.org', + 'hostname' => 'example.org', + 'wp-content' => 'wp-content/', + 'wp-includes' => 'wp-includes/', + 'wp_upload_dir' => 'wp-content/uploads/', + 'cdn' => 'cdn', + 'html' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Front/CDN/HTML/siteURL/original.html' ), + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Front/CDN/HTML/siteURL/rewrite.html' ), + ], + 'testSiteURLWithPath' => [ + 'config' => [ + 'homeurl' => 'http://example.org/blog', + 'hostname' => 'example.org', + 'wp-content' => 'blog/wp-content/', + 'wp-includes' => 'blog/wp-includes/', + 'wp_upload_dir' => 'blog/wp-content/uploads/', + 'cdn' => 'cdn', + 'html' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Front/CDN/HTML/siteURLWithPath/original.html' ), + ], + 'expected' => file_get_contents( WP_ROCKET_CDN_TESTS_FIXTURES_DIR . '/src/Front/CDN/HTML/siteURLWithPath/rewrite.html' ), + ], +]; diff --git a/tests/Fixtures/src/Front/CDN/rewriteUrl.php b/tests/Fixtures/src/Front/CDN/rewriteUrl.php new file mode 100644 index 0000000..4841bb6 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/rewriteUrl.php @@ -0,0 +1,51 @@ + [ + 'config' => [ + 'homeurl' => 'http://example.org', + 'host' => 'example.org', + 'cdn' => null, + 'url' => 'http://example.org/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + 'parsed_url' => [ + 'host' => 'example.org', + 'scheme' => 'http', + ], + ], + 'expected' => 'http://example.org/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + ], + 'testCdnShouldReturnUrlWithCdn' => [ + 'config' => [ + 'homeurl' => 'http://example.org', + 'host' => 'example.org', + 'url' => 'http://example.org/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + 'cdn' => 'cdn', + 'parsed_url' => [ + 'host' => 'example.org', + 'scheme' => 'http', + ], + ], + 'expected' => 'cdn/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + ], + 'testCdnNoHostShouldReturnUrlWithCdn' => [ + 'config' => [ + 'homeurl' => 'http://example.org', + 'host' => 'example.org', + 'url' => '/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + 'cdn' => 'cdn', + 'parsed_url' => [], + ], + 'expected' => 'cdn/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + ], + 'testCdnNoSchemeShouldReturnUrlWithCdn' => [ + 'config' => [ + 'homeurl' => 'http://example.org', + 'host' => 'example.org', + 'url' => 'example.org/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + 'cdn' => 'cdn', + 'parsed_url' => [ + 'host' => 'example.org', + ], + ], + 'expected' => 'cdn/wp-content/uploads/2018/03/sticker-mule-189122-unsplash-1568x1046.jpg', + ], +]; diff --git a/tests/Fixtures/src/Front/CDN/startBuffering.php b/tests/Fixtures/src/Front/CDN/startBuffering.php new file mode 100644 index 0000000..f30c149 --- /dev/null +++ b/tests/Fixtures/src/Front/CDN/startBuffering.php @@ -0,0 +1,63 @@ + [ + 'config' => [ + 'has_request_method' => true, + 'request_method' => 'GET', + 'is_admin' => false, + 'is_customize_preview' => false, + 'is_embed' => false, + ], + 'expected' => true, + ], + 'testNoRequestMethodShouldNotStartBuffer' => [ + 'config' => [ + 'has_request_method' => false, + 'request_method' => 'GET', + 'is_admin' => false, + 'is_customize_preview' => false, + 'is_embed' => false, + ], + 'expected' => false, + ], + 'testNotGetRequestMethodShouldNotStartBuffer' => [ + 'config' => [ + 'has_request_method' => true, + 'request_method' => 'POST', + 'is_admin' => false, + 'is_customize_preview' => false, + 'is_embed' => false, + ], + 'expected' => false, + ], + 'testAdminShouldNotStartBuffer' => [ + 'config' => [ + 'has_request_method' => true, + 'request_method' => 'GET', + 'is_admin' => true, + 'is_customize_preview' => false, + 'is_embed' => false, + ], + 'expected' => false, + ], + 'testCustomizePreviewShouldNotStartBuffer' => [ + 'config' => [ + 'has_request_method' => true, + 'request_method' => 'GET', + 'is_admin' => false, + 'is_customize_preview' => true, + 'is_embed' => false, + ], + 'expected' => false, + ], + 'testEmbdedShouldNotStartBuffer' => [ + 'config' => [ + 'has_request_method' => true, + 'request_method' => 'GET', + 'is_admin' => false, + 'is_customize_preview' => false, + 'is_embed' => true, + ], + 'expected' => false, + ], +]; diff --git a/tests/Fixtures/src/Options/Options/delete.php b/tests/Fixtures/src/Options/Options/delete.php new file mode 100644 index 0000000..d6fcb4d --- /dev/null +++ b/tests/Fixtures/src/Options/Options/delete.php @@ -0,0 +1,10 @@ + [ + 'config' => [ + 'prefix' => 'prefix', + 'name' => 'name', + ], + 'expected' => 'prefixname', + ], +]; diff --git a/tests/Fixtures/src/Options/Options/get.php b/tests/Fixtures/src/Options/Options/get.php new file mode 100644 index 0000000..82bb3b5 --- /dev/null +++ b/tests/Fixtures/src/Options/Options/get.php @@ -0,0 +1,33 @@ + [ + 'config' => [ + 'prefix' => 'prefix', + 'option_name' => 'option_name', + 'default' => 'default', + 'name' => 'name', + 'option' => 'option', + ], + 'expected' => 'option', + ], + 'testShouldReturnDefaultWhenNotExisting' => [ + 'config' => [ + 'prefix' => 'prefix', + 'option_name' => 'option_name', + 'default' => 'default', + 'name' => 'name', + 'option' => 'default', + ], + 'expected' => 'default', + ], + 'testShouldReturnConvertedValueWhenNotArray' => [ + 'config' => [ + 'prefix' => 'prefix', + 'option_name' => 'option_name', + 'default' => [], + 'name' => 'name', + 'option' => 'option', + ], + 'expected' => (array) 'option', + ], +]; diff --git a/tests/Fixtures/src/Options/Options/getOptionName.php b/tests/Fixtures/src/Options/Options/getOptionName.php new file mode 100644 index 0000000..3a5100a --- /dev/null +++ b/tests/Fixtures/src/Options/Options/getOptionName.php @@ -0,0 +1,17 @@ + [ + 'config' => [ + 'prefix' => '', + 'name' => 'name', + ], + 'expected' => 'name', + ], + 'testPrefixNonEmptyShouldReturnExpected' => [ + 'config' => [ + 'prefix' => 'prefix', + 'name' => 'name', + ], + 'expected' => 'prefixname', + ], +]; diff --git a/tests/Fixtures/src/Options/Options/set.php b/tests/Fixtures/src/Options/Options/set.php new file mode 100644 index 0000000..f782897 --- /dev/null +++ b/tests/Fixtures/src/Options/Options/set.php @@ -0,0 +1,15 @@ + [ + 'config' => [ + 'prefix' => 'prefix', + 'name' => 'name', + 'value' => 'value', + ], + 'expected' => [ + 'option_name' => 'prefixname', + 'value' => 'value', + ], + ], +]; diff --git a/tests/Integration/AdminTestCase.php b/tests/Integration/AdminTestCase.php new file mode 100644 index 0000000..50fb53b --- /dev/null +++ b/tests/Integration/AdminTestCase.php @@ -0,0 +1,81 @@ +error_level = error_reporting(); + error_reporting( $this->error_level & ~E_WARNING ); + } + + public function tear_down() { + $_POST = []; + $_GET = []; + unset( $GLOBALS['post'], $GLOBALS['comment'] ); + + parent::tear_down(); + + error_reporting( $this->error_level ); + set_current_screen( 'front' ); + if ( $this->user_id > 0 ) { + wp_delete_user( $this->user_id ); + } + } + + protected function setRoleCap( $role_type, $cap ) { + $role = get_role( $role_type ); + $role->add_cap( $cap ); + } + + protected function removeRoleCap( $role_type, $cap ) { + $role = get_role( $role_type ); + $role->remove_cap( $cap ); + } + + protected function setCurrentUser( $role ) { + $this->user_id = $this->factory->user->create( [ 'role' => $role ] ); + wp_set_current_user( $this->user_id ); + } + + protected function fireAdminInit() { + do_action( 'admin_init' ); + } + + protected function hasCallbackRegistered( $event, $class, $method, $priority = 10 ) { + global $wp_filter; + + $this->assertArrayHasKey( $event, $wp_filter ); + $this->assertArrayHasKey( $priority, $wp_filter[ $event ]->callbacks ); + + $object = null; + foreach ( $wp_filter['post_tag_row_actions']->callbacks[ $priority ] as $key => $callback ) { + if ( isset( $callback['function'][1] ) && $method === $callback['function'][1] ) { + $object = $callback['function'][0]; + break; + } + } + $this->assertInstanceOf( $class, $object ); + } + + protected function setEditTagsAsCurrentScreen( $tax = 'category' ) { + set_current_screen( "edit-tags.php?taxonomy={$tax}" ); + } +} diff --git a/tests/Integration/AjaxTestCase.php b/tests/Integration/AjaxTestCase.php new file mode 100644 index 0000000..84e9f07 --- /dev/null +++ b/tests/Integration/AjaxTestCase.php @@ -0,0 +1,104 @@ + $value ) { + if ( ! empty( $transient ) ) { + set_transient( $transient, $value ); + } else { + delete_transient( $transient ); + } + } + } + + public function set_up() { + if ( empty( $this->config ) ) { + $this->loadTestDataConfig(); + } + + parent::set_up(); + + if ( static::$use_settings_trait ) { + $this->setUpSettings(); + } + } + + public function tear_down() { + unset( $_POST['action'], $_POST['nonce'] ); + $this->action = null; + self::resetAdminCap(); + + parent::tear_down(); + + if ( static::$use_settings_trait ) { + $this->tearDownSettings(); + } + } + + public function configTestData() { + if ( empty( $this->config ) ) { + $this->loadTestDataConfig(); + } + + return isset( $this->config['test_data'] ) + ? $this->config['test_data'] + : $this->config; + } + + protected function loadTestDataConfig() { + $obj = new ReflectionObject( $this ); + $filename = $obj->getFileName(); + + $this->config = $this->getTestData( dirname( $filename ), basename( $filename, '.php' ) ); + } + + protected function setRoleCap( $role_type, $cap ) { + $role = get_role( $role_type ); + $role->add_cap( $cap ); + } + + protected function removeRoleCap( $role_type, $cap ) { + $role = get_role( $role_type ); + $role->remove_cap( $cap ); + } +} diff --git a/tests/Integration/CapTrait.php b/tests/Integration/CapTrait.php new file mode 100644 index 0000000..9c62ecc --- /dev/null +++ b/tests/Integration/CapTrait.php @@ -0,0 +1,26 @@ +has_cap( 'manage_options' ); + } + + public static function setAdminCap() { + $admin = get_role( 'administrator' ); + if ( ! static::$had_cap ) { + $admin->add_cap( 'manage_options' ); + } + } + + public static function resetAdminCap() { + $admin = get_role( 'administrator' ); + if ( ! static::$had_cap ) { + $admin->remove_cap( 'manage_options' ); + } + } +} diff --git a/tests/Integration/DBTrait.php b/tests/Integration/DBTrait.php new file mode 100644 index 0000000..153d2f5 --- /dev/null +++ b/tests/Integration/DBTrait.php @@ -0,0 +1,53 @@ +get( 'rucss_resources_query' ); + return $resource_query->query( $resource ); + } + + public static function installFresh() { + $container = apply_filters( 'rocket_container', null ); + + self::uninstallAll(); + } + + public static function uninstallAll() { + $container = apply_filters( 'rocket_container', null ); + } + + public static function removeDBHooks() { + $container = apply_filters( 'rocket_container', null ); + } + + public static function forceRemoveTableAdminInitHooks( $hook_name = '', $class_name = '', $method_name = '', $priority = 0 ) { + global $wp_filter; + + // Take only filters on right hook name and priority + if ( ! isset( $wp_filter[ $hook_name ][ $priority ] ) || ! is_array( $wp_filter[ $hook_name ][ $priority ] ) ) { + return false; + } + + // Loop on filters registered + foreach ( (array) $wp_filter[ $hook_name ][ $priority ] as $unique_id => $filter_array ) { + // Test if filter is an array ! (always for class/method) + if ( isset( $filter_array['function'] ) && is_array( $filter_array['function'] ) ) { + // Test if object is a class, class and method is equal to param ! + if ( is_object( $filter_array['function'][0] ) && get_class( $filter_array['function'][0] ) && get_class( $filter_array['function'][0] ) == $class_name && $filter_array['function'][1] == $method_name ) { + // Test for WordPress >= 4.7 WP_Hook class (https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/) + if ( is_a( $wp_filter[ $hook_name ], 'WP_Hook' ) ) { + unset( $wp_filter[ $hook_name ]->callbacks[ $priority ][ $unique_id ] ); + } else { + unset( $wp_filter[ $hook_name ][ $priority ][ $unique_id ] ); + } + } + } + } + + return false; + } +} diff --git a/tests/Integration/FilterTrait.php b/tests/Integration/FilterTrait.php new file mode 100644 index 0000000..0855188 --- /dev/null +++ b/tests/Integration/FilterTrait.php @@ -0,0 +1,36 @@ +original_wp_filter = $wp_filter[ $event_name ]->callbacks; + + foreach ( $this->original_wp_filter[ $priority ] as $key => $config ) { + + // Skip if not this tests callback. + if ( substr( $key, - strlen( $method_name ) ) !== $method_name ) { + continue; + } + + $wp_filter[ $event_name ]->callbacks = [ + $priority => [ $key => $config ], + ]; + } + } + + protected function restoreWpFilter( $event_name ) { + global $wp_filter; + $wp_filter[ $event_name ]->callbacks = $this->original_wp_filter; + + } +} diff --git a/tests/Integration/TestCase.php b/tests/Integration/TestCase.php new file mode 100644 index 0000000..7ac144e --- /dev/null +++ b/tests/Integration/TestCase.php @@ -0,0 +1,12 @@ + + + + + + src + + + + + + ../../src + + + diff --git a/tests/Integration/src/Admin/AdminBar/Subscriber/addAdminBarMenu.php b/tests/Integration/src/Admin/AdminBar/Subscriber/addAdminBarMenu.php new file mode 100644 index 0000000..78a5dad --- /dev/null +++ b/tests/Integration/src/Admin/AdminBar/Subscriber/addAdminBarMenu.php @@ -0,0 +1,132 @@ +setCurrentUser( 'administrator' ); + } else { + $this->setCurrentUser( 'editor' ); + } + + $this->option = $config['option']; + $_SERVER['REQUEST_URI'] = $config['request']; + $wp_admin_bar = $this->initAdminBar(); + + if ( false === $config['admin'] ) { + set_current_screen( 'front' ); + } + + Functions\when( 'wp_create_nonce' )->justReturn( 'wp_rocket_nonce' ); + + $this->expectProcessGenerate($config, $expected); + + // Fire the hook. + do_action_ref_array( 'admin_bar_menu', [ $wp_admin_bar ] ); + + // Check the results. + $base = $wp_admin_bar->get_node( 'rocketcdn' ); + $connect = $wp_admin_bar->get_node( 'rocketcdn-connect' ); + $settings = $wp_admin_bar->get_node( 'rocketcdn-settings' ); + $cache = $wp_admin_bar->get_node( 'rocketcdn-purge-cache' ); + $faq = $wp_admin_bar->get_node( 'rocketcdn-faq' ); + $support = $wp_admin_bar->get_node( 'rocketcdn-support' ); + if ( count( $expected ) > 0 ) { + $this->assertEquals( $base, $expected['base'] ); + $this->assertEquals( $expected['connect'], $connect ); + $this->assertEquals( $settings, $expected['settings'] ); + $this->assertEquals( $cache, $expected['cache'] ); + $this->assertEquals( $faq, $expected['faq'] ); + $this->assertEquals( $support, $expected['support'] ); + } else { + $this->assertNull( $base ); + $this->assertNull( $connect ); + $this->assertNull( $settings ); + $this->assertNull( $cache ); + $this->assertNull( $faq ); + $this->assertNull( $support ); + } + } + + private function expectProcessGenerate( $config, $expected ) { + if ( ! isset( $config['process_generate'] ) ) { + return; + } + + $headers = [ + 'Authorization' => "token {$config['option']['api_key']}", + ]; + + if ( ! empty( $config['process_generate']['is_wp_error'] ) ) { + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( new WP_Error( 'error', 'error_data' ) ); + } else { + $response = $config['process_generate']['response']; + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( $response ); + } + } + + protected function initAdminBar() { + global $wp_admin_bar; + + set_current_screen( 'edit.php' ); + $this->assertTrue( _wp_admin_bar_init() ); + + $this->assertTrue( is_admin_bar_showing() ); + $this->assertInstanceOf( 'WP_Admin_Bar', $wp_admin_bar ); + + return $wp_admin_bar; + } + + + public function api_key() { + return $this->option['api_key']; + } + + public function providerTestData() { + $dir = dirname( __FILE__ ); + return $this->getTestData( $dir, 'addAdminBarMenu' ); + } +} diff --git a/tests/Integration/src/Admin/AdminBar/Subscriber/enqueueStyle.php b/tests/Integration/src/Admin/AdminBar/Subscriber/enqueueStyle.php new file mode 100644 index 0000000..9d001c0 --- /dev/null +++ b/tests/Integration/src/Admin/AdminBar/Subscriber/enqueueStyle.php @@ -0,0 +1,29 @@ +assertArrayHasKey( 'rocketcdn-admin-bar', $wp_styles->registered ); + } + + + public function providerTestData() { + $dir = dirname( __FILE__ ); + return $this->getTestData( $dir, 'enqueueStyle' ); + } +} diff --git a/tests/Integration/src/Admin/AdminBar/Subscriber/purgeCache.php b/tests/Integration/src/Admin/AdminBar/Subscriber/purgeCache.php new file mode 100644 index 0000000..d0d2951 --- /dev/null +++ b/tests/Integration/src/Admin/AdminBar/Subscriber/purgeCache.php @@ -0,0 +1,100 @@ +never(); + $this->expectException( WPDieException::class ); + $this->expectExceptionMessage( 'The link you followed has expired.' ); + do_action( 'admin_post_rocketcdn-purge-cache' ); + } + + public function testShouldWPNonceAysWhenNonceInvalid() { + $_GET['_wpnonce'] = 'invalid'; + + Functions\expect( 'current_user_can' )->never(); + + $this->expectException( WPDieException::class ); + $this->expectExceptionMessage( 'The link you followed has expired.' ); + do_action( 'admin_post_rocketcdn-purge-cache' ); + } + + /** + * Test should wp_die() when the current user doesn't have 'manage_options' capability. + */ + public function testShouldWPDieWhenCurrentUserCant() { + $user_id = $this->factory->user->create( [ 'role' => 'contributor' ] ); + wp_set_current_user( $user_id ); + $_GET['_wpnonce'] = wp_create_nonce( 'rocketcdn_purge_cache' ); + + $this->assertFalse( current_user_can( 'manage_options' ) ); + + $this->expectException( WPDieException::class ); + do_action( 'admin_post_rocketcdn-purge-cache' ); + } + + public function testSetTransientAndRedirectWhenCurrentUserCan() { + // Set up everything. + $user_id = $this->factory->user->create( [ 'role' => 'administrator' ] ); + wp_set_current_user( $user_id ); + $_REQUEST['_wp_http_referer'] = addslashes( 'http://example.com/wp-admin/options-general.php?page=wprocket#page_cdn' ); + $_SERVER['REQUEST_URI'] = $_REQUEST['_wp_http_referer']; + $_GET['_wpnonce'] = wp_create_nonce( 'rocketcdn_purge_cache' ); + add_filter( 'wp_redirect', [ $this, 'return_empty_string' ] ); + + // Yes, we do expect wp_die() when running tests. + $this->expectException( WPDieException::class ); + + // Run it. + do_action( 'admin_post_rocketcdn-purge-cache' ); + + $this->assertTrue( current_user_can( 'manage_options' ) ); + + } + + public function return_empty_string() { + return ''; + } +} diff --git a/tests/Integration/src/Admin/Notices/Subscriber/emptyApiKeyNotice.php b/tests/Integration/src/Admin/Notices/Subscriber/emptyApiKeyNotice.php new file mode 100644 index 0000000..7a879b7 --- /dev/null +++ b/tests/Integration/src/Admin/Notices/Subscriber/emptyApiKeyNotice.php @@ -0,0 +1,59 @@ +option = $config['option']; + + $this->setCurrentUser( 'administrator' ); + + if ( false === $config['admin'] ) { + set_current_screen( 'front' ); + } + ob_start(); + + do_action( 'admin_notices' ); + + if ( $expected['contains'] ) { + $this->assertContains( ob_get_contents(), $expected ); + } else { + $this->assertNotContains( ob_get_contents(), $expected ); + } + ob_end_clean(); + } + + public function api_key() { + return $this->option['api_key']; + } + + public function providerTestData() { + $dir = dirname( __FILE__ ); + return $this->getTestData( $dir, 'emptyApiKeyNotice' ); + } +} diff --git a/tests/Integration/src/Admin/Notices/Subscriber/wrongApiKeyNotice.php b/tests/Integration/src/Admin/Notices/Subscriber/wrongApiKeyNotice.php new file mode 100644 index 0000000..dd9def6 --- /dev/null +++ b/tests/Integration/src/Admin/Notices/Subscriber/wrongApiKeyNotice.php @@ -0,0 +1,86 @@ +option = $config['option']; + + $this->setCurrentUser( 'administrator' ); + + $this->expectProcessGenerate($config, $expected); + + ob_start(); + + do_action( 'admin_notices' ); + + if ( $expected['contains'] ) { + $this->assertContains( $expected['html'], ob_get_contents() ); + } else { + $this->assertNotContains( $expected['html'], ob_get_contents() ); + } + ob_end_clean(); + } + + private function expectProcessGenerate( $config, $expected ) { + if ( ! isset( $config['process_generate'] ) ) { + return; + } + + $headers = [ + 'Authorization' => "token {$config['option']['api_key']}", + ]; + + if ( ! empty( $config['process_generate']['is_wp_error'] ) ) { + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( new WP_Error( 'error', 'error_data' ) ); + } else { + $response = $config['process_generate']['response']; + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( $response ); + } + } + + public function api_key() { + return $this->option['api_key']; + } + + public function providerTestData() { + $dir = dirname( __FILE__ ); + return $this->getTestData( $dir, 'wrongApiKeyNotice' ); + } +} diff --git a/tests/Integration/src/Admin/Settings/Subscriber/enqueueAssets.php b/tests/Integration/src/Admin/Settings/Subscriber/enqueueAssets.php new file mode 100644 index 0000000..6b75b2c --- /dev/null +++ b/tests/Integration/src/Admin/Settings/Subscriber/enqueueAssets.php @@ -0,0 +1,54 @@ +setRoleCap( 'administrator', 'rocket_manage_options' ); + } + + public function tear_down() { + parent::tear_down(); + + set_current_screen( 'front' ); + + $this->removeRoleCap( 'administrator', 'rocket_manage_options' ); + } + + + /** + * @dataProvider providerTestData + */ + public function testShouldMaybeEnqueueAssets( $config, $expected ) { + $this->setCurrentUser( 'administrator' ); + + set_current_screen( $config['hook'] ); + + do_action( 'admin_enqueue_scripts', $config['hook'] ); + $wp_styles = wp_styles(); + $wp_scripts = wp_scripts(); + $wp_scripts->init(); + if ( $expected ) { + $this->assertArrayHasKey( 'rocketcdn-settings', $wp_styles->registered ); + $this->assertArrayHasKey( 'rocketcdn_ajax', $wp_scripts->registered ); + $this->assertNotEmpty( $wp_scripts->registered['rocketcdn_ajax']->extra['data'] ); + } else { + $this->assertArrayNotHasKey( 'rocketcdn-settings', $wp_styles->registered ); + $this->assertArrayNotHasKey( 'rocketcdn_ajax', $wp_scripts->registered ); + } + } + + public function providerTestData() { + $dir = dirname( __FILE__ ); + return $this->getTestData( $dir, 'enqueueAssets' ); + } +} diff --git a/tests/Integration/src/Admin/Settings/Subscriber/purgeCache.php b/tests/Integration/src/Admin/Settings/Subscriber/purgeCache.php new file mode 100644 index 0000000..800a6da --- /dev/null +++ b/tests/Integration/src/Admin/Settings/Subscriber/purgeCache.php @@ -0,0 +1,107 @@ +user->create( [ 'role' => 'administrator' ] ); + } + + public function set_up() { + parent::set_up(); + add_filter( 'pre_option_rocketcdn_api_key', [ $this, 'api_key' ] ); + add_filter( 'pre_option_rocketcdn_cdn_url', [ $this, 'cdn_url' ] ); + $this->action = 'rocketcdn_purge_cache'; + } + + /** + * @dataProvider providerTestData + */ + public function testShouldMaybeClearCache( $config, $expected ) { + $this->setUserAndCapabilities( $config ); + $_POST['nonce'] = wp_create_nonce( 'rocketcdn_ajax' ); + $this->api = $config['api']; + $this->cdn = $config['cdn']; + + $this->expectProcessGenerate( $config, $expected ); + $response = $this->callAjaxAction(); + if ( $expected['bailout'] ) { + $this->assertFalse( $response->success ); + } else { + $this->assertTrue( $response->success ); + $this->assertSame( $expected['data']['status'], $response->data->status ); + } + } + + private function expectProcessGenerate( $config, $expected ) { + if ( ! isset( $config['process_generate'] ) ) { + return; + } + $headers = [ + 'Authorization' => "token {$config['api']}", + ]; + + if ( ! empty( $config['process_generate']['is_wp_error'] ) ) { + Functions\expect( 'wp_remote_request' ) + ->once() + ->with( + Client::ROCKETCDN_API . "website/{$this->cdn}/purge", + [ + 'method' => 'DELETE', + 'headers' => $headers, + ] + ) + ->andReturn( new WP_Error( 'error', 'error_data' ) ); + } else { + $message = $config['process_generate']['response']; + Functions\expect( 'wp_remote_request' ) + ->once() + ->with( + Client::ROCKETCDN_API . "website/{$this->cdn}/purge", + [ + 'method' => 'DELETE', + 'headers' => $headers, + ] + ) + ->andReturn( [ 'body' => $message ] ); + } + } + + public function setUserAndCapabilities( $config ) { + if ( ! empty( $config['can_manage_options'] ) ) { + $this->setRoleCap( 'administrator', 'manage_options' ); + } + + wp_set_current_user( self::$admin_user_id ); + } + + public function providerTestData() { + $dir = dirname( __FILE__ ); + + return $this->getTestData( $dir, 'purgeCache' ); + } + + public function api_key() { + return $this->api; + } + + public function cdn_url() { + return $this->cdn; + } +} diff --git a/tests/Integration/src/Admin/Settings/Subscriber/updateApiKey.php b/tests/Integration/src/Admin/Settings/Subscriber/updateApiKey.php new file mode 100644 index 0000000..24b997a --- /dev/null +++ b/tests/Integration/src/Admin/Settings/Subscriber/updateApiKey.php @@ -0,0 +1,108 @@ +user->create( [ 'role' => 'administrator' ] ); + } + + public function set_up() { + parent::set_up(); + add_filter( 'pre_option_rocketcdn_api_key', [ $this, 'api_key' ] ); + $this->action = 'rocketcdn_update_key'; + delete_transient( 'rocketcdn_customer_data' ); + } + + public function testCallbackIsRegistered() { + $this->assertCallbackRegistered( 'wp_ajax_rocketcdn_validate_key', 'validate_api_key' ); + } + + public function tear_down() { + + parent::tear_down(); + delete_transient( 'rocketcdn_customer_data' ); + remove_filter( 'pre_option_rocketcdn_api_key', [ $this, 'api_key' ] ); + } + + /** + * @dataProvider providerTestData + */ + public function testShouldMaybeChangeAPIKey( $config, $expected ) { + $this->setUserAndCapabilities( $config ); + + $_POST['api_key'] = $config['api']; + $_POST['nonce'] = wp_create_nonce( 'rocketcdn_ajax' ); + + if ( isset( $config['rocketcdn_customer_data'] ) ) { + set_transient( 'rocketcdn_customer_data', $config['rocketcdn_customer_data'], HOUR_IN_SECONDS ); + } + + $this->expectProcessGenerate( $config, $expected ); + $response = $this->callAjaxAction(); + + if ( $expected['bailout'] ) { + $this->assertFalse( $response->success ); + } else { + $this->assertTrue( $response->success ); + $this->assertSame( $expected['data']['status'], $response->data->status ); + } + } + + private function expectProcessGenerate( $config, $expected ) { + if ( ! isset( $config['process_generate'] ) ) { + return; + } + $headers = [ + 'Authorization' => "token {$config['api']}", + ]; + + if ( ! empty( $config['process_generate']['is_wp_error'] ) ) { + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( new WP_Error( 'error', 'error_data' ) ); + } else { + $message = $config['process_generate']['response']; + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( [ 'body' => $message ] ); + } + } + + public function setUserAndCapabilities( $config ) { + if ( ! empty( $config['can_manage_options'] ) ) { + $this->setRoleCap( 'administrator', 'manage_options' ); + } + + wp_set_current_user( self::$admin_user_id ); + } + + public function api_key() { + return $this->api_key; + } + + + public function providerTestData() { + $dir = dirname( __FILE__ ); + + return $this->getTestData( $dir, 'updateApiKey' ); + } +} diff --git a/tests/Integration/src/Admin/Settings/Subscriber/validateApiKey.php b/tests/Integration/src/Admin/Settings/Subscriber/validateApiKey.php new file mode 100644 index 0000000..5b6a7d7 --- /dev/null +++ b/tests/Integration/src/Admin/Settings/Subscriber/validateApiKey.php @@ -0,0 +1,109 @@ +user->create( [ 'role' => 'administrator' ] ); + } + + public function set_up() { + parent::set_up(); + add_filter( 'pre_option_rocketcdn_api_key', [ $this, 'api_key' ] ); + $this->action = 'rocketcdn_validate_key'; + delete_transient( 'rocketcdn_customer_data' ); + } + + public function testCallbackIsRegistered() { + $this->assertCallbackRegistered( 'wp_ajax_rocketcdn_validate_key', 'validate_api_key' ); + } + + public function tear_down() { + + parent::tear_down(); + delete_transient( 'rocketcdn_customer_data' ); + remove_filter( 'pre_option_rocketcdn_api_key', [ $this, 'api_key' ] ); + } + + /** + * @dataProvider providerTestData + */ + public function testShouldMaybeChangeAPIKey( $config, $expected ) { + + $this->setUserAndCapabilities( $config ); + + $_POST['api_key'] = $config['api']; + $_POST['nonce'] = wp_create_nonce( 'rocketcdn_ajax' ); + + if ( isset( $config['rocketcdn_customer_data'] ) ) { + set_transient( 'rocketcdn_customer_data', $config['rocketcdn_customer_data'], HOUR_IN_SECONDS ); + } + + $this->expectProcessGenerate( $config, $expected ); + $response = $this->callAjaxAction(); + + if ( $expected['bailout'] ) { + $this->assertFalse( $response->success ); + } else { + $this->assertTrue( $response->success ); + $this->assertSame( $expected['data']['status'], $response->data->status ); + } + } + + private function expectProcessGenerate( $config, $expected ) { + if ( ! isset( $config['process_generate'] ) ) { + return; + } + $headers = [ + 'Authorization' => "token {$config['api']}", + ]; + + if ( ! empty( $config['process_generate']['is_wp_error'] ) ) { + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( new WP_Error( 'error', 'error_data' ) ); + } else { + $message = $config['process_generate']['response']; + Functions\expect( 'wp_remote_get' ) + ->once() + ->with( Client::ROCKETCDN_API . 'customer/me', [ 'headers' => $headers ] ) + ->andReturn( [ 'body' => $message ] ); + } + } + + public function setUserAndCapabilities( $config ) { + if ( ! empty( $config['can_manage_options'] ) ) { + $this->setRoleCap( 'administrator', 'manage_options' ); + } + + wp_set_current_user( self::$admin_user_id ); + } + + public function api_key() { + return $this->api_key; + } + + + public function providerTestData() { + $dir = dirname( __FILE__ ); + + return $this->getTestData( $dir, 'validateApiKey' ); + } +} diff --git a/tests/Integration/src/Front/CDN/Subscriber/addPreconnectCdn.php b/tests/Integration/src/Front/CDN/Subscriber/addPreconnectCdn.php new file mode 100644 index 0000000..f3ae6ff --- /dev/null +++ b/tests/Integration/src/Front/CDN/Subscriber/addPreconnectCdn.php @@ -0,0 +1,52 @@ +unregisterAllCallbacksExcept( 'wp_resource_hints', 'add_preconnect_cdn', 10 ); + + parent::set_up(); + } + + public function tear_down() { + $this->restoreWpFilter( 'wp_resource_hints' ); + + parent::tear_down(); + } + + /** + * @dataProvider providerTestData + */ + public function testShouldAddPreconnectCdn( $config, $expected ) { + $this->cdn_url = $config['cdn_url']; + + add_filter( 'pre_option_rocketcdn_cdn_url', [ $this, 'setCdnUrl' ] ); + + ob_start(); + wp_resource_hints(); + + $this->assertSame( + $this->format_the_html( $expected['html'] ), + $this->format_the_html( ob_get_clean() ) + ); + } + + public function providerTestData() { + return $this->getTestData( __DIR__, 'addPreconnectCdn' ); + } + + public function setCdnUrl() { + return $this->cdn_url; + } +} diff --git a/tests/SettingsTrait.php b/tests/SettingsTrait.php new file mode 100644 index 0000000..4e25462 --- /dev/null +++ b/tests/SettingsTrait.php @@ -0,0 +1,37 @@ +old_settings = array_key_exists( 'settings', $this->config ) + ? array_merge( self::$before_settings, $this->config['settings'] ) + : self::$before_settings; + update_option( 'wp_rocket_settings', $this->old_settings ); + } + + public function tearDownSettings() { + delete_option( 'wp_rocket_settings' ); + } + + public function mergeExistingSettingsAndUpdate( array $settings ) { + update_option( + 'wp_rocket_settings', + array_merge( $this->old_settings, $settings ) + ); + } +} diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php new file mode 100644 index 0000000..81c2214 --- /dev/null +++ b/tests/Unit/TestCase.php @@ -0,0 +1,36 @@ +config ) ) { + $this->loadTestDataConfig(); + } + + parent::setUp(); + } + + public function configTestData() { + if ( empty( $this->config ) ) { + $this->loadTestDataConfig(); + } + + return isset( $this->config['test_data'] ) + ? $this->config['test_data'] + : $this->config; + } + + protected function loadTestDataConfig() { + $obj = new ReflectionObject( $this ); + $filename = $obj->getFileName(); + + $this->config = $this->getTestData( dirname( $filename ), basename( $filename, '.php' ) ); + } +} diff --git a/tests/Unit/bootstrap.php b/tests/Unit/bootstrap.php new file mode 100644 index 0000000..7df09f9 --- /dev/null +++ b/tests/Unit/bootstrap.php @@ -0,0 +1,14 @@ + + + + + + src + + + + + + ../../src + + + diff --git a/tests/Unit/src/API/Client/getCustomerData.php b/tests/Unit/src/API/Client/getCustomerData.php new file mode 100644 index 0000000..3a1d028 --- /dev/null +++ b/tests/Unit/src/API/Client/getCustomerData.php @@ -0,0 +1,77 @@ +client = new Client( $options_api ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config, $expected ) { + Functions\expect( 'get_transient' ) + ->once() + ->with( 'rocketcdn_customer_data' ) + ->andReturn( $config['cache'] ); + + if ( ! $config['cache'] && $config['api'] ) { + Functions\expect( 'wp_remote_get' ) + ->once()->with( $config['url'], $config['headers'] )->andReturn( $config['response'] ); + + Functions\expect( 'wp_remote_retrieve_response_code' ) + ->once()->with( $config['response'] )->andReturn( $config['code'] ); + + Functions\expect( 'apply_filters' ) + ->once()->with( 'rocketcdn_base_api_url', Client::ROCKETCDN_API )->andReturn( $config['baseurl'] ); + } else { + Functions\expect( 'wp_remote_get' ) + ->never(); + + Functions\expect( 'wp_remote_retrieve_response_code' ) + ->never(); + + Functions\expect( 'apply_filters' ) + ->never(); + } + + if ( $config['requestsucceed'] ) { + Functions\expect( 'wp_remote_retrieve_body' ) + ->once()->with( $config['response'] )->andReturn( $config['body'] ); + } else { + Functions\expect( 'wp_remote_retrieve_body' ) + ->never(); + } + + if ( $config['requestsucceed'] && count( $expected ) > 0 ) { + Functions\expect( 'set_transient' ) + ->once()->with( 'rocketcdn_customer_data', $expected, 2 * DAY_IN_SECONDS ); + } else { + Functions\expect( 'set_transient' ) + ->never(); + } + + $this->assertEquals( $expected, $this->client->get_customer_data( $config['api'] ) ); + } + + +} diff --git a/tests/Unit/src/API/Client/getWebsiteCdnUrl.php b/tests/Unit/src/API/Client/getWebsiteCdnUrl.php new file mode 100644 index 0000000..fd6652d --- /dev/null +++ b/tests/Unit/src/API/Client/getWebsiteCdnUrl.php @@ -0,0 +1,39 @@ +client = Mockery::mock( Client::class . '[get_customer_data]', [ $options_api ] ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExpected( $config, $expected ) { + Functions\expect( 'home_url' ) + ->with() + ->andReturn( $config['homeurl'] ); + Functions\expect( 'wp_parse_url' ) + ->with( $config['homeurl'], PHP_URL_HOST ) + ->andReturn( $config['hostname'] ); + $this->client->expects()->get_customer_data()->andReturn( $config['customerdata'] ); + $this->assertEquals( $expected, $this->client->get_website_cdn_url() ); + } +} diff --git a/tests/Unit/src/API/Client/isWebsiteSync.php b/tests/Unit/src/API/Client/isWebsiteSync.php new file mode 100644 index 0000000..432a4d5 --- /dev/null +++ b/tests/Unit/src/API/Client/isWebsiteSync.php @@ -0,0 +1,38 @@ +client = Mockery::mock( Client::class . '[get_customer_data]', [ $options_api ] ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config, $expected ) { + Functions\expect( 'home_url' ) + ->with() + ->andReturn( $config['homeurl'] ); + Functions\expect( 'wp_parse_url' ) + ->with( $config['homeurl'], PHP_URL_HOST ) + ->andReturn( $config['hostname'] ); + $this->client->expects()->get_customer_data( $config['api'] )->andReturn( $config['customerdata'] ); + $this->assertEquals( $expected, $this->client->is_website_sync( $config['api'] ) ); + } +} diff --git a/tests/Unit/src/API/Client/purgeCache.php b/tests/Unit/src/API/Client/purgeCache.php new file mode 100644 index 0000000..a3af076 --- /dev/null +++ b/tests/Unit/src/API/Client/purgeCache.php @@ -0,0 +1,63 @@ +expects()->get( 'api_key' )->andReturn( $config['api'] ); + if ( $config['api'] ) { + $options_api->expects()->get( 'cdn_url' )->andReturn( $config['cdn'] ); + } else { + $options_api->expects()->get( 'cdn_url' )->never(); + } + $client = new Client( $options_api ); + Functions\expect( '__' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + if ( $config['api'] && $config['cdn'] ) { + Functions\expect( 'wp_remote_request' ) + ->once()->with( $config['url'], $config['headers'] )->andReturn( $config['response'] ); + + Functions\expect( 'wp_remote_retrieve_response_code' ) + ->once()->with( $config['response'] )->andReturn( $config['code'] ); + + Functions\expect( 'apply_filters' ) + ->once()->with( 'rocketcdn_base_api_url', Client::ROCKETCDN_API )->andReturn( $config['baseurl'] ); + } else { + Functions\expect( 'wp_remote_get' ) + ->never(); + + Functions\expect( 'wp_remote_retrieve_response_code' ) + ->never(); + + Functions\expect( 'apply_filters' ) + ->never(); + } + + if ( $config['requestsucceed'] ) { + Functions\expect( 'wp_remote_retrieve_body' ) + ->once()->with( $config['response'] )->andReturn( $config['body'] ); + } else { + Functions\expect( 'wp_remote_retrieve_body' ) + ->never(); + } + + $this->assertEquals( $expected, $client->purge_cache() ); + } +} diff --git a/tests/Unit/src/Admin/AdminBar/AdminBar/addAdminBarMenu.php b/tests/Unit/src/Admin/AdminBar/AdminBar/addAdminBarMenu.php new file mode 100644 index 0000000..fc95a5e --- /dev/null +++ b/tests/Unit/src/Admin/AdminBar/AdminBar/addAdminBarMenu.php @@ -0,0 +1,71 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->admin_bar = Mockery::mock( WP_Admin_Bar::class ); + $this->admin_bar_menu = new AdminBar( $this->options, $this->client, '/' ); + parent::setUp(); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + Functions\expect( '__' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + Functions\expect( 'admin_url' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + Functions\expect( 'wp_nonce_url' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + Functions\expect( 'wp_unslash' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + Functions\expect( 'is_admin' ) + ->with() + ->andReturn( $config['is_admin'] ); + + if ( $config['is_admin'] ) { + Functions\expect( 'current_user_can' ) + ->with( 'manage_options' ) + ->andReturn( $config['has_right'] ); + } + if ( $config['has_right'] ) { + $this->options->expects()->get( 'api_key', '' )->andReturn( $config['api'] ); + } + if ( $config['api'] ) { + $this->client->expects()->get_customer_data( $config['api'] )->andReturn( $config['data'] ); + } + + $_SERVER['REQUEST_URI'] = $config['request_uri']; + + foreach ( $expected as $node ) { + $this->admin_bar->expects()->add_node( $node ); + } + if ( count( $expected ) == 0 ) { + $this->admin_bar->shouldReceive( 'addNode' )->never(); + } + + $this->admin_bar_menu->add_admin_bar_menu( $this->admin_bar ); + } +} diff --git a/tests/Unit/src/Admin/AdminBar/AdminBar/enqueueStyle.php b/tests/Unit/src/Admin/AdminBar/AdminBar/enqueueStyle.php new file mode 100644 index 0000000..aa6310d --- /dev/null +++ b/tests/Unit/src/Admin/AdminBar/AdminBar/enqueueStyle.php @@ -0,0 +1,28 @@ +with( $expected['id'], $expected['path'], $expected['options'], $expected['version'] ); + $admin_bar->enqueue_style(); + } +} diff --git a/tests/Unit/src/Admin/AdminBar/AdminBar/purgeCache.php b/tests/Unit/src/Admin/AdminBar/AdminBar/purgeCache.php new file mode 100644 index 0000000..3f721b1 --- /dev/null +++ b/tests/Unit/src/Admin/AdminBar/AdminBar/purgeCache.php @@ -0,0 +1,76 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->admin_bar_menu = Mockery::mock( AdminBar::class . '[exit]', [ $this->options, $this->client, '/' ] ) + ->shouldAllowMockingProtectedMethods(); + parent::setUp(); + } + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + $_GET['_wpnonce'] = $config['nonce']; + + Functions\expect( 'wp_verify_nonce' ) + ->with() + ->andReturn( $config['is_nonce_valid'] ); + + Functions\expect( 'sanitize_key' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + + Functions\expect( 'esc_url_raw' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + + if ( ! $config['nonce'] || ! $config['is_nonce_valid'] ) { + Functions\expect( 'wp_nonce_ays' ) + ->with( '' ); + } else { + Functions\expect( 'wp_nonce_ays' )->never(); + } + + if ( $config['nonce'] && $config['is_nonce_valid'] ) { + Functions\expect( 'current_user_can' ) + ->with( 'manage_options' )->andReturn( $config['has_right'] ); + } else { + Functions\expect( 'current_user_can' )->never(); + } + + if ( $config['has_right'] ) { + $this->client->expects()->purge_cache(); + Functions\expect( 'wp_get_referer' )->andReturn( $config['referer'] ); + Functions\expect( 'wp_safe_redirect' )->with( $config['referer'] ); + $this->admin_bar_menu->expects()->exit(); + Functions\expect( 'wp_die')->never(); + } else { + if($config['nonce'] && $config['is_nonce_valid'] ) { + Functions\expect( 'wp_die')->with(); + } else { + Functions\expect( 'wp_die')->never(); + } + } + + $this->admin_bar_menu->purge_cache(); + } +} diff --git a/tests/Unit/src/Admin/Notices/Notices/emptyApiKeyNotice.php b/tests/Unit/src/Admin/Notices/Notices/emptyApiKeyNotice.php new file mode 100644 index 0000000..831b659 --- /dev/null +++ b/tests/Unit/src/Admin/Notices/Notices/emptyApiKeyNotice.php @@ -0,0 +1,50 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->notices = new Notices( $this->options, $this->client ); + parent::setUp(); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + if ( $config['has_rights'] ) { + $this->options->expects()->get( 'api_key' )->andReturn( $config['api'] ); + } + Functions\expect( '__' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + Functions\expect( 'admin_url' ) + ->with( 'options-general.php?page=rocketcdn' ) + ->andReturn( $config['admin_url'] ); + Functions\expect( 'current_user_can' ) + ->with( 'manage_options' ) + ->andReturn( $config['has_rights'] ); + ob_start(); + $this->notices->empty_api_key_notice(); + $this->assertContains( ob_get_contents(), $expected ); + ob_end_clean(); + } +} diff --git a/tests/Unit/src/Admin/Notices/Notices/wrongApiKeyNotice.php b/tests/Unit/src/Admin/Notices/Notices/wrongApiKeyNotice.php new file mode 100644 index 0000000..eb59206 --- /dev/null +++ b/tests/Unit/src/Admin/Notices/Notices/wrongApiKeyNotice.php @@ -0,0 +1,52 @@ +options = Mockery::mock( \RocketCDN\Options\Options::class ); + $this->client = Mockery::mock( \RocketCDN\API\Client::class ); + $this->notices = new Notices( $this->options, $this->client ); + parent::setUp(); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + Functions\expect( 'current_user_can' ) + ->with( 'manage_options' ) + ->andReturn( $config['has_rights'] ); + + Functions\expect( '__' )->zeroOrMoreTimes() + ->andReturnFirstArg(); + + if ( $config['has_rights'] ) { + $this->options->expects()->get( 'api_key', '' )->andReturn( $config['api'] ); + } + + if ( $config['api'] ) { + $this->client->expects()->get_customer_data( $config['api'] )->andReturn( $config['data'] ); + } + + ob_start(); + $this->notices->wrong_api_key_notice(); + $this->assertContains( ob_get_contents(), $expected ); + ob_end_clean(); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/configureSettings.php b/tests/Unit/src/Admin/Settings/Page/configureSettings.php new file mode 100644 index 0000000..9bbfad5 --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/configureSettings.php @@ -0,0 +1,39 @@ +client = Mockery::mock( Client::class ); + $this->page = new Page( $options_api, $this->client, '/', '/' ); + } + + public function testShouldRegister() { + Functions\expect( 'register_setting' ) + ->with( + 'rocketcdn', + 'rocketcdn_api_key', + [ + 'sanitize_callback' => 'sanitize_key', + ] + ); + $this->page->configure_settings(); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/enqueueAssets.php b/tests/Unit/src/Admin/Settings/Page/enqueueAssets.php new file mode 100644 index 0000000..67e78de --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/enqueueAssets.php @@ -0,0 +1,51 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->page = new Page( $this->options, $this->client, WP_ROCKET_CDN_PLUGIN_ROOT . '/views/', '/' ); + } + /** + * @dataProvider configTestData + */ + public function testShouldMaybeRegister( $config, $expected ) { + if ( $config['should_register'] ) { + Functions\expect( 'wp_create_nonce' ) + ->with( 'rocketcdn_ajax' ) + ->andReturn( 'nonce' ); + Functions\expect( 'wp_enqueue_style' )->with( $expected['style']['id'], $expected['style']['url'], $expected['style']['dependencies'], $expected['version'] ); + Functions\expect( 'wp_enqueue_script' )->with( $expected['script']['id'], $expected['script']['url'], $expected['script']['dependencies'], $expected['version'], true ); + Functions\expect( 'wp_localize_script' )->with( + $expected['localize']['handle'], + $expected['localize']['object'], + [ + 'nonce' => 'nonce', + ] + ); + }else { + Functions\expect( 'wp_enqueue_style' )->never(); + Functions\expect( 'wp_enqueue_script' )->never(); + Functions\expect( 'wp_localize_script' )->never(); + } + $this->page->enqueue_assets( $config['hook'] ); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/purgeCache.php b/tests/Unit/src/Admin/Settings/Page/purgeCache.php new file mode 100644 index 0000000..2335366 --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/purgeCache.php @@ -0,0 +1,45 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->page = new Page( $this->options, $this->client, WP_ROCKET_CDN_PLUGIN_ROOT . '/views/', '/' ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config, $expected ) { + Functions\expect( '__' )->zeroOrMoreTimes()->andReturnFirstArg(); + Functions\expect( 'current_user_can' )->with( 'manage_options' )->andReturn( $config['has_right'] ); + Functions\expect( 'check_ajax_referer' ); + if ( $config['has_right'] ) { + $this->client->expects()->purge_cache()->andReturn( $config['response'] ); + } + if ( $expected['success'] ) { + Functions\expect( 'wp_send_json_success' )->with( $expected['message'] ); + } else { + Functions\expect( 'wp_send_json_error' )->with( $expected['message'] ); + } + $this->page->purge_cache(); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/renderPage.php b/tests/Unit/src/Admin/Settings/Page/renderPage.php new file mode 100644 index 0000000..a91d5a9 --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/renderPage.php @@ -0,0 +1,51 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->page = new Page( $this->options, $this->client, WP_ROCKET_CDN_PLUGIN_ROOT . '/views/', '/' ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config, $expected ) { + Functions\expect( '__' )->andReturnFirstArg()->zeroOrMoreTimes(); + Functions\expect( 'esc_html__' )->andReturnFirstArg()->zeroOrMoreTimes(); + Functions\expect( 'esc_url' )->andReturnFirstArg()->zeroOrMoreTimes(); + Functions\expect( 'esc_html' )->andReturnFirstArg()->zeroOrMoreTimes(); + Functions\expect( 'esc_html_e' )->andReturnFirstArg()->zeroOrMoreTimes(); + Functions\expect( 'esc_attr' )->andReturnFirstArg()->zeroOrMoreTimes(); + Functions\expect( 'get_admin_page_title' )->andReturn( $config['title'] )->zeroOrMoreTimes(); + Functions\expect( 'settings_fields' )->with( 'rocketcdn' )->andReturn( $config['configs'] )->zeroOrMoreTimes(); + $this->options->shouldReceive( 'get' )->with( 'api_key' )->andReturn( $config['api'] )->twice(); + $this->options->shouldReceive( 'get' )->with( 'cdn_url' )->andReturn( $config['api'] )->zeroOrMoreTimes(); + if ( $config['api'] ) { + $this->client->expects()->is_website_sync( $config['api'] )->andReturn( $config['is_sync'] ); + } + ob_start(); + $this->page->render_page(); + $this->assertEquals( $this->format_the_html( ob_get_contents() ), $this->format_the_html( $expected ) ); + ob_end_clean(); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/saveCdnUrl.php b/tests/Unit/src/Admin/Settings/Page/saveCdnUrl.php new file mode 100644 index 0000000..edccdca --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/saveCdnUrl.php @@ -0,0 +1,37 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->page = new Page( $this->options, $this->client, WP_ROCKET_CDN_PLUGIN_ROOT . '/views/', '/' ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config ) { + $this->client->expects()->get_website_cdn_url()->andReturn( $config['cdn'] ); + if ( $config['cdn'] ) { + $this->options->expects()->set( 'cdn_url', $config['cdn'] ); + } + $this->page->save_cdn_url(); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/updateApiKey.php b/tests/Unit/src/Admin/Settings/Page/updateApiKey.php new file mode 100644 index 0000000..9d2e3fa --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/updateApiKey.php @@ -0,0 +1,55 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->page = new Page( $this->options, $this->client, WP_ROCKET_CDN_PLUGIN_ROOT . '/views/', '/' ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config, $expected ) { + $_POST['api_key'] = $config['api']; + Functions\expect( '__' )->zeroOrMoreTimes()->andReturnFirstArg(); + Functions\expect( 'sanitize_key' )->zeroOrMoreTimes()->andReturnFirstArg(); + Functions\expect( 'check_ajax_referer' ); + Functions\expect( 'current_user_can' )->with( 'manage_options' )->andReturn( $config['has_right'] ); + + if ( $config['api'] ) { + Functions\expect( 'delete_transient' )->with( 'rocketcdn_customer_data' ); + $this->client->expects()->get_customer_data( $config['api'] )->andReturn( $config['is_valid'] ); + } + if ( ! empty( $config['is_valid'] ) ) { + $this->client->expects()->is_website_sync( $config['api'] )->andReturn( $config['is_sync'] ); + } + + if ( $config['is_sync'] ) { + $this->options->expects()->set( 'api_key', $config['api'] ); + Functions\expect( 'wp_send_json_success' )->with( $expected['message'] ); + } else { + Functions\expect( 'wp_send_json_error' )->with( $expected['message'] ); + } + $this->page->update_api_key(); + } +} diff --git a/tests/Unit/src/Admin/Settings/Page/validateApiKey.php b/tests/Unit/src/Admin/Settings/Page/validateApiKey.php new file mode 100644 index 0000000..5932d17 --- /dev/null +++ b/tests/Unit/src/Admin/Settings/Page/validateApiKey.php @@ -0,0 +1,53 @@ +options = Mockery::mock( Options::class ); + $this->client = Mockery::mock( Client::class ); + $this->page = new Page( $this->options, $this->client, WP_ROCKET_CDN_PLUGIN_ROOT . '/views/', '/' ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExcepted( $config, $expected ) { + $_POST['api_key'] = $config['api']; + Functions\expect( '__' )->zeroOrMoreTimes()->andReturnFirstArg(); + Functions\expect( 'sanitize_key' )->zeroOrMoreTimes()->andReturnFirstArg(); + Functions\expect( 'check_ajax_referer' )->zeroOrMoreTimes(); + Functions\expect( 'current_user_can' )->with( 'manage_options' )->andReturn( $config['has_right'] ); + + if ( $config['api'] ) { + $this->client->expects()->get_customer_data( $config['api'] )->andReturn( $config['is_valid'] ); + } + if ( ! empty( $config['is_valid'] ) ) { + $this->client->expects()->is_website_sync( $config['api'] )->andReturn( $config['is_sync'] ); + } + + if ( $config['is_sync'] ) { + Functions\expect( 'wp_send_json_success' )->with(); + } else { + Functions\expect( 'wp_send_json_error' )->with( $expected['message'] ); + } + $this->page->validate_api_key(); + } +} diff --git a/tests/Unit/src/Front/CDN/addPreconnectCdn.php b/tests/Unit/src/Front/CDN/addPreconnectCdn.php new file mode 100644 index 0000000..650e904 --- /dev/null +++ b/tests/Unit/src/Front/CDN/addPreconnectCdn.php @@ -0,0 +1,37 @@ +options = Mockery::mock( Options::class ); + $this->cdn = Mockery::mock( CDN::class . '[should_rewrite]', [ $this->options ] )->shouldAllowMockingProtectedMethods(); + } + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + if ( $config['relation_type'] == 'preconnect' && $config['rewrite'] ) { + $this->options->expects()->get( 'cdn_url' )->andReturn( $config['cdn'] ); + } + if ( $config['relation_type'] == 'preconnect' ) { + $this->cdn->expects()->should_rewrite()->andReturn( $config['rewrite'] ); + } + $this->assertEquals( $expected, $this->cdn->add_preconnect_cdn( $config['urls'], $config['relation_type'] ) ); + } +} diff --git a/tests/Unit/src/Front/CDN/endBuffering.php b/tests/Unit/src/Front/CDN/endBuffering.php new file mode 100644 index 0000000..9e54aa9 --- /dev/null +++ b/tests/Unit/src/Front/CDN/endBuffering.php @@ -0,0 +1,86 @@ +options = Mockery::mock( Options::class ); + $this->cdn = Mockery::mock( CDN::class . '[rewrite_url]', [ $this->options ] ); + } + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + Functions\expect( 'home_url' ) + ->with() + ->andReturn( $config['homeurl'] ); + Functions\expect( 'content_url' ) + ->with() + ->andReturn( $config['wp-content'] ); + Functions\expect( 'includes_url' ) + ->with() + ->andReturn( $config['wp-includes'] ); + Functions\expect( 'home_url' ) + ->with() + ->andReturn( $config['homeurl'] ); + Functions\expect( 'wp_upload_dir' ) + ->with() + ->andReturn( $config['wp_upload_dir'] ); + Functions\expect( 'wp_parse_url' ) + ->with( $config['homeurl'], PHP_URL_HOST ) + ->andReturnFirstArg(); + Functions\expect( 'wp_parse_url' ) + ->andReturnUsing( + function ( $arg, $mode = null ) use ( $config ) { + if ( $mode == PHP_URL_PATH ) { + return $arg; + } + if ( $mode == PHP_URL_HOST ) { + return $config['hostname']; + } + return $arg; + } + ); + $this->cdn->shouldReceive( 'rewrite_url' )->atLeast()->once()->andReturnUsing( + function( $arg ) use ( $config ) { + // execute closure + if ( str_contains( $arg, $config['cdn'] ) ) { + return $arg; + } + if ( str_contains( $arg, 'http://' ) ) { + $v = str_replace( 'http://', 'http://' . $config['cdn'] . '.', $arg ); + } else { + if ( ! str_contains( $arg, 'https://' ) ) { + $v = 'http://' . $config['cdn'] . '.' . $config['hostname'] . $arg; + } else { + $v = str_replace( 'https://', 'http://' . $config['cdn'] . '.', $arg ); + } + } + return $v; + } + ); + $this->assertEquals( $expected, $this->cdn->end_buffering( $config['html'] ) ); + } +} diff --git a/tests/Unit/src/Front/CDN/rewriteUrl.php b/tests/Unit/src/Front/CDN/rewriteUrl.php new file mode 100644 index 0000000..5ee4284 --- /dev/null +++ b/tests/Unit/src/Front/CDN/rewriteUrl.php @@ -0,0 +1,50 @@ +options = Mockery::mock( Options::class ); + $this->cdn = new CDN( $this->options ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + $this->options->expects()->get( 'cdn_url' )->andReturn( $config['cdn'] ); + + Functions\expect( 'home_url' ) + ->with() + ->andReturn( $config['homeurl'] ); + + Functions\expect( 'wp_parse_url' ) + ->with( $config['url'] )->andReturnUsing( + function( $arg1, $arg2 = null ) use ( $config ) { + if ( $arg2 ) { + return $config['host']; + } + return $config['parsed_url']; + } + ); + + $this->assertEquals( $expected, $this->cdn->rewrite_url( $config['url'] ) ); + } +} diff --git a/tests/Unit/src/Front/CDN/startBuffering.php b/tests/Unit/src/Front/CDN/startBuffering.php new file mode 100644 index 0000000..8b372b3 --- /dev/null +++ b/tests/Unit/src/Front/CDN/startBuffering.php @@ -0,0 +1,45 @@ +cdn = new CDN( $options ); + } + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + if ( $config['has_request_method'] ) { + $_SERVER['REQUEST_METHOD'] = $config['request_method']; + } else { + unset( $_SERVER['REQUEST_METHOD'] ); + } + if ( $expected ) { + Functions\expect( 'ob_start' )->once(); + } else { + Functions\expect( 'ob_start' )->never(); + } + Functions\expect( 'is_admin' )->zeroOrMoreTimes()->andReturn( $config['is_admin'] ); + Functions\expect( 'is_customize_preview' )->zeroOrMoreTimes()->andReturn( $config['is_customize_preview'] ); + Functions\expect( 'is_embed' )->zeroOrMoreTimes()->andReturn( $config['is_embed'] ); + $this->cdn->start_buffering(); + } +} diff --git a/tests/Unit/src/Options/Options/delete.php b/tests/Unit/src/Options/Options/delete.php new file mode 100644 index 0000000..7015677 --- /dev/null +++ b/tests/Unit/src/Options/Options/delete.php @@ -0,0 +1,25 @@ +with( $expected ); + $option->delete( $config['name'] ); + } +} diff --git a/tests/Unit/src/Options/Options/get.php b/tests/Unit/src/Options/Options/get.php new file mode 100644 index 0000000..bf30126 --- /dev/null +++ b/tests/Unit/src/Options/Options/get.php @@ -0,0 +1,27 @@ +with( $config['option_name'], $config['default'] ) + ->andReturn( $config['option'] ); + $this->assertEquals( $expected, $option->get( $config['name'], $config['default'] ) ); + } +} diff --git a/tests/Unit/src/Options/Options/getOptionName.php b/tests/Unit/src/Options/Options/getOptionName.php new file mode 100644 index 0000000..c82fc8e --- /dev/null +++ b/tests/Unit/src/Options/Options/getOptionName.php @@ -0,0 +1,22 @@ +assertEquals( $expected, $option->get_option_name( $config['name'] ) ); + } +} diff --git a/tests/Unit/src/Options/Options/set.php b/tests/Unit/src/Options/Options/set.php new file mode 100644 index 0000000..7f3c588 --- /dev/null +++ b/tests/Unit/src/Options/Options/set.php @@ -0,0 +1,25 @@ +with( $expected['option_name'], $expected['value'] ); + $option->set( $config['name'], $config['value'] ); + } +} diff --git a/tests/patchwork.json b/tests/patchwork.json new file mode 100644 index 0000000..78458af --- /dev/null +++ b/tests/patchwork.json @@ -0,0 +1 @@ +{"redefinable-internals": ["ob_start", "exit"]}