Tamslo has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/207464

Change subject: Implemented basic API for violations
......................................................................

Implemented basic API for violations

With getviolations and the parameter entity all violations or null that
belong to an entity are returned.

Change-Id: Ia3fa6ee23706d23e1f1f6ce51deea6538f0874b8
---
A Api/GetViolations.php
M WikidataQuality.php
M composer.json
A includes/Serializer/ViolationSerializer.php
M phpunit.xml.dist
A tests/phpunit/Api/GetViolationsTest.php
A tests/phpunit/Serializer/ViolationSerializerTest.php
7 files changed, 394 insertions(+), 0 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikidataQuality 
refs/changes/64/207464/1

diff --git a/Api/GetViolations.php b/Api/GetViolations.php
new file mode 100644
index 0000000..1eb1c59
--- /dev/null
+++ b/Api/GetViolations.php
@@ -0,0 +1,157 @@
+<?php
+
+namespace WikidataQuality\Api;
+
+use ApiMain;
+use DataValues\Serializers;
+use DataValues\Serializers\DataValueSerializer;
+use Wikibase\Api\ApiWikibase;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Statement\StatementList;
+use Wikibase\Repo\WikibaseRepo;
+use WikidataQuality\Violations\ViolationLookup;
+use WikidataQuality\Violations\ViolationQuery;
+use WikidataQuality\Serializer\ViolationSerializer;
+
+
+/**
+ * Class GetViolations
+ *
+ * API module to access found violations
+ *
+ * @package WikidataQuality\Api
+ * @author BP2014N1
+ * @license GNU GPL v2+
+ */
+class GetViolations extends ApiWikibase {
+
+       /**
+        * Wikibase entity id parser
+        *
+        * @var \Wikibase\DataModel\Entity\EntityIdParser
+        */
+       private $entityIdParser;
+
+       /**
+        * Wikibase entity lookup
+        *
+        * @var \Wikibase\Lib\Store\EntityLookup
+        */
+       private $entityLookup;
+
+       /**
+        * Wikibase claim guid parser
+        *
+        * @var \Wikibase\DataModel\Claim\ClaimGuidParser
+        */
+       private $claimGuidParser;
+
+       /**
+        * Wikibase clam guid validator
+        *
+        * @var \Wikibase\Lib\ClaimGuidValidator
+        */
+       private $claimGuidValidator;
+
+       /**
+        * @var ViolationLookup
+        */
+       private $violationLookup;
+
+       /**
+        * @var ViolationSerializer
+        */
+       private $violationSerializer;
+
+       /**
+        * @param ApiMain $main
+        * @param string $name
+        * @param string $prefix
+        */
+       public function __construct( ApiMain $main, $name, $prefix = '' ) {
+               parent::__construct( $main, $name, $prefix );
+
+               $repo = WikibaseRepo::getDefaultInstance();
+               $this->entityIdParser = $repo->getEntityIdParser();
+               $this->entityLookup = $repo->getEntityLookup();
+               $this->claimGuidParser = $repo->getClaimGuidParser();
+               $this->claimGuidValidator = $repo->getClaimGuidValidator();
+               $this->violationLookup = new ViolationLookup();
+               $this->violationSerializer = new ViolationSerializer();
+       }
+
+       /**
+        * Gets violations from the violations table belonging to given entity 
and outputs them in the form of:
+        * result
+        *              { claimGuidOfViolation { violation }
+        *      { claimGuidOfAnotherViolation { anotherViolation }}
+        */
+       public function execute() {
+               $params = $this->extractRequestParams();
+
+               if ( $params['entity'] ) {
+                       $result = $this->getViolationsFromEntity( 
$params['entity'][0] );
+               } else {
+                       $this->dieError( 'Invalid parameters.', 'param-invalid' 
);
+               }
+
+               $this->writeResultOutput( $result );
+       }
+
+       /**
+        * @param string $entityId
+        *
+        * @return array
+        */
+       private function getViolationsFromEntity( $entityId ) {
+               $query = new ViolationQuery();
+               $query->setEntityId( $entityId );
+               $result = $this->violationLookup->getWhere( $query );
+               return $result;
+       }
+
+       private function writeResultOutput( $result ) {
+               $output = array();
+               if ( $result ) {
+                       foreach ( $result as $violation ) {
+                               $serializedViolation = 
$this->violationSerializer->serialize( $violation );
+                               $output[ $serializedViolation['claimGuid'] ] = 
$serializedViolation;
+                       }
+
+                       $this->getResult()->setIndexedTagName( $output, 
'violatedClaims' );
+                       $this->getResult()->addValue( null, 'results', $output 
);
+                       $this->getResultBuilder()->markSuccess( 1 );
+               } else {
+                       $this->getResult()->addValue( null, 'results', null );
+                       $this->getResult()->addValue( null, 'message', 'no 
violations found' );
+                       $this->getResultBuilder()->markSuccess( 1 );
+               }
+       }
+
+       /**
+        * Returns an array of allowed parameters
+        *
+        * @return array
+        * @codeCoverageIgnore
+        */
+       public function getAllowedParams() {
+               return array_merge( parent::getAllowedParams(), array (
+                       'entity' => array (
+                               ApiWikibase::PARAM_TYPE => 'string',
+                               ApiWikibase::PARAM_ISMULTI => true
+                       )
+               ) );
+       }
+
+       /**
+        * Returns usage examples for this module
+        *
+        * @return array
+        * @codeCoverageIgnore
+        */
+       public function getExamplesMessages() {
+               return array (
+                       'action=wdqagetviolations&entity=Q76' => 
'apihelp-wdqacrosscheck-examples-1'
+               );
+       }
+}
\ No newline at end of file
diff --git a/WikidataQuality.php b/WikidataQuality.php
index bec172e..85c9845 100644
--- a/WikidataQuality.php
+++ b/WikidataQuality.php
@@ -40,6 +40,9 @@
                'localBasePath' => __DIR__,
                'remoteExtPath' => 'WikidataQuality'
        );
