Merge "docs: Fix typo"
[mediawiki.git] / tests / phpunit / includes / Revision / RevisionQueryInfoTest.php
blob01068cc98de781aacadac4ecf4838546ee0dcbff
1 <?php
3 namespace MediaWiki\Tests\Revision;
5 use MediaWikiIntegrationTestCase;
7 /**
8 * Tests RevisionStore against the post-migration MCR DB schema.
10 * @group RevisionStore
11 * @group Storage
12 * @group Database
14 class RevisionQueryInfoTest extends MediaWikiIntegrationTestCase {
16 protected function getRevisionQueryFields( $returnTextIdField = true ) {
17 $fields = [
18 'rev_id',
19 'rev_page',
20 'rev_timestamp',
21 'rev_minor_edit',
22 'rev_deleted',
23 'rev_len',
24 'rev_parent_id',
25 'rev_sha1',
27 if ( $returnTextIdField ) {
28 $fields[] = 'rev_text_id';
30 return $fields;
33 protected function getArchiveQueryFields( $returnTextFields = true ) {
34 $fields = [
35 'ar_id',
36 'ar_page_id',
37 'ar_namespace',
38 'ar_title',
39 'ar_rev_id',
40 'ar_timestamp',
41 'ar_minor_edit',
42 'ar_deleted',
43 'ar_len',
44 'ar_parent_id',
45 'ar_sha1',
47 if ( $returnTextFields ) {
48 $fields[] = 'ar_text_id';
50 return $fields;
53 protected function getCommentQueryFields( $prefix ) {
54 return [
55 "{$prefix}_comment_text" => "comment_{$prefix}_comment.comment_text",
56 "{$prefix}_comment_data" => "comment_{$prefix}_comment.comment_data",
57 "{$prefix}_comment_cid" => "comment_{$prefix}_comment.comment_id",
61 protected function getActorQueryFields( $prefix, $tmp = false ) {
62 if ( $tmp ) {
63 return [
64 "{$prefix}_user" => "actor_{$prefix}_user.actor_user",
65 "{$prefix}_user_text" => "actor_{$prefix}_user.actor_name",
66 "{$prefix}_actor" => "temp_{$prefix}_user.{$prefix}actor_actor",
68 } elseif ( $prefix === 'ar' ) {
69 return [
70 "{$prefix}_actor",
71 "{$prefix}_user" => 'archive_actor.actor_user',
72 "{$prefix}_user_text" => 'archive_actor.actor_name',
74 } else {
75 return [
76 "{$prefix}_actor" => "{$prefix}_actor",
77 "{$prefix}_user" => "actor_{$prefix}_user.actor_user",
78 "{$prefix}_user_text" => "actor_{$prefix}_user.actor_name",
83 protected function getTextQueryFields() {
84 return [
85 'old_text',
86 'old_flags',
90 protected function getPageQueryFields() {
91 return [
92 'page_namespace',
93 'page_title',
94 'page_id',
95 'page_latest',
96 'page_is_redirect',
97 'page_len',
101 protected function getUserQueryFields() {
102 return [
103 'user_name',
107 protected function getContentHandlerQueryFields( $prefix ) {
108 return [
109 "{$prefix}_content_format",
110 "{$prefix}_content_model",
114 public function provideArchiveQueryInfo() {
115 yield 'no options' => [
118 'tables' => [
119 'archive',
120 'archive_actor' => 'actor',
121 'comment_ar_comment' => 'comment',
123 'fields' => array_merge(
124 $this->getArchiveQueryFields( false ),
125 $this->getActorQueryFields( 'ar' ),
126 $this->getCommentQueryFields( 'ar' )
128 'joins' => [
129 'comment_ar_comment'
130 => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
131 'archive_actor' => [ 'JOIN', 'actor_id=ar_actor' ],
137 public function provideQueryInfo() {
138 // TODO: more option variations
139 yield 'page and user option, actor-new' => [
141 [ 'page', 'user' ],
143 'tables' => [
144 'revision',
145 'page',
146 'user',
147 'actor_rev_user' => 'actor',
148 'comment_rev_comment' => 'comment',
150 'fields' => array_merge(
151 $this->getRevisionQueryFields( false ),
152 $this->getPageQueryFields(),
153 $this->getUserQueryFields(),
154 $this->getActorQueryFields( 'rev' ),
155 $this->getCommentQueryFields( 'rev' )
157 'joins' => [
158 'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
159 'user' => [
160 'LEFT JOIN',
161 [ 'actor_rev_user.actor_user != 0', 'user_id = actor_rev_user.actor_user' ],
163 'comment_rev_comment' => [ 'JOIN', 'comment_rev_comment.comment_id = rev_comment_id' ],
164 'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = rev_actor' ]
168 yield 'no options, actor-new' => [
172 'tables' => [
173 'revision',
174 'actor_rev_user' => 'actor',
175 'comment_rev_comment' => 'comment',
177 'fields' => array_merge(
178 $this->getRevisionQueryFields( false ),
179 $this->getActorQueryFields( 'rev' ),
180 $this->getCommentQueryFields( 'rev' )
182 'joins' => [
183 'comment_rev_comment' => [ 'JOIN', 'comment_rev_comment.comment_id = rev_comment_id' ],
184 'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = rev_actor' ],
190 public static function provideSlotsQueryInfo() {
191 yield 'no options' => [
195 'tables' => [
196 'slots'
198 'fields' => [
199 'slot_revision_id',
200 'slot_content_id',
201 'slot_origin',
202 'slot_role_id',
204 'joins' => [],
205 'keys' => [
206 'rev_id' => 'slot_revision_id',
207 'role_id' => 'slot_role_id'
211 yield 'role option' => [
213 [ 'role' ],
215 'tables' => [
216 'slots',
217 'slot_roles',
219 'fields' => [
220 'slot_revision_id',
221 'slot_content_id',
222 'slot_origin',
223 'slot_role_id',
224 'role_name',
226 'joins' => [
227 'slot_roles' => [ 'LEFT JOIN', [ 'slot_role_id = role_id' ] ],
229 'keys' => [
230 'rev_id' => 'slot_revision_id',
231 'role_id' => 'slot_role_id'
235 yield 'content option' => [
237 [ 'content' ],
239 'tables' => [
240 'slots',
241 'content',
243 'fields' => [
244 'slot_revision_id',
245 'slot_content_id',
246 'slot_origin',
247 'slot_role_id',
248 'content_size',
249 'content_sha1',
250 'content_address',
251 'content_model',
253 'joins' => [
254 'content' => [ 'JOIN', [ 'slot_content_id = content_id' ] ],
256 'keys' => [
257 'rev_id' => 'slot_revision_id',
258 'role_id' => 'slot_role_id',
259 'model_id' => 'content_model',
263 yield 'content and model options' => [
265 [ 'content', 'model' ],
267 'tables' => [
268 'slots',
269 'content',
270 'content_models',
272 'fields' => [
273 'slot_revision_id',
274 'slot_content_id',
275 'slot_origin',
276 'slot_role_id',
277 'content_size',
278 'content_sha1',
279 'content_address',
280 'content_model',
281 'model_name',
283 'joins' => [
284 'content' => [ 'JOIN', [ 'slot_content_id = content_id' ] ],
285 'content_models' => [ 'LEFT JOIN', [ 'content_model = model_id' ] ],
287 'keys' => [
288 'rev_id' => 'slot_revision_id',
289 'role_id' => 'slot_role_id',
290 'model_id' => 'content_model',
297 * @dataProvider provideQueryInfo
298 * @covers \MediaWiki\Revision\RevisionStore::getQueryInfo
300 public function testRevisionStoreGetQueryInfo( $migrationStageSettings, $options, $expected ) {
301 $this->overrideConfigValues( $migrationStageSettings );
303 $store = $this->getServiceContainer()->getRevisionStore();
305 $queryInfo = $store->getQueryInfo( $options );
306 $this->assertQueryInfoEquals( $expected, $queryInfo );
310 * @dataProvider provideSlotsQueryInfo
311 * @covers \MediaWiki\Revision\RevisionStore::getSlotsQueryInfo
313 public function testRevisionStoreGetSlotsQueryInfo(
314 $migrationStageSettings,
315 $options,
316 $expected
318 $this->overrideConfigValues( $migrationStageSettings );
320 $store = $this->getServiceContainer()->getRevisionStore();
322 $queryInfo = $store->getSlotsQueryInfo( $options );
323 $this->assertQueryInfoEquals( $expected, $queryInfo );
327 * @dataProvider provideArchiveQueryInfo
328 * @covers \MediaWiki\Revision\RevisionStore::getArchiveQueryInfo
330 public function testRevisionStoreGetArchiveQueryInfo( $migrationStageSettings, $expected ) {
331 $this->overrideConfigValues( $migrationStageSettings );
333 $store = $this->getServiceContainer()->getRevisionStore();
335 $queryInfo = $store->getArchiveQueryInfo();
336 $this->assertQueryInfoEquals( $expected, $queryInfo );
339 private function assertQueryInfoEquals( $expected, $queryInfo ) {
340 $this->assertArrayEqualsIgnoringIntKeyOrder(
341 $expected['tables'],
342 $queryInfo['tables'],
343 'tables'
345 $this->assertArrayEqualsIgnoringIntKeyOrder(
346 $expected['fields'],
347 $queryInfo['fields'],
348 'fields'
350 $this->assertArrayEqualsIgnoringIntKeyOrder(
351 $expected['joins'],
352 $queryInfo['joins'],
353 'joins'
355 if ( isset( $expected['keys'] ) ) {
356 $this->assertArrayEqualsIgnoringIntKeyOrder(
357 $expected['keys'],
358 $queryInfo['keys'],
359 'keys'
365 * Assert that the two arrays passed are equal, ignoring the order of the values that integer
366 * keys.
368 * Note: Failures of this assertion can be slightly confusing as the arrays are actually
369 * split into a string key array and an int key array before assertions occur.
371 * @param array $expected
372 * @param array $actual
373 * @param string|null $message
375 private function assertArrayEqualsIgnoringIntKeyOrder(
376 array $expected,
377 array $actual,
378 $message = null
380 $this->objectAssociativeSort( $expected );
381 $this->objectAssociativeSort( $actual );
383 // Separate the int key values from the string key values so that assertion failures are
384 // easier to understand.
385 $expectedIntKeyValues = [];
386 $actualIntKeyValues = [];
388 // Remove all int keys and re add them at the end after sorting by value
389 // This will result in all int keys being in the same order with same ints at the end of
390 // the array
391 foreach ( $expected as $key => $value ) {
392 if ( is_int( $key ) ) {
393 unset( $expected[$key] );
394 $expectedIntKeyValues[] = $value;
397 foreach ( $actual as $key => $value ) {
398 if ( is_int( $key ) ) {
399 unset( $actual[$key] );
400 $actualIntKeyValues[] = $value;
404 $this->objectAssociativeSort( $expected );
405 $this->objectAssociativeSort( $actual );
407 $this->objectAssociativeSort( $expectedIntKeyValues );
408 $this->objectAssociativeSort( $actualIntKeyValues );
410 $this->assertEquals( $expected, $actual, $message );
411 $this->assertEquals( $expectedIntKeyValues, $actualIntKeyValues, $message );