<?php
+use MediaWiki\Edit\PreparedEdit;
use MediaWiki\MediaWikiServices;
use MediaWiki\Storage\RevisionSlotsUpdate;
+use PHPUnit\Framework\MockObject\MockObject;
use Wikimedia\TestingAccessWrapper;
/**
/**
* @param string|Title|WikiPage $page
- * @param string $text
+ * @param string|Content|Content[] $content
* @param int|null $model
*
* @return WikiPage
*/
- protected function createPage( $page, $text, $model = null, $user = null ) {
+ protected function createPage( $page, $content, $model = null, $user = null ) {
if ( is_string( $page ) || $page instanceof Title ) {
$page = $this->newPage( $page, $model );
}
- $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
- $page->doEditContent( $content, "testing", EDIT_NEW, false, $user );
+ if ( !$user ) {
+ $user = $this->getTestUser()->getUser();
+ }
+
+ if ( is_string( $content ) ) {
+ $content = ContentHandler::makeContent( $content, $page->getTitle(), $model );
+ }
+
+ if ( !is_array( $content ) ) {
+ $content = [ 'main' => $content ];
+ }
+
+ $updater = $page->newPageUpdater( $user );
+
+ foreach ( $content as $role => $cnt ) {
+ $updater->setContent( $role, $cnt );
+ }
+
+ $updater->saveRevision( CommentStoreComment::newUnsavedComment( "testing" ) );
return $page;
}
// Re-using the prepared info if possible
$sameEdit = $page->prepareContentForEdit( $content, null, $user, null, false );
- $this->assertEquals( $edit, $sameEdit, 'equivalent PreparedEdit' );
+ $this->assertPreparedEditEquals( $edit, $sameEdit, 'equivalent PreparedEdit' );
$this->assertSame( $edit->pstContent, $sameEdit->pstContent, 're-use output' );
$this->assertSame( $edit->output, $sameEdit->output, 're-use output' );
// Not re-using the same PreparedEdit if not possible
$rev = $page->getRevision();
$edit2 = $page->prepareContentForEdit( $content2, null, $user, null, false );
- $this->assertNotEquals( $edit, $edit2 );
+ $this->assertPreparedEditNotEquals( $edit, $edit2 );
$this->assertContains( 'At vero eos', $edit2->pstContent->serialize(), "content" );
// Check pre-safe transform
$this->assertNotContains( '~~~~', $edit2->pstContent->serialize() );
$edit3 = $page->prepareContentForEdit( $content2, null, $sysop, null, false );
- $this->assertNotEquals( $edit2, $edit3 );
+ $this->assertPreparedEditNotEquals( $edit2, $edit3 );
// TODO: test with passing revision, then same without revision.
}
* @covers WikiPage::doDeleteUpdates
*/
public function testDoDeleteUpdates() {
+ $user = $this->getTestUser()->getUser();
$page = $this->createPage(
__METHOD__,
"[[original text]] foo",
CONTENT_MODEL_WIKITEXT
);
$id = $page->getId();
+ $page->loadPageData(); // make sure the current revision is cached.
// Similar to MovePage logic
wfGetDB( DB_MASTER )->delete( 'page', [ 'page_id' => $id ], __METHOD__ );
- $page->doDeleteUpdates( $id );
+ $page->doDeleteUpdates( $page->getId(), $page->getContent(), $page->getRevision(), $user );
// Run the job queue
JobQueueGroup::destroySingletons();
$this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
}
+ /**
+ * @param string $name
+ *
+ * @return ContentHandler
+ */
+ protected function defineMockContentModelForUpdateTesting( $name ) {
+ /** @var ContentHandler|MockObject $handler */
+ $handler = $this->getMockBuilder( TextContentHandler::class )
+ ->setConstructorArgs( [ $name ] )
+ ->setMethods(
+ [ 'getSecondaryDataUpdates', 'getDeletionUpdates', 'unserializeContent' ]
+ )
+ ->getMock();
+
+ $dataUpdate = new MWCallableUpdate( 'time' );
+ $dataUpdate->_name = "$name data update";
+
+ $deletionUpdate = new MWCallableUpdate( 'time' );
+ $deletionUpdate->_name = "$name deletion update";
+
+ $handler->method( 'getSecondaryDataUpdates' )->willReturn( [ $dataUpdate ] );
+ $handler->method( 'getDeletionUpdates' )->willReturn( [ $deletionUpdate ] );
+ $handler->method( 'unserializeContent' )->willReturnCallback(
+ function ( $text ) use ( $handler ) {
+ return $this->createMockContent( $handler, $text );
+ }
+ );
+
+ $this->mergeMwGlobalArrayValue(
+ 'wgContentHandlers', [
+ $name => function () use ( $handler ){
+ return $handler;
+ }
+ ]
+ );
+
+ return $handler;
+ }
+
+ /**
+ * @param ContentHandler $handler
+ * @param string $text
+ *
+ * @return Content
+ */
+ protected function createMockContent( ContentHandler $handler, $text ) {
+ /** @var Content|MockObject $content */
+ $content = $this->getMockBuilder( TextContent::class )
+ ->setConstructorArgs( [ $text ] )
+ ->setMethods( [ 'getModel', 'getContentHandler' ] )
+ ->getMock();
+
+ $content->method( 'getModel' )->willReturn( $handler->getModelID() );
+ $content->method( 'getContentHandler' )->willReturn( $handler );
+
+ return $content;
+ }
+
+ public function testGetDeletionUpdates() {
+ $m1 = $this->defineMockContentModelForUpdateTesting( 'M1' );
+
+ $mainContent1 = $this->createMockContent( $m1, 'main 1' );
+
+ $page = new WikiPage( Title::newFromText( __METHOD__ ) );
+ $page = $this->createPage(
+ $page,
+ [ 'main' => $mainContent1 ]
+ );
+
+ $dataUpdates = $page->getDeletionUpdates( $page->getRevisionRecord() );
+ $this->assertNotEmpty( $dataUpdates );
+
+ $updateNames = array_map( function ( $du ) {
+ return isset( $du->_name ) ? $du->_name : get_class( $du );
+ }, $dataUpdates );
+
+ $this->assertContains( LinksDeletionUpdate::class, $updateNames );
+ $this->assertContains( 'M1 deletion update', $updateNames );
+ }
+
/**
* @covers WikiPage::getRevision
*/
$this->assertNotSame( $updater5, $updater6 );
}
+ protected function assertPreparedEditEquals(
+ PreparedEdit $edit, PreparedEdit $edit2, $message = ''
+ ) {
+ // suppress differences caused by a clock tick between generating the two PreparedEdits
+ if ( abs( $edit->timestamp - $edit2->timestamp ) < 3 ) {
+ $edit2 = clone $edit2;
+ $edit2->timestamp = $edit->timestamp;
+ }
+ $this->assertEquals( $edit, $edit2, $message );
+ }
+
+ protected function assertPreparedEditNotEquals(
+ PreparedEdit $edit, PreparedEdit $edit2, $message = ''
+ ) {
+ if ( abs( $edit->timestamp - $edit2->timestamp ) < 3 ) {
+ $edit2 = clone $edit2;
+ $edit2->timestamp = $edit->timestamp;
+ }
+ $this->assertNotEquals( $edit, $edit2, $message );
+ }
+
}