mediawiki-extensions-Discus.../tests/phpunit/CommentFormatterTest.php
Arlo Breault 7e5f9b59a2 Invert logic on empty talk page
Record if a talk page is not empty, rather than empty.

This helps prevent Parsoid from mislabelling pages as empty when they
contain extension tags it needs to call out to the legacy parser to
process.  Metadata from the legacy parse is merged into the overall
metadata for the page.

For example, a templatestyles extension tag parsed in the context of a
talk page would set the empty state which would then fail to cleared if
the overall parse of the page wasn't empty.

Bartosz (@matmarex) proposed this idea in T371125#10053043

Setting and using these flags all appear to be post-retrieval from
cache.

Alternative to I1deb679ef0e19dc3a36e377c183dd1b4ab0003e9

Bug: T371125
Change-Id: I5c1877f7f9eb73f88a33e001ca3c2f3d06bb90e4
2024-08-14 18:26:25 -04:00

148 lines
5.2 KiB
PHP

<?php
namespace MediaWiki\Extension\DiscussionTools\Tests;
use FormatJson;
use MediaWiki\Cache\GenderCache;
use MediaWiki\Context\IContextSource;
use MediaWiki\MainConfigNames;
use MediaWiki\Output\OutputPage;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Title\Title;
use MediaWiki\User\User;
use Skin;
use Wikimedia\TestingAccessWrapper;
/**
* @covers \MediaWiki\Extension\DiscussionTools\CommentFormatter
* @covers \MediaWiki\Extension\DiscussionTools\CommentUtils
*/
class CommentFormatterTest extends IntegrationTestCase {
/**
* @dataProvider provideIsLanguageRequiringReplyIcon
*/
public function testIsLanguageRequiringReplyIcon(
string $langCode, bool $expected, ?array $config = null
): void {
$lang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( $langCode );
if ( $config ) {
$this->overrideConfigValues( [
'DiscussionTools_visualenhancements_reply_icon_languages' => $config
] );
}
$actual = MockCommentFormatter::isLanguageRequiringReplyIcon( $lang );
static::assertEquals( $expected, $actual, $langCode );
}
public static function provideIsLanguageRequiringReplyIcon(): array {
return [
[ 'zh', true ],
[ 'zh-hant', true ],
[ 'ar', true ],
[ 'arz', true ],
[ 'arz', false, [ 'ar' => true, 'arz' => false ] ],
[ 'en', false ],
[ 'he', false ],
];
}
/**
* @dataProvider provideAddDiscussionToolsInternal
*/
public function testAddDiscussionToolsInternal(
string $name, string $titleText, string $dom, string $expected, string $config, string $data,
bool $isMobile, bool $useButtons
): void {
$this->setService( 'GenderCache', $this->createNoOpMock( GenderCache::class ) );
$dom = static::getHtml( $dom );
$expectedPath = $expected;
$expected = static::getText( $expectedPath );
$config = static::getJson( $config );
$data = static::getJson( $data );
$this->overrideConfigValues( [
// Consistent defaults for generating canonical URLs
MainConfigNames::Server => 'https://example.org',
MainConfigNames::CanonicalServer => 'https://example.org',
MainConfigNames::ArticlePath => '/wiki/$1',
MainConfigNames::ScriptPath => '/w',
MainConfigNames::Script => '/w/index.php',
] );
$title = Title::newFromText( $titleText );
$subscriptionStore = new MockSubscriptionStore();
$user = $this->createMock( User::class );
$qqxLang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'qqx' );
$skin = $this->createMock( Skin::class );
$skin->method( 'getSkinName' )->willReturn( 'minerva' );
$outputPage = $this->createMock( IContextSource::class );
$outputPage->method( 'getTitle' )->willReturn( $title );
$outputPage->method( 'getUser' )->willReturn( $user );
$outputPage->method( 'getLanguage' )->willReturn( $qqxLang );
$outputPage->method( 'getSkin' )->willReturn( $skin );
$outputPage->method( 'msg' )->willReturn( 'a label' );
MockCommentFormatter::$parser = $this->createParser( $config, $data );
$commentFormatter = TestingAccessWrapper::newFromClass( MockCommentFormatter::class );
$pout = new ParserOutput();
$preprocessed = $commentFormatter->addDiscussionToolsInternal( $dom, $pout, $title );
$preprocessed .= "\n<pre>\n" .
"newestComment: " . FormatJson::encode(
$pout->getExtensionData( 'DiscussionTools-newestComment' ), "\t", FormatJson::ALL_OK ) . "\n" .
( $pout->getExtensionData( 'DiscussionTools-hasLedeContent' ) ?
"hasLedeContent\n" : '' ) .
( $pout->getExtensionData( 'DiscussionTools-hasCommentsInLedeContent' ) ?
"hasCommentsInLedeContent\n" : '' ) .
( $pout->getExtensionData( 'DiscussionTools-isNotEmptyTalkPage' ) ?
'' : "isEmptyTalkPage\n" ) .
FormatJson::encode( $pout->getJsConfigVars(), "\t", FormatJson::ALL_OK ) .
"\n</pre>";
OutputPage::setupOOUI();
$actual = $preprocessed;
$actual = MockCommentFormatter::postprocessTopicSubscription(
$actual, $outputPage, $subscriptionStore, $isMobile, $useButtons
);
$actual = MockCommentFormatter::postprocessVisualEnhancements(
$actual, $outputPage, $isMobile
);
$actual = MockCommentFormatter::postprocessReplyTool(
$actual, $outputPage, $isMobile, $useButtons
);
// OOUI ID's are non-deterministic, so strip them from test output
$actual = preg_replace( '/ id=[\'"]ooui-php-[0-9]+[\'"]/', '', $actual );
// Optionally write updated content to the "reply HTML" files
if ( getenv( 'DISCUSSIONTOOLS_OVERWRITE_TESTS' ) ) {
static::overwriteTextFile( $expectedPath, $actual );
}
static::assertEquals( $expected, $actual, $name );
}
/**
* @return iterable<array>
*/
public static function provideAddDiscussionToolsInternal() {
foreach ( static::getJson( '../cases/formatted.json' ) as $case ) {
// Run each test case twice, for desktop and mobile output
yield array_merge( $case,
[ 'expected' => $case['expected']['desktop'], 'isMobile' => false, 'useButtons' => true ] );
yield array_merge( $case,
[ 'expected' => $case['expected']['mobile'], 'isMobile' => true, 'useButtons' => true ] );
// Test the legacy output without visual enhancements (only available on desktop)
yield array_merge( $case,
[ 'expected' => $case['expected']['legacy'], 'isMobile' => false, 'useButtons' => false ] );
}
}
}