This reverts commit ec22840c4a.
This patch currently creates issues on beta, which still runs with the
latest vendor version of Parsoid. If, for some reason, Parsoid doesn't
get deployed with this patch, I2acfd0b7a1e48aec107ded3bbe4963e2df24f4d3
doesn't get included, and the REST page handler breaks.
Staggered deploy seems safer in this context, hence the proposal for a
temporary revert, and a merge after the next Parsoid vendor patch is
deployed.
Change-Id: I3f859fa807a04892a67323cd4e98be0d3fbb1676
302 lines
9.8 KiB
PHP
302 lines
9.8 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Rest\Handler\Helper;
|
|
|
|
use MediaWiki\Config\ServiceOptions;
|
|
use MediaWiki\MainConfigNames;
|
|
use MediaWiki\Page\ExistingPageRecord;
|
|
use MediaWiki\Permissions\Authority;
|
|
use MediaWiki\Rest\Handler\Helper\PageContentHelper;
|
|
use MediaWiki\Rest\Handler\Helper\RevisionContentHelper;
|
|
use MediaWiki\Rest\HttpException;
|
|
use MediaWiki\Rest\Response;
|
|
use MediaWiki\Revision\RevisionRecord;
|
|
use MediaWiki\Revision\SlotRecord;
|
|
use MediaWiki\Tests\Unit\Permissions\MockAuthorityTrait;
|
|
use MediaWikiIntegrationTestCase;
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\Helper\RevisionContentHelper
|
|
* @group Database
|
|
*/
|
|
class RevisionContentHelperTest extends MediaWikiIntegrationTestCase {
|
|
use MockAuthorityTrait;
|
|
|
|
private const NO_REVISION_ETAG = '"b620cd7841f9ea8f545f11cc44ce794f848fa2d3"';
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
// Clean up these tables after each test
|
|
$this->tablesUsed = [
|
|
'page',
|
|
'revision',
|
|
'comment',
|
|
'text',
|
|
'content'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array $params
|
|
* @param Authority|null $authority
|
|
* @return RevisionContentHelper
|
|
* @throws \Exception
|
|
*/
|
|
private function newHelper(
|
|
array $params = [],
|
|
Authority $authority = null
|
|
): RevisionContentHelper {
|
|
$helper = new RevisionContentHelper(
|
|
new ServiceOptions(
|
|
PageContentHelper::CONSTRUCTOR_OPTIONS,
|
|
[
|
|
MainConfigNames::RightsUrl => 'https://example.com/rights',
|
|
MainConfigNames::RightsText => 'some rights',
|
|
]
|
|
),
|
|
$this->getServiceContainer()->getRevisionLookup(),
|
|
$this->getServiceContainer()->getTitleFormatter(),
|
|
$this->getServiceContainer()->getPageStore()
|
|
);
|
|
|
|
$authority = $authority ?: $this->mockRegisteredUltimateAuthority();
|
|
$helper->init( $authority, $params );
|
|
return $helper;
|
|
}
|
|
|
|
private function getExistingPageWithRevisions( $name ) {
|
|
$page = $this->getNonexistingTestPage( $name );
|
|
|
|
$this->editPage( $page, 'First revision of ' . $name );
|
|
$revisions['first'] = $page->getRevisionRecord();
|
|
|
|
$this->editPage( $page, 'DEAD BEEF' );
|
|
$revisions['latest'] = $page->getRevisionRecord();
|
|
|
|
return [ $page, $revisions ];
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getRole()
|
|
*/
|
|
public function testGetRole() {
|
|
$helper = $this->newHelper();
|
|
$this->assertSame( SlotRecord::MAIN, $helper->getRole() );
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTitleText()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getPage()
|
|
*/
|
|
public function testGetPage() {
|
|
[ $page, $revisions ] = $this->getExistingPageWithRevisions( __METHOD__ );
|
|
|
|
$helper = $this->newHelper( [ 'id' => $revisions['first']->getId() ] );
|
|
$this->assertSame( $page->getTitle()->getPrefixedDBKey(), $helper->getTitleText() );
|
|
|
|
$this->assertInstanceOf( ExistingPageRecord::class, $helper->getPage() );
|
|
$this->assertTrue( $helper->getPage()->isSamePageAs( $page->getTitle() ) );
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTargetRevision()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getContent()
|
|
*/
|
|
public function testGetTargetRevisionAndContent() {
|
|
[ $page, $revisions ] = $this->getExistingPageWithRevisions( __METHOD__ );
|
|
|
|
$helper = $this->newHelper( [ 'id' => $revisions['first']->getId() ] );
|
|
|
|
$targetRev = $helper->getTargetRevision();
|
|
$this->assertInstanceOf( RevisionRecord::class, $targetRev );
|
|
$this->assertSame( $revisions['first']->getId(), $targetRev->getId() );
|
|
|
|
$pageContent = $helper->getContent();
|
|
$this->assertSame(
|
|
$revisions['first']->getContent( SlotRecord::MAIN )->serialize(),
|
|
$pageContent->serialize()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTitleText()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getPage()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::isAccessible()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::hasContent()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTargetRevision()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getContent()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getLastModified()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getETag()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::checkAccess()
|
|
*/
|
|
public function testNoTitle() {
|
|
$helper = $this->newHelper();
|
|
|
|
$this->assertNull( $helper->getTitleText() );
|
|
$this->assertNull( $helper->getPage() );
|
|
|
|
$this->assertFalse( $helper->hasContent() );
|
|
$this->assertFalse( $helper->isAccessible() );
|
|
|
|
$this->assertNull( $helper->getTargetRevision() );
|
|
|
|
$this->assertNull( $helper->getLastModified() );
|
|
$this->assertSame( self::NO_REVISION_ETAG, $helper->getETag() );
|
|
|
|
try {
|
|
$helper->getContent();
|
|
$this->fail( 'Expected HttpException' );
|
|
} catch ( HttpException $ex ) {
|
|
$this->assertSame( 404, $ex->getCode() );
|
|
}
|
|
|
|
try {
|
|
$helper->checkAccess();
|
|
$this->fail( 'Expected HttpException' );
|
|
} catch ( HttpException $ex ) {
|
|
$this->assertSame( 404, $ex->getCode() );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTitleText()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getPage()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::isAccessible()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::hasContent()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTargetRevision()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getContent()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getLastModified()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getETag()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::checkAccess()
|
|
*/
|
|
public function testNonExistingRevision() {
|
|
$helper = $this->newHelper( [ 'id' => 287436534 ] );
|
|
|
|
$this->assertSame( 287436534, $helper->getRevisionId() );
|
|
$this->assertNull( $helper->getTitleText() );
|
|
$this->assertNull( $helper->getPage() );
|
|
|
|
$this->assertFalse( $helper->hasContent() );
|
|
$this->assertFalse( $helper->isAccessible() );
|
|
|
|
$this->assertNull( $helper->getTargetRevision() );
|
|
|
|
$this->assertNull( $helper->getLastModified() );
|
|
$this->assertSame( self::NO_REVISION_ETAG, $helper->getETag() );
|
|
|
|
try {
|
|
$helper->getContent();
|
|
$this->fail( 'Expected HttpException' );
|
|
} catch ( HttpException $ex ) {
|
|
$this->assertSame( 404, $ex->getCode() );
|
|
}
|
|
|
|
try {
|
|
$helper->checkAccess();
|
|
$this->fail( 'Expected HttpException' );
|
|
} catch ( HttpException $ex ) {
|
|
$this->assertSame( 404, $ex->getCode() );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTitleText()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getPage()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::isAccessible()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::hasContent()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getTargetRevision()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getContent()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getLastModified()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getETag()
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::checkAccess()
|
|
*/
|
|
public function testForbidenPage() {
|
|
[ $page, $revisions ] = $this->getExistingPageWithRevisions( __METHOD__ );
|
|
$title = $page->getTitle();
|
|
$helper = $this->newHelper(
|
|
[ 'id' => $revisions['first']->getId() ],
|
|
$this->mockAnonNullAuthority()
|
|
);
|
|
|
|
$this->assertSame( $title->getPrefixedDBkey(), $helper->getTitleText() );
|
|
$this->assertTrue( $helper->getPage()->isSamePageAs( $title ) );
|
|
|
|
$this->assertTrue( $helper->hasContent() );
|
|
$this->assertFalse( $helper->isAccessible() );
|
|
|
|
$this->assertNull( $helper->getLastModified() );
|
|
|
|
try {
|
|
$helper->checkAccess();
|
|
$this->fail( 'Expected HttpException' );
|
|
} catch ( HttpException $ex ) {
|
|
$this->assertSame( 403, $ex->getCode() );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::getParamSettings()
|
|
*/
|
|
public function testParameterSettings() {
|
|
$helper = $this->newHelper();
|
|
$settings = $helper->getParamSettings();
|
|
$this->assertArrayHasKey( 'id', $settings );
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::setCacheControl()
|
|
*/
|
|
public function testCacheControl() {
|
|
$helper = $this->newHelper();
|
|
|
|
$response = new Response();
|
|
|
|
$helper->setCacheControl( $response ); // default
|
|
$this->assertStringContainsString( 'max-age=5', $response->getHeaderLine( 'Cache-Control' ) );
|
|
|
|
$helper->setCacheControl( $response, 2 ); // explicit
|
|
$this->assertStringContainsString( 'max-age=2', $response->getHeaderLine( 'Cache-Control' ) );
|
|
|
|
$helper->setCacheControl( $response, 1000 * 1000 ); // too big
|
|
$this->assertStringContainsString( 'max-age=5', $response->getHeaderLine( 'Cache-Control' ) );
|
|
}
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Handler\RevisionContentHelper::constructMetadata()
|
|
*/
|
|
public function testConstructMetadata() {
|
|
[ $page, $revisions ] = $this->getExistingPageWithRevisions( __METHOD__ );
|
|
$title = $page->getTitle();
|
|
|
|
$revision = $revisions['first'];
|
|
$content = $revision->getContent( SlotRecord::MAIN );
|
|
$expected = [
|
|
'id' => $revision->getId(),
|
|
'size' => $revision->getSize(),
|
|
'minor' => $revision->isMinor(),
|
|
'timestamp' => wfTimestampOrNull( TS_ISO_8601, $revision->getTimestamp() ),
|
|
'content_model' => $content->getModel(),
|
|
'page' => [
|
|
'id' => $title->getArticleID(),
|
|
'key' => $title->getPrefixedDBkey(),
|
|
'title' => $title->getPrefixedText(),
|
|
],
|
|
'license' => [
|
|
'url' => 'https://example.com/rights',
|
|
'title' => 'some rights',
|
|
],
|
|
'user' => [
|
|
'id' => $revision->getUser()->getId(),
|
|
'name' => $revision->getUser()->getName(),
|
|
],
|
|
'comment' => '',
|
|
'delta' => null, // first revision doesn't have a delta for now
|
|
];
|
|
|
|
$helper = $this->newHelper( [ 'id' => $revision->getId() ] );
|
|
$data = $helper->constructMetadata();
|
|
$this->assertEquals( $expected, $data );
|
|
}
|
|
|
|
}
|