Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .env.testing.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# WP-Browser configuration
# https://wpbrowser.wptestkit.dev/
# Copy to .env.testing and adjust for your environment.
# These defaults match the reusable codecoverage workflow (MySQL service on 33306, MYSQL_DATABASE=tests-wordpress).

WP_ROOT_FOLDER="wordpress"

TEST_DB_HOST="127.0.0.1"
TEST_DB_PORT="33306"
TEST_DB_USER="root"
TEST_DB_PASSWORD="password"

TEST_DB_NAME="tests-wordpress"
TEST_TABLE_PREFIX="wp_"

TEST_SITE_WP_DOMAIN="localhost:8888"
TEST_SITE_ADMIN_EMAIL="admin@example.org"
194 changes: 22 additions & 172 deletions .github/workflows/codecoverage-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,179 +13,29 @@ on:
- main
workflow_dispatch:

jobs:
permissions:
contents: read

codecoverage:
jobs:
get-repo-name:
runs-on: ubuntu-latest

services:
mysql:
image: mysql:5.7 # Password auth did not work on 8.0 on PHP 7.3, it did seem to work for PHP 7.4+
env: # These are the same username and password as the wp-env container defaults
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: tests-wordpress
ports: # This mapping matches the .wp-env.json configuration
- 33306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

strategy:
matrix: # Supported PHP versions
php: [ '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]

outputs:
repository-name: ${{ steps.repo-name.outputs.name }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0 # attempting to get all branch names.

# TODO: a DEPLOY_KEY is needed to enable gh-pages for the first time (the branch can be created and pushed but
# it will not be reachable as a website).
# Consider @see https://github.com/peaceiris/actions-gh-pages
# - name: Check does gh-pages branch need to be created
# run: |
# git branch -l;
# if [[ $(git branch -l gh-pages) == "" ]]; then
# gh_pages_branch_needed=true;
# echo "gh-pages branch is needed";
# else
# gh_pages_branch_needed=false
# echo "gh-pages branch already exists";
# fi
# echo "GH_PAGES_BRANCH_NEEDED=$gh_pages_branch_needed" >> $GITHUB_ENV;
# mkdir gh-pages
#
# - name: Maybe create gh-pages branch
# if: ${{ env.GH_PAGES_BRANCH_NEEDED }}
# uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
# with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_dir: ./gh-pages
# force_orphan: true
# allow_empty_commit: true
# commit_message: "🤖 Creating gh-pages branch"

- name: Checkout GitHub Pages branch for code coverage report
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: gh-pages
path: gh-pages

- name: Install PHP
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
with:
php-version: ${{ matrix.php }}
coverage: xdebug
tools: composer, jaschilz/php-coverage-badger
extensions: zip

- name: Read .env.testing
uses: c-py/action-dotenv-to-setenv@925b5d99a3f1e4bd7b4e9928be4e2491e29891d9 # v5
with:
env-file: .env.testing

- name: Run composer install
continue-on-error: true
run: composer install -v

- name: Allow writing to wp-content
if: ${{ hashFiles('wp-content') != '' }} # TODO: This may be incorrect since it's a directory.
run: sudo chmod -R a+w wp-content

# On main, there will be a previous coverage report. On PRs we create a new directory using the commit SHA.
- name: Clear previous code coverage
if: ${{ (matrix.php == '7.3') && (github.ref == 'refs/heads/main') }}
run: |
rm -rf gh-pages/phpunit || true;
mkdir gh-pages/phpunit || true;
- name: Extract repository name
id: repo-name
run: echo "name=$(echo ${{ github.repository }} | cut -d'/' -f2)" >> $GITHUB_OUTPUT

- name: Run unit tests
if: ${{ hashFiles('tests/phpunit/bootstrap.php') != '' }} # Only run unit tests if they are present.
run: XDEBUG_MODE=coverage vendor/bin/phpunit --bootstrap tests/phpunit/bootstrap.php --coverage-php tests/_output/unit.cov --debug

- name: Run wpunit tests
run: XDEBUG_MODE=coverage vendor/bin/codecept run wpunit --coverage tests/_output/wpunit.cov --debug

# For PRs, we'll generate the coverage report on each pushed commit
- name: Merge code coverage for PR
if: ${{ matrix.php == '7.3' && github.event_name == 'pull_request' }}
run: |
vendor/bin/phpcov merge --clover clover.xml tests/_output/;
vendor/bin/phpcov merge --clover gh-pages/${{ github.event.pull_request.head.sha }}/phpunit/clover.xml --php gh-pages/${{ github.event.pull_request.head.sha }}/phpunit/phpunit.cov --html gh-pages/${{ github.event.pull_request.head.sha }}/phpunit/html/ tests/_output/;

# On main, we want it output to a different path
- name: Merge code coverage for main
if: ${{ (matrix.php == '7.3') && (github.ref == 'refs/heads/main') }}
run: |
vendor/bin/phpcov merge --clover clover.xml tests/_output/;
vendor/bin/phpcov merge --clover gh-pages/phpunit/clover.xml --php gh-pages/phpunit/phpunit.cov --html gh-pages/phpunit/html/ tests/_output/;

# This makes the coverage percentage available in `{{ steps.coverage-percentage.outputs.coverage-rounded }}`.
- name: Check test coverage
if: ${{ matrix.php == '7.3' }}
uses: johanvanhelden/gha-clover-test-coverage-check@2543c79a701f179bd63aa14c16c6938c509b2cec # v1
id: coverage-percentage
with:
percentage: 25
exit: false
filename: clover.xml
rounded-precision: "0"

# See: https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/
- name: Add `.nojekyll` file so code coverage report successfully deploys to gh-pages
if: ${{ (matrix.php == '7.3') }}
working-directory: gh-pages
run: |
touch .nojekyll
git add -- .nojekyll *

- name: Update README coverage badge
if: ${{ (matrix.php == '7.3') && (github.ref == 'refs/heads/main') }} # only commit on main, on the PHP version we're using in production.
run: php-coverage-badger clover.xml gh-pages/phpunit/coverage.svg

- name: Generate PR coverage badge
if: ${{ (matrix.php == '7.3') && github.event_name == 'pull_request' }}
run: php-coverage-badger clover.xml gh-pages/${{ github.event.pull_request.head.sha }}/phpunit/coverage.svg

- name: Commit code coverage to gh-pages
if: ${{ matrix.php == '7.3' }}
uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
with:
repository: gh-pages
branch: gh-pages
commit_message: ${{ format('🤖 Save code coverage report to gh-pages {0}%', steps.coverage-percentage.outputs.coverage-rounded) }}
commit_options: ""
env:
GITHUB_TOKEN: "${{ github.token }}"

- name: Add coverage badge to PR comment
if: ${{ matrix.php == '7.3' && github.event_name == 'pull_request' }}
run: |
echo "[![Code Coverage ](https://newfold-labs.github.io/wp-module-performance/${{ github.event.pull_request.head.sha }}/phpunit/coverage.svg)](https://newfold-labs.github.io/wp-module-performance/${{ github.event.pull_request.head.sha }}/phpunit/html/)" >> coverage-comment.md
echo "" >> coverage-comment.md
echo "" >> coverage-comment.md

- name: Add coverage report link to PR comment
if: ${{ matrix.php == '7.3' && github.event_name == 'pull_request' }}
run: |
echo "${{ format('[project coverage report {0}%](https://newfold-labs.github.io/wp-module-performance/{1}/phpunit/html/) @ {2}', steps.coverage-percentage.outputs.coverage-rounded, github.event.pull_request.head.sha, github.event.pull_request.head.sha) }}" >> coverage-comment.md
echo "" >> coverage-comment.md
echo "" >> coverage-comment.md

- name: Add phpcov uncovered lines report to PR comment
if: ${{ matrix.php == '7.3' && github.event_name == 'pull_request' }}
continue-on-error: true # phpcov can fail if there are no uncovered lines
run: |
BRANCHED_COMMIT=$(git rev-list origin..HEAD | tail -n 1);
echo "BRANCHED_COMMIT=$BRANCHED_COMMIT"
git diff $BRANCHED_COMMIT...${{ github.event.pull_request.head.sha }} > branch.diff;
cat branch.diff;
OUTPUT=${vendor/bin/phpcov patch-coverage --path-prefix $(pwd) ./gh-pages/${{ github.event.pull_request.head.sha }}/phpunit/phpunit.cov branch.diff || true}
echo $OUTPUT;
echo "$OUTPUT" >> coverage-comment.md

- name: Add coverage PR comment
uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
if: ${{ matrix.php == '7.3' && github.event_name == 'pull_request' }}
with:
message-id: coverage-report
message-path: coverage-comment.md
codecoverage:
needs: get-repo-name
permissions:
contents: write
pull-requests: write
uses: newfold-labs/workflows/.github/workflows/reusable-codecoverage.yml@main
with:
php-versions: '["7.4", "8.0", "8.1", "8.2", "8.3", "8.4"]'
coverage-php-version: '7.4'
repository-name: ${{ needs.get-repo-name.outputs.repository-name }}
minimum-coverage: 25
secrets:
repo_token: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
.env.testing
.vscode
/node_modules
/tests/_output
Expand Down
10 changes: 7 additions & 3 deletions codeception.dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ params:
coverage:
enabled: true
include:
- /includes/*
# - /upgrades/*
bootstrap: bootstrap.php
- includes/*
exclude:
- tests/*
- vendor/*
- build/*
- src/*
- languages/*
Empty file added tests/_data/.gitkeep
Empty file.
3 changes: 2 additions & 1 deletion tests/wpunit.suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ modules:

domain: "%TEST_SITE_WP_DOMAIN%"
adminEmail: "%TEST_SITE_ADMIN_EMAIL%"
title: "wp-module-data"
adminEmailFallback: "admin@example.org"
title: "wp-module-performance"
plugins: []
activatePlugins: []

Expand Down
12 changes: 0 additions & 12 deletions tests/wpunit/ExampleWPUnitTest.php

This file was deleted.

52 changes: 52 additions & 0 deletions tests/wpunit/ModuleLoadingWPUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace NewfoldLabs\WP\Module\Performance;

use NewfoldLabs\WP\Module\Performance\RestApi\RestApi;
use NewfoldLabs\WP\Module\Performance\Data\Constants;

/**
* Module loading wpunit tests.
*
* @coversDefaultClass \NewfoldLabs\WP\Module\Performance\Performance
*/
class ModuleLoadingWPUnitTest extends \lucatume\WPBrowser\TestCase\WPTestCase {

/**
* Verify core module classes exist.
*
* RestApi\CacheController is not asserted here because it can fail to load in CI
* when its dependencies (e.g. CacheManager, container) are not fully available.
*
* @return void
*/
public function test_module_classes_load() {
$this->assertTrue( class_exists( Performance::class ), 'Performance class should exist' );
$this->assertTrue( class_exists( PerformanceFeature::class ), 'PerformanceFeature class should exist' );
$this->assertTrue( class_exists( Permissions::class ), 'Permissions class should exist' );
$this->assertTrue( class_exists( RestApi::class ), 'RestApi class should exist' );
$this->assertTrue( class_exists( Constants::class ), 'Data\Constants class should exist' );
$this->assertTrue( class_exists( Cache\Cache::class ), 'Cache\Cache class should exist' );
}

/**
* Verify WordPress factory is available.
*
* @return void
*/
public function test_wordpress_factory_available() {
$this->assertTrue( function_exists( 'get_option' ) );
$this->assertNotEmpty( get_option( 'blogname' ) );
}

/**
* Performance constants are defined.
*
* @return void
*/
public function test_performance_constants() {
$this->assertSame( 'nfd_purge_all', Performance::PURGE_ALL );
$this->assertSame( 'nfd_purge_url', Performance::PURGE_URL );
$this->assertSame( 'nfd-performance', Performance::PAGE_SLUG );
}
}
55 changes: 55 additions & 0 deletions tests/wpunit/PermissionsWPUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace NewfoldLabs\WP\Module\Performance;

/**
* Permissions wpunit tests.
*
* @coversDefaultClass \NewfoldLabs\WP\Module\Performance\Permissions
*/
class PermissionsWPUnitTest extends \lucatume\WPBrowser\TestCase\WPTestCase {

/**
* Permission constants are defined.
*
* @return void
*/
public function test_permission_constants() {
$this->assertSame( 'manage_options', Permissions::ADMIN );
$this->assertSame( 'upload_files', Permissions::UPLOAD_FILES );
$this->assertSame( 'edit_posts', Permissions::EDIT_POSTS );
$this->assertSame( 'manage_media_library', Permissions::MANAGE_MEDIA_LIBRARY );
}

/**
* Rest_is_authorized_admin returns false when not logged in.
*
* @return void
*/
public function test_rest_is_authorized_admin_when_logged_out() {
wp_set_current_user( 0 );
$this->assertFalse( Permissions::rest_is_authorized_admin() );
}

/**
* Rest_is_authorized_admin returns true for administrator.
*
* @return void
*/
public function test_rest_is_authorized_admin_when_administrator() {
$user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
wp_set_current_user( $user_id );
$this->assertTrue( Permissions::rest_is_authorized_admin() );
}

/**
* Rest_can_upload_media returns true for administrator.
*
* @return void
*/
public function test_rest_can_upload_media_for_administrator() {
$user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
wp_set_current_user( $user_id );
$this->assertTrue( Permissions::rest_can_upload_media() );
}
}
Loading