Skip to content

Commit f826ddb

Browse files
authored
Merge branch 'trunk' into fix/65068-oembed-provider-validation
2 parents 92839da + 67094ee commit f826ddb

12 files changed

Lines changed: 133 additions & 61 deletions

File tree

src/wp-includes/abilities-api/class-wp-ability.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,15 +502,27 @@ public function validate_input( $input = null ) {
502502
*
503503
* @param callable $callback The callable to invoke.
504504
* @param mixed $input Optional. The input data for the ability. Default `null`.
505-
* @return mixed The result of the callable execution.
505+
* @return mixed The result of the callable execution, or a `WP_Error` if the callback threw.
506506
*/
507507
protected function invoke_callback( callable $callback, $input = null ) {
508508
$args = array();
509509
if ( ! empty( $this->get_input_schema() ) ) {
510510
$args[] = $input;
511511
}
512512

513-
return $callback( ...$args );
513+
try {
514+
return $callback( ...$args );
515+
} catch ( Throwable $e ) {
516+
return new WP_Error(
517+
'ability_callback_exception',
518+
sprintf(
519+
/* translators: 1: Ability name, 2: Exception message. */
520+
__( 'Ability "%1$s" callback threw an exception: %2$s' ),
521+
esc_html( $this->name ),
522+
esc_html( $e->getMessage() )
523+
)
524+
);
525+
}
514526
}
515527

516528
/**

src/wp-includes/ai-client.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,22 @@
1717
* @return bool Whether AI features are supported.
1818
*/
1919
function wp_supports_ai(): bool {
20-
$is_enabled = defined( 'WP_AI_SUPPORT' ) ? WP_AI_SUPPORT : true;
20+
// Return early if AI is disabled by the current environment.
21+
if ( defined( 'WP_AI_SUPPORT' ) && ! WP_AI_SUPPORT ) {
22+
return false;
23+
}
2124

2225
/**
23-
* Filters whether the current request should use AI.
26+
* Filters whether the current request can use AI.
2427
*
2528
* This allows plugins and 3rd-party code to disable AI features on a per-request basis, or to even override explicit
2629
* preferences defined by the site owner.
2730
*
2831
* @since 7.0.0
2932
*
30-
* @param bool $is_enabled Whether the current request should use AI. Default to WP_AI_SUPPORT constant, or true if
31-
* the constant is not defined.
33+
* @param bool $is_enabled Whether AI is available. Default to true.
3234
*/
33-
return (bool) apply_filters( 'wp_supports_ai', $is_enabled );
35+
return (bool) apply_filters( 'wp_supports_ai', true );
3436
}
3537

3638
/**

tests/phpunit/tests/abilities-api/wpAbility.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,54 @@ public function test_execute_no_input() {
497497
$this->assertSame( 42, $ability->execute() );
498498
}
499499

500+
/**
501+
* Tests that an exception thrown by the execute callback is converted to a WP_Error
502+
* instead of being propagated as an uncaught throwable.
503+
*
504+
* @ticket 65058
505+
*/
506+
public function test_execute_catches_callback_exception() {
507+
$args = array_merge(
508+
self::$test_ability_properties,
509+
array(
510+
'execute_callback' => static function (): int {
511+
throw new RuntimeException( 'boom' );
512+
},
513+
)
514+
);
515+
516+
$ability = new WP_Ability( self::$test_ability_name, $args );
517+
$result = $ability->execute();
518+
519+
$this->assertWPError( $result, 'Ability::execute() should return WP_Error when the callback throws.' );
520+
$this->assertSame( 'ability_callback_exception', $result->get_error_code() );
521+
$this->assertStringContainsString( 'boom', $result->get_error_message() );
522+
}
523+
524+
/**
525+
* Tests that an exception thrown by the permission callback is converted to a WP_Error
526+
* instead of being propagated as an uncaught throwable.
527+
*
528+
* @ticket 65058
529+
*/
530+
public function test_check_permissions_catches_callback_exception() {
531+
$args = array_merge(
532+
self::$test_ability_properties,
533+
array(
534+
'permission_callback' => static function (): bool {
535+
throw new RuntimeException( 'permission exploded' );
536+
},
537+
)
538+
);
539+
540+
$ability = new WP_Ability( self::$test_ability_name, $args );
541+
$result = $ability->check_permissions();
542+
543+
$this->assertWPError( $result, 'Ability::check_permissions() should return WP_Error when the callback throws.' );
544+
$this->assertSame( 'ability_callback_exception', $result->get_error_code() );
545+
$this->assertStringContainsString( 'permission exploded', $result->get_error_message() );
546+
}
547+
500548
/**
501549
* Tests that before_execute_ability action is fired with correct parameters.
502550
*

tests/phpunit/tests/admin/includesTheme.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ public function test_get_theme_featured_list_api() {
241241
*
242242
* Differences in the structure can also trigger failure by causing PHP notices/warnings.
243243
*
244-
* @group external-http
245244
* @ticket 28121
246245
*/
247246
public function test_get_theme_featured_list_hardcoded() {

tests/phpunit/tests/blocks/wpBlockTypeRegistry.php

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* @since 5.0.0
88
*
99
* @group blocks
10+
*
11+
* @coversDefaultClass WP_Block_Type_Registry
1012
*/
1113
class Tests_Blocks_wpBlockTypeRegistry extends WP_UnitTestCase {
1214

@@ -41,57 +43,42 @@ public function tear_down() {
4143
}
4244

4345
/**
44-
* Should reject numbers
46+
* Should reject invalid block names.
4547
*
4648
* @ticket 45097
4749
*
48-
* @expectedIncorrectUsage WP_Block_Type_Registry::register
49-
*/
50-
public function test_invalid_non_string_names() {
51-
$result = $this->registry->register( 1, array() );
52-
$this->assertFalse( $result );
53-
}
54-
55-
/**
56-
* Should reject blocks without a namespace
50+
* @covers ::register
5751
*
58-
* @ticket 45097
52+
* @dataProvider data_invalid_block_names
5953
*
6054
* @expectedIncorrectUsage WP_Block_Type_Registry::register
6155
*/
62-
public function test_invalid_names_without_namespace() {
63-
$result = $this->registry->register( 'paragraph', array() );
56+
public function test_invalid_block_names( $name ) {
57+
$result = $this->registry->register( $name, array() );
6458
$this->assertFalse( $result );
6559
}
6660

6761
/**
68-
* Should reject blocks with invalid characters
69-
*
70-
* @ticket 45097
62+
* Data provider for test_invalid_block_names().
7163
*
72-
* @expectedIncorrectUsage WP_Block_Type_Registry::register
64+
* @return array<string, array{ 0: mixed }>
7365
*/
74-
public function test_invalid_characters() {
75-
$result = $this->registry->register( 'still/_doing_it_wrong', array() );
76-
$this->assertFalse( $result );
66+
public function data_invalid_block_names(): array {
67+
return array(
68+
'non-string name' => array( 1 ),
69+
'no namespace' => array( 'paragraph' ),
70+
'invalid characters' => array( 'still/_doing_it_wrong' ),
71+
'uppercase characters' => array( 'Core/Paragraph' ),
72+
);
7773
}
7874

7975
/**
80-
* Should reject blocks with uppercase characters
76+
* Should accept valid block names.
8177
*
8278
* @ticket 45097
8379
*
84-
* @expectedIncorrectUsage WP_Block_Type_Registry::register
85-
*/
86-
public function test_uppercase_characters() {
87-
$result = $this->registry->register( 'Core/Paragraph', array() );
88-
$this->assertFalse( $result );
89-
}
90-
91-
/**
92-
* Should accept valid block names
93-
*
94-
* @ticket 45097
80+
* @covers ::register
81+
* @covers ::get_registered
9582
*/
9683
public function test_register_block_type() {
9784
$name = 'core/paragraph';
@@ -106,10 +93,12 @@ public function test_register_block_type() {
10693
}
10794

10895
/**
109-
* Should fail to re-register the same block
96+
* Should fail to re-register the same block.
11097
*
11198
* @ticket 45097
11299
*
100+
* @covers ::register
101+
*
113102
* @expectedIncorrectUsage WP_Block_Type_Registry::register
114103
*/
115104
public function test_register_block_type_twice() {
@@ -125,9 +114,11 @@ public function test_register_block_type_twice() {
125114
}
126115

127116
/**
128-
* Should accept a WP_Block_Type instance
117+
* Should accept a WP_Block_Type instance.
129118
*
130119
* @ticket 45097
120+
*
121+
* @covers ::register
131122
*/
132123
public function test_register_block_type_instance() {
133124
$block_type = new WP_Fake_Block_Type( 'core/fake' );
@@ -137,10 +128,12 @@ public function test_register_block_type_instance() {
137128
}
138129

139130
/**
140-
* Unregistering should fail if a block is not registered
131+
* Unregistering should fail if a block is not registered.
141132
*
142133
* @ticket 45097
143134
*
135+
* @covers ::unregister
136+
*
144137
* @expectedIncorrectUsage WP_Block_Type_Registry::unregister
145138
*/
146139
public function test_unregister_not_registered_block() {
@@ -149,9 +142,12 @@ public function test_unregister_not_registered_block() {
149142
}
150143

151144
/**
152-
* Should unregister existing blocks
145+
* Should unregister existing blocks.
153146
*
154147
* @ticket 45097
148+
*
149+
* @covers ::unregister
150+
* @covers ::is_registered
155151
*/
156152
public function test_unregister_block_type() {
157153
$name = 'core/paragraph';
@@ -168,6 +164,8 @@ public function test_unregister_block_type() {
168164

169165
/**
170166
* @ticket 45097
167+
*
168+
* @covers ::get_all_registered
171169
*/
172170
public function test_get_all_registered() {
173171
$names = array( 'core/paragraph', 'core/image', 'core/blockquote' );

tests/phpunit/tests/link/getAdjacentPost.php

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -477,14 +477,14 @@ public function test_get_adjacent_post_term_array_processing_order() {
477477

478478
// Should find post_one (previous post that shares term1).
479479
$this->assertInstanceOf( WP_Post::class, $result );
480-
$this->assertEquals( $post1_id, $result->ID );
480+
$this->assertSame( $post1_id, $result->ID );
481481

482482
// Test next post.
483483
$result = get_adjacent_post( true, array( $term2_id ), false, 'wptests_tax' );
484484

485485
// Should find post_three (next post that shares term1).
486486
$this->assertInstanceOf( WP_Post::class, $result );
487-
$this->assertEquals( $post3_id, $result->ID );
487+
$this->assertSame( $post3_id, $result->ID );
488488
}
489489

490490
/**
@@ -614,12 +614,12 @@ public function test_get_adjacent_post_with_identical_dates() {
614614
// Previous post should be the 2nd post (lower ID, same date).
615615
$previous = get_adjacent_post( false, '', true );
616616
$this->assertInstanceOf( 'WP_Post', $previous );
617-
$this->assertEquals( $post_ids[1], $previous->ID );
617+
$this->assertSame( $post_ids[1], $previous->ID );
618618

619619
// Next post should be the 4th post (higher ID, same date).
620620
$next = get_adjacent_post( false, '', false );
621621
$this->assertInstanceOf( 'WP_Post', $next );
622-
$this->assertEquals( $post_ids[3], $next->ID );
622+
$this->assertSame( $post_ids[3], $next->ID );
623623
}
624624

625625
/**
@@ -661,38 +661,38 @@ public function test_get_adjacent_post_mixed_dates_with_identical_groups() {
661661
// Previous should be the early post (different date).
662662
$previous = get_adjacent_post( false, '', true );
663663
$this->assertInstanceOf( 'WP_Post', $previous );
664-
$this->assertEquals( $post_early, $previous->ID );
664+
$this->assertSame( $post_early, $previous->ID );
665665

666666
// Next should be the second identical post (same date, higher ID).
667667
$next = get_adjacent_post( false, '', false );
668668
$this->assertInstanceOf( 'WP_Post', $next );
669-
$this->assertEquals( $post_ids[1], $next->ID );
669+
$this->assertSame( $post_ids[1], $next->ID );
670670

671671
// Test from middle identical post.
672672
$this->go_to( get_permalink( $post_ids[1] ) );
673673

674674
// Previous should be the first identical post (same date, lower ID).
675675
$previous = get_adjacent_post( false, '', true );
676676
$this->assertInstanceOf( 'WP_Post', $previous );
677-
$this->assertEquals( $post_ids[0], $previous->ID );
677+
$this->assertSame( $post_ids[0], $previous->ID );
678678

679679
// Next should be the third identical post (same date, higher ID).
680680
$next = get_adjacent_post( false, '', false );
681681
$this->assertInstanceOf( 'WP_Post', $next );
682-
$this->assertEquals( $post_ids[2], $next->ID );
682+
$this->assertSame( $post_ids[2], $next->ID );
683683

684684
// Test from last identical post.
685685
$this->go_to( get_permalink( $post_ids[2] ) );
686686

687687
// Previous should be the second identical post (same date, lower ID).
688688
$previous = get_adjacent_post( false, '', true );
689689
$this->assertInstanceOf( 'WP_Post', $previous );
690-
$this->assertEquals( $post_ids[1], $previous->ID );
690+
$this->assertSame( $post_ids[1], $previous->ID );
691691

692692
// Next should be the late post (different date).
693693
$next = get_adjacent_post( false, '', false );
694694
$this->assertInstanceOf( 'WP_Post', $next );
695-
$this->assertEquals( $post_late, $next->ID );
695+
$this->assertSame( $post_late, $next->ID );
696696
}
697697

698698
/**
@@ -719,26 +719,26 @@ public function test_get_adjacent_post_navigation_through_identical_dates() {
719719

720720
// From post 1, next should be post 2.
721721
$next = get_adjacent_post( false, '', false );
722-
$this->assertEquals( $post_ids[1], $next->ID );
722+
$this->assertSame( $post_ids[1], $next->ID );
723723

724724
// From post 2, previous should be post 1, next should be post 3.
725725
$this->go_to( get_permalink( $post_ids[1] ) );
726726
$previous = get_adjacent_post( false, '', true );
727-
$this->assertEquals( $post_ids[0], $previous->ID );
727+
$this->assertSame( $post_ids[0], $previous->ID );
728728
$next = get_adjacent_post( false, '', false );
729-
$this->assertEquals( $post_ids[2], $next->ID );
729+
$this->assertSame( $post_ids[2], $next->ID );
730730

731731
// From post 3, previous should be post 2, next should be post 4.
732732
$this->go_to( get_permalink( $post_ids[2] ) );
733733
$previous = get_adjacent_post( false, '', true );
734-
$this->assertEquals( $post_ids[1], $previous->ID );
734+
$this->assertSame( $post_ids[1], $previous->ID );
735735
$next = get_adjacent_post( false, '', false );
736-
$this->assertEquals( $post_ids[3], $next->ID );
736+
$this->assertSame( $post_ids[3], $next->ID );
737737

738738
// From post 4, previous should be post 3.
739739
$this->go_to( get_permalink( $post_ids[3] ) );
740740
$previous = get_adjacent_post( false, '', true );
741-
$this->assertEquals( $post_ids[2], $previous->ID );
741+
$this->assertSame( $post_ids[2], $previous->ID );
742742
}
743743

744744
/**
@@ -777,6 +777,6 @@ public function test_get_adjacent_post_identical_dates_with_category() {
777777

778778
$next = get_adjacent_post( true, '', false, 'category' );
779779
$this->assertInstanceOf( 'WP_Post', $next );
780-
$this->assertEquals( $post_ids[3], $next->ID ); // Post 4 (in category)
780+
$this->assertSame( $post_ids[3], $next->ID ); // Post 4 (in category)
781781
}
782782
}

tests/phpunit/tests/multisite/getBlogDetails.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* @group ms-required
66
* @group ms-site
77
* @group multisite
8+
*
9+
* @covers ::get_blog_details
810
*/
911
class Tests_Multisite_GetBlogDetails extends WP_UnitTestCase {
1012

0 commit comments

Comments
 (0)