Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
23 changes: 23 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
coverage:
status:
project:
default:
target: auto
threshold: 1%
informational: true
patch:
default:
target: 80%
informational: true

flags:
php-unit:
carryforward: true
php-integration:
carryforward: true
js-unit:
carryforward: true

comment:
layout: "reach, diff, flags, files"
behavior: default
11 changes: 11 additions & 0 deletions .distignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,14 @@ bin/
.husky/
.packagejsonignore
.distignore

# Tests
tests/
phpunit-unit.xml.dist
phpunit-integration.xml.dist
jest.config.js
.phpunit.result.cache
coverage/
.codecov.yml
.gitattributes
docs/
4 changes: 3 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
],
"rules": {
// Add Rules for Jest here
"jest/unbound-method": "off",
"jest/prefer-expect-assertions": "off",
"@wordpress/dependency-group": "off"
}
}]
}

9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Exclude development-only files from `git archive` output.
/tests export-ignore
/docs export-ignore
/phpunit-unit.xml.dist export-ignore
/phpunit-integration.xml.dist export-ignore
/jest.config.js export-ignore
/.codecov.yml export-ignore
/.github export-ignore
/bin export-ignore
24 changes: 24 additions & 0 deletions .github/workflows/release_on_tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@ jobs:
npm install
npm run build:prod

- name: Verify tests are excluded from build artifact
shell: bash
run: |
# Reproduce what 10up/action-wordpress-plugin-deploy will ship.
mkdir -p /tmp/godam-stage
rsync -a --exclude-from=.distignore --exclude='.git' ./ /tmp/godam-stage/

fail=0
for path in tests phpunit-unit.xml.dist phpunit-integration.xml.dist jest.config.js docs .codecov.yml .github; do
if [ -e "/tmp/godam-stage/$path" ]; then
echo "::error::$path leaked into the build artifact"
fail=1
fi
done

# Also confirm the runtime dep we DO need to ship is still present.
if [ ! -d /tmp/godam-stage/vendor ]; then
echo "::error::vendor/ missing from build artifact (action-scheduler runtime dep required)"
fail=1
fi

rm -rf /tmp/godam-stage
exit "$fail"

- name: WordPress Plugin Deploy
id: deploy
uses: 10up/action-wordpress-plugin-deploy@2.3.0
Expand Down
116 changes: 116 additions & 0 deletions .github/workflows/tests_on_pull_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Tests on Pull Request

on:
pull_request:
branches: [develop, main]
workflow_dispatch:

permissions:
contents: read

jobs:
php-unit:
name: PHP unit (${{ matrix.php }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['7.4', '8.1', '8.4']
steps:
- uses: actions/checkout@v6
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: pcov
tools: composer:v2
- name: Cache composer
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: composer-${{ runner.os }}-${{ matrix.php }}-
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run unit suite with coverage
run: composer test:unit -- --coverage-clover=coverage-unit.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: coverage-unit.xml
flags: php-unit
fail_ci_if_error: false

php-integration:
name: PHP integration (php ${{ matrix.php }} / wp ${{ matrix.wp }})
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping --silent"
--health-interval=10s
--health-timeout=5s
--health-retries=10
strategy:
fail-fast: false
matrix:
include:
- php: '7.4'
wp: '6.5'
- php: '8.1'
wp: 'latest'
- php: '8.4'
wp: 'latest'
steps:
- uses: actions/checkout@v6
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: pcov
extensions: mysqli, zip
tools: composer:v2
- name: Cache composer
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: composer-${{ runner.os }}-${{ matrix.php }}-
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Install WordPress test suite
run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 ${{ matrix.wp }}
- name: Run integration suite with coverage
run: composer test:integration -- --coverage-clover=coverage-integration.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: coverage-integration.xml
flags: php-integration
fail_ci_if_error: false

js-unit:
name: JS unit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Jest with coverage
run: npm run test:js -- --coverage --ci
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: coverage/js/lcov.info
flags: js-unit
fail_ci_if_error: false
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ node_modules
vendor/
assets/build/

# Test artifacts
.phpunit.result.cache
coverage/

62 changes: 62 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Thank you for your interest in contributing to GoDAM! This document provides gui
- [Commit Messages](#commit-messages)
- [Types](#types)
- [Examples](#examples)
- [Running Tests](#running-tests)
- [Tier 1 — Fast PHP unit tests (Brain Monkey)](#tier-1--fast-php-unit-tests-brain-monkey)
- [Tier 2 — PHP integration tests (wp-phpunit)](#tier-2--php-integration-tests-wp-phpunit)
- [JavaScript tests (Jest + Testing Library)](#javascript-tests-jest--testing-library)
- [Running everything](#running-everything)
- [Coverage reports](#coverage-reports)


## About GoDAM
Expand Down Expand Up @@ -290,3 +296,59 @@ perf(media): optimize thumbnail generation
test(unit): add video migration tests
chore(deps): update action-scheduler
```

## Running Tests

GoDAM ships with two PHP test tiers and a Jest suite for the React/block layer.

### Tier 1 — Fast PHP unit tests (Brain Monkey)

No WordPress required. Runs on the host PHP CLI.

```bash
composer test:unit
```

These tests live in `tests/phpunit/unit/`, extend `GoDAM\Tests\TestCase`, and use Brain Monkey to fake WordPress functions. Target: < 5 s total runtime.

### Tier 2 — PHP integration tests (wp-phpunit)

Boots WordPress through `wp-phpunit`. First-time setup requires a MySQL server and the WordPress test suite:

```bash
# One-time setup (uses ~/mysql; adjust the host/user/password as needed):
bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 latest

# Then:
composer test:integration
```

These tests live in `tests/phpunit/integration/`, extend `GoDAM\Tests\IntegrationTestCase`, and use the standard `WP_UnitTestCase` factories.

### JavaScript tests (Jest + Testing Library)

Block and React component tests:

```bash
npm run test:js # one-shot
npm run test:js:watch # watch mode
npm run test:js:coverage # with coverage report
```

JS tests live alongside source (`assets/src/**/__tests__/*.test.js`) or under `tests/js/`. The Jest preset is `@wordpress/jest-preset-default` plus `@testing-library/jest-dom` matchers.

### Running everything

```bash
composer test # PHP unit + integration
npm test # PHP + JS in parallel
```

### Coverage reports

```bash
composer test:coverage # writes coverage/php/ HTML
npm run test:js:coverage # writes coverage/js/
```

Coverage uploads to Codecov in CI; see `.codecov.yml` for the flag layout and `docs/superpowers/plans/2026-05-22-unit-testing-setup.md` for the architectural rationale and per-section coverage targets.
Loading
Loading