Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion admin/class-enqueue-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public static function maybe_enqueue_admin_and_editor_app_scripts() {
'postID' => $post_id,
'nonce' => wp_create_nonce( 'ajax-nonce' ),
'edacApiUrl' => esc_url_raw( rest_url( 'accessibility-checker/v1' ) ),
'fixesRestUrl' => esc_url_raw( rest_url( 'edac/v1' ) ),
'fixesRestUrl' => esc_url_raw( rest_url( 'accessibility-checker/v1' ) ),
'restNonce' => wp_create_nonce( 'wp_rest' ),
'proUrl' => esc_url_raw( edac_generate_link_type( [ 'utm_content' => '__name__' ] ) ),
'hasDismissEndpoint' => method_exists( \EDAC\Inc\REST_Api::class, 'dismiss_issue' ),
Expand Down
41 changes: 20 additions & 21 deletions includes/classes/Fixes/FixesManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,34 +261,27 @@ public static function maybe_show_accessibility_ready_conflict_notice() {
* @return void
*/
public function register_rest_routes() {
register_rest_route(
'edac/v1',
'/fixes',
[
$namespaces = [
'accessibility-checker/v1',
'edac/v1', // Retained for backward compatibility while integrations migrate.
];

$routes = [
'/fixes' => [
'methods' => 'GET',
'callback' => [ $this, 'get_fixes' ],
'callback' => [ $this, 'get_fixes_settings' ],
'permission_callback' => function () {
return current_user_can( apply_filters( 'edac_filter_settings_capability', 'manage_options' ) );
},
]
);

register_rest_route(
'edac/v1',
'/fixes/update',
[
],
'/fixes/update' => [
'methods' => 'POST',
'callback' => [ $this, 'update_fix_settings' ],
'permission_callback' => function () {
return current_user_can( apply_filters( 'edac_filter_settings_capability', 'manage_options' ) );
},
]
);

register_rest_route(
'edac/v1',
'/fix-fields/(?P<slug>[a-zA-Z0-9_-]+)',
[
],
'/fix-fields/(?P<slug>[a-zA-Z0-9_-]+)' => [
'methods' => 'GET',
'callback' => [ $this, 'get_fix_fields' ],
'args' => [
Expand All @@ -300,8 +293,14 @@ public function register_rest_routes() {
'permission_callback' => function () {
return current_user_can( 'edit_posts' );
},
]
);
],
];

foreach ( $namespaces as $namespace ) {
foreach ( $routes as $route => $args ) {
register_rest_route( $namespace, $route, $args );
}
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion includes/classes/class-enqueue-frontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public static function maybe_enqueue_frontend_highlighter() {
'userCanEdit' => current_user_can( 'edit_post', $post_id ),
'edacUrl' => esc_url_raw( get_site_url() ),
'restUrl' => esc_url_raw( rest_url( 'accessibility-checker/v1' ) ),
'fixesRestUrl' => esc_url_raw( rest_url( 'edac/v1' ) ),
'fixesRestUrl' => esc_url_raw( rest_url( 'accessibility-checker/v1' ) ),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'loggedIn' => is_user_logged_in(),
'appCssUrl' => EDAC_PLUGIN_URL . 'build/css/frontendHighlighterApp.css?ver=' . EDAC_VERSION,
Expand Down
4 changes: 2 additions & 2 deletions src/issueModal/components/FixCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const FixCard = ( { slug, onSave, onError } ) => {
setIsLoading( true );
setError( null );

apiFetch( { path: `/edac/v1/fix-fields/${ slug }`, method: 'GET' } )
apiFetch( { path: `/accessibility-checker/v1/fix-fields/${ slug }`, method: 'GET' } )
.then( ( response ) => {
if ( cancelled ) {
return;
Expand Down Expand Up @@ -78,7 +78,7 @@ const FixCard = ( { slug, onSave, onError } ) => {
setNotice( null );
try {
await apiFetch( {
path: '/edac/v1/fixes/update',
path: '/accessibility-checker/v1/fixes/update',
method: 'POST',
data: { [ fixInfo.fix_slug ]: formValues },
} );
Expand Down
90 changes: 90 additions & 0 deletions tests/jest/issueModal/FixCard.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { act } from 'react';
import apiFetch from '@wordpress/api-fetch';
import FixCard from '../../../src/issueModal/components/FixCard';
import { renderReact } from '../helpers/renderReact';

jest.mock( '@wordpress/api-fetch', () => ( {
__esModule: true,
default: jest.fn(),
} ), { virtual: true } );

jest.mock( '@wordpress/components', () => ( {
Button: ( { children, type = 'button', disabled } ) => (
<button type={ type } disabled={ disabled }>{ children }</button>
),
Spinner: () => <span className="mock-spinner" aria-hidden="true">...</span>,
Notice: ( { children } ) => <div className="mock-notice">{ children }</div>,
ToggleControl: ( { label, checked, onChange } ) => (
<label>
{ label }
<input type="checkbox" checked={ checked } onChange={ ( event ) => onChange( event.target.checked ) } />
</label>
),
TextControl: ( { id, value, onChange } ) => (
<input id={ id } value={ value } onChange={ ( event ) => onChange( event.target.value ) } />
),
TextareaControl: ( { id, value, onChange } ) => (
<textarea id={ id } value={ value } onChange={ ( event ) => onChange( event.target.value ) } />
),
} ) );

const flushPromises = () => new Promise( ( resolve ) => setTimeout( resolve, 0 ) );

describe( 'FixCard', () => {
beforeEach( () => {
apiFetch.mockReset();
} );

test( 'uses the canonical namespace to load and save fix settings', async () => {
apiFetch
.mockResolvedValueOnce( {
success: true,
fix_slug: 'meta_viewport_scalable',
fix_name: 'Meta Viewport Scalable',
enabled: false,
fields: {
edac_fix_meta_viewport_scalable: {
label: 'Enable fix',
description: '',
type: 'checkbox',
value: '0',
},
},
} )
.mockResolvedValueOnce( { success: true } );

const onSave = jest.fn();
const { container, unmount } = renderReact(
<FixCard slug="meta_viewport_scalable" onSave={ onSave } onError={ jest.fn() } />,
);

await act( async () => {
await flushPromises();
} );

expect( apiFetch ).toHaveBeenNthCalledWith( 1, {
path: '/accessibility-checker/v1/fix-fields/meta_viewport_scalable',
method: 'GET',
} );

await act( async () => {
container.querySelector( 'form' ).dispatchEvent(
new Event( 'submit', { bubbles: true, cancelable: true } ),
);
await flushPromises();
} );

expect( apiFetch ).toHaveBeenNthCalledWith( 2, {
path: '/accessibility-checker/v1/fixes/update',
method: 'POST',
data: {
meta_viewport_scalable: {
edac_fix_meta_viewport_scalable: false,
},
},
} );
expect( onSave ).toHaveBeenCalledTimes( 1 );

unmount();
} );
} );
12 changes: 6 additions & 6 deletions tests/phpunit/Admin/EnqueueAdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,18 +148,17 @@ public function testLocalizedAdminDataIncludesProFlag(): void {
}

/**
* FixesRestUrl uses the edac/v1 namespace and matches rest_url().
* FixesRestUrl uses the accessibility-checker/v1 namespace and matches rest_url().
*/
public function testAdminFixesRestUrlContainsEdacV1Namespace(): void {
public function testAdminFixesRestUrlUsesAccessibilityCheckerV1Namespace(): void {
global $wp_scripts;

$this->enqueue_admin::maybe_enqueue_admin_and_editor_app_scripts();

$localized_data = (string) $wp_scripts->get_data( 'edac', 'data' );
$expected = rest_url( 'edac/v1' );
$expected = esc_url_raw( rest_url( 'accessibility-checker/v1' ) );

$this->assertStringContainsString( 'edac', $localized_data );
$this->assertStringContainsString( (string) wp_parse_url( $expected, PHP_URL_HOST ), $localized_data );
$this->assertStringContainsString( '"fixesRestUrl":"' . $expected . '"', str_replace( '\/', '/', $localized_data ) );
}

/**
Expand Down Expand Up @@ -193,13 +192,14 @@ public function testAdminFixesRestUrlRespectsCustomRestPrefix(): void {
add_filter( 'rest_url_prefix', $prefix_callback );

$this->enqueue_admin::maybe_enqueue_admin_and_editor_app_scripts();
$expected = esc_url_raw( rest_url( 'accessibility-checker/v1' ) );

remove_filter( 'rest_url_prefix', $prefix_callback );
delete_option( 'permalink_structure' );

$localized_data = (string) $wp_scripts->get_data( 'edac', 'data' );

$this->assertStringContainsString( 'custom-api', $localized_data );
$this->assertStringContainsString( '"fixesRestUrl":"' . $expected . '"', str_replace( '\/', '/', $localized_data ) );
$this->assertStringNotContainsString( 'wp-json', $localized_data );
}

Expand Down
12 changes: 6 additions & 6 deletions tests/phpunit/includes/classes/EnqueueFrontendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,13 @@ public function testLocalizedDataIncludesFixesRestUrl(): void {
}

/**
* FixesRestUrl uses the edac/v1 namespace and matches rest_url().
* FixesRestUrl uses the accessibility-checker/v1 namespace and matches rest_url().
*/
public function testFixesRestUrlContainsEdacV1Namespace(): void {
public function testFixesRestUrlUsesAccessibilityCheckerV1Namespace(): void {
$localized_data = $this->enqueueAndGetLocalizedData();
$expected = rest_url( 'edac/v1' );
$expected = esc_url_raw( rest_url( 'accessibility-checker/v1' ) );

$this->assertStringContainsString( 'edac', $localized_data );
$this->assertStringContainsString( (string) wp_parse_url( $expected, PHP_URL_HOST ), $localized_data );
$this->assertStringContainsString( '"fixesRestUrl":"' . $expected . '"', str_replace( '\/', '/', $localized_data ) );
}

/**
Expand Down Expand Up @@ -243,11 +242,12 @@ public function testFixesRestUrlRespectsCustomRestPrefix(): void {
$this->added_filters['rest_url_prefix'] = $prefix_callback;

$localized_data = $this->enqueueAndGetLocalizedData();
$expected = esc_url_raw( rest_url( 'accessibility-checker/v1' ) );

remove_filter( 'rest_url_prefix', $prefix_callback );
delete_option( 'permalink_structure' );

$this->assertStringContainsString( 'custom-api', $localized_data );
$this->assertStringContainsString( '"fixesRestUrl":"' . $expected . '"', str_replace( '\/', '/', $localized_data ) );
$this->assertStringNotContainsString( 'wp-json', $localized_data );
}

Expand Down
56 changes: 56 additions & 0 deletions tests/phpunit/includes/classes/Fixes/FixesManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,60 @@ public function test_register_fixes_handles_scalar_filter_output() {

$this->assertEmpty( $fixes_manager->get_fixes_settings() );
}

/**
* Test that current and legacy REST routes share the same configuration.
*
* @return void
*/
public function test_register_rest_routes_preserves_legacy_namespace() {
$registered_routes = rest_get_server()->get_routes();
$expected_routes = [
'/fixes' => 'GET',
'/fixes/update' => 'POST',
'/fix-fields/(?P<slug>[a-zA-Z0-9_-]+)' => 'GET',
];

foreach ( $expected_routes as $route => $method ) {
$current_route = '/accessibility-checker/v1' . $route;
$legacy_route = '/edac/v1' . $route;

$this->assertArrayHasKey( $current_route, $registered_routes );
$this->assertArrayHasKey( $legacy_route, $registered_routes );

$current_handler = $registered_routes[ $current_route ][0];
$legacy_handler = $registered_routes[ $legacy_route ][0];

$this->assertArrayHasKey( $method, $current_handler['methods'] );
$this->assertArrayHasKey( $method, $legacy_handler['methods'] );
$this->assertTrue( is_callable( $current_handler['callback'] ) );
$this->assertTrue( is_callable( $legacy_handler['callback'] ) );
$this->assertSame( $current_handler['callback'], $legacy_handler['callback'] );
$this->assertSame( $current_handler['permission_callback'], $legacy_handler['permission_callback'] );
}
}

/**
* Test that authorized requests receive the same fixes payload from both namespaces.
*
* @return void
*/
public function test_fixes_routes_return_the_same_response() {
rest_get_server();

$admin_id = self::factory()->user->create( [ 'role' => 'administrator' ] );
wp_set_current_user( $admin_id );

try {
$current_response = rest_do_request( '/accessibility-checker/v1/fixes' );
$legacy_response = rest_do_request( '/edac/v1/fixes' );

$this->assertSame( 200, $current_response->get_status() );
$this->assertSame( 200, $legacy_response->get_status() );
$this->assertSame( $current_response->get_data(), $legacy_response->get_data() );
} finally {
wp_set_current_user( 0 );
wp_delete_user( $admin_id );
}
}
}
Loading