+
+       // Define API modules
+       $GLOBALS['wgAPIModules']['wdqagetviolations'] = 
'WikidataQuality\Api\GetViolations';
 });
 
 // Define database table names
diff --git a/composer.json b/composer.json
index 628ad99..f7a7deb 100644
--- a/composer.json
+++ b/composer.json
@@ -25,6 +25,7 @@
        "autoload": {
                "psr-4": {
                        "WikidataQuality\\": "includes/",
+                       "WikidataQuality\\Api\\": "api/",
                        "WikidataQuality\\Specials\\": "specials/",
                        "WikidataQuality\\Tests\\": "tests/phpunit/"
                },
diff --git a/includes/Serializer/ViolationSerializer.php 
b/includes/Serializer/ViolationSerializer.php
new file mode 100644
index 0000000..8d368bc
--- /dev/null
+++ b/includes/Serializer/ViolationSerializer.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace WikidataQuality\Serializer;
+
+
+use Serializers\DispatchableSerializer;
+use WikidataQuality\Violations\Violation;
+use Serializers\Exceptions\UnsupportedObjectException;
+
+
+class ViolationSerializer implements DispatchableSerializer {
+
+       /**
+        * @see DispatchableSerializer::isSerializerFor
+        *
+        * @param mixed $object
+        *
+        * @return bool
+        */
+       public function isSerializerFor( $object ) {
+               return $object instanceof Violation;
+       }
+
+       /**
+        * @see Serializer::serialize
+        *
+        * @param mixed $object
+        *
+        * @return array
+        * @throws UnsupportedObjectException
+        */
+       public function serialize( $object ) {
+               if ( !$this->isSerializerFor( $object ) ) {
+                       throw new UnsupportedObjectException(
+                               $object,
+                               'ViolationSerializer can only serialize 
Violation objects.'
+                       );
+               }
+
+               return $this->getSerialized( $object );
+       }
+
+       private function getSerialized( Violation $violation ) {
+               return array(
+                       'entityId' => 
$violation->getEntityId()->getSerialization(),
+                       'propertyId' => 
$violation->getPropertyId()->getSerialization(),
+                       'claimGuid' => $violation->getClaimGuid(),
+                       'constraintId' => $violation->getConstraintId(),
+                       // TODO: ->getSerialization (when it really is an 
EntityId and not just a string)
+                       'constraintTypeEntityId' => 
$violation->getConstraintTypeEntityId(),
+                       'additionalInfo' => $violation->getAdditionalInfo(),
+                       'updatedAt' => $violation->getUpdatedAt(),
+                       'revisionId' => $violation->getRevisionId(),
+                       'status' => $violation->getStatus()
+               );
+       }
+
+}
\ No newline at end of file
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 582bb0b..cfaf556 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -19,6 +19,7 @@
     </testsuites>
     <filter>
         <whitelist addUncoveredFilesFromWhitelist="true">
