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
This commit is contained in:
Moon 2024-02-28 15:47:15 -08:00 committed by GitHub
parent 467d16f212
commit 839ea67577
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 243 additions and 2 deletions

View File

@ -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';

View File

@ -0,0 +1,34 @@
<?php
defined( 'ABSPATH' ) || exit;
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\RuleEvaluator;
register_woocommerce_admin_test_helper_rest_route(
'/remote-spec-validator/validate',
'wca_test_helper_validate_remote_spec',
array(
'methods' => '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 );
}

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add Remote Spec Rule validator

View File

@ -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",

View File

@ -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;
} );
} );

View File

@ -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: <RestAPIFilters />,
},
{
name: 'remote-spec-validator',
title: 'Remote Spec Rule Validator',
content: <RemoteSpecValidator />,
},
] );
export function App() {

View File

@ -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;
}
}

View File

@ -0,0 +1,6 @@
const TYPES = {
VALIDATE: 'VALIDATE',
SET_MESSAGE: 'SET_MESSAGE',
};
export default TYPES;

View File

@ -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,
},
};
}

View File

@ -0,0 +1,2 @@
export const STORE_KEY = 'wc-admin-helper/remote-spec-validator';
export const API_NAMESPACE = '/wc-admin-test-helper';

View File

@ -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,
} );

View File

@ -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;

View File

@ -0,0 +1,3 @@
export function getMessage( state ) {
return state.message;
}

View File

@ -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 (
<>
<p>Paste your Remote Spec rule and click Validate button.</p>
<div id="wc-admin-test-helper-remote-spec-validator">
<textarea
value={ spec }
onChange={ ( e ) => setSpec( e.target.value ) }
/>
{ message && message.text && (
<div className={ message.type }>{ message.text }</div>
) }
<input
type="button"
className="button btn-primary btn-validate"
value="Validate"
onClick={ () => {
try {
if ( JSON.parse( spec ) ) {
setMessage( null, null );
}
validate( spec );
} catch ( e ) {
setMessage( 'error', 'Invalid JSON' );
}
} }
/>
</div>
</>
);
}
export default compose(
withSelect( ( select ) => {
const { getMessage } = select( STORE_KEY );
return {
message: getMessage(),
};
} ),
withDispatch( ( dispatch ) => {
const { validate, setMessage } = dispatch( STORE_KEY );
return {
validate,
setMessage,
};
} )
)( RemoteSpecValidator );