Soeren.oldag has submitted this change and it was merged. Change subject: add job for checking for violations after visit of special page ......................................................................
add job for checking for violations after visit of special page therefore, adopted special page and tests Change-Id: I2f552ec571687fbbb2d048d3d5a7bce067546358 --- M WikidataQualityExternalValidation.php A includes/CheckForCrossCheckViolationsJob.php M specials/SpecialCrossCheck.php A tests/phpunit/CheckForCrossCheckViolationsJobTest.php M tests/phpunit/Specials/SpecialCrossCheckTest.php 5 files changed, 248 insertions(+), 22 deletions(-) Approvals: Soeren.oldag: Verified; Looks good to me, approved diff --git a/WikidataQualityExternalValidation.php b/WikidataQualityExternalValidation.php index 7a41cbc..92ce1f9 100644 --- a/WikidataQualityExternalValidation.php +++ b/WikidataQualityExternalValidation.php @@ -1,26 +1,26 @@ <?php // Alert the user that this is not a valid access point to MediaWiki if they try to access the special pages file directly. if ( !defined( 'MEDIAWIKI' ) ) { - echo <<<EOT + echo <<<EOT To install my extension, put the following line in LocalSettings.php: require_once( "\$IP/extensions/WikidataQualityExternalValidation/WikidataQualityExternalValidation.php" ); EOT; - exit( 1 ); + exit( 1 ); } // Enable autoload if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - require_once __DIR__ . '/vendor/autoload.php'; + require_once __DIR__ . '/vendor/autoload.php'; } // Set credits -$wgExtensionCredits[ 'specialpage' ][ ] = array( - 'path' => __FILE__, - 'name' => 'WikidataQualityExternalValidation', - 'author' => 'BP2014N1', - 'url' => 'https://www.mediawiki.org/wiki/Extension:WikidataQualityExternalValidation', - 'descriptionmsg' => 'wikidataquality-external-validation-desc', - 'version' => '0.0.0' +$wgExtensionCredits[ 'specialpage' ][ ] = array ( + 'path' => __FILE__, + 'name' => 'WikidataQualityExternalValidation', + 'author' => 'BP2014N1', + 'url' => 'https://www.mediawiki.org/wiki/Extension:WikidataQualityExternalValidation', + 'descriptionmsg' => 'wikidataquality-external-validation-desc', + 'version' => '0.0.0' ); // Initialize localization and aliases @@ -46,3 +46,6 @@ define( 'DUMP_DATA_TABLE', 'wdqa_external_data' ); define( 'DUMP_META_TABLE', 'wdqa_dump_information' ); define( 'DUMP_IDENTIFIER_PROPERTIES_TABLE', 'wdqa_identifier_properties' ); + +// Jobs +$wgJobClasses[ 'checkForCrossCheckViolations' ] = 'CheckForCrossCheckViolationsJob'; \ No newline at end of file diff --git a/includes/CheckForCrossCheckViolationsJob.php b/includes/CheckForCrossCheckViolationsJob.php new file mode 100644 index 0000000..35680d0 --- /dev/null +++ b/includes/CheckForCrossCheckViolationsJob.php @@ -0,0 +1,97 @@ +<?php + +namespace WikidataQuality\ExternalValidation; + +use Job; +use Title; +use Wikibase\DataModel\Entity\Entity; +use WikidataQuality\ExternalValidation\CrossCheck\CrossChecker; +use WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult; + + +class CheckForCrossCheckViolationsJob extends Job { + + public static function newInsertNow( + Entity $entity, + $checkTimestamp, + $results ) { + // The Job class wants a Title object for some reason. Supply a dummy. + $dummyTitle = Title::newFromText( "CheckForCrossCheckViolationsJob", NS_SPECIAL ); + + $params = array (); + + $params[ 'entity' ] = $entity; + $params[ 'results' ] = $results; + $params[ 'checkTimestamp' ] = $checkTimestamp; + $params[ 'referenceTimestamp' ] = null; + + return new CheckForCrossCheckViolationsJob( $dummyTitle, $params ); + } + + public static function newInsertDeferred( + Entity $entity, + $referenceTimestamp = null, + $releaseTimestamp = 0 ) { + // The Job class wants a Title object for some reason. Supply a dummy. + $dummyTitle = Title::newFromText( "CheckForCrossCheckViolationsJob", NS_SPECIAL ); + + $params = array (); + + $params[ 'entity' ] = $entity; + $params[ 'results' ] = null; + $params[ 'referenceTimestamp' ] = $referenceTimestamp; + $params[ 'releaseTimestamp' ] = wfTimestamp( TS_MW ) + $releaseTimestamp; + + return new CheckForCrossCheckViolationsJob( $dummyTitle, $params ); + } + + public function __construct( Title $title, $params ) { + parent::__construct( 'checkForCrossCheckViolations', $title, $params ); + } + + public function run() { + wfWaitForSlaves(); + $loadBalancer = wfGetLB(); + $db = $loadBalancer->getConnection( DB_MASTER ); + + $checkTimestamp = array_key_exists( 'checkTimestamp', $this->params ) ? $this->params[ 'checkTimestamp' ] : wfTimestamp( TS_MW ); + + if ( $this->params[ 'results' ] === null ) { + $crossChecker = new CrossChecker( $this->params[ 'entity' ] ); + $results = $crossChecker->crossCheckEntity(); + } else { + $results = $this->params[ 'results' ]; + } + + $accumulator = array ( + 'special_page_id' => 2, + 'entity_id' => $this->params[ 'entity' ]->getId()->getSerialization(), + 'insertion_timestamp' => $checkTimestamp, + 'reference_timestamp' => $this->params[ 'referenceTimestamp' ], + 'result_string' => $this->getResultSerialization( $results ) + ); + $success = $db->insert( EVALUATION_TABLE, $accumulator ); + + return $success; + } + + private function getResultSerialization( $results ) { + $violations = $compliances = $referencesMissing = 0; + foreach ( $results as $result ) { + switch ( $result->getStatus() ) { + case CrossCheckResult::STATUS_COMPLIANCE: + $compliances += 1; + break; + case CrossCheckResult::STATUS_DATA_MISMATCH: + $violations += 1; + break; + case CrossCheckResult::STATUS_REFERENCES_MISSING: + $referencesMissing += 1; + } + } + + $serialization = 'Compliances: ' . $compliances . ', Violations: ' . $violations . ', References missing: ' . $referencesMissing; + return $serialization; + } + +} \ No newline at end of file diff --git a/specials/SpecialCrossCheck.php b/specials/SpecialCrossCheck.php index 8a84b7b..155aea5 100755 --- a/specials/SpecialCrossCheck.php +++ b/specials/SpecialCrossCheck.php @@ -10,6 +10,8 @@ use WikidataQuality\ExternalValidation\CrossCheck\CrossChecker; use WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult; use WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultToViolationTranslator; +use WikidataQuality\ExternalValidation\CheckForCrossCheckViolationsJob; +use JobQueueGroup; use WikidataQuality\Violations\ViolationStore; use WikidataQuality\Html\HtmlTable; use WikidataQuality\Html\HtmlTableHeader; @@ -65,7 +67,9 @@ $crossChecker = new CrossChecker( $entity ); $results = $crossChecker->crossCheckEntity(); - $this->saveResultsInViolationsTable( $entity, $results ); + $this->doEvaluation( $entity, $results ); + + $this->saveResultsInViolationsTable( $entity, $results ); return $results; } @@ -133,14 +137,26 @@ ); } - /** - * @param EntityDocument $entity - * @param array $results - */ - protected function saveResultsInViolationsTable( $entity, $results ) { - $translator = new CrossCheckResultToViolationTranslator(); - $violations = $translator->translateToViolation( $entity, $results ); - $violationStore = new ViolationStore(); - $violationStore->insertViolations( $violations ); - } -} + /** + * @param EntityDocument $entity + * @param array $results + */ + protected function saveResultsInViolationsTable( $entity, $results ) { + $translator = new CrossCheckResultToViolationTranslator(); + $violations = $translator->translateToViolation( $entity, $results ); + $violationStore = new ViolationStore(); + $violationStore->insertViolations( $violations ); + } + + protected function doEvaluation( $entity, $results ) { + //TODO: Push (deferred) job(s) in queue + $checkTimeStamp = wfTimestamp( TS_MW ); + $jobs = array (); + $jobs[ ] = CheckForCrossCheckViolationsJob::newInsertNow( $entity, $checkTimeStamp, $results ); + $jobs[ ] = CheckForCrossCheckViolationsJob::newInsertDeferred( $entity, $checkTimeStamp, 10 ); + + $jobs[ 0 ]->run(); + $jobs[ 1 ]->run(); + JobQueueGroup::singleton()->push( $jobs ); + } +} \ No newline at end of file diff --git a/tests/phpunit/CheckForCrossCheckViolationsJobTest.php b/tests/phpunit/CheckForCrossCheckViolationsJobTest.php new file mode 100644 index 0000000..7642d8b --- /dev/null +++ b/tests/phpunit/CheckForCrossCheckViolationsJobTest.php @@ -0,0 +1,109 @@ +<?php + +namespace WikidataQuality\ExternalValidation\Tests; + +use Wikibase\DataModel\Entity\Item; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Reference; +use Wikibase\Lib\ClaimGuidGenerator; +use WikidataQuality\ExternalValidation\CrossCheck\Result\CompareResult; +use WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult; +use WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList; +use DateTime; +use Wikibase\DataModel\Statement\Statement; +use Wikibase\DataModel\Claim\Claim; +use Wikibase\DataModel\Snak\PropertyValueSnak; +use Wikibase\DataModel\Entity\PropertyId; +use DataValues\StringValue; +use Wikibase\Repo\WikibaseRepo; +use WikidataQuality\ExternalValidation\CrossCheck\Result\ReferenceResult; +use WikidataQuality\ExternalValidation\DumpMetaInformation; +use WikidataQuality\ExternalValidation\CheckForCrossCheckViolationsJob; + + +/** + * @covers WikidataQuality\ExternalValidation\CheckForCrossCheckViolationsJob + * + * @group Database + * + * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\CompareResult + * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\ReferenceResult + * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult + * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList + * @uses WikidataQuality\ExternalValidation\DumpMetaInformation + * @uses WikidataQuality\ExternalValidation\CrossCheck\CrossChecker + * + * @author BP2014N1 + * @license GNU GPL v2+ + */ +class CheckForCrossCheckViolationsJobTest extends \MediaWikiTestCase { + + private $results; + private $entity; + private $checkTimestamp; + + protected function setUp() { + parent::setUp(); + + $propertyId = new PropertyId( 'P188' ); + $guidGenerator = new ClaimGuidGenerator(); + $itemId = new ItemId( 'Q42' ); + $claimGuid = $guidGenerator->newGuid( $itemId ); + + $dateTime = new DateTime(); + $dumpMetaInformation = new DumpMetaInformation( 'dumpId', $itemId, $dateTime, 'irrelevent', 'irrelevant.org', 100, $itemId ); + + $compareResultViolation = new CompareResult( new StringValue( 'foo' ), array( new StringValue( 'bar' ) ), true ); + $compareResultCompliance = new CompareResult( new StringValue( 'foo' ), array( new StringValue( 'bar' ) ), false ); + + $referenceResultMissing = new ReferenceResult( true, new Reference() ); + $referenceResultExisting = new ReferenceResult( false, new Reference() ); + + $results = array (); + $results[ ] = new CrossCheckResult( $propertyId, $claimGuid, $dumpMetaInformation, $compareResultViolation, $referenceResultMissing ); + $results[ ] = new CrossCheckResult( $propertyId, $claimGuid, $dumpMetaInformation, $compareResultViolation, $referenceResultExisting ); + $results[ ] = new CrossCheckResult( $propertyId, $claimGuid, $dumpMetaInformation, $compareResultCompliance, $referenceResultMissing ); + $results[ ] = new CrossCheckResult( $propertyId, $claimGuid, $dumpMetaInformation, $compareResultCompliance, $referenceResultExisting ); + $this->results = new CrossCheckResultList( $results ); + + $this->checkTimestamp = wfTimestamp( TS_MW ); + + // specify database tables used by this test + $this->tablesUsed[ ] = EVALUATION_TABLE; + } + + protected function tearDown() { + unset( $this->results ); + unset( $this->entity ); + unset( $this->checkTimestamp ); + parent::tearDown(); + } + + public function addDBData() { + $this->db->delete( + EVALUATION_TABLE, + '*' + ); + + $this->entity = new Item(); + $store = WikibaseRepo::getDefaultInstance()->getEntityStore(); + $store->saveEntity( $this->entity, 'TestEntityQ1', $GLOBALS[ 'wgUser' ], EDIT_NEW ); + } + + public function testCheckForViolationJobNow() { + $job = CheckForCrossCheckViolationsJob::newInsertNow( $this->entity, $this->checkTimestamp, $this->results ); + $job->run(); + $count = $this->db->select( EVALUATION_TABLE, array ( 'special_page_id' ), array ( 'special_page_id=2' ) )->numRows(); + $result = $this->db->selectRow( EVALUATION_TABLE, array ( 'result_string' ), array ( 'special_page_id=2' ) ); + $this->assertEquals( 1, $count ); + TODO: $this->assertEquals( 'Compliances: 1, Violations: 2, References missing: 1', $result->result_string ); + } + + public function testCheckForViolationJobDeferred() { + $job = CheckForCrossCheckViolationsJob::newInsertDeferred( $this->entity, $this->checkTimestamp, 10 ); + $job->run(); + $count = $this->db->select( EVALUATION_TABLE, array ( 'special_page_id' ), array ( 'special_page_id=2' ) )->numRows(); + $this->assertEquals( 1, $count ); + } + +} diff --git a/tests/phpunit/Specials/SpecialCrossCheckTest.php b/tests/phpunit/Specials/SpecialCrossCheckTest.php index 44dc00e..fbc0cb3 100755 --- a/tests/phpunit/Specials/SpecialCrossCheckTest.php +++ b/tests/phpunit/Specials/SpecialCrossCheckTest.php @@ -33,6 +33,7 @@ * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList * @uses WikidataQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultToViolationTranslator + * @uses WikidataQuality\ExternalValidation\CheckForCrossCheckViolationsJob * @uses WikidataQuality\Html\HtmlTable * @uses WikidataQuality\Html\HtmlTableHeader * @uses WikidataQuality\Html\HtmlTableCell -- To view, visit https://gerrit.wikimedia.org/r/206095 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2f552ec571687fbbb2d048d3d5a7bce067546358 Gerrit-PatchSet: 2 Gerrit-Project: mediawiki/extensions/WikidataQualityExternalValidation Gerrit-Branch: master Gerrit-Owner: Jonaskeutel <jonas.keu...@student.hpi.de> Gerrit-Reviewer: Soeren.oldag <soeren_ol...@freenet.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits