Skip to content

Commit 77de9ee

Browse files
committed
fixed unit tests
* fix unit tests for 1.40+ * delegate handling of suppressed modal from magic word to class BootstrapComponentsService
1 parent f5a9c9f commit 77de9ee

19 files changed

+209
-179
lines changed

.github/workflows/installWiki.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ echo '$wgArticlePath = $wgScriptPath . "/$1";' >> LocalSettings.php
5353
echo '$wgEnableUploads = true;' >> LocalSettings.php
5454

5555
echo 'wfLoadSkin( "Vector" );' >> LocalSettings.php
56+
echo '$wgDefaultSkin = "vector-2022";' >> LocalSettings.php
5657

5758
echo 'wfLoadExtension( "Bootstrap" );' >> LocalSettings.php
5859
echo 'wfLoadExtension( "Scribunto" );' >> LocalSettings.php

.github/workflows/uploadCoverageReport.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ COVERAGE_REPORT=${MW_ROOT}/coverage.clover
44

55
if [[ ! -e ${COVERAGE_REPORT} ]]; then
66
echo "File coverage.clover is missing. Abort the upload!"
7-
exit 127
7+
# this was exit 127; restore exit value when code coverage is again supported
8+
exit
89
fi
910

1011
cd EarlyCopy

src/BootstrapComponentsService.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ class BootstrapComponentsService
2020
*/
2121
private Config $mainConfig;
2222

23+
/**
24+
* @var bool
25+
*/
26+
private bool $modalsSuppressedByMagicWord;
2327

2428
/**
2529
* Holds the name of the skin we use (or false, if there is no skin).
@@ -31,6 +35,15 @@ class BootstrapComponentsService
3135
public function __construct( Config $mainConfig ) {
3236
$this->mainConfig = $mainConfig;
3337
$this->activeComponents = [];
38+
$this->modalsSuppressedByMagicWord = false;
39+
}
40+
41+
42+
/**
43+
* @return bool
44+
*/
45+
public function areModalsSuppressedByMagicWord(): bool {
46+
return $this->modalsSuppressedByMagicWord;
3447
}
3548

3649
/**
@@ -61,6 +74,14 @@ public function registerComponentAsActive( string $componentName ): void {
6174
$this->activeComponents[$componentName] = true;
6275
}
6376

77+
/**
78+
* @param bool $modalsSuppressedByMagicWord
79+
* @return void
80+
*/
81+
public function setModalsSuppressedByMagicWord( bool $modalsSuppressedByMagicWord ): void {
82+
$this->modalsSuppressedByMagicWord = $modalsSuppressedByMagicWord;
83+
}
84+
6485
/**
6586
* Returns true, if active skin is vector
6687
*

src/Hooks/OutputPageParserOutput.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
use MediaWiki\Extension\BootstrapComponents\BootstrapComponentsService;
3131
use OutputPage;
3232
use ParserOutput;
33+
/*
34+
* TODO: When dropping support for 1.39, use these:
35+
use MediaWiki\Output\OutputPage;
36+
use MediaWiki\Parser\ParserOutput;
37+
*/
3338

