git clone git@github.com:trustedlogin/vendor.git
yarn
composer install
docker run --rm -it --volume "$(pwd)":/app prooph/composer:7.4 install
wp-scripts
is installed globally
yarn global add @wordpress/scripts
JS and CSS:
yarn start:css
yarn start:js
yarn test --watch
yarn test
yarn test --ci
yarn lint
PHP:
This local dev with Docker was built to work with ngrok, which is not what we're doing now.
Do not install in a directory that includes a space in the path, for example, one under "Local Sites". That will cause issues with wp.js.
IMPORTANT: You must use PHP 7.4 and composer 2.2+ when running composer. The wp.js script runs composer in Docker with the right versions.
git clone git@github.com:trustedlogin/vendor.git
yarn
composer install
docker run --rm -it --volume "$(pwd)":/app prooph/composer:7.4 install
cp .env.example .env
NGROK_WP_URL
, NGROK_USERS
,TL_VENDOR_ENCRYTPTION_KEY
and NGROK_AUTH_TOKEN
.wp.js
script.It is important that you use the wp.js
script to setup the local dev site, which is served via ngork. The e2e tests assume that site is running and was setup using this script. This script should work with Node 14 or later. Josh developed it using Node 16.
node wp.js
NGROK_USERS
env variableyarn
node wp.js zip
Note: if that doesn't work, make sure Docker is running and then run the following instead:
yarn build && npx --yes plugin-machine plugin build --token=notempty && npx --yes plugin-machine plugin zip --token=notempty
node wp.js --activate
node wp.js ---reset
The wp.js
script uses docker compose.
There is a React app, for the admin page. It is located in /src
. We create two different builds from this app:
react-scripts
.yarn build
yarn build:js
yarn build:app
npx
is installed.npx
is used to run react-scripts
, instead of installing it in this repo and using yarn
, in order to avoid potential conflicts with @wordpress/scripts
.yarn start
yarn start:css
, yarn start:js
yarn start:js
yarn test --watch
yarn test
yarn test --ci
yarn lint
yarn build:css
yarn start:css
The file admin/tailwind.css
is used, with Tailwind CSS to write CSS for the admin screens. We are using Tailwind 3, with just in time compliation.
When Tailwind does its purge, it is configured to look for classes in PHP or JavaScript files in the admin directory only.
PHP classes should be located in the "php" directory and follow the PSR-4 standard.
The root namespace is TrustedLoginVendor
.
$container = trustedlogin_connector();
Interactions with TrustedLogin are in the TrustedLoginService
. You can get this service, using the container, which it needs, like this:
$service = new TrustedLoginService(
trustedlogin_connector()
);
Before doing this, you must create a ".env" file in the root of this plugin. You need to set the correct value for TL_VENDOR_ENCRYTPTION_KEY
. Its value is saved in Zack and Josh's password managers. It is set as a Github actions environment variable. This is not needed in production.
composer test
The integration tests mock the SASS API. The mock data was generated using encryption keys for Zack's "Test" team. This is different from the "ngrok" team used for e2e tests.
The integration tests rely on the environment variable TL_VENDOR_ENCRYTPTION_KEY
:
{
/*
* private_key: (string) The private key used for encrypt/decrypt.
* public_key: (string) The public key used for encrypt/decrypt.
* sign_public_key: (string) The public key used for signing/verifying.
* sign_private_key: (string) The private key used for signing/verifying.
*/
}
PHPCS is installed for linting and automatic code fixing. You can also run these commands in Docker, using wp.js.
Run linter and autofix
composer fixes
node wp.js fixes
Run linter to identify issues.
compose sniffs
node wp.js sniffs
Check backwards compat
compose compat
node wp.js compat
A docker-compose-based local development environment is provided.
docker-compose up -d
docker kill $(docker ps -q) && docker-compose up -d
docker-compose run wpcli wp user create admin admin@example.com --role=admin user_pass=pass
WP_DEBUG
and TRUSTEDLOGIN_DEBUG
are set to true, errors will be logged to ./trustedlogin.log
.
docker-compose.yml
, in services.wordpress.environment
, under WORDPRESS_CONFIG_EXTRA
.There is a special phpunit container for running WordPress tests, with WordPress and MySQL configured.
docker-compose run phpunit
composer test:wordpress
**docker-compose run phpunit phpunit --config=phpunit-integration.xml
If you see prompt Do you trust "dealerdirect/phpcodesniffer-composer-installer" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y
you should answer "y". This is fine.
The WordPress site will also be on the internets at https://trustedlogin.ngrok.io/. This requires setting the variable NGROK_AUTH_TOKEN
in the .env file.
Find the auth token in the ngrok dashboard, while logged in to the TrustedLogin account. Ask Zack for access if needed.
The ngrok container has a UI for inspecting ngrok requests. It can be accessed at http://localhost:4551/.
We use cypress for end to end testing (e2e) the vendor plugin, and the e2e client. These tests use the production eCommerce app and Vault. These tests use an "ngrok" team. Zack can add and remove people from that team.
The e2e client plugin is installed at https://e2e.trustedlogin.dev/. The e2e tests in that plugin will use that site to grant access to the "ngrok" team. We can get the accessKey from that HTTP request's response. The ngrok endpoint will be serving a WordPress site using whatever version of this plugin is being tested, served at the ngrok endpoint.
Then the tests will log into the vendor site and attempt to use the plugin's setting screen to login to the client site, using the access key.
CLIENT_WP_URL
CLIENT_WP_URL=https://e2e.trustedlogin.dev/
CLIENT_WP_PASSWORD
CLIENT_WP_USER
CLIENT_WP_USER=githubactions
NGROK_AUTH_TOKEN
NGROK_WP_URL
NGROK_WP_URL=https://trustedlogin.ngrok.io
https://trustedlogin-ci.ngrok.io
When working on this project, you may occasionally encounter failing tests or need to add new tests for new features. Here are some steps to guide you through this process.
yarn test --watch
.Understand the test: Look at the test that is failing and understand what it is testing and what the expected behavior is.
You are going to see an error like this:
["Warning: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.%s", "
1 | import React from "react";
2 |
> 3 | export const SelectFieldArea = ({ id, label, children, htmlFor }) => (
| ^
4 | <div className="">
5 | <label
6 | htmlFor={htmlFor ? htmlFor : id}
at SelectFieldArea (src/components/teams/fields.js:3:35)
at SelectField (src/components/teams/fields.js:39:31)
at HelpDeskSelect (src/components/teams/EditTeam.js:14:34)
at ViewProvider (src/hooks/useView.js:12:3)
at SettingsProvider (src/hooks/useSettings.js:267:3)
at TestProvider (src/components/TestProvider.js:33:3)
at Provider"]
Write the test: Using the Jest framework, write a test that checks whether the feature behaves as expected.
The following example is a new test to verify how the application would work when the value has changed.
import { render, fireEvent } from "@testing-library/react";
it("Updates on change", () => {
const handleChange = jest.fn();
const { getByLabelText } = render(
<HelpDeskSelect value={"helpscout"} options={options} onChange={handleChange} />,
{
wrapper: Provider,
}
);
const select = getByLabelText(teamFields.helpdesk.label);
fireEvent.change(select, { target: { value: 'new value' } });
expect(handleChange).toBeCalledWith('new value');
});
onChange
handler was called with the new value.Sometimes, a test might fail because of changes in the component structure or design, even though the component's functionality hasn't changed. If you verify that the changes are expected and not the result of a bug, you'll need to update the snapshot that Jest uses to compare in future test runs.
Here's how you update Jest snapshots:
yarn test -- -u
.Remember, updating snapshots should be done cautiously. Ensure that you've fully reviewed and understand any snapshot changes before committing them.
Never update a snapshot if you see an unexpected change, as this might be an indication of a regression or bug in your code.