diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63a0d33..7052e32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,10 @@ on: push: pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + jobs: test: name: "PHPUnit: MW ${{ matrix.mw }}, PHP ${{ matrix.php }}" @@ -13,21 +17,12 @@ jobs: fail-fast: false matrix: include: - - mw: 'REL1_39' - php: 8.1 - experimental: false - - mw: 'REL1_40' - php: 8.1 - experimental: false - - mw: 'REL1_41' - php: 8.2 - experimental: false - - mw: 'REL1_42' - php: 8.2 - experimental: false - mw: 'REL1_43' php: 8.3 experimental: false + - mw: 'REL1_44' + php: 8.4 + experimental: false - mw: 'master' php: 8.4 experimental: true @@ -43,7 +38,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: mbstring, intl + extensions: mbstring, intl, pdo_sqlite, php-ast tools: composer - name: Cache MediaWiki @@ -54,49 +49,80 @@ jobs: mediawiki !mediawiki/extensions/ !mediawiki/vendor/ - key: mw_${{ matrix.mw }}-php${{ matrix.php }} + key: mw_${{ matrix.mw }}-php${{ matrix.php }}-${{ runner.os }} + restore-keys: | + mw_${{ matrix.mw }}-php${{ matrix.php }}- + mw_${{ matrix.mw }}- - - name: Cache Composer cache + - name: Cache composer cache + id: cache-composer uses: actions/cache@v4 with: - path: ~/.composer/cache - key: composer-php${{ matrix.php }} + path: ~/.cache/composer + key: composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + composer-${{ matrix.php }}- - - uses: actions/checkout@v4 + - name: Checkout (EarlyCopy) + uses: actions/checkout@v4 with: path: EarlyCopy - name: Install MediaWiki if: steps.cache-mediawiki.outputs.cache-hit != 'true' - working-directory: ~ + working-directory: ${{ github.workspace }} run: bash EarlyCopy/.github/workflows/installMediaWiki.sh ${{ matrix.mw }} ExternalContent - - uses: actions/checkout@v4 + - name: Checkout extension into MediaWiki tree + uses: actions/checkout@v4 with: path: mediawiki/extensions/ExternalContent - name: Composer allow-plugins run: composer config --no-plugins allow-plugins.composer/installers true - - run: composer update + - name: Composer update (extension + deps) + run: composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader - name: Run update.php run: php maintenance/update.php --quick - - name: Run PHPUnit - run: php tests/phpunit/phpunit.php -c extensions/ExternalContent/ + - name: Run PHPUnit (junit) + continue-on-error: true + run: php tests/phpunit/phpunit.php -c extensions/ExternalContent/ --log-junit tests/junit.xml - - name: Run PHPUnit with code coverage - run: php tests/phpunit/phpunit.php -c extensions/ExternalContent/ --coverage-clover coverage.xml + - name: Upload PHPUnit JUnit result + uses: actions/upload-artifact@v4 + with: + name: phpunit-junit-${{ matrix.mw }}-php${{ matrix.php }} + path: mediawiki/tests/junit.xml + + - name: Run PHPUnit with code coverage (master only) if: matrix.mw == 'master' + run: php tests/phpunit/phpunit.php -c extensions/ExternalContent/ --coverage-clover coverage.xml - - name: Upload code coverage - run: bash <(curl -s https://codecov.io/bash) + - name: Upload code coverage (master only) securely if: matrix.mw == 'master' + continue-on-error: true + uses: codecov/codecov-action@v4 + with: + files: coverage.xml - - name: Run parser tests - run: php tests/parser/parserTests.php --file=extensions/ExternalContent/tests/parser/parserTests.txt - if: matrix.mw >= 'REL1_43' + - name: Upload coverage artifact (master only) + if: matrix.mw == 'master' + uses: actions/upload-artifact@v4 + with: + name: coverage-${{ matrix.mw }}-php${{ matrix.php }} + path: coverage.xml + + - name: Run parser tests (explicit targets) + if: matrix.mw == 'REL1_43' || matrix.mw == 'REL1_44' || matrix.mw == 'master' + run: | + if [[ "${{ matrix.mw }}" == "REL1_43" ]]; then + php tests/parser/parserTests.php --file=extensions/ExternalContent/tests/parser/parserTests-mw143.txt + else + php tests/parser/parserTests.php --file=extensions/ExternalContent/tests/parser/parserTests.txt + fi static-analysis: name: "Static Analysis: MW ${{ matrix.mw }}, PHP ${{ matrix.php }}" @@ -106,6 +132,8 @@ jobs: include: - mw: 'REL1_43' php: '8.3' + - mw: 'REL1_44' + php: '8.4' runs-on: ubuntu-latest @@ -118,7 +146,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: mbstring + extensions: mbstring, intl, pdo_sqlite, php-ast tools: composer, cs2pr - name: Cache MediaWiki @@ -129,24 +157,32 @@ jobs: mediawiki !mediawiki/extensions/ !mediawiki/vendor/ + # Shared cache key across static-analysis and code-style jobs + # Safe to share because both jobs use the same MW core code key: mw_static_analysis + restore-keys: | + mw_static_analysis - - name: Cache Composer cache + - name: Cache composer cache uses: actions/cache@v4 with: - path: ~/.composer/cache - key: composer_static_analysis + path: ~/.cache/composer + key: composer_shared-${{ hashFiles('**/composer.lock') }} + restore-keys: | + composer_shared- - - uses: actions/checkout@v4 + - name: Checkout (EarlyCopy) + uses: actions/checkout@v4 with: path: EarlyCopy - - name: Install MediaWiki + - name: Install MediaWiki (if needed) if: steps.cache-mediawiki.outputs.cache-hit != 'true' - working-directory: ~ + working-directory: ${{ github.workspace }} run: bash EarlyCopy/.github/workflows/installMediaWiki.sh ${{ matrix.mw }} ExternalContent - - uses: actions/checkout@v4 + - name: Checkout extension into MediaWiki tree + uses: actions/checkout@v4 with: path: mediawiki/extensions/ExternalContent @@ -159,9 +195,11 @@ jobs: - name: PHPStan run: php vendor/bin/phpstan analyse --error-format=checkstyle --no-progress | cs2pr - - run: php vendor/bin/psalm --shepherd --stats - if: true - + - name: Psalm + # Skip Psalm on PHP 8.4 until we can upgrade psalm to 5.x + # MediaWiki core locks psalm to ^4.3 + if: matrix.php != '8.4' + run: php vendor/bin/psalm --shepherd --stats code-style: name: "Code style: MW ${{ matrix.mw }}, PHP ${{ matrix.php }}" @@ -171,6 +209,8 @@ jobs: include: - mw: 'REL1_43' php: '8.3' + - mw: 'REL1_44' + php: '8.4' runs-on: ubuntu-latest @@ -183,7 +223,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: mbstring, intl, php-ast + extensions: mbstring, intl, pdo_sqlite, php-ast tools: composer - name: Cache MediaWiki @@ -194,24 +234,32 @@ jobs: mediawiki !mediawiki/extensions/ !mediawiki/vendor/ + # Shared cache key across static-analysis and code-style jobs + # Safe to share because both jobs use the same MW core code key: mw_static_analysis + restore-keys: | + mw_static_analysis - - name: Cache Composer cache + - name: Cache composer cache uses: actions/cache@v4 with: - path: ~/.composer/cache - key: composer_static_analysis + path: ~/.cache/composer + key: composer_shared-${{ hashFiles('**/composer.lock') }} + restore-keys: | + composer_shared- - - uses: actions/checkout@v4 + - name: Checkout (EarlyCopy) + uses: actions/checkout@v4 with: path: EarlyCopy - - name: Install MediaWiki + - name: Install MediaWiki (if needed) if: steps.cache-mediawiki.outputs.cache-hit != 'true' - working-directory: ~ + working-directory: ${{ github.workspace }} run: bash EarlyCopy/.github/workflows/installMediaWiki.sh ${{ matrix.mw }} ExternalContent - - uses: actions/checkout@v4 + - name: Checkout extension into MediaWiki tree + uses: actions/checkout@v4 with: path: mediawiki/extensions/ExternalContent @@ -221,4 +269,5 @@ jobs: - name: Composer install run: composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader - - run: vendor/bin/phpcs -p -s + - name: PHP CodeSniffer + run: vendor/bin/phpcs -p -s \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3d34031..065b9bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ .phpunit.result.cache composer.lock -vendor/ \ No newline at end of file +vendor/ + +# Local CI/testing artifacts (act, generated directories, logs) +.actrc +*.log +mediawiki/ +EarlyCopy/ \ No newline at end of file diff --git a/Makefile b/Makefile index 8ad09d6..7902367 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: ci test cs phpunit phpcs stan psalm parser +.PHONY: ci test cs phpunit phpcs stan psalm parser parser-mw143 ci: test cs test: phpunit parser @@ -18,3 +18,6 @@ psalm: parser: php ../../tests/parser/parserTests.php --file=tests/parser/parserTests.txt + +parser-mw143: + php ../../tests/parser/parserTests.php --file=tests/parser/parserTests-mw143.txt \ No newline at end of file diff --git a/README.md b/README.md index 8606641..6d1b093 100644 --- a/README.md +++ b/README.md @@ -97,10 +97,12 @@ Parameters: none ## Installation -Platform requirements: +Platform requirements of 4.x: -* [PHP] 8.0 or later (tested up to 8.3) -* [MediaWiki] 1.39 or later (tested up to 1.43 and master) +* [PHP] 8.0 or later (tested up to 8.4) +* [MediaWiki] 1.43 or later (tested up to 1.44 and master) + +For older PHP or MediaWiki, use older versions of External Content. The recommended way to install External Content is using [Composer] with [MediaWiki's built-in support for Composer][Composer install]. @@ -108,7 +110,7 @@ The recommended way to install External Content is using [Composer] with On the commandline, go to your wikis root directory. Then run these two commands: ```shell script -COMPOSER=composer.local.json composer require --no-update professional-wiki/external-content:~3.0 +COMPOSER=composer.local.json composer require --no-update professional-wiki/external-content:~4.0 ``` ```shell script composer update professional-wiki/external-content --no-dev -o @@ -244,6 +246,13 @@ Alternatively, you can execute commands from the MediaWiki root directory: ## Release notes +### Version 4.0.0 - 2025-07-04 + +* Raised minimum MediaWiki version from 1.39 to 1.43 +* Added support for MediaWiki 1.44 +* Fixed compatibility issue with the Network extension +* Translation updates + ### Version 3.0.1 - 2025-04-06 * Fixed compatibility with MediaWiki 1.43 and above (IDatabase TypeError) diff --git a/extension.json b/extension.json index 082b975..0c62216 100644 --- a/extension.json +++ b/extension.json @@ -1,6 +1,6 @@ { "name": "External Content", - "version": "3.0.1", + "version": "4.0.0", "license-name": "GPL-2.0-or-later", "author": [ @@ -13,7 +13,7 @@ "descriptionmsg": "external-content-desc", "requires": { - "MediaWiki": ">= 1.39.0", + "MediaWiki": ">= 1.43.0", "platform": { "php": ">= 8.0" } diff --git a/i18n/ce.json b/i18n/ce.json new file mode 100644 index 0000000..22d9b3e --- /dev/null +++ b/i18n/ce.json @@ -0,0 +1,19 @@ +{ + "@metadata": { + "authors": [ + "Умар" + ] + }, + "external-content-desc": "Бакъо ло арахьара чулацам чубаккха, масала, «markdown» файлаш, хьан вики агӀонаш тӀехь", + "external-content-fetch-failed": "Файл схьаэца аьтто ца баьлла", + "external-content-domain-not-allowed": "Оцу доменера файлаш дӀахӀотто бакъо йац", + "external-content-extension-not-allowed": "Оцу форматан файлаш дӀахӀотто бакъо йац", + "external-content-url-missing-host": "URL чохь хост йац", + "external-content-url-missing-path": "URL-адрес чохь бац файлан некъ", + "external-content-url-not-bitbucket": "Bitbucket-ан нийса йоцу URL", + "external-content-url-missing-repository": "URL-адресехь йац репозиторин цӀе", + "external-content-tracking-category": "Арахьара чулацам болу агӀонаш", + "external-content-tracking-category-desc": "ХӀокху агӀонан тӀехь чубиллина арахьара чулацам бу", + "external-content-broken-tracking-category": "Боьхна арахьара чулацам болу агӀонаш", + "external-content-broken-tracking-category-desc": "ХӀокху агӀонна арахьара чулацам чубаккха аьтто ца баьлла" +} diff --git a/i18n/pt-br.json b/i18n/pt-br.json index c726793..d4eac00 100644 --- a/i18n/pt-br.json +++ b/i18n/pt-br.json @@ -5,5 +5,15 @@ ] }, "external-content-desc": "Permite a incorporação de conteúdo externo, como arquivos markdown, em suas páginas wiki", - "external-content-extension-not-allowed": "Incorporar arquivos com esta extensão não é permitido" + "external-content-fetch-failed": "Não foi possível recuperar o arquivo", + "external-content-domain-not-allowed": "Não é permitido incorporar arquivos deste domínio.", + "external-content-extension-not-allowed": "Incorporar arquivos com esta extensão não é permitido", + "external-content-url-missing-host": "URL está sem host", + "external-content-url-missing-path": "URL está sem o caminho do arquivo", + "external-content-url-not-bitbucket": "Não é um URL de Bitbucket válido", + "external-content-url-missing-repository": "O URL tem em falta o nome do repositório", + "external-content-tracking-category": "Páginas com conteúdo externo", + "external-content-tracking-category-desc": "Esta página incorpora conteúdo externo", + "external-content-broken-tracking-category": "Páginas com conteúdo externo corrompido", + "external-content-broken-tracking-category-desc": "Esta página não conseguiu incorporar conteúdo externo" } diff --git a/src/Adapters/EmbedPresenter/CategoryUsageTracker.php b/src/Adapters/EmbedPresenter/CategoryUsageTracker.php index 5f20a2b..4b3805c 100644 --- a/src/Adapters/EmbedPresenter/CategoryUsageTracker.php +++ b/src/Adapters/EmbedPresenter/CategoryUsageTracker.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter; -use Parser; +use MediaWiki\Parser\Parser; class CategoryUsageTracker implements UsageTracker { diff --git a/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php b/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php index f538943..288daf2 100644 --- a/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php +++ b/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter; -use Html; +use MediaWiki\Html\Html; use MessageLocalizer; use ProfessionalWiki\ExternalContent\UseCases\Embed\EmbedPresenter; diff --git a/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php b/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php index cf38e9c..c9a9819 100644 --- a/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php +++ b/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Adapters\EmbedResourceLoader; -use ParserOutput; +use MediaWiki\Parser\ParserOutput; use ProfessionalWiki\ExternalContent\Domain\ContentRenderer; use ProfessionalWiki\ExternalContent\Domain\ContentRenderer\CodeRenderer; use ProfessionalWiki\ExternalContent\UseCases\Embed\EmbedResourceLoader; diff --git a/src/Domain/ContentRenderer/CodeRenderer.php b/src/Domain/ContentRenderer/CodeRenderer.php index 84a466e..0969b89 100644 --- a/src/Domain/ContentRenderer/CodeRenderer.php +++ b/src/Domain/ContentRenderer/CodeRenderer.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Domain\ContentRenderer; -use Html; +use MediaWiki\Html\Html; use ProfessionalWiki\ExternalContent\Domain\ContentRenderer; class CodeRenderer implements ContentRenderer { @@ -77,7 +77,7 @@ private function normalizeLines( string $lines ): string { $ranges = array_filter( $exploded, static function( $value ): bool { return ( preg_match( '/^\d+$/', $value ) || preg_match( '/^(\d+)-(\d+)$/', $value ) ); } ); - + return implode( ',', $ranges ); } } diff --git a/src/EntryPoints/BitbucketFunction.php b/src/EntryPoints/BitbucketFunction.php index 62c0b70..abc26d3 100644 --- a/src/EntryPoints/BitbucketFunction.php +++ b/src/EntryPoints/BitbucketFunction.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\EntryPoints; -use Parser; +use MediaWiki\Parser\Parser; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\CategoryUsageTracker; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\ParserFunctionEmbedPresenter; use ProfessionalWiki\ExternalContent\Adapters\EmbedResourceLoader\ParserFunctionEmbedResourceLoader; diff --git a/src/EntryPoints/EmbedFunction.php b/src/EntryPoints/EmbedFunction.php index 644e81f..2e2ce43 100644 --- a/src/EntryPoints/EmbedFunction.php +++ b/src/EntryPoints/EmbedFunction.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\EntryPoints; -use Parser; +use MediaWiki\Parser\Parser; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\CategoryUsageTracker; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\ParserFunctionEmbedPresenter; use ProfessionalWiki\ExternalContent\Adapters\EmbedResourceLoader\ParserFunctionEmbedResourceLoader; diff --git a/src/EntryPoints/MediaWikiHooks.php b/src/EntryPoints/MediaWikiHooks.php index 3daf24d..8962407 100644 --- a/src/EntryPoints/MediaWikiHooks.php +++ b/src/EntryPoints/MediaWikiHooks.php @@ -4,11 +4,11 @@ namespace ProfessionalWiki\ExternalContent\EntryPoints; -use ContentHandler; +use MediaWiki\Content\ContentHandler; use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionRecord; -use Parser; -use ParserOutput; +use MediaWiki\Parser\Parser; +use MediaWiki\Parser\ParserOutput; use ProfessionalWiki\ExternalContent\EmbedExtensionFactory; use SearchEngine; use WikiPage; diff --git a/test-ci.sh b/test-ci.sh new file mode 100755 index 0000000..7df0cf0 --- /dev/null +++ b/test-ci.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Helper script to test CI workflow locally with act +# Usage: ./test-ci.sh [job-name] [mw-version] [php-version] +# e.g. ./test-ci.sh test REL1_44 8.4 +# Turns into the underlying 'act' command: +# act -j test --matrix mw:REL1_44 --matrix php:8.4 --matrix experimental:false -v +# +# `./test-ci.sh list` to list available jobs + +set -e + +# Verify act is installed +if ! command -v act &> /dev/null; then + echo "Error: 'act' is not installed. See: https://github.com/nektos/act" + exit 1 +fi + +# Read parameters with defaults +JOB="${1:-test}" +MW_VERSION="${2:-REL1_43}" +PHP_VERSION="${3:-8.3}" + +echo "Testing job: $JOB with MediaWiki $MW_VERSION and PHP $PHP_VERSION" + +case "$JOB" in + test) + act -j test \ + --matrix mw:"$MW_VERSION" \ + --matrix php:"$PHP_VERSION" \ + --matrix experimental:false \ + --verbose + ;; + static-analysis) + act -j static-analysis --verbose + ;; + code-style) + act -j code-style --verbose + ;; + all) + echo "Running all jobs with $MW_VERSION..." + act -j static-analysis --verbose + act -j code-style --verbose + act -j test --matrix mw:"$MW_VERSION" --matrix php:"$PHP_VERSION" --matrix experimental:false --verbose + ;; + list) + echo "Available jobs:" + act -l + ;; + *) + echo "Unknown job: $JOB" + echo "Available jobs: test, static-analysis, code-style, all, list" + exit 1 + ;; +esac diff --git a/tests/Integration/EmbedFunctionIntegrationTest.php b/tests/Integration/EmbedFunctionIntegrationTest.php index 11a7641..035447f 100644 --- a/tests/Integration/EmbedFunctionIntegrationTest.php +++ b/tests/Integration/EmbedFunctionIntegrationTest.php @@ -7,6 +7,9 @@ use FileFetcher\InMemoryFileFetcher; use FileFetcher\StubFileFetcher; use MediaWiki\MediaWikiServices; +use MediaWiki\Parser\ParserOptions; +use MediaWiki\Title\Title; +use MediaWiki\User\User; use ProfessionalWiki\ExternalContent\Tests\TestEnvironment; /** @@ -51,22 +54,24 @@ public function testUsageIsTracked(): void { $this->extensionFactory->setFileFetcher( new InMemoryFileFetcher( [] ) ); $parser = MediaWikiServices::getInstance()->getParser(); - - $parser->parse( + $parserOptions = new ParserOptions( User::newSystemUser( 'TestUser' ) ); + $parserOutput = $parser->parse( '{{#embed:https://example.com/KITTENS.md}}', - \Title::newFromText( 'EmbedFunctionIntegrationTest' ), - new \ParserOptions( \User::newSystemUser( 'TestUser' ) ) - )->getText(); + Title::newFromText( 'EmbedFunctionIntegrationTest' ), + $parserOptions + ); + + $parserOutput = $parserOutput->runOutputPipeline( $parserOptions ); // Since the category name depends on the wiki language, we need to skip this test when it is not English. if ( MediaWikiServices::getInstance()->getContentLanguage()->getCode() === 'en' ) { $this->assertSame( [ 'Pages_with_external_content', 'Pages_with_broken_external_content' ], - $parser->getOutput()->getCategoryNames() + $parserOutput->getCategoryNames() ); } - $this->assertCount( 2, $parser->getOutput()->getCategoryNames() ); + $this->assertCount( 2, $parserOutput->getCategoryNames() ); } public function testGitHubNormalization(): void { diff --git a/tests/Integration/EmbedFunctionSystemTest.php b/tests/Integration/EmbedFunctionSystemTest.php index 4392f64..9e711a2 100644 --- a/tests/Integration/EmbedFunctionSystemTest.php +++ b/tests/Integration/EmbedFunctionSystemTest.php @@ -6,8 +6,8 @@ use CommentStoreComment; use FileFetcher\StubFileFetcher; -use Title; -use User; +use MediaWiki\Title\Title; +use MediaWiki\User\User; use WikiPage; /** diff --git a/tests/TestEnvironment.php b/tests/TestEnvironment.php index 2f9c5dd..9e7101f 100644 --- a/tests/TestEnvironment.php +++ b/tests/TestEnvironment.php @@ -5,7 +5,9 @@ namespace ProfessionalWiki\ExternalContent\Tests; use MediaWiki\MediaWikiServices; -use Title; +use MediaWiki\Parser\ParserOptions; +use MediaWiki\Title\Title; +use MediaWiki\User\User; class TestEnvironment { @@ -22,12 +24,17 @@ public function wikiUrl( string $pageName ): ?string { } public function parse( string $textToParse, ?Title $contextPage = null ): string { - return MediaWikiServices::getInstance()->getParser() + $parserOptions = new ParserOptions( User::newSystemUser( 'TestUser' ) ); + $contextPage = $contextPage ?? Title::newFromText( 'ContextPage' ); + $parserOutput = MediaWikiServices::getInstance()->getParser() ->parse( $textToParse, - $contextPage ?? Title::newFromText( 'ContextPage' ), - new \ParserOptions( \User::newSystemUser( 'TestUser' ) ) - )->getText(); + $contextPage, + $parserOptions + ); + + return $parserOutput->runOutputPipeline( $parserOptions ) + ->getContentHolderText(); } } diff --git a/tests/parser/README.md b/tests/parser/README.md new file mode 100644 index 0000000..531d616 --- /dev/null +++ b/tests/parser/README.md @@ -0,0 +1,72 @@ +# Parser Tests + +This directory contains parser tests for the ExternalContent extension. + +## Version Compatibility + +Due to changes in MediaWiki's Codex message box implementation between versions, the HTML output differs slightly: + +- **MediaWiki 1.43**: `