+            <directory suffix=".php">api</directory>
             <directory suffix=".php">includes</directory>
         </whitelist>
     </filter>
diff --git a/tests/phpunit/Api/GetViolationsTest.php 
b/tests/phpunit/Api/GetViolationsTest.php
new file mode 100644
index 0000000..2c0d439
--- /dev/null
+++ b/tests/phpunit/Api/GetViolationsTest.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace WikidataQuality\Tests\Api;
+
+use Wikibase\Test\Api\WikibaseApiTestCase;
+
+
+/**
+ * @covers WikidataQuality\Api\GetViolations
+ *
+ * @group Database
+ * @group API
+ * @group medium
+ *
+ * @author BP2014N1
+ * @license GNU GPL v2+
+ */
+class GetViolationsTest extends WikibaseApiTestCase {
+
+       protected function setup() {
+               parent::setup();
+               $this->tablesUsed[] = VIOLATION_TABLE;
+       }
+
+       public function addDBData() {
+               $this->db->delete(
+                       VIOLATION_TABLE,
+                       '*'
+               );
+
+               $this->db->insert(
+                       VIOLATION_TABLE,
+                       array(
+                               array(
+                                       'entity_id' => 'Q1',
+                                       'pid' => 'P1',
+                                       'claim_guid' => 
'P1$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                                       'constraint_id' => 
'P666$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                                       'constraint_type_entity_id' => 'Q666',
+                                       'additional_info' => '{"type":"JSON", 
"mandatory":false}',
+                                       'updated_at' => wfTimestamp( TS_MW, 
'2014-10-15T15:00:00Z' ),
+                                       'revision_id' => 1234,
+                                       'status' => 'compliance'
+                               ),
+                               array(
+                                       'entity_id' => 'Q1',
+                                       'pid' => 'P2',
+                                       'claim_guid' => 
'P2$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                                       'constraint_id' => 
'P667$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                                       'constraint_type_entity_id' => 'Q667',
+                                       'additional_info' => '{"type":"JSON", 
"mandatory":false}',
+                                       'updated_at' => wfTimestamp( TS_MW, 
'2014-10-15T15:00:00Z' ),
+                                       'revision_id' => 2345,
+                                       'status' => 'exception'
+                               ),
+                               array(
+                                       'entity_id' => 'Q2',
+                                       'pid' => 'P3',
+                                       'claim_guid' => 
'P3$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                                       'constraint_id' => 
'P668$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                                       'constraint_type_entity_id' => 'Q668',
+                                       'additional_info' => '{"type":"JSON", 
"mandatory":false}',
+                                       'updated_at' => wfTimestamp( TS_MW, 
'2014-10-15T15:00:00Z' ),
+                                       'revision_id' => 3456,
+                                       'status' => 'unverified'
+                               )
+                       )
+               );
+       }
+
+       public function testInvalidExecute() {
+               $params = array(
+                       'action' => 'wdqagetviolations'
+               );
+               $this->setExpectedException( 'UsageException' );
+               $this->doApiRequest( $params );
+       }
+
+       public function testExecuteWithNoResult() {
+               $params = array(
+                       'action' => 'wdqagetviolations',
+                       'entity' => 'Q3'
+               );
+               $result = $this->doApiRequest( $params );
+               $this->assertNull( $result[0]['results'] );
+               $this->assertArrayHasKey( 'message', $result[0] );
+       }
+
+       public function testExecuteWithEntity() {
+               $params = array(
+                       'action' => 'wdqagetviolations',
+                       'entity' => 'Q1'
+               );
+               $result = $this->doApiRequest( $params );
+
+               $claimGuidP1 = 'P1$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
+               $claimGuidP2 = 'P2$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
+               $claimGuidP3 = 'P3$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
+
+               $this->assertArrayHasKey( $claimGuidP1, $result[0]['results'] );
+               $this->assertEquals( 9, count( $result[0]['results'][ 
$claimGuidP1 ] ) );
+
+               $this->assertArrayHasKey( $claimGuidP2, $result[0]['results'] );
+               $this->assertArrayNotHasKey( $claimGuidP3, 
$result[0]['results'] );
+       }
+}
diff --git a/tests/phpunit/Serializer/ViolationSerializerTest.php 
b/tests/phpunit/Serializer/ViolationSerializerTest.php
new file mode 100644
index 0000000..7e13887
--- /dev/null
+++ b/tests/phpunit/Serializer/ViolationSerializerTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace WikidataQuality\Tests\Serializer;
+
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Entity\PropertyId;
+use WikidataQuality\Serializer\ViolationSerializer;
+use WikidataQuality\Violations\Violation;
+
+
+/**
+ * @covers WikidataQuality\Serializer\ViolationSerializer
+ *
+ * @group WikidataQuality
+ *
+ * @uses   WikidataQuality\Violations\Violation
+ *
+ * @author BP2014N1
+ * @license GNU GPL v2+
+ */
+class ViolationSerializerTest extends \MediaWikiTestCase {
+
+       /**
+        * @var ViolationSerializer
+        */
+       private $violationSerializer;
+
+       protected function setUp() {
+               parent::setUp();
+               $this->violationSerializer = new ViolationSerializer();
+       }
+
+       protected function tearDown() {
+               parent::tearDown();
+               unset( $this->violationSerializer );
+       }
+
+       public function testSerialize() {
+               $violation = new Violation(
+                       new ItemId( 'Q1' ),
+                       new PropertyId( 'P1' ),
+                       'P1$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                       'Q666$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
+                       new ItemId( 'Q666' ),
+                       1234,
+                       'exception',
+                       'foobar',
+                       '2014-10-15T15:00:00Z'
+               );
+
+               $serializedViolation = $this->violationSerializer->serialize( 
$violation );
+
+               $this->assertEquals( 
$violation->getEntityId()->getSerialization(), $serializedViolation['entityId'] 
);
+               $this->assertEquals( 
$violation->getPropertyId()->getSerialization(), 
$serializedViolation['propertyId'] );
+               $this->assertEquals( $violation->getClaimGuid(), 
$serializedViolation['claimGuid'] );
+               $this->assertEquals( $violation->getConstraintId(), 
$serializedViolation['constraintId'] );
+               $this->assertEquals( $violation->getConstraintTypeEntityId(), 
$serializedViolation['constraintTypeEntityId'] );
+               $this->assertEquals( $violation->getRevisionId(), 
$serializedViolation['revisionId'] );
+               $this->assertEquals( $violation->getStatus(), 
$serializedViolation['status'] );
+               $this->assertEquals( $violation->getAdditionalInfo(), 
$serializedViolation['additionalInfo'] );
+               $this->assertEquals( $violation->getUpdatedAt(), 
$serializedViolation['updatedAt'] );
+       }
+
+       public function testSerializeWithInvalidParam() {
+               $this->setExpectedException( 
'Serializers\Exceptions\UnsupportedObjectException' );
+               $this->violationSerializer->serialize( 'foo' );
+       }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/207464
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia3fa6ee23706d23e1f1f6ce51deea6538f0874b8
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikidataQuality
Gerrit-Branch: master
Gerrit-Owner: Tamslo <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to