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