diff --git a/.github/workflows/test-php.yml b/.github/workflows/test-php.yml index 7cc722ad..7ac4fbe8 100644 --- a/.github/workflows/test-php.yml +++ b/.github/workflows/test-php.yml @@ -8,7 +8,7 @@ concurrency: cancel-in-progress: true jobs: phplint: - name: Phplint + name: PHPCS on PHP 8.0 runs-on: ubuntu-latest steps: - name: Setup PHP version @@ -17,62 +17,45 @@ jobs: php-version: '8.0' extensions: simplexml - name: Checkout source code - uses: actions/checkout@v2 - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Setup Composer cache - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - name: Install composer + uses: actions/checkout@v4 + - name: Install Composer dependencies run: composer install --prefer-dist --no-progress --no-suggest - name: Run PHPCS - run: composer run lint + run: composer phpcs phpunit: - name: Phpunit + name: PHPUnit tests on ${{ matrix.php-versions }} runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: [ '7.4', '8.0', '8.1', '8.2', '8.3' ] services: - mysql: - image: mysql:5.7 + database: + image: mysql:latest env: + MYSQL_DATABASE: wordpress_tests MYSQL_ROOT_PASSWORD: root ports: - - 3306/tcp - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + - 3306:3306 steps: - name: Setup PHP version uses: shivammathur/setup-php@v2 with: - php-version: '8.0' + php-version: ${{ matrix.php-version }} extensions: simplexml, mysql - tools: phpunit-polyfills + tools: phpunit-polyfills:1.1 + - name: Install Subversion + run: sudo apt-get update && sudo apt-get install -y subversion - name: Checkout source code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Install WordPress Test Suite - run: | - bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:${{ job.services.mysql.ports['3306'] }} - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Setup Composer cache - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - name: Install composer - run: composer install --prefer-dist --no-progress --no-suggest --no-dev + run: composer install-wp-tests + - name: Install Composer dependencies + run: composer install --prefer-dist --no-progress --no-suggest - name: Run phpunit - run: phpunit + run: composer phpunit phpstan: - name: PHPStan + name: PHPStan on PHP 8.0 runs-on: ubuntu-latest steps: - name: Setup PHP version @@ -81,19 +64,8 @@ jobs: php-version: '8.0' extensions: simplexml, mysql - name: Checkout source code - uses: actions/checkout@v2 - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Setup Composer cache - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - name: Install composer + uses: actions/checkout@v4 + - name: Install Composer dependencies run: composer install --prefer-dist --no-progress --no-suggest - name: PHPStan Static Analysis run: composer phpstan \ No newline at end of file diff --git a/assets/src/dashboard/parts/connected/index.js b/assets/src/dashboard/parts/connected/index.js index 2c927ca2..0453819e 100644 --- a/assets/src/dashboard/parts/connected/index.js +++ b/assets/src/dashboard/parts/connected/index.js @@ -32,9 +32,9 @@ if ( 'undefined' !== typeof window && optimoleDashboardApp.user_data.plan ) { status: optimoleDashboardApp.user_data.status, language: optimoleDashboardApp.language, cname_assigned: optimoleDashboardApp.user_data.is_cname_assigned || 'no', - connected_websites: optimoleDashboardApp.user_data.whitelist.length.toString(), - traffic: convertToCategory( optimoleDashboardApp.user_data.traffic, 500 ).toString(), - images_number: convertToCategory( optimoleDashboardApp.user_data.images_number, 100 ).toString(), + connected_websites: optimoleDashboardApp.user_data.whitelist && optimoleDashboardApp.user_data.whitelist.length.toString(), + traffic: convertToCategory( optimoleDashboardApp.user_data.traffic || 0, 500 ).toString(), + images_number: convertToCategory( optimoleDashboardApp.user_data.images_number || 0, 100 ).toString(), days_since_install: convertToCategory( optimoleDashboardApp.days_since_install ).toString() } }); diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh index 1cd99ed0..6341bdca 100755 --- a/bin/install-wp-tests.sh +++ b/bin/install-wp-tests.sh @@ -12,21 +12,43 @@ DB_HOST=${4-localhost} WP_VERSION=${5-latest} SKIP_DB_CREATE=${6-false} -WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} +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} -command_exists() { - type -t "$1" >/dev/null 2>&1 -} download() { - if command_exists "curl"; then - curl -s -o "${2:--}" "$1" - elif command_exists "wget"; then - wget -nv -O "${2:--}" "$1" + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + else + echo "Error: Neither curl nor wget is installed." + exit 1 fi } -if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then - WP_TESTS_TAG="tags/$WP_VERSION" + +# Check if svn is installed +check_svn_installed() { + if ! command -v svn > /dev/null; then + echo "Error: svn is not installed. Please install svn and try again." + exit 1 + fi +} + +if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then + WP_BRANCH=${WP_VERSION%\-*} + WP_TESTS_TAG="branches/$WP_BRANCH" + +elif [[ $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 @@ -40,10 +62,8 @@ else fi WP_TESTS_TAG="tags/$LATEST_VERSION" fi - set -ex - install_wp() { if [ -d $WP_CORE_DIR ]; then @@ -53,27 +73,44 @@ install_wp() { mkdir -p $WP_CORE_DIR if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - mkdir -p /tmp/wordpress-nightly - download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip - unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ - mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR + mkdir -p $TMPDIR/wordpress-trunk + rm -rf $TMPDIR/wordpress-trunk/* + check_svn_installed + svn export --quiet https://core.svn.wordpress.org/trunk $TMPDIR/wordpress-trunk/wordpress + mv $TMPDIR/wordpress-trunk/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 /tmp/wordpress.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + 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 + download https://raw.githubusercontent.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' + local ioption='-i.bak' else local ioption='-i' fi @@ -82,8 +119,10 @@ install_test_suite() { 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 + rm -rf $WP_TESTS_DIR/{includes,data} + check_svn_installed + svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data fi if [ ! -f wp-tests-config.php ]; then @@ -91,6 +130,7 @@ install_test_suite() { # 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:__DIR__ . '/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 @@ -99,6 +139,23 @@ install_test_suite() { } +recreate_db() { + shopt -s nocasematch + if [[ $1 =~ ^(y|yes)$ ]] + then + mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA + create_db + echo "Recreated the database ($DB_NAME)." + else + echo "Leaving the existing database ($DB_NAME) in place." + fi + shopt -u nocasematch +} + +create_db() { + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + install_db() { if [ ${SKIP_DB_CREATE} = "true" ]; then @@ -122,7 +179,14 @@ install_db() { fi # create database - mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute "CREATE DATABASE IF NOT EXISTS $DB_NAME;" + if [ $(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep ^$DB_NAME$) ] + then + echo "Reinstalling will delete the existing test database ($DB_NAME)" + read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB + recreate_db $DELETE_EXISTING_DB + else + create_db + fi } install_wp diff --git a/composer.json b/composer.json index e55f605f..1404a98a 100644 --- a/composer.json +++ b/composer.json @@ -46,11 +46,10 @@ }, "scripts": { "format": "phpcbf --standard=phpcs.xml --report-summary --report-source", - "phpcs": "phpcs --standard=phpcs.xml --extensions=php -s", - "test": "[ -z \"$WP_TESTS_DIR\" ] || [ -z \"$WP_CORE_DIR\" ] && echo 'Error: Both WP_TESTS_DIR and WP_CORE_DIR must be defined.' && exit 1 || phpunit --configuration=phpunit.xml", - "lint": "composer run-script phpcs", - "phpstan": "phpstan analyse --memory-limit 2G", - "install-wp-tests": "bash bin/install-wp-tests.sh wordpress_test root '' localhost latest" + "phpcs": "phpcs --standard=phpcs.xml --extensions=php -s -d memory_limit=-1", + "phpstan": "phpstan analyse --memory-limit=-1", + "phpunit": "phpunit --configuration=phpunit.xml", + "install-wp-tests": "bash bin/install-wp-tests.sh wordpress_tests root root 127.0.0.1 latest true" }, "require": { "php": ">=7.4", diff --git a/composer.lock b/composer.lock index 28ece043..02bc7e25 100644 --- a/composer.lock +++ b/composer.lock @@ -64,20 +64,21 @@ }, { "name": "codeinwp/themeisle-sdk", - "version": "3.3.30", + "version": "3.3.32", "source": { "type": "git", "url": "https://github.com/Codeinwp/themeisle-sdk.git", - "reference": "801a07604a297f02de3067948176f91b4c84bd8a" + "reference": "422f55c1d5c99350b849ba63f456aec120400b76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/801a07604a297f02de3067948176f91b4c84bd8a", - "reference": "801a07604a297f02de3067948176f91b4c84bd8a", + "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/422f55c1d5c99350b849ba63f456aec120400b76", + "reference": "422f55c1d5c99350b849ba63f456aec120400b76", "shasum": "" }, "require-dev": { - "codeinwp/phpcs-ruleset": "dev-main" + "codeinwp/phpcs-ruleset": "dev-main", + "yoast/phpunit-polyfills": "^2.0" }, "type": "library", "notification-url": "https://packagist.org/downloads/", @@ -98,9 +99,9 @@ ], "support": { "issues": "https://github.com/Codeinwp/themeisle-sdk/issues", - "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.3.30" + "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.3.32" }, - "time": "2024-09-10T23:53:07+00:00" + "time": "2024-10-16T10:32:45+00:00" }, { "name": "enshrined/svg-sanitize", diff --git a/development.php b/development.php index 3c3290d9..601db978 100644 --- a/development.php +++ b/development.php @@ -4,12 +4,22 @@ * * @package ThemeIsle */ -if ( ! empty( getenv( 'WP_TESTS_DIR' ) ) ) { + +// This condition tries to detect if we're running PHPUnit. This is complex because the file is loaded via the +// composer autoloader. You can detect that 99% of the time because PHPUnit uses the constant +// PHPUNIT_COMPOSER_INSTALL to load the autoloader. That said, if you run a test in a separate process, it won't +// run that code again and the constant doesn't exist. As a fallback, we use the PHPUNIT_RUNNING environment variable +// defined in the phpunit.xml to detect if we're in a PHPUnit process. We can't always use the environment variable +// because by default PHPUnit loads the composer autoloader before it assigns those environment variables. That's +// why both conditions are needed. +if ( defined( 'PHPUNIT_COMPOSER_INSTALL' ) || getenv( 'PHPUNIT_RUNNING' ) ) { return; } + if ( ! defined( 'ENABLE_OPTIMOLE_WP_DEV' ) ) { define( 'ENABLE_OPTIMOLE_WP_DEV', true ); } + if ( ENABLE_OPTIMOLE_WP_DEV ) { $optiml_constants = [ 'OPTIML_API_ROOT' => 'https://staging-dashboard.optimole.com/api/', diff --git a/optimole-wp.php b/optimole-wp.php index 5d73050c..7f99d193 100644 --- a/optimole-wp.php +++ b/optimole-wp.php @@ -50,7 +50,7 @@ function optml_deactivate() { } /** - * Shows a notice for sites running PHP less than 5.4. + * Shows a notice for sites running PHP less than 7.4. */ function optml_php_notice() { ?> diff --git a/phpunit.xml b/phpunit.xml index 8aa68717..8492ff93 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,6 +6,10 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" > + + + + ./tests/ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index acf960e2..3e4a50c0 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,28 +1,30 @@ set_role( 'administrator' ); + wp_update_user( array( 'ID' => 1, 'first_name' => 'Admin', 'last_name' => 'User' ) ); \ No newline at end of file