Skip to content

Commit 9f1cd83

Browse files
committed
[skip ci] sync with master
2 parents eaaf44c + 5f05f4c commit 9f1cd83

File tree

4 files changed

+347
-0
lines changed

4 files changed

+347
-0
lines changed

.distignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ cypress.json
2626
.wordpress-org
2727
.releaserc.yml
2828
docker-compose.ci.yml
29+
CONTRIBUTING.md

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
### Summary
2+
<!-- Please describe the changes you made. -->
3+
4+
### Will affect visual aspect of the product
5+
<!-- It includes visual changes? -->
6+
YES/NO
7+
8+
### Screenshots <!-- if applicable -->
9+
10+
### Test instructions
11+
<!-- Describe how this pull request can be tested. -->
12+
13+
-
14+
-
15+
16+
## Check before Pull Request is ready:
17+
18+
* [ ] I have [written a test](CONTRIBUTING.md#writing-an-acceptance-test) and included it in this PR
19+
* [ ] I have [run all tests](CONTRIBUTING.md#run-tests) and they pass
20+
* [ ] The code passes when [running the PHP CodeSniffer](CONTRIBUTING.md#run-php-codesniffer)
21+
* [ ] Code meets [WordPress Coding Standards](CONTRIBUTING.md#coding-standards) for PHP, HTML, CSS and JS
22+
* [ ] [Security and Sanitization](CONTRIBUTING.md#security-and-sanitization) requirements have been followed
23+
* [ ] I have assigned a reviewer or two to review this PR (if you're not sure who to assign, we can do this step for you)
24+
25+
<!-- Issues that this pull request closes. -->
26+
Closes #.
27+
<!-- Should look like this: `Closes #1, #2, #3.` . -->

.github/workflows/pr-checklist.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Add labels to pull request based on checklist
2+
3+
on:
4+
pull_request:
5+
types: [ opened, edited, synchronize, labeled, unlabeled ]
6+
branches-ignore:
7+
- 'master'
8+
- 'update_dependencies'
9+
10+
permissions: write-all
11+
12+
jobs:
13+
add-labels:
14+
runs-on: ubuntu-latest
15+
name: Label PR based on checklist
16+
if: github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name && github.actor != 'dependabot[bot]'
17+
steps:
18+
- name: Check if checklist items are completed
19+
uses: Codeinwp/gha-pr-check-helper@master
20+
with:
21+
token: ${{ secrets.BOT_TOKEN }}
22+
requireChecklist: true
23+
onlyCheckBody: true
24+
completedLabel: "pr-checklist-complete"
25+
incompleteLabel: "pr-checklist-incomplete"
26+
skipLabel: "pr-checklist-skip"

CONTRIBUTING.md

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,296 @@ For specific signs:
119119

120120
1. For displaying a sign like `$` (like `$2.345`), you need to follow the same steps as for the amount.
121121
2. Except the number formatting will be `$#,###`.
122+
123+
# CONTRIBUTING GUIDELINES
124+
+ [Setup Guide](#setup-guide)
125+
+ [Development Guide](#development-guide)
126+
+ [Testing Guide](#testing-guide)
127+
128+
# Setup Guide
129+
130+
This document describes how to set up your development environment, so that it is ready to run, develop and test this WordPress Plugin or Theme.
131+
132+
Suggestions are provided for the LAMP/LEMP stack and Git client are for those who prefer the UI over a command line and/or are less familiar with
133+
WordPress, PHP, MySQL and Git - but you're free to use your preferred software.
134+
135+
## Setup
136+
137+
### LAMP/LEMP stack
138+
139+
Any Apache/nginx, PHP 7.x+ and MySQL 5.8+ stack running WordPress. For example, but not limited to:
140+
- Valet (recommended)
141+
- Local by Flywheel
142+
- Docker
143+
- MAMP
144+
- WAMP
145+
146+
### Composer
147+
148+
If [Composer](https://getcomposer.org) is not installed on your local environment, enter the following commands at the command line to install it:
149+
150+
```bash
151+
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
152+
php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
153+
php composer-setup.php
154+
php -r "unlink('composer-setup.php');"
155+
sudo mv composer.phar /usr/local/bin/composer
156+
```
157+
158+
Confirm that installation was successful by entering the `composer --version` command at the command line
159+
160+
### Clone Repository
161+
162+
Using your preferred Git client or command line, clone this repository into the `wp-content/plugins/` folder of your local WordPress installation.
163+
164+
If you prefer to clone the repository elsewhere, and them symlink it to your local WordPress installation, that will work as well.
165+
166+
If you're new to this, use [GitHub Desktop](https://desktop.github.com/) or [Tower](https://www.git-tower.com/mac)
167+
168+
For Plugins the cloned folder should be under `wp-content/plugins/` and for Themes under `wp-content/themes/`.
169+
170+
### Install Dependencies for PHP and JS
171+
172+
In the cloned repository's directory, at the command line, run `composer install`.
173+
This will install the development dependencies. If you want to install just the production dependencies, run `composer install --no-dev`.
174+
175+
The development dependencies include:
176+
- PHPStan
177+
- PHPUnit
178+
- PHP_CodeSniffer
179+
- WordPress Coding Standards
180+
- WordPress PHPUnit Polyfills
181+
182+
For the JS dependencies, run `npm install`.
183+
To watch for changes in the JS files, run `npm run dev` if present or `npm run dist` to build a new version.
184+
185+
### PHP_CodeSniffer
186+
187+
To run PHP_CodeSniffer, run `composer lint`. This will run the WordPress Coding Standards checks.
188+
To fix automatically fixable issues, run `composer format`.
189+
190+
### PHPUnit
191+
192+
To run PHPUnit, run `phpunit` or `./vendor/bin/phpunit` if it is not configured globally.
193+
194+
### E2E Tests
195+
If the folder `e2e-tests` is present, you can run the E2E tests by following the instructions in the [E2E testing](./e2e-tests/README.md).
196+
197+
### Next Steps
198+
199+
With your development environment setup, you'll probably want to start development, which is covered bellow in the **Development Guide**.
200+
201+
202+
203+
# Development Guide
204+
205+
This document describes the high level workflow used when working on a WordPress Plugin or Theme.
206+
207+
You're free to use your preferred IDE and Git client. We recommend PHPStorm or Visual Studio Code, and GitHub CLI.
208+
209+
## Prerequisites
210+
211+
If you haven't yet set up your local development environment with a WordPress Plugin repository installed, refer to the [Setup Guide](#setup-guide).
212+
213+
his is for a new feature that does not have a GitHub Issue number, enter a short descriptive name for the branch, relative to what you're working on
214+
- If this is for a feature/bug that has a GitHub Issue number, enter feat/issue_name or fix/issue_name, where issue_name is a descriptive name for the issue
215+
216+
Once done, make sure you've switched to your new branch, and begin making the necessary code additions/changes/deletions.
217+
218+
## Coding Standards
219+
220+
Code must follow [WordPress Coding standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/), which is checked
221+
when running tests (more on this below).
222+
223+
## Security and Sanitization
224+
225+
When [outputting data](https://developer.wordpress.org/plugins/security/securing-output/), escape it using WordPress' escaping functions such as `esc_html()`, `esc_attr__()`, `wp_kses()`, `wp_kses_post()`.
226+
227+
When reading [user input](https://developer.wordpress.org/plugins/security/securing-input/), sanitize it using WordPress' sanitization functions such as `sanitize_text_field()`, `sanitize_textarea_field()`.
228+
229+
When writing to the database, prepare database queries using ``$wpdb->prepare()``
230+
231+
Never trust user input. Sanitize it.
232+
233+
Make use of [WordPress nonces](https://codex.wordpress.org/WordPress_Nonces) for saving form submitted data.
234+
235+
Coding standards will catch any sanitization, escaping or database queries that aren't prepared.
236+
237+
## Composer Packages
238+
239+
We use Composer for package management. A package can be added to one of two sections of the `composer.json` file: `require` or `require-dev`.
240+
241+
### "require"
242+
243+
Packages listed in the "require" directive are packages that the Plugin needs in order to function for end users.
244+
245+
These packages are included when the Plugin is deployed to WordPress.org
246+
247+
Typically, packages listed in this section would be libraries that the Plugin uses.
248+
249+
### "require-dev"
250+
251+
Packages listed in the "require-dev" directive are packages that the Plugin **does not** need in order to function for end users.
252+
253+
These packages are **not** included when the Plugin is deployed to wordpress.org
254+
255+
Typically, packages listed in this section would be internal development tools for testing, such as:
256+
- Coding Standards
257+
- PHPStan
258+
- PHPUnit
259+
260+
## Committing Work
261+
262+
Remember to commit your changes to your branch relatively frequently, with a meaningful, short summary that explains what the change(s) do.
263+
This helps anyone looking at the commit history in the future to find what they might be looking for.
264+
265+
If it's a particularly large commit, be sure to include more information in the commit description.
266+
267+
## Next Steps
268+
269+
Once you've finished your feature or issue, you must write/amend tests for it. Refer to the [Testing Guide](#testing-guide) for a detailed walkthrough
270+
on how to write a test.
271+
272+
273+
274+
# Testing Guide
275+
276+
This document describes how to:
277+
- create and run tests for your development work,
278+
- ensure code meets PHP and WordPress Coding Standards, for best practices and security,
279+
- ensure code passes static analysis, to catch potential errors that tests might miss
280+
281+
If you're new to creating and running tests, this guide will walk you through how to do this.
282+
283+
For those more experienced with creating and running tests, our tests are written in TS for [Playwright](https://playwright.dev/) used for End-to-End testing,
284+
and in PHP for [PHPUnit](https://phpunit.de/).
285+
286+
A PHPUnit guide for WordPress can be found [here](https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/).
287+
288+
## Prerequisites
289+
290+
If you haven't yet set up your local development environment with this Plugin repository installed, refer to the [Setup Guide](#setup-guide).
291+
292+
If you haven't yet created a branch and made any code changes to the Plugin or Theme, refer to the [Development Guide](#development-guide)
293+
294+
## Write (or modify) a test
295+
296+
If your work creates new functionality, write a test.
297+
298+
If your work fixes existing functionality, check if a test exists. Either update that test, or create a new test if one doesn't exist.
299+
300+
Tests are written in TS using [Playwright](https://playwright.dev/) and PHP using [PHPUnit](https://phpunit.de/).
301+
302+
## Types of Test
303+
304+
There are different types of tests that can be written:
305+
- Acceptance Tests: Test as a non-technical user in the web browser.
306+
- Functional Tests: Test the framework (WordPress).
307+
- Integration Tests: Test code modules in the context of a WordPress website.
308+
- Unit Tests: Test single PHP classes or functions in isolation.
309+
- WordPress Unit Tests: Test single PHP classes or functions in isolation, with WordPress functions and classes loaded.
310+
311+
There is no definitive / hard guide, as a test can typically overlap into different types (such as Acceptance and Functional).
312+
313+
The most important thing is that you have a test for *something*. If in doubt, an Acceptance Test will suffice.
314+
315+
### Writing an Acceptance Test
316+
317+
An acceptance test is a test that simulates a user interacting with the Plugin or Theme in a web browser.
318+
Refer to Writing an End-to-End Test below.
319+
320+
### Writing an End-to-End Test
321+
322+
To write an End-to-End test, create a new file under `e2e-tests/specs` with the name of the spec or functionality you are testing, and add `.spec.test` to the file name.
323+
324+
E.g. for `e2e-tests/specs/checkout.spec.test.js`, the test file should be `checkout.spec.test.js`.
325+
326+
For more information on writing End-to-End tests, refer to the [Playwright documentation](https://playwright.dev/docs/test-intro).
327+
328+
You can check End-to-End [README](./e2e-tests/README.md) for more details.
329+
330+
## Writing a WordPress Unit Test
331+
332+
WordPress Unit tests provide testing of Plugin/Theme specific functions and/or classes, typically to assert that they perform as expected
333+
by a developer. This is primarily useful for testing our API class, and confirming that any Plugin registered filters return
334+
the correct data.
335+
336+
To create a new WordPress Unit Test, create a new file under `tests/php/unit` with the name of the class you are testing, and the suffix `Test`.
337+
The filename should be in `lower-case-with-dash`, and the class name should be in `CamelCase`.
338+
339+
E.g. for `tests/php/unit/class-api-test.php`, the test class should be `class APITest extends \PHPUnit\Framework\TestCase`.
340+
341+
```php
342+
<?php
343+
class APITest extends \PHPUnit\Framework\TestCase
344+
{
345+
/**
346+
* @var \WpunitTester
347+
*/
348+
protected $tester;
349+
350+
public function setUp(): void
351+
{
352+
// Before...
353+
parent::setUp();
354+
// Your set up methods here.
355+
}
356+
public function tearDown(): void
357+
{
358+
// Your tear down methods here.
359+
// Then...
360+
parent::tearDown();
361+
}
362+
// Tests
363+
public function test_it_works()
364+
{
365+
$post = static::factory()->post->create_and_get();
366+
367+
$this->assertInstanceOf(\WP_Post::class, $post);
368+
}
369+
}
370+
```
371+
372+
## Run PHPUnit Tests
373+
374+
Once you have written your code and test(s), run the tests to make sure there are no errors.
375+
376+
```bash
377+
./vendor/bin/phpunit tests/php/unit/class-api-test.php
378+
```
379+
380+
Any errors should be corrected by making applicable code or test changes.
381+
382+
## Run PHP CodeSniffer
383+
384+
In the Plugin's or Theme's directory, run the following command to run PHP_CodeSniffer, which will check the code meets Coding Standards
385+
as defined in the `phpcs.tests.xml` configuration:
386+
387+
```bash
388+
composer run lint
389+
```
390+
391+
`--standard=phpcs.tests.xml` tells PHP CodeSniffer to use the Coding Standards rules / configuration defined in `phpcs.tests.xml`.
392+
These differ slightly from WordPress' Coding Standards, to ensure that writing tests isn't a laborious task, whilst maintain consistency
393+
in test coding style.
394+
`-v` produces verbose output
395+
`-s` specifies the precise rule that failed
396+
397+
Any errors should be corrected by either:
398+
- making applicable code changes
399+
- running `composer run format` to automatically fix coding standards
400+
401+
Need to change the PHP or WordPress coding standard rules applied? Either:
402+
- ignore a rule in the affected code, by adding `phpcs:ignore {rule}`, where {rule} is the given rule that failed in the above output.
403+
- edit the [phpcs.tests.xml](phpcs.tests.xml) file.
404+
405+
## Next Steps
406+
407+
Once your test(s) are written and successfully run locally, submit your branch via a new **Pull Request**.
408+
409+
It's best to create a Pull Request in draft mode, as this will trigger all tests to run as a GitHub Action, allowing you to
410+
double-check all tests pass.
411+
412+
If the PR tests fail, you can make code changes as necessary, pushing to the same branch. This will trigger the tests to run again.
413+
414+
If the PR tests pass, you can publish the PR, assigning some reviewers.

0 commit comments

Comments
 (0)