3439
/**
3540
* Class OutputPageParserOutput
@@ -126,16 +131,14 @@ protected function getBootstrapComponentsService(): BootstrapComponentsService {
126131
/**
127132
* @return OutputPage
128133
*/
129-
protected function getOutputPage(): OutputPage
130-
{
134+
protected function getOutputPage(): OutputPage {
131135
return $this->outputPage;
132136
}
133137

134138
/**
135139
* @return ParserOutput
136140
*/
137-
protected function getParserOutput(): ParserOutput
138-
{
141+
protected function getParserOutput(): ParserOutput {
139142
return $this->parserOutput;
140143
}
141144
}

src/HooksHandler.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use MediaWiki\Hook\ParserFirstCallInitHook;
1515
use MediaWiki\Hook\SetupAfterCacheHook;
1616
use MediaWiki\MediaWikiServices;
17-
use Parser;
17+
use MediaWiki\Parser\Parser;
1818
use SMW\Utils\File;
1919
use StripState;
2020

@@ -168,14 +168,10 @@ public function onImageBeforeProduceHTML(
168168
* @return bool
169169
*/
170170
public function onInternalParseBeforeLinks( $parser, &$text, $stripState ): bool {
171-
// we do not use our ParserOutputHelper class here, for we would need to reset it in integration tests.
172-
// resetting our factory build classes is unfortunately a little skittish
173-
$parser->getOutput()->setExtensionData(
174-
BootstrapComponents::EXTENSION_DATA_NO_IMAGE_MODAL,
175-
MediaWikiServices::getInstance()->getMagicWordFactory()->get( 'BSC_NO_IMAGE_MODAL' )
176-
->matchAndRemove( $text )
171+
$this->getBootstrapComponentsService()->setModalsSuppressedByMagicWord(
172+
MediaWikiServices::getInstance()
173+
->getMagicWordFactory()->get( 'BSC_NO_IMAGE_MODAL' )->matchAndRemove( $text )
177174
);
178-
179175
return true;
180176
}
181177

src/ImageModal.php

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Contains the class for replacing image normal image display with a modal.
3+
* Contains the class for replacing normal image display with a modal.
44
*
55
* @copyright (C) 2018, Tobias Oetterer, Paderborn University
66
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later)
@@ -26,7 +26,6 @@
2626

2727
namespace MediaWiki\Extension\BootstrapComponents;
2828

29-
use DummyLinker;
3029
use File;
3130
use Html;
3231
use MediaTransformOutput;
@@ -54,11 +53,6 @@ class ImageModal implements NestableInterface {
5453
*/
5554
private BootstrapComponentsService $bootstrapComponentService;
5655

57-
/**
58-
* @var DummyLinker $dummyLinker
59-
*/
60-
private DummyLinker $dummyLinker;
61-
6256
/**
6357
* @var File $file
6458
*/
@@ -97,7 +91,7 @@ class ImageModal implements NestableInterface {
9791
/**
9892
* ImageModal constructor.
9993
*
100-
* @param DummyLinker $dummyLinker
94+
* @param null $null (was DummyLinker $dummyLinker)
10195
* @param Title $title
10296
* @param File $file
10397
* @param NestingController $nestingController
@@ -107,12 +101,11 @@ class ImageModal implements NestableInterface {
107101
* @throws MWException cascading {@see ApplicationFactory} methods
108102
*/
109103
public function __construct(
110-
DummyLinker $dummyLinker, Title $title, File $file,
104+
$null, Title $title, File $file,
111105
NestingController $nestingController, BootstrapComponentsService $bootstrapComponentService,
112106
ParserOutputHelper $parserOutputHelper = null
113107
) {
114108
$this->file = $file;
115-
$this->dummyLinker = $dummyLinker;
116109
$this->title = $title;
117110

118111
$this->nestingController = $nestingController;
@@ -195,6 +188,7 @@ public function parse( array &$frameParams, array &$handlerParams, &$time, &$res
195188

196189
if ( $res === '' ) {
197190
// ImageModal::turnParamsIntoModal returns the empty string, when something went wrong
191+
// returning true means, delegating the image rendering back to \MediaWiki\Linker\Linker::makeImageLink
198192
return true;
199193
}
200194
return false;
@@ -281,14 +275,6 @@ protected function getBootstrapComponentsService(): BootstrapComponentsService {
281275
return $this->bootstrapComponentService;
282276
}
283277

284-
/**
285-
* @return DummyLinker
286-
*/
287-
/** @scrutinizer ignore-unused */
288-
protected function getDummyLinker(): DummyLinker {
289-
return $this->dummyLinker;
290-
}
291-
292278
/**
293279
* @return File
294280
*/
@@ -312,7 +298,6 @@ protected function getParentComponent(): bool|NestableInterface|null {
312298

313299
/**
314300
* @return ParserOutputHelper
315-
* @deprecated
316301
*/
317302
protected function getParserOutputHelper(): ParserOutputHelper {
318303
return $this->parserOutputHelper;
@@ -422,16 +407,13 @@ private function assertImageModalNotSuppressed( array $frameParams ): bool
422407
) {
423408
return false;
424409
}
425-
/** @see ParserOutputHelper::areImageModalsSuppressed as to why we need to use the global parser! */
426-
$parser = MediaWikiServices::getInstance()->getParser();
427-
// the is_null test has to be added because otherwise some unit tests will fail
428-
return is_null( $parser->getOutput() )
429-
|| !$parser->getOutput()->getExtensionData( BootstrapComponents::EXTENSION_DATA_NO_IMAGE_MODAL );
410+
return !MediaWikiServices::getInstance()->getService( 'BootstrapComponentsService' )
411+
->areModalsSuppressedByMagicWord();
430412
}
431413

432414
/**
433415
* @param MediaTransformOutput $img
434-
* @param array $sanitizedFrameParams
416+
* @param array $sanitizedFrameParams
435417
*
436418
* @return string
437419
*/

src/ModalBuilder.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
namespace MediaWiki\Extension\BootstrapComponents;
2828

2929
use \Html;
30+
use MediaWiki\MediaWikiServices;
3031

3132
/**
3233
* Class ModalBase

src/ParserOutputHelper.php

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,21 @@
2626

2727
namespace MediaWiki\Extension\BootstrapComponents;
2828

29-
use \Html;
30-
use \ParserOutput;
31-
use \Title;
29+
/*
30+
* TODO: When dropping support for MW1.39, use these class imports:
31+
use MediaWiki\Html\Html;
32+
use MediaWiki\Message\Message;
33+
use MediaWiki\Parser\Parser;
34+
use MediaWiki\Parser\ParserOutput;
35+
use MediaWiki\Title\Title;
36+
*/
37+
38+
use Html;
39+
use Message;
40+
use Parser;
41+
use ParserOutput;
42+
use Title;
43+
3244

3345
/**
3446
* Class ParserOutputHelper
@@ -54,7 +66,7 @@ class ParserOutputHelper {
5466
private $articleTrackedOnError;
5567

5668
/**
57-
* @var \Parser $parser
69+
* @var Parser $parser
5870
*/
5971
private $parser;
6072

@@ -64,7 +76,7 @@ class ParserOutputHelper {
6476
*
6577
* Do not instantiate directly, but use {@see ApplicationFactory::getParserOutputHelper} instead.
6678
*
67-
* @param \Parser $parser
79+
* @param Parser $parser
6880
*
6981
* @see ApplicationFactory::getParserOutputHelper
7082
*/
@@ -115,7 +127,7 @@ public function addTrackingCategory() {
115127
* Unless I find a solution for the integration test problem, I cannot use an instance of
116128
* ParserOutputHelper in ImageModal to ascertain this. In integration tests, "we" use a
117129
* different parser than the InternalParseBeforeLinks-Hook. At least, after I added
118-
* Scribunto _unit_ tests. All messes up, I'm afraid. ImageModal better use global parser, and
130+
* Scribunto _unit_ tests. All messed up, I'm afraid. ImageModal better use global parser, and
119131
* for the time being this method will be
120132
* @deprecated
121133
*
@@ -157,22 +169,25 @@ public function injectLater( $id, $rawHtml ) {
157169
*
158170
* @return string
159171
*/
160-
public function renderErrorMessage( $errorMessageName ) {
172+
public function renderErrorMessage( string $errorMessageName ): string {
161173
if ( !$errorMessageName || !trim( $errorMessageName ) ) {
162174
return '';
163175
}
164176
$this->addErrorTrackingCategory();
165177
return Html::rawElement(
166178
'span',
167179
[ 'class' => 'error' ],
168-
wfMessage( trim( $errorMessageName ) )->inContentLanguage()->title( $this->parser->getTitle() )->parse()
180+
(new Message( trim( $errorMessageName ) ))->inContentLanguage()->page(
181+
$this->getParser()->getPage()
182+
)->parse()
169183
);
184+
170185
}
171186

172187
/**
173-
* @return \Parser
188+
* @return Parser
174189
*/
175-
protected function getParser() {
190+
protected function getParser(): Parser {
176191
return $this->parser;
177192
}
178193

@@ -181,11 +196,11 @@ protected function getParser() {
181196
*
182197
* @param String $trackingCategoryMessageName name of the message, containing the tracking category
183198
*/
184-
private function placeTrackingCategory( $trackingCategoryMessageName ) {
185-
$categoryMessage = wfMessage( $trackingCategoryMessageName )->inContentLanguage();
199+
private function placeTrackingCategory( string $trackingCategoryMessageName ): void {
200+
$categoryMessage = (new Message( $trackingCategoryMessageName ))->inContentLanguage();
186201
$parserOutput = $this->parser->getOutput();
187202
if ( !$categoryMessage->isDisabled() && is_a( $parserOutput, ParserOutput::class ) ) {
188-
// Q: when do we expect \Parser->getOutput() no to be a \ParserOutput? A:During tests.
203+
// Q: when do we expect Parser->getOutput() no to be a ParserOutput? A:During tests.
189204
$cat = Title::makeTitleSafe( NS_CATEGORY, $categoryMessage->text() );
190205
if ( $cat ) {
191206
$sort = (string)$parserOutput->getPageProperty('defaultsort') ?? '';

tests/phpunit/Unit/AbstractComponentTest.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,15 @@ public function testSimpleOutput( string $component ) {
119119
$parsedString = reset( $parsedString );
120120
}
121121
$this->assertIsString( $parsedString );
122-
$this->assertRegExp(
123-
'/class="[^"]*test-class"/',
124-
$parsedString
125-
);
126-
$this->assertRegExp(
127-
'/style="[^"]*color:black"/',
128-
$parsedString
129-
);
122+
123+
// TODO when we drop support for MW1.39
124+
if ( version_compare( $GLOBALS['wgVersion'], '1.40', 'lt' ) ) {
125+
$this->assertRegExp( '/class="[^"]*test-class"/', $parsedString );
126+
$this->assertRegExp( '/style="[^"]*color:black"/', $parsedString );
127+
} else {
128+
$this->assertMatchesRegularExpression( '/class="[^"]*test-class"/', $parsedString );
129+
$this->assertMatchesRegularExpression( '/style="[^"]*color:black"/', $parsedString );
130+
}
130131
}
131132

132133
/**

tests/phpunit/Unit/BootstrapComponentServiceTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ public function testCanGetNameOfActiveSkin() {
3838
$instance = new BootstrapComponentsService( $this->getMockBuilder( Config::class )->getMock() );
3939

4040
$this->assertEquals(
41-
'vector',
41+
'vector-2022',
4242
$instance->getNameOfActiveSkin()
4343
);
4444
}
4545

46-
public function testRegisterModules() {
46+
public function testRegisterComponentAsActive() {
4747
$instance = new BootstrapComponentsService( $this->getMockBuilder( Config::class )->getMock() );
4848

4949
$instance->registerComponentAsActive( 'Foo' );
@@ -70,10 +70,11 @@ public function testPrivateCanDetectSkinInUse() {
7070

7171
$reflection = new ReflectionClass( BootstrapComponentsService::class );
7272
$method = $reflection->getMethod( 'detectSkinInUse' );
73+
$method->setAccessible( true );
7374

7475
// this is default
7576
$this->assertEquals(
76-
'vector',
77+
'vector-2022',
7778
$method->invokeArgs( $instance, [ false ] )
7879
);
7980

0 commit comments

Comments
 (0)