Remove Revision::getRevisionText from migrateArchiveText
[lhc/web/wiklou.git] / tests / phpunit / includes / Revision / McrRevisionStoreDbTest.php
1 <?php
2
3 namespace MediaWiki\Tests\Revision;
4
5 use CommentStoreComment;
6 use MediaWiki\MediaWikiServices;
7 use MediaWiki\Revision\MutableRevisionRecord;
8 use MediaWiki\Revision\RevisionRecord;
9 use MediaWiki\Revision\SlotRecord;
10 use TextContent;
11 use Title;
12 use WikitextContent;
13
14 /**
15 * Tests RevisionStore against the post-migration MCR DB schema.
16 *
17 * @covers \MediaWiki\Revision\RevisionStore
18 *
19 * @group RevisionStore
20 * @group Storage
21 * @group Database
22 * @group medium
23 */
24 class McrRevisionStoreDbTest extends RevisionStoreDbTestBase {
25
26 use McrSchemaOverride;
27
28 protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
29 $numberOfSlots = count( $rev->getSlotRoles() );
30
31 // new schema is written
32 $this->assertSelect(
33 'slots',
34 [ 'count(*)' ],
35 [ 'slot_revision_id' => $rev->getId() ],
36 [ [ (string)$numberOfSlots ] ]
37 );
38
39 $store = MediaWikiServices::getInstance()->getRevisionStore();
40 $revQuery = $store->getSlotsQueryInfo( [ 'content' ] );
41
42 $this->assertSelect(
43 $revQuery['tables'],
44 [ 'count(*)' ],
45 [
46 'slot_revision_id' => $rev->getId(),
47 ],
48 [ [ (string)$numberOfSlots ] ],
49 [],
50 $revQuery['joins']
51 );
52
53 parent::assertRevisionExistsInDatabase( $rev );
54 }
55
56 /**
57 * @param SlotRecord $a
58 * @param SlotRecord $b
59 */
60 protected function assertSameSlotContent( SlotRecord $a, SlotRecord $b ) {
61 parent::assertSameSlotContent( $a, $b );
62
63 // Assert that the same content ID has been used
64 $this->assertSame( $a->getContentId(), $b->getContentId() );
65 }
66
67 public function provideInsertRevisionOn_successes() {
68 foreach ( parent::provideInsertRevisionOn_successes() as $case ) {
69 yield $case;
70 }
71
72 yield 'Multi-slot revision insertion' => [
73 [
74 'content' => [
75 'main' => new WikitextContent( 'Chicken' ),
76 'aux' => new TextContent( 'Egg' ),
77 ],
78 'page' => true,
79 'comment' => $this->getRandomCommentStoreComment(),
80 'timestamp' => '20171117010101',
81 'user' => true,
82 ],
83 ];
84 }
85
86 public function provideNewNullRevision() {
87 foreach ( parent::provideNewNullRevision() as $case ) {
88 yield $case;
89 }
90
91 yield [
92 Title::newFromText( 'UTPage_notAutoCreated' ),
93 [
94 'content' => [
95 'main' => new WikitextContent( 'Chicken' ),
96 'aux' => new WikitextContent( 'Omelet' ),
97 ],
98 ],
99 CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment multi' ),
100 ];
101 }
102
103 public function provideNewMutableRevisionFromArray() {
104 foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
105 yield $case;
106 }
107
108 yield 'Basic array, multiple roles' => [
109 [
110 'id' => 2,
111 'page' => 1,
112 'timestamp' => '20171017114835',
113 'user_text' => '111.0.1.2',
114 'user' => 0,
115 'minor_edit' => false,
116 'deleted' => 0,
117 'len' => 29,
118 'parent_id' => 1,
119 'sha1' => '89qs83keq9c9ccw9olvvm4oc9oq50ii',
120 'comment' => 'Goat Comment!',
121 'content' => [
122 'main' => new WikitextContent( 'Söme Cöntent' ),
123 'aux' => new TextContent( 'Öther Cöntent' ),
124 ]
125 ]
126 ];
127 }
128
129 public function testGetQueryInfo_NoSlotDataJoin() {
130 $store = MediaWikiServices::getInstance()->getRevisionStore();
131 $queryInfo = $store->getQueryInfo();
132
133 // with the new schema enabled, query info should not join the main slot info
134 $this->assertFalse( array_key_exists( 'a_slot_data', $queryInfo['tables'] ) );
135 $this->assertFalse( array_key_exists( 'a_slot_data', $queryInfo['joins'] ) );
136 }
137
138 /**
139 * @covers \MediaWiki\Revision\RevisionStore::insertRevisionOn
140 * @covers \MediaWiki\Revision\RevisionStore::insertSlotRowOn
141 * @covers \MediaWiki\Revision\RevisionStore::insertContentRowOn
142 */
143 public function testInsertRevisionOn_T202032() {
144 // This test only makes sense for MySQL
145 if ( $this->db->getType() !== 'mysql' ) {
146 $this->assertTrue( true );
147 return;
148 }
149
150 // NOTE: must be done before checking MAX(rev_id)
151 $page = $this->getTestPage();
152
153 $maxRevId = $this->db->selectField( 'revision', 'MAX(rev_id)' );
154
155 // Construct a slot row that will conflict with the insertion of the next revision ID,
156 // to emulate the failure mode described in T202032. Nothing will ever read this row,
157 // we just need it to trigger a primary key conflict.
158 $this->db->insert( 'slots', [
159 'slot_revision_id' => $maxRevId + 1,
160 'slot_role_id' => 1,
161 'slot_content_id' => 0,
162 'slot_origin' => 0
163 ], __METHOD__ );
164
165 $rev = new MutableRevisionRecord( $page->getTitle() );
166 $rev->setTimestamp( '20180101000000' );
167 $rev->setComment( CommentStoreComment::newUnsavedComment( 'test' ) );
168 $rev->setUser( $this->getTestUser()->getUser() );
169 $rev->setContent( 'main', new WikitextContent( 'Text' ) );
170 $rev->setPageId( $page->getId() );
171
172 $store = MediaWikiServices::getInstance()->getRevisionStore();
173 $return = $store->insertRevisionOn( $rev, $this->db );
174
175 $this->assertSame( $maxRevId + 2, $return->getId() );
176
177 // is the new revision correct?
178 $this->assertRevisionCompleteness( $return );
179 $this->assertRevisionRecordsEqual( $rev, $return );
180
181 // can we find it directly in the database?
182 $this->assertRevisionExistsInDatabase( $return );
183
184 // can we load it from the store?
185 $loaded = $store->getRevisionById( $return->getId() );
186 $this->assertRevisionCompleteness( $loaded );
187 $this->assertRevisionRecordsEqual( $return, $loaded );
188 }
189
190 /**
191 * Conditions to use together with getSlotsQueryInfo() when selecting slot rows for a given
192 * revision.
193 *
194 * @return array
195 */
196 protected function getSlotRevisionConditions( $revId ) {
197 return [ 'slot_revision_id' => $revId ];
198 }
199
200 /**
201 * @covers \MediaWiki\Revision\RevisionStore::newRevisionsFromBatch
202 * @throws \MWException
203 */
204 public function testNewRevisionsFromBatch_error() {
205 $page = $this->getTestPage();
206 $text = __METHOD__ . 'b-ä';
207 /** @var Revision $rev1 */
208 $rev1 = $page->doEditContent(
209 new WikitextContent( $text . '1' ),
210 __METHOD__ . 'b',
211 0,
212 false,
213 $this->getTestUser()->getUser()
214 )->value['revision'];
215 $invalidRow = $this->revisionToRow( $rev1 );
216 $invalidRow->rev_id = 100500;
217 $result = MediaWikiServices::getInstance()->getRevisionStore()
218 ->newRevisionsFromBatch(
219 [ $this->revisionToRow( $rev1 ), $invalidRow ],
220 [
221 'slots' => [ SlotRecord::MAIN ],
222 'content' => true
223 ]
224 );
225 $this->assertFalse( $result->isGood() );
226 $this->assertNotEmpty( $result->getErrors() );
227 $records = $result->getValue();
228 $this->assertRevisionRecordMatchesRevision( $rev1, $records[$rev1->getId()] );
229 $this->assertSame( $text . '1',
230 $records[$rev1->getId()]->getContent( SlotRecord::MAIN )->serialize() );
231 $this->assertEquals( $page->getTitle()->getDBkey(),
232 $records[$rev1->getId()]->getPageAsLinkTarget()->getDBkey() );
233 $this->assertNull( $records[$invalidRow->rev_id] );
234 $this->assertSame( [ [
235 'type' => 'warning',
236 'message' => 'internalerror',
237 'params' => [
238 "Couldn't find slots for rev 100500"
239 ]
240 ] ], $result->getErrors() );
241 }
242 }