Skip to content
Merged
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
10 changes: 8 additions & 2 deletions inc/compatibility/elementor.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,17 @@ public function enqueue() {
* @return \WP_REST_Response|\WP_Error
*/
public function alter_global_colors_front_end( $response, $handler, \WP_REST_Request $request ) {
if ( is_wp_error( $response ) ) {
$route = $request->get_route();

// Elementor never knows Neve IDs, so not-found is expected on the colors route.
$is_color_not_found = is_wp_error( $response )
&& 'global_not_found' === $response->get_error_code()
&& 0 === strpos( $route, '/elementor/v1/globals/colors/' );

if ( is_wp_error( $response ) && ! $is_color_not_found ) {
return $response;
}

$route = $request->get_route();
$rest_to_slugs = [
'nvprimaryaccent' => 'nv-primary-accent',
'nvsecondaryaccent' => 'nv-secondary-accent',
Expand Down
102 changes: 98 additions & 4 deletions tests/test-elementor-compatibility.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,53 @@ class TestElementorCompatibility extends WP_UnitTestCase {
*/
const COLOR_ROUTE = self::GLOBALS_ROUTE . '/colors/nvprimaryaccent';

/**
* Reset the static custom colors so they don't leak into other tests.
*/
public function tearDown(): void {
$this->set_custom_global_colors( null );

parent::tearDown();
}

/**
* Set the static custom global colors on the compatibility class.
*
* @param array<string, array{label: string, val: string}>|null $colors Custom global colors, or null for the unloaded default.
*/
private function set_custom_global_colors( ?array $colors ): void {
$custom_colors = new ReflectionProperty( \Neve\Compatibility\Elementor::class, 'custom_global_colors' );
$custom_colors->setAccessible( true );
$custom_colors->setValue( null, $colors );
}

/**
* Build a compatibility instance in a post-init state.
*
* Avoids ::init(), which needs ELEMENTOR_VERSION defined and would leak that
* constant plus its hooks into the rest of the suite.
*
* @param array<string, array{label: string, val: string}> $custom_global_colors Custom global colors theme mod value.
*
* @return \Neve\Compatibility\Elementor
*/
private function get_elementor_compat() {
private function get_elementor_compat( array $custom_global_colors = [] ) {
$elementor = new \Neve\Compatibility\Elementor();

$custom_colors = new ReflectionProperty( $elementor, 'custom_global_colors' );
$custom_colors->setAccessible( true );
$custom_colors->setValue( $elementor, [] );
$this->set_custom_global_colors( $custom_global_colors );

return $elementor;
}

/**
* Elementor's error for a global ID missing from its kit.
*
* @return WP_Error
*/
private function get_global_not_found_error() {
return new WP_Error( 'global_not_found', 'The Global value you are trying to use is not available.', [ 'status' => 404 ] );
}

/**
* Errored responses should be passed through untouched.
*/
Expand Down Expand Up @@ -89,4 +118,69 @@ public function test_global_colors_front_end_overrides_color() {
$this->assertSame( 'nvprimaryaccent', $data['id'] );
$this->assertArrayHasKey( 'value', $data );
}

/**
* Elementor's not-found error for a Neve color should resolve to the palette color.
*/
public function test_global_colors_front_end_resolves_neve_color_on_not_found() {
$elementor = $this->get_elementor_compat();
$request = new WP_REST_Request( 'GET', self::COLOR_ROUTE );

$filtered = $elementor->alter_global_colors_front_end( $this->get_global_not_found_error(), [], $request );

$this->assertInstanceOf( WP_REST_Response::class, $filtered );

$palettes = neve_get_global_colors_default( true );
$expected = $palettes['palettes'][ $palettes['activePalette'] ]['colors']['nv-primary-accent'];
$data = $filtered->get_data();

$this->assertSame( 'nvprimaryaccent', $data['id'] );
$this->assertSame( neve_sanitize_colors( $expected ), $data['value'] );
}

/**
* Elementor's not-found error for a custom Neve color should resolve to that color.
*/
public function test_global_colors_front_end_resolves_custom_color_on_not_found() {
$elementor = $this->get_elementor_compat(
[
'custom' => [
'label' => 'Custom',
'val' => '#123456',
],
]
);
$request = new WP_REST_Request( 'GET', self::GLOBALS_ROUTE . '/colors/custom' );

$filtered = $elementor->alter_global_colors_front_end( $this->get_global_not_found_error(), [], $request );

$this->assertInstanceOf( WP_REST_Response::class, $filtered );

$data = $filtered->get_data();

$this->assertSame( 'custom', $data['id'] );
$this->assertSame( '#123456', $data['value'] );
}

/**
* Elementor's not-found error for a non-Neve color should be passed through untouched.
*/
public function test_global_colors_front_end_passes_through_not_found_for_unknown_color() {
$elementor = $this->get_elementor_compat();
$request = new WP_REST_Request( 'GET', self::GLOBALS_ROUTE . '/colors/primary' );
$error = $this->get_global_not_found_error();

$this->assertSame( $error, $elementor->alter_global_colors_front_end( $error, [], $request ) );
}

/**
* Elementor's not-found error on a non-color route should be passed through for a Neve ID.
*/
public function test_global_colors_front_end_passes_through_not_found_on_typography_route() {
$elementor = $this->get_elementor_compat();
$request = new WP_REST_Request( 'GET', self::GLOBALS_ROUTE . '/typography/nvprimaryaccent' );
$error = $this->get_global_not_found_error();

$this->assertSame( $error, $elementor->alter_global_colors_front_end( $error, [], $request ) );
}
}
Loading