* @covers WikiPage::doEditUpdates
*/
public function testDoEditContent() {
+ $this->setMwGlobals( 'wgPageCreationLog', true );
+
$page = $this->newPage( __METHOD__ );
$title = $page->getTitle();
$page->doEditContent( $content, "[[testing]] 1" );
+ $id = $page->getId();
+
+ // Test page creation logging
+ $this->assertSelect(
+ 'logging',
+ [ 'log_type', 'log_action' ],
+ [ 'log_page' => $id ],
+ [ [ 'create', 'create' ] ]
+ );
+
$this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
- $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
+ $this->assertTrue( $id > 0, "WikiPage should have new page id" );
$this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
$this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
- $id = $page->getId();
-
# ------------------------
$dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
}
/**
+ * Undeletion is covered in PageArchiveTest::testUndeleteRevisions()
+ * TODO: Revision deletion
+ *
* @covers WikiPage::doDeleteArticle
* @covers WikiPage::doDeleteArticleReal
*/
$this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
}
+ /**
+ * @covers WikiPage::doDeleteArticleReal
+ */
+ public function testDoDeleteArticleReal_user0() {
+ $page = $this->createPage(
+ __METHOD__,
+ "[[original text]] foo",
+ CONTENT_MODEL_WIKITEXT
+ );
+ $id = $page->getId();
+
+ $errorStack = '';
+ $status = $page->doDeleteArticleReal(
+ /* reason */ "testing user 0 deletion",
+ /* suppress */ false,
+ /* unused 1 */ null,
+ /* unused 2 */ null,
+ /* errorStack */ $errorStack,
+ null
+ );
+ $logId = $status->getValue();
+ $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+ $this->assertSelect(
+ [ 'logging' ] + $actorQuery['tables'], /* table */
+ [
+ 'log_type',
+ 'log_action',
+ 'log_comment',
+ 'log_user' => $actorQuery['fields']['log_user'],
+ 'log_user_text' => $actorQuery['fields']['log_user_text'],
+ 'log_namespace',
+ 'log_title',
+ ],
+ [ 'log_id' => $logId ],
+ [ [
+ 'delete',
+ 'delete',
+ 'testing user 0 deletion',
+ '0',
+ '127.0.0.1',
+ (string)$page->getTitle()->getNamespace(),
+ $page->getTitle()->getDBkey(),
+ ] ],
+ [],
+ $actorQuery['joins']
+ );
+ }
+
+ /**
+ * @covers WikiPage::doDeleteArticleReal
+ */
+ public function testDoDeleteArticleReal_userSysop() {
+ $page = $this->createPage(
+ __METHOD__,
+ "[[original text]] foo",
+ CONTENT_MODEL_WIKITEXT
+ );
+ $id = $page->getId();
+
+ $user = $this->getTestSysop()->getUser();
+ $errorStack = '';
+ $status = $page->doDeleteArticleReal(
+ /* reason */ "testing sysop deletion",
+ /* suppress */ false,
+ /* unused 1 */ null,
+ /* unused 2 */ null,
+ /* errorStack */ $errorStack,
+ $user
+ );
+ $logId = $status->getValue();
+ $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+ $this->assertSelect(
+ [ 'logging' ] + $actorQuery['tables'], /* table */
+ [
+ 'log_type',
+ 'log_action',
+ 'log_comment',
+ 'log_user' => $actorQuery['fields']['log_user'],
+ 'log_user_text' => $actorQuery['fields']['log_user_text'],
+ 'log_namespace',
+ 'log_title',
+ ],
+ [ 'log_id' => $logId ],
+ [ [
+ 'delete',
+ 'delete',
+ 'testing sysop deletion',
+ (string)$user->getId(),
+ $user->getName(),
+ (string)$page->getTitle()->getNamespace(),
+ $page->getTitle()->getDBkey(),
+ ] ],
+ [],
+ $actorQuery['joins']
+ );
+ }
+
+ /**
+ * TODO: Test more stuff about suppression.
+ *
+ * @covers WikiPage::doDeleteArticleReal
+ */
+ public function testDoDeleteArticleReal_suppress() {
+ $page = $this->createPage(
+ __METHOD__,
+ "[[original text]] foo",
+ CONTENT_MODEL_WIKITEXT
+ );
+ $id = $page->getId();
+
+ $user = $this->getTestSysop()->getUser();
+ $errorStack = '';
+ $status = $page->doDeleteArticleReal(
+ /* reason */ "testing deletion",
+ /* suppress */ true,
+ /* unused 1 */ null,
+ /* unused 2 */ null,
+ /* errorStack */ $errorStack,
+ $user
+ );
+ $logId = $status->getValue();
+ $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+ $this->assertSelect(
+ [ 'logging' ] + $actorQuery['tables'], /* table */
+ [
+ 'log_type',
+ 'log_action',
+ 'log_comment',
+ 'log_user' => $actorQuery['fields']['log_user'],
+ 'log_user_text' => $actorQuery['fields']['log_user_text'],
+ 'log_namespace',
+ 'log_title',
+ ],
+ [ 'log_id' => $logId ],
+ [ [
+ 'suppress',
+ 'delete',
+ 'testing deletion',
+ (string)$user->getId(),
+ $user->getName(),
+ (string)$page->getTitle()->getNamespace(),
+ $page->getTitle()->getDBkey(),
+ ] ],
+ [],
+ $actorQuery['joins']
+ );
+
+ $this->assertNull(
+ $page->getContent( Revision::FOR_PUBLIC ),
+ "WikiPage::getContent should return null after the page was suppressed for general users"
+ );
+
+ $this->assertNull(
+ $page->getContent( Revision::FOR_THIS_USER, null ),
+ "WikiPage::getContent should return null after the page was suppressed for user zero"
+ );
+
+ $this->assertNull(
+ $page->getContent( Revision::FOR_THIS_USER, $user ),
+ "WikiPage::getContent should return null after the page was suppressed even for a sysop"
+ );
+ }
+
/**
* @covers WikiPage::doDeleteUpdates
*/
# sanity check, because this test seems to fail for no reason for some people.
$c = $page->getContent();
- $this->assertEquals( 'WikitextContent', get_class( $c ) );
+ $this->assertEquals( WikitextContent::class, get_class( $c ) );
# now, test the actual redirect
$t = $page->getRedirectTarget();
true
],
- // comma
- [ 'WikiPageTest_testIsCountable',
- CONTENT_MODEL_WIKITEXT,
- 'Foo',
- 'comma',
- false
- ],
- [ 'WikiPageTest_testIsCountable',
- CONTENT_MODEL_WIKITEXT,
- 'Foo, bar',
- 'comma',
- true
- ],
-
// link
[ 'WikiPageTest_testIsCountable',
CONTENT_MODEL_WIKITEXT,
'any',
false
],
- [ 'WikiPageTest_testIsCountable',
- CONTENT_MODEL_WIKITEXT,
- '#REDIRECT [[bar]]',
- 'comma',
- false
- ],
[ 'WikiPageTest_testIsCountable',
CONTENT_MODEL_WIKITEXT,
'#REDIRECT [[bar]]',
'any',
false
],
- [ 'Talk:WikiPageTest_testIsCountable',
- CONTENT_MODEL_WIKITEXT,
- 'Foo, bar',
- 'comma',
- false
- ],
[ 'Talk:WikiPageTest_testIsCountable',
CONTENT_MODEL_WIKITEXT,
'Foo [[bar]]',
'any',
false
],
- [ 'MediaWiki:WikiPageTest_testIsCountable.js',
- null,
- 'Foo, bar',
- 'comma',
- false
- ],
[ 'MediaWiki:WikiPageTest_testIsCountable.js',
null,
'Foo [[bar]]',
public function testWikiPageFactory() {
$title = Title::makeTitle( NS_FILE, 'Someimage.png' );
$page = WikiPage::factory( $title );
- $this->assertEquals( 'WikiFilePage', get_class( $page ) );
+ $this->assertEquals( WikiFilePage::class, get_class( $page ) );
$title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' );
$page = WikiPage::factory( $title );
- $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
+ $this->assertEquals( WikiCategoryPage::class, get_class( $page ) );
$title = Title::makeTitle( NS_MAIN, 'SomePage' );
$page = WikiPage::factory( $title );
- $this->assertEquals( 'WikiPage', get_class( $page ) );
+ $this->assertEquals( WikiPage::class, get_class( $page ) );
}
/**
*/
public function testCommentMigrationOnDeletion( $writeStage, $readStage ) {
$this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $writeStage );
+ $this->overrideMwServices();
+
$dbr = wfGetDB( DB_REPLICA );
$page = $this->createPage(
}
$this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $readStage );
+ $this->overrideMwServices();
$page->doDeleteArticle( "testing deletion" );
* @covers WikiPage::newFromID
*/
public function testNewFromId_returnsNullOnNonExistingId() {
- $this->assertNull( WikiPage::newFromID( 73574757437437743743 ) );
+ $this->assertNull( WikiPage::newFromID( 2147483647 ) );
}
public function provideTestInsertProtectNullRevision() {
- // @codingStandardsIgnoreStart Generic.Files.LineLength
+ // phpcs:disable Generic.Files.LineLength
yield [
'goat-message-key',
[ 'edit' => 'sysop' ],
true,
'(goat-key: WikiPageDbTestBase::testInsertProtectNullRevision, UTSysop)(colon-separator)Goat Goat(word-separator)(parentheses: (protect-summary-desc: (restriction-edit), (protect-level-sysop), (protect-expiring: 04:04, 1 (january) 2020, 1 (january) 2020, 04:04))(word-separator)(protect-summary-desc: (restriction-move), (protect-level-something), (protect-expiring: 05:05, 1 (january) 2021, 1 (january) 2021, 05:05)))'
];
- // @codingStandardsIgnoreEnd Generic.Files.LineLength
+ // phpcs:enable
}
/**
);
}
+ public function provideTestDoUpdateRestrictions_setBasicRestrictions() {
+ // Note: Once the current dates passes the date in these tests they will fail.
+ yield 'move something' => [
+ true,
+ [ 'move' => 'something' ],
+ [],
+ [ 'edit' => [], 'move' => [ 'something' ] ],
+ [],
+ ];
+ yield 'move something, edit blank' => [
+ true,
+ [ 'move' => 'something', 'edit' => '' ],
+ [],
+ [ 'edit' => [], 'move' => [ 'something' ] ],
+ [],
+ ];
+ yield 'edit sysop, with expiry' => [
+ true,
+ [ 'edit' => 'sysop' ],
+ [ 'edit' => '21330101020202' ],
+ [ 'edit' => [ 'sysop' ], 'move' => [] ],
+ [ 'edit' => '21330101020202' ],
+ ];
+ yield 'move and edit, move with expiry' => [
+ true,
+ [ 'move' => 'something', 'edit' => 'another' ],
+ [ 'move' => '22220202010101' ],
+ [ 'edit' => [ 'another' ], 'move' => [ 'something' ] ],
+ [ 'move' => '22220202010101' ],
+ ];
+ yield 'move and edit, edit with infinity expiry' => [
+ true,
+ [ 'move' => 'something', 'edit' => 'another' ],
+ [ 'edit' => 'infinity' ],
+ [ 'edit' => [ 'another' ], 'move' => [ 'something' ] ],
+ [ 'edit' => 'infinity' ],
+ ];
+ yield 'non existing, create something' => [
+ false,
+ [ 'create' => 'something' ],
+ [],
+ [ 'create' => [ 'something' ] ],
+ [],
+ ];
+ yield 'non existing, create something with expiry' => [
+ false,
+ [ 'create' => 'something' ],
+ [ 'create' => '23451212112233' ],
+ [ 'create' => [ 'something' ] ],
+ [ 'create' => '23451212112233' ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideTestDoUpdateRestrictions_setBasicRestrictions
+ * @covers WikiPage::doUpdateRestrictions
+ */
+ public function testDoUpdateRestrictions_setBasicRestrictions(
+ $pageExists,
+ array $limit,
+ array $expiry,
+ array $expectedRestrictions,
+ array $expectedRestrictionExpiries
+ ) {
+ if ( $pageExists ) {
+ $page = $this->createPage( __METHOD__, 'ABC' );
+ } else {
+ $page = new WikiPage( Title::newFromText( __METHOD__ . '-nonexist' ) );
+ }
+ $user = $this->getTestSysop()->getUser();
+ $cascade = false;
+
+ $status = $page->doUpdateRestrictions( $limit, $expiry, $cascade, 'aReason', $user, [] );
+
+ $logId = $status->getValue();
+ $allRestrictions = $page->getTitle()->getAllRestrictions();
+
+ $this->assertTrue( $status->isGood() );
+ $this->assertInternalType( 'int', $logId );
+ $this->assertSame( $expectedRestrictions, $allRestrictions );
+ foreach ( $expectedRestrictionExpiries as $key => $value ) {
+ $this->assertSame( $value, $page->getTitle()->getRestrictionExpiry( $key ) );
+ }
+
+ // Make sure the log entry looks good
+ // log_params is not checked here
+ $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+ $this->assertSelect(
+ [ 'logging' ] + $actorQuery['tables'],
+ [
+ 'log_comment',
+ 'log_user' => $actorQuery['fields']['log_user'],
+ 'log_user_text' => $actorQuery['fields']['log_user_text'],
+ 'log_namespace',
+ 'log_title',
+ ],
+ [ 'log_id' => $logId ],
+ [ [
+ 'aReason',
+ (string)$user->getId(),
+ $user->getName(),
+ (string)$page->getTitle()->getNamespace(),
+ $page->getTitle()->getDBkey(),
+ ] ],
+ [],
+ $actorQuery['joins']
+ );
+ }
+
+ /**
+ * @covers WikiPage::doUpdateRestrictions
+ */
+ public function testDoUpdateRestrictions_failsOnReadOnly() {
+ $page = $this->createPage( __METHOD__, 'ABC' );
+ $user = $this->getTestSysop()->getUser();
+ $cascade = false;
+
+ // Set read only
+ $readOnly = $this->getMockBuilder( ReadOnlyMode::class )
+ ->disableOriginalConstructor()
+ ->setMethods( [ 'isReadOnly', 'getReason' ] )
+ ->getMock();
+ $readOnly->expects( $this->once() )
+ ->method( 'isReadOnly' )
+ ->will( $this->returnValue( true ) );
+ $readOnly->expects( $this->once() )
+ ->method( 'getReason' )
+ ->will( $this->returnValue( 'Some Read Only Reason' ) );
+ $this->setService( 'ReadOnlyMode', $readOnly );
+
+ $status = $page->doUpdateRestrictions( [], [], $cascade, 'aReason', $user, [] );
+ $this->assertFalse( $status->isOK() );
+ $this->assertSame( 'readonlytext', $status->getMessage()->getKey() );
+ }
+
+ /**
+ * @covers WikiPage::doUpdateRestrictions
+ */
+ public function testDoUpdateRestrictions_returnsGoodIfNothingChanged() {
+ $page = $this->createPage( __METHOD__, 'ABC' );
+ $user = $this->getTestSysop()->getUser();
+ $cascade = false;
+ $limit = [ 'edit' => 'sysop' ];
+
+ $status = $page->doUpdateRestrictions(
+ $limit,
+ [],
+ $cascade,
+ 'aReason',
+ $user,
+ []
+ );
+
+ // The first entry should have a logId as it did something
+ $this->assertTrue( $status->isGood() );
+ $this->assertInternalType( 'int', $status->getValue() );
+
+ $status = $page->doUpdateRestrictions(
+ $limit,
+ [],
+ $cascade,
+ 'aReason',
+ $user,
+ []
+ );
+
+ // The second entry should not have a logId as nothing changed
+ $this->assertTrue( $status->isGood() );
+ $this->assertNull( $status->getValue() );
+ }
+
+ /**
+ * @covers WikiPage::doUpdateRestrictions
+ */
+ public function testDoUpdateRestrictions_logEntryTypeAndAction() {
+ $page = $this->createPage( __METHOD__, 'ABC' );
+ $user = $this->getTestSysop()->getUser();
+ $cascade = false;
+
+ // Protect the page
+ $status = $page->doUpdateRestrictions(
+ [ 'edit' => 'sysop' ],
+ [],
+ $cascade,
+ 'aReason',
+ $user,
+ []
+ );
+ $this->assertTrue( $status->isGood() );
+ $this->assertInternalType( 'int', $status->getValue() );
+ $this->assertSelect(
+ 'logging',
+ [ 'log_type', 'log_action' ],
+ [ 'log_id' => $status->getValue() ],
+ [ [ 'protect', 'protect' ] ]
+ );
+
+ // Modify the protection
+ $status = $page->doUpdateRestrictions(
+ [ 'edit' => 'somethingElse' ],
+ [],
+ $cascade,
+ 'aReason',
+ $user,
+ []
+ );
+ $this->assertTrue( $status->isGood() );
+ $this->assertInternalType( 'int', $status->getValue() );
+ $this->assertSelect(
+ 'logging',
+ [ 'log_type', 'log_action' ],
+ [ 'log_id' => $status->getValue() ],
+ [ [ 'protect', 'modify' ] ]
+ );
+
+ // Remove the protection
+ $status = $page->doUpdateRestrictions(
+ [],
+ [],
+ $cascade,
+ 'aReason',
+ $user,
+ []
+ );
+ $this->assertTrue( $status->isGood() );
+ $this->assertInternalType( 'int', $status->getValue() );
+ $this->assertSelect(
+ 'logging',
+ [ 'log_type', 'log_action' ],
+ [ 'log_id' => $status->getValue() ],
+ [ [ 'protect', 'unprotect' ] ]
+ );
+ }
+
}