Skip to content

Commit 92952de

Browse files
Add comprehensive unit tests for get_post()
Adds a new test suite for get_post() to ensure complete coverage of: - Global $post retrieval with various empty-like inputs. - Different input types (ID, object, WP_Post instance). - All output formats (OBJECT, ARRAY_A, ARRAY_N). - Filter application and field sanitization. - Handling of unrecognized output types. Co-authored-by: gemini-cli <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 917ccfc commit 92952de

1 file changed

Lines changed: 294 additions & 0 deletions

File tree

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
<?php
2+
3+
/**
4+
* @group post
5+
* @group template
6+
*
7+
* @covers ::get_post
8+
*/
9+
class Tests_Post_GetPost extends WP_UnitTestCase {
10+
11+
private static int $post_id;
12+
13+
public static function set_up_before_class(): void {
14+
parent::set_up_before_class();
15+
$post_id = self::factory()->post->create();
16+
assert( is_int( $post_id ) );
17+
self::$post_id = $post_id;
18+
19+
global $wpdb;
20+
$wpdb->update(
21+
$wpdb->posts,
22+
array( 'post_title' => 'Test <script>document.write("Hello, World!")</script> Title' ),
23+
array( 'ID' => self::$post_id )
24+
);
25+
clean_post_cache( self::$post_id );
26+
}
27+
28+
public function tear_down(): void {
29+
$GLOBALS['post'] = null;
30+
parent::tear_down();
31+
}
32+
33+
/**
34+
* Tests that the global $post is returned.
35+
*
36+
* @ticket 64238
37+
*/
38+
public function test_get_post_global(): void {
39+
global $post;
40+
$post = $this->get_test_post_instance();
41+
$this->assertSame( $post, get_post() );
42+
$this->assertSame( $post, get_post( null ) );
43+
$this->assertSame( $post, get_post( 0 ) );
44+
$this->assertSame( $post, get_post( '0' ) ); // @phpstan-ignore argument.type (Testing another value that is empty.)
45+
$this->assertSame( $post, get_post( '' ) ); // @phpstan-ignore argument.type (Testing another value that is empty.)
46+
$this->assertSame( $post, get_post( false ) ); // @phpstan-ignore argument.type (Testing another value that is empty.)
47+
$this->assertSame( $post->to_array(), get_post( null, ARRAY_A ) );
48+
$this->assertSame( array_values( $post->to_array() ), get_post( null, ARRAY_N ) );
49+
}
50+
51+
/**
52+
* Tests inputs and outputs.
53+
*
54+
* @ticket 64238
55+
* @dataProvider data_provider_to_test_get_post
56+
*
57+
* @param callable(): mixed $input Input to get_post.
58+
* @param string $output The required return type.
59+
* @param string $filter Type of filter to apply.
60+
* @param callable(): (int|null) $expected_id Expected ID of the returned post, or null if expecting null.
61+
*/
62+
public function test_get_post( callable $input, string $output, string $filter, callable $expected_id ): void {
63+
$input_val = $input();
64+
$expected_id_val = $expected_id();
65+
66+
$post = get_post( $input_val, $output, $filter );
67+
68+
if ( null === $expected_id_val ) {
69+
$this->assertNull( $post );
70+
return;
71+
}
72+
73+
$this->assertNotNull( $post );
74+
75+
if ( ARRAY_A === $output ) {
76+
$this->assertIsArray( $post );
77+
$this->assertArrayHasKey( 'ID', $post );
78+
$this->assertSame( $expected_id_val, $post['ID'] );
79+
} elseif ( ARRAY_N === $output ) {
80+
$this->assertIsArray( $post );
81+
$this->assertContains( $expected_id_val, $post );
82+
} else {
83+
$this->assertInstanceOf( WP_Post::class, $post );
84+
85+
if ( 'raw' === $filter && $input_val instanceof WP_Post ) {
86+
$this->assertSame( $input_val, $post, 'Should return the same instance when input is a WP_Post and filter is raw.' );
87+
}
88+
89+
$this->assertSame( $expected_id_val, $post->ID );
90+
}
91+
92+
if ( $post instanceof WP_Post ) {
93+
$this->assertSame( $filter, $post->filter );
94+
}
95+
}
96+
97+
/**
98+
* Tests that sanitize_post() is called as expected.
99+
*
100+
* @ticket 64238
101+
* @dataProvider data_provider_to_test_get_post_sanitization
102+
*
103+
* @param string $filter Type of filter to apply.
104+
* @param string $expected Expected sanitized post title.
105+
*/
106+
public function test_get_post_sanitization( string $filter, string $expected ): void {
107+
$post = get_post( self::$post_id, OBJECT, $filter );
108+
109+
$this->assertInstanceOf( WP_Post::class, $post );
110+
$this->assertSame( $expected, $post->post_title );
111+
$this->assertSame( $filter, $post->filter );
112+
}
113+
114+
115+
/**
116+
* Data provider for test_get_post_sanitization.
117+
*
118+
* @return array<string, array{
119+
* filter: string,
120+
* expected: string,
121+
* }>
122+
*/
123+
public function data_provider_to_test_get_post_sanitization(): array {
124+
return array(
125+
'Raw filter' => array(
126+
'filter' => 'raw',
127+
'expected' => 'Test <script>document.write("Hello, World!")</script> Title',
128+
),
129+
'Edit filter' => array(
130+
'filter' => 'edit',
131+
'expected' => 'Test &lt;script&gt;document.write(&quot;Hello, World!&quot;)&lt;/script&gt; Title',
132+
),
133+
'Display filter' => array(
134+
'filter' => 'display',
135+
'expected' => 'Test <script>document.write("Hello, World!")</script> Title',
136+
),
137+
'Attribute filter' => array(
138+
'filter' => 'attribute',
139+
'expected' => 'Test &lt;script&gt;document.write(&quot;Hello, World!&quot;)&lt;/script&gt; Title',
140+
),
141+
'JS filter' => array(
142+
'filter' => 'js',
143+
'expected' => 'Test &lt;script&gt;document.write(&quot;Hello, World!&quot;)&lt;/script&gt; Title',
144+
),
145+
);
146+
}
147+
148+
/**
149+
* Data provider for test_get_post.
150+
*
151+
* @return array<string, array{
152+
* input: Closure(): mixed,
153+
* output: string,
154+
* filter: string,
155+
* expected_id: Closure(): (int|null),
156+
* }>
157+
*/
158+
public function data_provider_to_test_get_post(): array {
159+
return array(
160+
'Valid ID' => array(
161+
'input' => fn() => self::$post_id,
162+
'output' => OBJECT,
163+
'filter' => 'raw',
164+
'expected_id' => fn() => self::$post_id,
165+
),
166+
'WP_Post instance' => array(
167+
'input' => fn() => $this->get_test_post_instance(),
168+
'output' => OBJECT,
169+
'filter' => 'raw',
170+
'expected_id' => fn() => self::$post_id,
171+
),
172+
'Valid numeric string ID' => array(
173+
'input' => fn() => (string) self::$post_id,
174+
'output' => OBJECT,
175+
'filter' => 'raw',
176+
'expected_id' => fn() => self::$post_id,
177+
),
178+
'Object with raw filter' => array(
179+
'input' => fn() => (object) array(
180+
'ID' => self::$post_id,
181+
'filter' => 'raw',
182+
),
183+
'output' => OBJECT,
184+
'filter' => 'raw',
185+
'expected_id' => fn() => self::$post_id,
186+
),
187+
'Object with non-raw filter and ID' => array(
188+
'input' => fn() => (object) array(
189+
'ID' => self::$post_id,
190+
'filter' => 'edit',
191+
),
192+
'output' => OBJECT,
193+
'filter' => 'raw',
194+
'expected_id' => fn() => self::$post_id,
195+
),
196+
'Object with non-raw filter and NO ID' => array(
197+
'input' => fn() => (object) array( 'filter' => 'edit' ),
198+
'output' => OBJECT,
199+
'filter' => 'raw',
200+
'expected_id' => fn() => null,
201+
),
202+
'Invalid ID' => array(
203+
'input' => fn() => 9999999,
204+
'output' => OBJECT,
205+
'filter' => 'raw',
206+
'expected_id' => fn() => null,
207+
),
208+
'ARRAY_A output' => array(
209+
'input' => fn() => self::$post_id,
210+
'output' => ARRAY_A,
211+
'filter' => 'raw',
212+
'expected_id' => fn() => self::$post_id,
213+
),
214+
'ARRAY_N output' => array(
215+
'input' => fn() => self::$post_id,
216+
'output' => ARRAY_N,
217+
'filter' => 'raw',
218+
'expected_id' => fn() => self::$post_id,
219+
),
220+
'Display filter' => array(
221+
'input' => fn() => self::$post_id,
222+
'output' => OBJECT,
223+
'filter' => 'display',
224+
'expected_id' => fn() => self::$post_id,
225+
),
226+
'Empty input and no global post' => array(
227+
'input' => fn() => null,
228+
'output' => OBJECT,
229+
'filter' => 'raw',
230+
'expected_id' => fn() => null,
231+
),
232+
'0 input and no global post' => array(
233+
'input' => fn() => 0,
234+
'output' => OBJECT,
235+
'filter' => 'raw',
236+
'expected_id' => fn() => null,
237+
),
238+
'Non-numeric string' => array(
239+
'input' => fn() => 'not-a-post-id',
240+
'output' => OBJECT,
241+
'filter' => 'raw',
242+
'expected_id' => fn() => null,
243+
),
244+
'Boolean false' => array(
245+
'input' => fn() => false,
246+
'output' => OBJECT,
247+
'filter' => 'raw',
248+
'expected_id' => fn() => null,
249+
),
250+
'Object with invalid ID' => array(
251+
'input' => fn() => (object) array(
252+
'ID' => 9999999,
253+
'filter' => 'edit',
254+
),
255+
'output' => OBJECT,
256+
'filter' => 'raw',
257+
'expected_id' => fn() => null,
258+
),
259+
'Object with no filter' => array(
260+
'input' => fn() => (object) array(
261+
'ID' => 123,
262+
'post_title' => 'Test',
263+
'extra' => 'prop',
264+
),
265+
'output' => OBJECT,
266+
'filter' => 'raw',
267+
'expected_id' => fn() => 123,
268+
),
269+
'Invalid output type' => array(
270+
'input' => fn() => self::$post_id,
271+
'output' => 'invalid',
272+
'filter' => 'raw',
273+
'expected_id' => fn() => self::$post_id,
274+
),
275+
'Invalid output value "WP_Post"' => array(
276+
'input' => fn() => self::$post_id,
277+
'output' => 'WP_Post',
278+
'filter' => 'raw',
279+
'expected_id' => fn() => self::$post_id,
280+
),
281+
);
282+
}
283+
284+
/**
285+
* Gets a test post instance.
286+
*
287+
* @return WP_Post Post object.
288+
*/
289+
private function get_test_post_instance(): WP_Post {
290+
$post = WP_Post::get_instance( self::$post_id );
291+
$this->assertInstanceOf( WP_Post::class, $post );
292+
return $post;
293+
}
294+
}

0 commit comments

Comments
 (0)