From 839ea67577ebd9259dbe7781c1114403dfefc378 Mon Sep 17 00:00:00 2001 From: Moon Date: Wed, 28 Feb 2024 15:47:15 -0800 Subject: [PATCH] Add remote spec rule validator UI (#45099) * Add Remote Spec Rule validator * Add changelog * Remove unused var * Add remote spec validator * Load composer autoload * Remove remote spec validation --- plugins/woocommerce-beta-tester/api/api.php | 1 + ...-wca-test-helper-remote-spec-validator.php | 34 +++++++++ .../changelog/add-remote-spec-rule-validator | 4 + plugins/woocommerce-beta-tester/composer.lock | 2 +- plugins/woocommerce-beta-tester/plugin.php | 3 +- .../woocommerce-beta-tester/src/app/app.js | 6 ++ .../woocommerce-beta-tester/src/index.scss | 11 +++ .../data/action-types.js | 6 ++ .../src/remote-spec-validator/data/actions.js | 52 +++++++++++++ .../remote-spec-validator/data/constants.js | 2 + .../src/remote-spec-validator/data/index.js | 22 ++++++ .../src/remote-spec-validator/data/reducer.js | 25 +++++++ .../remote-spec-validator/data/resolvers.js | 0 .../remote-spec-validator/data/selectors.js | 3 + .../src/remote-spec-validator/index.js | 74 +++++++++++++++++++ 15 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 plugins/woocommerce-beta-tester/api/remote-spec-validator/class-wca-test-helper-remote-spec-validator.php create mode 100644 plugins/woocommerce-beta-tester/changelog/add-remote-spec-rule-validator create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/action-types.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/actions.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/constants.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/index.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/reducer.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/resolvers.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/data/selectors.js create mode 100644 plugins/woocommerce-beta-tester/src/remote-spec-validator/index.js diff --git a/plugins/woocommerce-beta-tester/api/api.php b/plugins/woocommerce-beta-tester/api/api.php index 2f8a0c9de77..6bb18ac9cd5 100644 --- a/plugins/woocommerce-beta-tester/api/api.php +++ b/plugins/woocommerce-beta-tester/api/api.php @@ -59,3 +59,4 @@ require 'rest-api-filters/class-wca-test-helper-rest-api-filters.php'; require 'rest-api-filters/hook.php'; require 'live-branches/manifest.php'; require 'tools/set-block-template-logging-threshold.php'; +require 'remote-spec-validator/class-wca-test-helper-remote-spec-validator.php'; \ No newline at end of file diff --git a/plugins/woocommerce-beta-tester/api/remote-spec-validator/class-wca-test-helper-remote-spec-validator.php b/plugins/woocommerce-beta-tester/api/remote-spec-validator/class-wca-test-helper-remote-spec-validator.php new file mode 100644 index 00000000000..d0b00a4c50f --- /dev/null +++ b/plugins/woocommerce-beta-tester/api/remote-spec-validator/class-wca-test-helper-remote-spec-validator.php @@ -0,0 +1,34 @@ + 'POST', + 'args' => array( + 'spec' => array( + 'description' => 'The remote spec to validate.', + 'type' => 'string', + 'required' => true, + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ) +); + +/** + * @param WP_REST_Request $request The full request data. + */ +function wca_test_helper_validate_remote_spec( $request ) { + $spec = json_decode( $request->get_param( 'spec' ) ); + $rule_evaluator = new RuleEvaluator(); + $result = [ + 'valid' => $rule_evaluator->evaluate( $spec ), + ]; + + return new WP_REST_RESPONSE( $result, 200 ); +} diff --git a/plugins/woocommerce-beta-tester/changelog/add-remote-spec-rule-validator b/plugins/woocommerce-beta-tester/changelog/add-remote-spec-rule-validator new file mode 100644 index 00000000000..0f732d54c8e --- /dev/null +++ b/plugins/woocommerce-beta-tester/changelog/add-remote-spec-rule-validator @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add Remote Spec Rule validator \ No newline at end of file diff --git a/plugins/woocommerce-beta-tester/composer.lock b/plugins/woocommerce-beta-tester/composer.lock index 1a608c200b2..f7876fed498 100644 --- a/plugins/woocommerce-beta-tester/composer.lock +++ b/plugins/woocommerce-beta-tester/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e1ae720be342a5fd2aa3cbac6514537d", + "content-hash": "b373f29961b944cda3ae2f767107523c", "packages": [ { "name": "composer/installers", diff --git a/plugins/woocommerce-beta-tester/plugin.php b/plugins/woocommerce-beta-tester/plugin.php index 810c1bfb1cd..60ffe6283f3 100644 --- a/plugins/woocommerce-beta-tester/plugin.php +++ b/plugins/woocommerce-beta-tester/plugin.php @@ -12,6 +12,7 @@ add_action( 'admin_menu', function() { } ); add_action( 'wp_loaded', function() { + require_once __DIR__ . '/vendor/autoload.php'; require( 'api/api.php' ); } ); @@ -24,4 +25,4 @@ add_filter( 'woocommerce_admin_get_feature_config', function( $feature_config ) } } return $feature_config; -} ); \ No newline at end of file +} ); diff --git a/plugins/woocommerce-beta-tester/src/app/app.js b/plugins/woocommerce-beta-tester/src/app/app.js index 44e52fe4d3e..699bba2e7e3 100644 --- a/plugins/woocommerce-beta-tester/src/app/app.js +++ b/plugins/woocommerce-beta-tester/src/app/app.js @@ -13,6 +13,7 @@ import { default as Options } from '../options'; import { default as Experiments } from '../experiments'; import { default as Features } from '../features'; import { default as RestAPIFilters } from '../rest-api-filters'; +import RemoteSpecValidator from '../remote-spec-validator'; const tabs = applyFilters( 'woocommerce_admin_test_helper_tabs', [ { @@ -45,6 +46,11 @@ const tabs = applyFilters( 'woocommerce_admin_test_helper_tabs', [ title: 'REST API FIlters', content: , }, + { + name: 'remote-spec-validator', + title: 'Remote Spec Rule Validator', + content: , + }, ] ); export function App() { diff --git a/plugins/woocommerce-beta-tester/src/index.scss b/plugins/woocommerce-beta-tester/src/index.scss index ffd37268e99..7a6dc32fec1 100644 --- a/plugins/woocommerce-beta-tester/src/index.scss +++ b/plugins/woocommerce-beta-tester/src/index.scss @@ -173,3 +173,14 @@ form.rest-api-filter-new-form { margin-top: 10px; } } + +#wc-admin-test-helper-remote-spec-validator { + textarea { + width: 100%; + height: 300px; + } + + .btn-validate { + float: right; + } +} \ No newline at end of file diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/action-types.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/action-types.js new file mode 100644 index 00000000000..b6df3ed6b71 --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/action-types.js @@ -0,0 +1,6 @@ +const TYPES = { + VALIDATE: 'VALIDATE', + SET_MESSAGE: 'SET_MESSAGE', +}; + +export default TYPES; diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/actions.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/actions.js new file mode 100644 index 00000000000..c94b5941da9 --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/actions.js @@ -0,0 +1,52 @@ +/** + * External dependencies + */ +import { apiFetch } from '@wordpress/data-controls'; + +/** + * Internal dependencies + */ +import TYPES from './action-types'; +import { API_NAMESPACE } from './constants'; + +export function* validate( jsonString ) { + try { + const response = yield apiFetch( { + method: 'POST', + path: `${ API_NAMESPACE }/remote-spec-validator/validate`, + headers: { 'content-type': 'application/json' }, + data: { + spec: JSON.stringify( JSON.parse( jsonString ) ), + }, + } ); + if ( response.valid ) { + yield { + type: TYPES.SET_MESSAGE, + message: { + type: 'notice notice-success', + text: 'Validation passed', + }, + }; + } else { + yield { + type: TYPES.SET_MESSAGE, + message: { + type: 'error', + text: 'Validation failed', + }, + }; + } + } catch { + throw new Error(); + } +} + +export function setMessage( type, text ) { + return { + type: TYPES.SET_MESSAGE, + message: { + type, + text, + }, + }; +} diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/constants.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/constants.js new file mode 100644 index 00000000000..2b5793ddc2c --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/constants.js @@ -0,0 +1,2 @@ +export const STORE_KEY = 'wc-admin-helper/remote-spec-validator'; +export const API_NAMESPACE = '/wc-admin-test-helper'; diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/index.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/index.js new file mode 100644 index 00000000000..e476479ea88 --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/index.js @@ -0,0 +1,22 @@ +/** + * External dependencies + */ +import { registerStore } from '@wordpress/data'; +import { controls } from '@wordpress/data-controls'; + +/** + * Internal dependencies + */ +import * as actions from './actions'; +import * as resolvers from './resolvers'; +import * as selectors from './selectors'; +import reducer from './reducer'; +import { STORE_KEY } from './constants'; + +export default registerStore( STORE_KEY, { + actions, + selectors, + resolvers, + controls, + reducer, +} ); diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/reducer.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/reducer.js new file mode 100644 index 00000000000..ec265f924cb --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/reducer.js @@ -0,0 +1,25 @@ +/** + * Internal dependencies + */ +import TYPES from './action-types'; + +const DEFAULT_STATE = { + message: { + type: null, + text: null, + }, +}; + +const reducer = ( state = DEFAULT_STATE, action ) => { + switch ( action.type ) { + case TYPES.SET_MESSAGE: + return { + ...state, + message: action.message, + }; + default: + return state; + } +}; + +export default reducer; diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/resolvers.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/resolvers.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/selectors.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/selectors.js new file mode 100644 index 00000000000..8fc8bbdff3c --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/data/selectors.js @@ -0,0 +1,3 @@ +export function getMessage( state ) { + return state.message; +} diff --git a/plugins/woocommerce-beta-tester/src/remote-spec-validator/index.js b/plugins/woocommerce-beta-tester/src/remote-spec-validator/index.js new file mode 100644 index 00000000000..c5066e36b78 --- /dev/null +++ b/plugins/woocommerce-beta-tester/src/remote-spec-validator/index.js @@ -0,0 +1,74 @@ +/** + * External dependencies + */ +import { withDispatch, withSelect } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { STORE_KEY } from './data/constants'; +import './data'; + +function RemoteSpecValidator( { validate, message, setMessage } ) { + const exampleText = JSON.stringify( + [ + { + type: 'plugin_version', + plugin: 'woocommerce', + version: '6.5.0-dev', + operator: '>=', + }, + ], + null, + 4 + ); + const [ spec, setSpec ] = useState( exampleText ); + return ( + <> +

Paste your Remote Spec rule and click Validate button.

+
+