├── block
├── Save.js
├── index.js
├── block.json
├── Edit.js
├── __snapshots__
│ └── Edit.test.js.snap
└── Edit.test.js
├── .github
└── workflows
│ └── test-js.yml
├── .gitignore
├── makeZip.js
├── testing-react-wordpress.php
├── package.json
├── webpack.config.js
├── docker-compose.yml
└── README.md
/block/Save.js:
--------------------------------------------------------------------------------
1 | import { __ } from '@wordpress/i18n';
2 | import { useBlockProps } from '@wordpress/block-editor';
3 |
4 | export default function save({ attributes }) {
5 | return
{attributes.content}
;
6 | }
--------------------------------------------------------------------------------
/block/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { registerBlockType } from "@wordpress/blocks";
3 | import Edit from './Edit';
4 | import Save from './Save';
5 |
6 | const blockConfig = require('./block.json');
7 | registerBlockType(blockConfig.name, {
8 | ...blockConfig,
9 | edit: Edit,
10 | save: Save
11 | });
--------------------------------------------------------------------------------
/.github/workflows/test-js.yml:
--------------------------------------------------------------------------------
1 | name: JavaScripts
2 |
3 | on: [push]
4 |
5 | jobs:
6 | buildAndTest:
7 | name: Test
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v1
11 | - uses: actions/setup-node@v1
12 | with:
13 | node-version: "12"
14 | - name: Install dependencies
15 | run: yarn
16 | - name: Test
17 | run: yarn test --ci
18 |
--------------------------------------------------------------------------------
/block/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "testing-react-wordpress/block",
3 | "title": "Testing block",
4 | "description": "BLOCK DESCRIPTION",
5 | "attributes": {
6 | "content": {
7 | "type": "string",
8 | "default": "Hi Roy"
9 | }
10 | },
11 | "category": "widgets",
12 | "icon": "smiley",
13 | "supports": {
14 | "html": false
15 | }
16 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Logs
3 | logs
4 | *.log
5 | npm-debug.log*
6 | yarn-debug.log*
7 | yarn-error.log*
8 | lerna-debug.log*
9 |
10 | # Diagnostic reports (https://nodejs.org/api/report.html)
11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 |
13 | # Dependency directories
14 | node_modules/
15 | vendor/
16 |
17 | # dotenv environment variables file
18 | .env
19 | .env.test
20 |
21 | vendor
22 | wordpress
23 | build
24 | .phpunit.result.cache
--------------------------------------------------------------------------------
/makeZip.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var archiver = require('archiver');
3 |
4 | var output = fs.createWriteStream('test-react-wordpress.zip');
5 | var archive = archiver('zip');
6 |
7 | console.log( 'Zipping!')
8 | output.on('close', function () {
9 | console.log('Zipped!');
10 | console.log(archive.pointer() + ' total bytes');
11 | });
12 |
13 | archive.on('error', function(err){
14 | throw err;
15 | });
16 |
17 | archive.pipe(output);
18 |
19 | archive.append(fs.createReadStream(
20 | __dirname + '/test-react-wordpress.php'
21 | ), { name: 'test-react-wordpress.php' });
22 |
23 | archive.directory('build', '/build');
24 |
25 | archive.finalize();
--------------------------------------------------------------------------------
/testing-react-wordpress.php:
--------------------------------------------------------------------------------
1 | 'testing-react-wordpress-block',
23 | ]);
24 |
25 |
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {"name":"test-react-wordpress","private":true,"version":"0.1.0","license":"GPL-2.0-or-later","main":"build/index.js","scripts":{"test":"yarn test:unit","test:unit":"wp-scripts test-unit-js","build":"wp-scripts build","test:ci":"wp-scripts test-unit-js --ci","format:js":"wp-scripts format-js","lint:css":"wp-scripts lint-style","lint:js":"wp-scripts lint-js","start":"wp-scripts start","zip":"yarn build && node makeZip.js"},"devDependencies":{"@babel/core":"^7","@testing-library/react":"@latest","@wordpress/scripts":"@latest"},"dependencies":{"@axe-core/react":"^4.0.0","@wordpress/block-editor":"@latest","@wordpress/blocks":"@latest","@wordpress/components":"@latest","@wordpress/element":"@latest","@wordpress/i18n":"@latest","@wordpress/scripts":"@latest"}}
--------------------------------------------------------------------------------
/block/Edit.js:
--------------------------------------------------------------------------------
1 | import { TextControl } from '@wordpress/components';
2 | import { __ } from '@wordpress/i18n';
3 | import { useBlockProps } from '@wordpress/block-editor';
4 |
5 | export const Editor = ({ value, onChange, isSelected }) => (
6 | <>
7 | {isSelected ?
8 | : {value}
12 | }
13 | >
14 | );
15 | export default function Edit({ attributes, setAttributes, isSelected }) {
16 | return (
17 |
18 | setAttributes({ content })} />
19 |
20 | );
21 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require("@wordpress/scripts/config/webpack.config");
2 | const path = require("path");
3 | const isProduction = "production" === process.env.NODE_ENV;
4 |
5 | let entry = {};
6 | /**
7 | * Array of entry points
8 | */
9 | let entryPoints = ["block"]
10 |
11 | entryPoints.forEach(
12 | (entryPoint) => {
13 | entry[entryPoint] = path.resolve(process.cwd(), `${entryPoint}/index.js`);
14 | }
15 | );
16 | module.exports = {
17 | mode: isProduction ? "production" : "development",
18 | ...defaultConfig,
19 | module: {
20 | ...defaultConfig.module,
21 | rules: [
22 | ...defaultConfig.module.rules,
23 | {
24 | test: /\.css$/,
25 | use: ["style-loader", "css-loader"],
26 | },
27 | ],
28 | },
29 | entry,
30 | output: {
31 | filename: "[name].js",
32 | path: path.join(__dirname, "/build"),
33 | },
34 | };
35 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | #https://docs.docker.com/samples/wordpress/
3 | version: "3.9"
4 |
5 | services:
6 | db:
7 | image: mysql:5.7
8 | volumes:
9 | - db_data:/var/lib/mysql
10 | restart: always
11 | environment:
12 | MYSQL_ROOT_PASSWORD: somewordpress
13 | MYSQL_DATABASE: wordpress
14 | MYSQL_USER: wordpress
15 | MYSQL_PASSWORD: wordpress
16 |
17 | wordpress:
18 | depends_on:
19 | - db
20 | image: wordpress:latest
21 | volumes:
22 | - wordpress_data:/var/www/html
23 | - ./:/var/www/html/wp-content/plugins/testing-react-wordpress
24 |
25 | ports:
26 | - "8000:80"
27 | restart: always
28 | environment:
29 | WORDPRESS_DB_HOST: db:3306
30 | WORDPRESS_DB_USER: wordpress
31 | WORDPRESS_DB_PASSWORD: wordpress
32 | WORDPRESS_DB_NAME: wordpress
33 | volumes:
34 | db_data: {}
35 | wordpress_data: {}
--------------------------------------------------------------------------------
/block/__snapshots__/Edit.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Editor componet matches snapshot when not selected 1`] = `
4 |
20 | `;
21 |
22 | exports[`Editor componet matches snapshot when selected 1`] = `
23 |
39 | `;
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Testing JavaScript In And Around WordPress: Part 2 Example Code
2 |
3 | * [JavaScript Testing In And Around WordPress](https://shelob9.github.io/testing-javascript-in-and-around-wordpress)
4 |
5 | ## Development Quick Start
6 |
7 | - Git clone:
8 | - `git clone git@github.com:shelob9/testing-react-wordpress.git`
9 | - Install.
10 | - `yarn`
11 | - Build JS/CSS
12 | - `yarn build`
13 | - Start JS/CSS for development
14 | - `yarn start`
15 | - Test changed files
16 | - `yarn test --watch`
17 | - Test all files once
18 | - `yarn test`
19 | - `yarn test --ci`
20 | - Create an installable zip file of your plugin.
21 | - `yarn zip`
22 |
23 | ### To Add A New Entry Point
24 |
25 | If you want to add additional entry points, for example if you want to add blocks or to have separate JavaScript/ CSS for the front-end, follow these steps:
26 |
27 | - Choose a one word handle for the entry point
28 | - Create a directory named for the handle.
29 | - Add an index.js file to that directory
30 | - Add the handle to the array `entryPoints` in webpack.config.js
31 | - Run `yarn build`
32 | - Check that `build/$handle.js` and `build/$handle.asset.php` where created.
33 |
34 | ## Local Development
35 |
36 | - `docker-compose up -d`
37 | - [http://localhost:8000/](http://localhost:8000/)
38 |
39 | ## Contributing
40 |
41 | Please feel free to [open a pull request](https://github.com/shelob9/test-react-wordpress/pulls) if you would like to contribute.
--------------------------------------------------------------------------------
/block/Edit.test.js:
--------------------------------------------------------------------------------
1 |
2 | //Import React
3 | import React from 'react';
4 | //Import test renderer
5 | import { render, fireEvent, cleanup } from '@testing-library/react';
6 | //Import component to test
7 | import { Editor } from './Edit';
8 |
9 |
10 | describe("Editor componet", () => {
11 | afterEach(cleanup);
12 | it('matches snapshot when selected', () => {
13 | const onChange = jest.fn();
14 | const { container } = render();
19 | expect(container).toMatchSnapshot();
20 | });
21 |
22 | it('matches snapshot when not selected', () => {
23 | const onChange = jest.fn();
24 | const { container } = render();
29 | expect(container).toMatchSnapshot();
30 | });
31 |
32 | it("Calls the onchange function", () => {
33 | const onChange = jest.fn();
34 | const { getByDisplayValue } = render();
39 | fireEvent.change(getByDisplayValue("Salad"), {
40 | target: { value: "New Value" }
41 | });
42 | expect(onChange).toHaveBeenCalledTimes(1);
43 | });
44 |
45 | it("Passes updated value, not event to onChange callback", () => {
46 | const onChange = jest.fn();
47 | const { getByDisplayValue } = render();
52 | fireEvent.change(getByDisplayValue("Seltzer"), {
53 | target: { value: "Boring Water" }
54 | });
55 | expect(onChange).toHaveBeenCalledWith("Boring Water");
56 | });
57 | });
--------------------------------------------------------------------------------