Tamslo has uploaded a new change for review.

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

Change subject: [WIP] Check if cross-check is exception on SP
......................................................................

[WIP] Check if cross-check is exception on SP

* also sort table by status

Bug: T103108
Change-Id: I479e9b5720762d99d3fc9b04133f4652639099f8
---
M i18n/en.json
M i18n/qqq.json
M includes/CrossCheck/CrossCheckInteractor.php
M includes/CrossCheck/CrossChecker.php
M includes/CrossCheck/Result/CrossCheckResult.php
M includes/ExternalValidationServices.php
D includes/Violations/CrossCheckResultToViolationTranslator.php
A includes/Violations/MagicalGateToBaseExtension.php
M modules/ext.WikibaseExternalValidation.SpecialCrossCheckPage.css
M specials/SpecialCrossCheck.php
M tests/phpunit/CrossCheck/CrossCheckerTest.php
M tests/phpunit/Serializer/CrossCheckResultSerializerTest.php
M tests/phpunit/Specials/SpecialCrossCheckTest.php
D tests/phpunit/Violations/CrossCheckResultToViolationTranslatorTest.php
A tests/phpunit/Violations/MagicalGateToBaseExtensionTest.php
15 files changed, 685 insertions(+), 521 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseQualityExternalValidation
 refs/changes/22/220322/1

diff --git a/i18n/en.json b/i18n/en.json
index 1f0ece2..adf3a43 100755
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -25,6 +25,7 @@
   "wbqev-crosscheck-status-mismatch": "Mismatch",
   "wbqev-crosscheck-status-references-missing": "missing",
   "wbqev-crosscheck-status-references-stated": "stated",
+  "wbqev-crosscheck-status-exception": "Exception",
 
   "wbqev-externaldbs": "List of external databases",
   "wbqev-externaldbs-instructions": "All databases that are supported for 
cross-checks against Wikidata entites are listed below.",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index c2b3dad..1d2aac7 100755
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -5,7 +5,7 @@
                        "Raymond"
                ]
        },
-    "wbqev-desc": "Sub extension for WikibaseQuality extension that checks 
statements against external data sources.",
+       "wbqev-desc": "Sub extension for WikibaseQuality extension that checks 
statements against external data sources.",
        "wbqev-crosscheck": "{{doc-special|CrossCheck}}",
        "wbqev-crosscheck-explanation-general": "General explanation text for 
special page.",
        "wbqev-crosscheck-explanation-detail": "Mre detailed explanation text 
for special page.",
@@ -25,6 +25,7 @@
        "wbqev-crosscheck-status-mismatch": "Status for claims that have a 
mismatch with any external data.",
        "wbqev-crosscheck-status-references-missing": "Status for claims for 
which references are missing.",
        "wbqev-crosscheck-status-references-stated": "Status for claims for 
which references are stated.",
+       "wbqev-crosscheck-status-exception": "Status for claims that were 
marked as exception",
        "wbqev-externaldbs": "{{doc-special|ExternalDbs}}",
        "wbqev-externaldbs-instructions": "Purpose of SpecialPage:ExternalDbs",
        "wbqev-externaldbs-overview-headline": "Headline that appears above the 
overview of external databases.\n{{Identical|Database}}",
diff --git a/includes/CrossCheck/CrossCheckInteractor.php 
b/includes/CrossCheck/CrossCheckInteractor.php
index e392944..10f2782 100755
--- a/includes/CrossCheck/CrossCheckInteractor.php
+++ b/includes/CrossCheck/CrossCheckInteractor.php
@@ -93,7 +93,9 @@
         */
        public function crossCheckEntity( Entity $entity ) {
                $statements = $entity->getStatements();
-               return $this->crossChecker->crossCheckStatements( $entity, 
$statements );
+               $result = $this->crossChecker->crossCheckStatements( $entity, 
$statements );
+               $sortedResult = $this->sortResult( $result );
+               return $sortedResult;
        }
 
        /**
@@ -289,4 +291,19 @@
                        }
                }
        }
+
+       /**
+        * @param CrossCheckResultList $results
+        *
+        * @return CrossCheckResultList
+        */
+       private function sortResult( $result ) {
+               if ( count( $result ) < 2 ) {
+                       return $result;
+               }
+               //TODO: actually sort (first fix tests)
+
+
+               return $result;
+       }
 }
\ No newline at end of file
diff --git a/includes/CrossCheck/CrossChecker.php 
b/includes/CrossCheck/CrossChecker.php
index 4daa541..e8eb8ce 100755
--- a/includes/CrossCheck/CrossChecker.php
+++ b/includes/CrossCheck/CrossChecker.php
@@ -22,6 +22,7 @@
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformationLookup;
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\SqlDumpMetaInformationRepo;
 use WikibaseQuality\ExternalValidation\ExternalDataRepo;
+use WikibaseQuality\ExternalValidation\Violations\MagicalGateToBaseExtension;
 
 
 /**
@@ -66,19 +67,26 @@
        private $externalDataRepo;
 
        /**
+        * @var MagicalGateToBaseExtension
+        */
+       private $magicalGateToBaseExtension;
+
+       /**
         * @param EntityLookup $entityLookup
         * @param ComparativeValueParser $comparativeValueParser
         * @param DataValueComparer $dataValueComparer
         * @param ReferenceChecker $referenceHandler
         * @param DumpMetaInformationLookup $dumpMetaInformationLookup
         * @param ExternalDataRepo $externalDataRepo
+        * @param MagicalGateToBaseExtension $magicalGateToBaseExtension
         */
        public function __construct( EntityLookup $entityLookup,
                ComparativeValueParser $comparativeValueParser,
                DataValueComparer $dataValueComparer,
                ReferenceChecker $referenceHandler,
                DumpMetaInformationLookup $dumpMetaInformationLookup,
-               ExternalDataRepo $externalDataRepo
+               ExternalDataRepo $externalDataRepo,
+               MagicalGateToBaseExtension $magicalGateToBaseExtension
        ) {
                $this->entityLookup = $entityLookup;
                $this->comparativeValueParser = $comparativeValueParser;
@@ -86,6 +94,7 @@
                $this->referenceHandler = $referenceHandler;
                $this->dumpMetaInformationLookup = $dumpMetaInformationLookup;
                $this->externalDataRepo = $externalDataRepo;
+               $this->magicalGateToBaseExtension = $magicalGateToBaseExtension;
        }
 
        /**
@@ -123,6 +132,8 @@
                                }
                        }
                }
+
+               $this->magicalGateToBaseExtension->saveAsViolations( $entity, 
$resultList );
 
                return $resultList;
        }
@@ -217,14 +228,18 @@
                        if ( $comparisonResult ) {
                                $referencesResult = 
$this->referenceHandler->checkForReferences( $statement, $identifierPropertyId, 
$externalId, $dumpMetaInformation );
 
+                               $claimGuid = $statement->getGuid();
+                               $isException = 
$this->magicalGateToBaseExtension->isException( $dumpMetaInformation, 
$claimGuid );
+
                                $resultList->add(
                                        new CrossCheckResult(
                                                $statement->getPropertyId(),
-                                               $statement->getGuid(),
+                                               $claimGuid,
                                                $externalId,
                                                $dumpMetaInformation,
                                                $comparisonResult,
-                                               $referencesResult
+                                               $referencesResult,
+                                               $isException
                                        )
                                );
                        }
diff --git a/includes/CrossCheck/Result/CrossCheckResult.php 
b/includes/CrossCheck/Result/CrossCheckResult.php
index 7c33add..f8c2263 100755
--- a/includes/CrossCheck/Result/CrossCheckResult.php
+++ b/includes/CrossCheck/Result/CrossCheckResult.php
@@ -60,23 +60,31 @@
        private $referenceResult;
 
        /**
+        * States if violation is already
+        *
+        * @var bool
+        */
+       private $isException;
+
+       /**
         * @param PropertyId $propertyId
         * @param string $claimGuid
         * @param string $externalId
         * @param DumpMetaInformation $dumpMetaInformation
         * @param ComparisonResult $comparisonResult
         * @param ReferenceResult $referenceResult
-        *
-        * @throws InvalidArgumentException
+        * @param bool $isException
         */
        public function __construct( PropertyId $propertyId,
                                                                 $claimGuid,
                                                                 $externalId,
                                                                 
DumpMetaInformation $dumpMetaInformation,
                                                                 
ComparisonResult $comparisonResult,
-                                                                
ReferenceResult $referenceResult ) {
+                                                                
ReferenceResult $referenceResult,
+                                                                $isException ) 
{
                Assert::parameterType( 'string', $claimGuid, '$claimGuid' );
                Assert::parameterType( 'string', $externalId, '$externalId' );
+               Assert::parameterType( 'boolean', $isException, '$isException' 
);
 
                $this->propertyId = $propertyId;
                $this->claimGuid = $claimGuid;
@@ -84,6 +92,7 @@
                $this->dumpMetaInformation = $dumpMetaInformation;
                $this->comparisonResult = $comparisonResult;
                $this->referenceResult = $referenceResult;
+               $this->isException = $isException;
        }
 
        /**
@@ -127,4 +136,11 @@
        public function getReferenceResult() {
                return $this->referenceResult;
        }
+
+       /**
+        * @return bool
+        */
+       public function isException() {
+               return $this->isException;
+       }
 }
\ No newline at end of file
diff --git a/includes/ExternalValidationServices.php 
b/includes/ExternalValidationServices.php
index 94991b6..99ab4e9 100755
--- a/includes/ExternalValidationServices.php
+++ b/includes/ExternalValidationServices.php
@@ -31,9 +31,13 @@
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformationStore;
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\SqlDumpMetaInformationRepo;
 use WikibaseQuality\ExternalValidation\Serializer\SerializerFactory;
-use 
WikibaseQuality\ExternalValidation\Violations\CrossCheckResultToViolationTranslator;
+use WikibaseQuality\ExternalValidation\Violations\MagicalGateToBaseExtension;
 use WikibaseQuality\ExternalValidation\Violations\CrossCheckViolationFormatter;
+use WikibaseQuality\Violations\SqlViolationRepo;
 use WikibaseQuality\Violations\ViolationFormatter;
+use WikibaseQuality\Violations\ExceptionLookup;
+use WikibaseQuality\Violations\ViolationStore;
+use WikibaseQuality\WikibaseQualityFactory;
 
 
 /**
@@ -45,180 +49,215 @@
  */
 class ExternalValidationServices {
 
-    /**
-     * @var EntityLookup
-     */
-    private $entityLookup;
+       /**
+        * @var EntityLookup
+        */
+       private $entityLookup;
 
-    /**
-     * @var EntityRevisionLookup
-     */
-    private $entityRevisionLookup;
+       /**
+        * @var EntityRevisionLookup
+        */
+       private $entityRevisionLookup;
 
        /**
         * @var TermIndex
         */
        private $termIndex;
 
-    /**
-     * @var TermLookup
-     */
-    private $termLookup;
+       /**
+        * @var TermLookup
+        */
+       private $termLookup;
 
-    /**
-     * @var EntityTitleLookup
-     */
-    private $entityTitleLookup;
+       /**
+        * @var EntityTitleLookup
+        */
+       private $entityTitleLookup;
 
-    /**
-     * @var EntityIdParser
-     */
-    private $entityIdParser;
+       /**
+        * @var EntityIdParser
+        */
+       private $entityIdParser;
 
-    /**
-     * @var StatementGuidParser
-     */
-    private $statementGuidParser;
+       /**
+        * @var StatementGuidParser
+        */
+       private $statementGuidParser;
 
-    /**
-     * @var ValueFormatter
-     */
-    private $valueFormatterFactory;
+       /**
+        * @var ValueFormatter
+        */
+       private $valueFormatterFactory;
 
        /**
         * @var ValueParserFactory
         */
        private $valueParserFactory;
 
-    /**
-     * @var CrossChecker
-     */
-    private $crossChecker;
+       /**
+        * @var CrossChecker
+        */
+       private $crossChecker;
 
-    /**
-     * @var CrossCheckInteractor
-     */
-    private $crossCheckInteractor;
+       /**
+        * @var CrossCheckInteractor
+        */
+       private $crossCheckInteractor;
 
-    /**
-     * @var DataValueComparerFactory
-     */
-    private $dataValueComparerFactory;
+       /**
+        * @var DataValueComparerFactory
+        */
+       private $dataValueComparerFactory;
 
        /**
         * @var ComparativeValueParserFactory
         */
        private $comparativeValueParserFactory;
 
-    /**
-     * @var DumpMetaInformationLookup
-     */
-    private $dumpMetaInformationLookup;
+       /**
+        * @var DumpMetaInformationLookup
+        */
+       private $dumpMetaInformationLookup;
 
-    /**
-     * @var DumpMetaInformationStore
-     */
-    private $dumpMetaInformationStore;
+       /**
+        * @var DumpMetaInformationStore
+        */
+       private $dumpMetaInformationStore;
 
-    /**
-     * @var ExternalDataRepo
-     */
-    private $externalDataRepo;
+       /**
+        * @var ExternalDataRepo
+        */
+       private $externalDataRepo;
 
-    /**
-     * @var SerializerFactory
-     */
-    private $serializerFactory;
+       /**
+        * @var SerializerFactory
+        */
+       private $serializerFactory;
 
-    /**
-     * @var CrossCheckResultToViolationTranslator
-     */
-    private $crossCheckResultToViolationTranslator;
+       /**
+        * @var ViolationStore
+        */
+       private $violationStore;
 
-    /**
-     * @param EntityLookup $entityLookup
-     * @param EntityRevisionLookup $entityRevisionLookup
-     * @param TermLookup $termLookup
-     * @param EntityTitleLookup $entityTitleLookup
-     * @param EntityIdParser $entityIdParser
-     * @param StatementGuidParser $statementGuidParser
-     * @param OutputFormatValueFormatterFactory $valueFormatterFactory
-     * @param ValueParserFactory $valueParserFactory
-     */
-    public function __construct( EntityLookup $entityLookup, 
EntityRevisionLookup $entityRevisionLookup,
-                                 TermIndex $termIndex, TermLookup $termLookup, 
EntityTitleLookup $entityTitleLookup,
-                                 EntityIdParser $entityIdParser, 
StatementGuidParser $statementGuidParser,
-                                 OutputFormatValueFormatterFactory 
$valueFormatterFactory,
-                                                                
ValueParserFactory $valueParserFactory ) {
-        $this->entityLookup = $entityLookup;
-        $this->entityRevisionLookup = $entityRevisionLookup;
-        $this->termLookup = $termLookup;
+       /**
+        * @var ExceptionLookup
+        */
+       private $exceptionLookup;
+
+       /**
+        * @var MagicalGateToBaseExtension
+        */
+       private $magicalGateToBaseExtension;
+
+       /**
+        * @param EntityLookup $entityLookup
+        * @param EntityRevisionLookup $entityRevisionLookup
+        * @param TermIndex $termIndex
+        * @param TermLookup $termLookup
+        * @param EntityTitleLookup $entityTitleLookup
+        * @param EntityIdParser $entityIdParser
+        * @param StatementGuidParser $statementGuidParser
+        * @param OutputFormatValueFormatterFactory $valueFormatterFactory
+        * @param ValueParserFactory $valueParserFactory
+        * @param ViolationStore $violationStore
+        * @param ExceptionLookup $exceptionLookup
+        */
+       public function __construct( EntityLookup $entityLookup, 
EntityRevisionLookup $entityRevisionLookup,
+                                                                TermIndex 
$termIndex, TermLookup $termLookup, EntityTitleLookup $entityTitleLookup,
+                                                                EntityIdParser 
$entityIdParser, StatementGuidParser $statementGuidParser,
+                                                                
OutputFormatValueFormatterFactory $valueFormatterFactory,
+                                                                
ValueParserFactory $valueParserFactory,
+                                                                ViolationStore 
$violationStore,
+                                                                
ExceptionLookup $exceptionLookup ) {
+               $this->entityLookup = $entityLookup;
+               $this->entityRevisionLookup = $entityRevisionLookup;
+               $this->termLookup = $termLookup;
                $this->termIndex = $termIndex;
-        $this->entityTitleLookup = $entityTitleLookup;
-        $this->entityIdParser = $entityIdParser;
-        $this->statementGuidParser = $statementGuidParser;
-        $this->valueFormatterFactory = $valueFormatterFactory;
+               $this->entityTitleLookup = $entityTitleLookup;
+               $this->entityIdParser = $entityIdParser;
+               $this->statementGuidParser = $statementGuidParser;
+               $this->valueFormatterFactory = $valueFormatterFactory;
                $this->valueParserFactory = $valueParserFactory;
-    }
+               $this->violationStore = $violationStore;
+               $this->exceptionLookup = $exceptionLookup;
+       }
 
-    /**
-     * Returns the default instance.
-     * IMPORTANT: Use only when it is not feasible to inject an instance 
properly.
-     *
-     * @return ExternalValidationServices
-     */
-    public static function getDefaultInstance() {
-        static $instance = null;
+       /**
+        * Returns the default instance.
+        * IMPORTANT: Use only when it is not feasible to inject an instance 
properly.
+        *
+        * @return ExternalValidationServices
+        */
+       public static function getDefaultInstance() {
+               static $instance = null;
 
-        if ( $instance === null ) {
-            $repo = WikibaseRepo::getDefaultInstance()->getDefaultInstance();
-            $instance = new self(
-                $repo->getEntityLookup(),
-                $repo->getEntityRevisionLookup(),
+               if ( $instance === null ) {
+                       $repo = 
WikibaseRepo::getDefaultInstance()->getDefaultInstance();
+                       $qualityServices = 
WikibaseQualityFactory::getDefaultInstance();
+                       $instance = new self(
+                               $repo->getEntityLookup(),
+                               $repo->getEntityRevisionLookup(),
                                $repo->getStore()->getTermIndex(),
-                $repo->getTermLookup(),
-                $repo->getEntityTitleLookup(),
-                $repo->getEntityIdParser(),
-                $repo->getClaimGuidParser(),
-                $repo->getValueFormatterFactory(),
-                               new ValueParserFactory( 
$GLOBALS['wgValueParsers'] )
-            );
-        }
+                               $repo->getTermLookup(),
+                               $repo->getEntityTitleLookup(),
+                               $repo->getEntityIdParser(),
+                               $repo->getClaimGuidParser(),
+                               $repo->getValueFormatterFactory(),
+                               new ValueParserFactory( 
$GLOBALS['wgValueParsers'] ),
+                               $qualityServices->getViolationStore(),
+                               $qualityServices->getExceptionLookup()
+                       );
+               }
 
-        return $instance;
-    }
+               return $instance;
+       }
 
-    /**
-     * @return CrossChecker
-     */
-    public function getCrossChecker() {
-        if ( $this->crossChecker === null ) {
-            $this->crossChecker = new CrossChecker(
+       /**
+        * @return CrossChecker
+        */
+       public function getCrossChecker() {
+               if ( $this->crossChecker === null ) {
+                       $this->crossChecker = new CrossChecker(
                                $this->entityLookup,
                                
$this->getComparativeValueParserFactory()->newDispatchingComparativeValueParser(),
                                
$this->getDataValueComparerFactory()->newDispatchingDataValueComparer(),
-                new ReferenceChecker(),
-                $this->getDumpMetaInformationLookup(),
-                $this->getExternalDataRepo()
-            );
-        }
+                               new ReferenceChecker(),
+                               $this->getDumpMetaInformationLookup(),
+                               $this->getExternalDataRepo(),
+                               $this->getMagicalGateToBaseExtension()
+                       );
+               }
 
-        return $this->crossChecker;
-    }
+               return $this->crossChecker;
+       }
 
-    /**
-     * @return CrossCheckInteractor
-     */
-    public function getCrossCheckInteractor() {
-        if ( $this->crossCheckInteractor === null ) {
-            $this->crossCheckInteractor = new CrossCheckInteractor(
-                $this->entityLookup,
-                $this->statementGuidParser,
-                $this->getCrossChecker() );
-        }
+       /**
+        * @return MagicalGateToBaseExtension
+        */
+       public function getMagicalGateToBaseExtension() {
+               if ( $this->magicalGateToBaseExtension === null ) {
+                       $this->magicalGateToBaseExtension = new 
MagicalGateToBaseExtension(
+                               $this->entityRevisionLookup,
+                               $this->violationStore,
+                               $this->exceptionLookup
+                       );
+               }
+               return $this->magicalGateToBaseExtension;
+       }
 
-        return $this->crossCheckInteractor;
-    }
+       /**
+        * @return CrossCheckInteractor
+        */
+       public function getCrossCheckInteractor() {
+               if ( $this->crossCheckInteractor === null ) {
+                       $this->crossCheckInteractor = new CrossCheckInteractor(
+                               $this->entityLookup,
+                               $this->statementGuidParser,
+                               $this->getCrossChecker() );
+               }
+
+               return $this->crossCheckInteractor;
+       }
 
        /**
         * @return ComparativeValueParserFactory
@@ -234,112 +273,101 @@
                return $this->comparativeValueParserFactory;
        }
 
-    /**
-     * @return DataValueComparerFactory
-     */
-    public function getDataValueComparerFactory() {
-        if ( $this->dataValueComparerFactory === null ) {
-            $this->dataValueComparerFactory = new DataValueComparerFactory( 
$this->termIndex );
-        }
+       /**
+        * @return DataValueComparerFactory
+        */
+       public function getDataValueComparerFactory() {
+               if ( $this->dataValueComparerFactory === null ) {
+                       $this->dataValueComparerFactory = new 
DataValueComparerFactory( $this->termIndex );
+               }
 
-        return $this->dataValueComparerFactory;
-    }
+               return $this->dataValueComparerFactory;
+       }
 
-    /**
-     * @return DumpMetaInformationLookup
-     */
-    public function getDumpMetaInformationLookup() {
-        if( $this->dumpMetaInformationLookup === null ) {
-            $this->dumpMetaInformationLookup = new SqlDumpMetaInformationRepo( 
$this->entityIdParser );
-        }
+       /**
+        * @return DumpMetaInformationLookup
+        */
+       public function getDumpMetaInformationLookup() {
+               if( $this->dumpMetaInformationLookup === null ) {
+                       $this->dumpMetaInformationLookup = new 
SqlDumpMetaInformationRepo( $this->entityIdParser );
+               }
 
-        return $this->dumpMetaInformationLookup;
-    }
+               return $this->dumpMetaInformationLookup;
+       }
 
-    /**
-     * @return DumpMetaInformationStore
-     */
-    public function getDumpMetaInformationStore() {
-        if( $this->dumpMetaInformationStore === null ) {
-            $this->dumpMetaInformationStore = new SqlDumpMetaInformationRepo( 
$this->entityIdParser );
-        }
+       /**
+        * @return DumpMetaInformationStore
+        */
+       public function getDumpMetaInformationStore() {
+               if( $this->dumpMetaInformationStore === null ) {
+                       $this->dumpMetaInformationStore = new 
SqlDumpMetaInformationRepo( $this->entityIdParser );
+               }
 
-        return $this->dumpMetaInformationStore;
-    }
+               return $this->dumpMetaInformationStore;
+       }
 
-    /**
-     * @return ExternalDataRepo
-     */
-    public function getExternalDataRepo() {
-        if( $this->externalDataRepo === null ) {
-            $this->externalDataRepo = new ExternalDataRepo();
-        }
+       /**
+        * @return ExternalDataRepo
+        */
+       public function getExternalDataRepo() {
+               if( $this->externalDataRepo === null ) {
+                       $this->externalDataRepo = new ExternalDataRepo();
+               }
 
-        return $this->externalDataRepo;
-    }
+               return $this->externalDataRepo;
+       }
 
-    /**
-     * @return SerializerFactory
-     */
-    public function getSerializerFactory() {
-        if ( $this->serializerFactory === null ) {
-            $dataValueSerializer = new DataValueSerializer();
-            $dataModelSerializerFactory = new 
\Wikibase\DataModel\SerializerFactory( $dataValueSerializer );
-            $this->serializerFactory = new SerializerFactory(
-                $dataValueSerializer,
-                $dataModelSerializerFactory->newReferenceSerializer()
-            );
-        }
+       /**
+        * @return SerializerFactory
+        */
+       public function getSerializerFactory() {
+               if ( $this->serializerFactory === null ) {
+                       $dataValueSerializer = new DataValueSerializer();
+                       $dataModelSerializerFactory = new 
\Wikibase\DataModel\SerializerFactory( $dataValueSerializer );
+                       $this->serializerFactory = new SerializerFactory(
+                               $dataValueSerializer,
+                               
$dataModelSerializerFactory->newReferenceSerializer()
+                       );
+               }
 
-        return $this->serializerFactory;
-    }
+               return $this->serializerFactory;
+       }
 
-    /**
-     * @return CrossCheckResultToViolationTranslator
-     */
-    public function getCrossCheckResultToViolationTranslator() {
-        if ( $this->crossCheckResultToViolationTranslator === null ) {
-            $this->crossCheckResultToViolationTranslator = new 
CrossCheckResultToViolationTranslator( $this->entityRevisionLookup );
-        }
+       /**
+        * @return ViolationFormatter
+        */
+       public function getViolationFormatter() {
+               $languageCode = 
RequestContext::getMain()->getLanguage()->getCode();
 
-        return $this->crossCheckResultToViolationTranslator;
-    }
+               $dataValueDeserializer = new DataValueDeserializer(
+                       array (
+                               'boolean' => 'DataValues\BooleanValue',
+                               'number' => 'DataValues\NumberValue',
+                               'string' => 'DataValues\StringValue',
+                               'unknown' => 'DataValues\UnknownValue',
+                               'globecoordinate' => 
'DataValues\GlobeCoordinateValue',
+                               'monolingualtext' => 
'DataValues\MonolingualTextValue',
+                               'multilingualtext' => 
'DataValues\MultilingualTextValue',
+                               'quantity' => 'DataValues\QuantityValue',
+                               'time' => 'DataValues\TimeValue',
+                               'wikibase-entityid' => 
'Wikibase\DataModel\Entity\EntityIdValue',
+                       )
+               );
+               $labelLookup = new LanguageLabelDescriptionLookup( 
$this->termLookup, $languageCode );
+               $entityIdLinkFormatter = new EntityIdHtmlLinkFormatter(
+                       $labelLookup,
+                       $this->entityTitleLookup,
+                       new LanguageNameLookup()
+               );
+               $formatterOptions = new FormatterOptions();
+               $formatterOptions->setOption( SnakFormatter::OPT_LANG, 
$languageCode );
+               $dataValueFormatter = 
$this->valueFormatterFactory->getValueFormatter( SnakFormatter::FORMAT_HTML, 
$formatterOptions );
 
-    /**
-     * @return ViolationFormatter
-     */
-    public function getViolationFormatter() {
-        $languageCode = RequestContext::getMain()->getLanguage()->getCode();
-
-        $dataValueDeserializer = new DataValueDeserializer(
-            array (
-                'boolean' => 'DataValues\BooleanValue',
-                'number' => 'DataValues\NumberValue',
-                'string' => 'DataValues\StringValue',
-                'unknown' => 'DataValues\UnknownValue',
-                'globecoordinate' => 'DataValues\GlobeCoordinateValue',
-                'monolingualtext' => 'DataValues\MonolingualTextValue',
-                'multilingualtext' => 'DataValues\MultilingualTextValue',
-                'quantity' => 'DataValues\QuantityValue',
-                'time' => 'DataValues\TimeValue',
-                'wikibase-entityid' => 
'Wikibase\DataModel\Entity\EntityIdValue',
-            )
-        );
-        $labelLookup = new LanguageLabelDescriptionLookup( $this->termLookup, 
$languageCode );
-        $entityIdLinkFormatter = new EntityIdHtmlLinkFormatter(
-            $labelLookup,
-            $this->entityTitleLookup,
-            new LanguageNameLookup()
-        );
-        $formatterOptions = new FormatterOptions();
-        $formatterOptions->setOption( SnakFormatter::OPT_LANG, $languageCode );
-        $dataValueFormatter = $this->valueFormatterFactory->getValueFormatter( 
SnakFormatter::FORMAT_HTML, $formatterOptions );
-
-        return new CrossCheckViolationFormatter(
-            $dataValueDeserializer,
-            $entityIdLinkFormatter,
-            $dataValueFormatter,
-            $this->getDumpMetaInformationLookup()
-        );
-    }
+               return new CrossCheckViolationFormatter(
+                       $dataValueDeserializer,
+                       $entityIdLinkFormatter,
+                       $dataValueFormatter,
+                       $this->getDumpMetaInformationLookup()
+               );
+       }
 }
\ No newline at end of file
diff --git a/includes/Violations/CrossCheckResultToViolationTranslator.php 
b/includes/Violations/CrossCheckResultToViolationTranslator.php
deleted file mode 100755
index ca022a6..0000000
--- a/includes/Violations/CrossCheckResultToViolationTranslator.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-namespace WikibaseQuality\ExternalValidation\Violations;
-
-use DataValues\Serializers\DataValueSerializer;
-use Wikibase\DataModel\Entity\Entity;
-use Wikibase\Lib\Store\EntityRevisionLookup;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList;
-use WikibaseQuality\Violations\Violation;
-
-
-class CrossCheckResultToViolationTranslator {
-
-       /**
-        * @var EntityRevisionLookup
-        */
-       private $entityRevisionLookup;
-
-       /**
-        * @param EntityRevisionLookup $entityRevisionLookup
-        */
-       public function __construct( EntityRevisionLookup $entityRevisionLookup 
) {
-               $this->entityRevisionLookup = $entityRevisionLookup;
-       }
-
-       /**
-        * @param Entity $entity
-        * @param CrossCheckResultList $crossCheckResultList
-        *
-        * @return Violation[]
-        */
-       public function translateToViolation( Entity $entity, 
CrossCheckResultList $crossCheckResultList ) {
-
-               $violationArray = array();
-               foreach ( $crossCheckResultList as $crossCheckResult ) {
-                       if ( 
$crossCheckResult->getComparisonResult()->getStatus() !== 
ComparisonResult::STATUS_MISMATCH ) {
-                               continue;
-                       }
-
-
-                       $entityId = $entity->getId();
-                       $propertyId = $crossCheckResult->getPropertyId();
-                       $claimGuid = $crossCheckResult->getClaimGuid();
-                       //TODO: Use real ClaimGuid and TypeEntityId
-                       $constraintTypeEntityId = 
$crossCheckResult->getDumpMetaInformation()->getSourceItemId();
-                       $constraintId = md5( 
$crossCheckResult->getDumpMetaInformation()->getImportDate() . 
$constraintTypeEntityId );
-                       $constraintId = WBQ_EXTERNAL_VALIDATION_ID . 
Violation::CONSTRAINT_ID_DELIMITER . $constraintId;
-                       $revisionId = 
$this->entityRevisionLookup->getLatestRevisionId( $entityId );
-                       $status = Violation::STATUS_VIOLATION;
-                       $additionalInformation = 
$this->buildAdditionalInformation( $crossCheckResult );
-
-                       $violationArray[] = new Violation( $entityId, 
$propertyId, $claimGuid, $constraintId, $constraintTypeEntityId, $revisionId, 
$status, $additionalInformation );
-               }
-
-               return $violationArray;
-       }
-
-       private function buildAdditionalInformation( CrossCheckResult 
$crossCheckResult ) {
-
-               $serializer = new DataValueSerializer();
-               $externalValues = 
$crossCheckResult->getComparisonResult()->getExternalValues();
-               $externalValuesSerialized = array();
-               foreach ( $externalValues as $externalValue ) {
-                       $externalValuesSerialized[] = $serializer->serialize( 
$externalValue );
-               }
-               $additionalInformation = array(
-                       'dump_id' => 
$crossCheckResult->getDumpMetaInformation()->getDumpId(),
-                       'external_values' => $externalValuesSerialized
-               );
-
-               return $additionalInformation;
-       }
-}
diff --git a/includes/Violations/MagicalGateToBaseExtension.php 
b/includes/Violations/MagicalGateToBaseExtension.php
new file mode 100644
index 0000000..990a6d4
--- /dev/null
+++ b/includes/Violations/MagicalGateToBaseExtension.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace WikibaseQuality\ExternalValidation\Violations;
+
+use DataValues\Serializers\DataValueSerializer;
+use Wikibase\DataModel\Entity\Entity;
+use Wikibase\Lib\Store\EntityRevisionLookup;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList;
+use WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation;
+use WikibaseQuality\Violations\ExceptionLookup;
+use WikibaseQuality\Violations\Violation;
+use WikibaseQuality\Violations\ViolationStore;
+use Wikimedia\Assert\Assert;
+
+
+class MagicalGateToBaseExtension {
+
+       /**
+        * @var EntityRevisionLookup
+        */
+       private $entityRevisionLookup;
+
+       /**
+        * @var ViolationStore
+        */
+       private $violationStore;
+
+       /**
+        * @var ExceptionLookup
+        */
+       private $exceptionLookup;
+
+       /**
+        * @param EntityRevisionLookup $entityRevisionLookup
+        * @param ViolationStore $violationStore
+        * @param ExceptionLookup $exceptionLookup
+        */
+       public function __construct( EntityRevisionLookup 
$entityRevisionLookup, ViolationStore $violationStore, ExceptionLookup 
$exceptionLookup ) {
+               $this->entityRevisionLookup = $entityRevisionLookup;
+               $this->violationStore = $violationStore;
+               $this->exceptionLookup = $exceptionLookup;
+       }
+
+       /**
+        * @param DumpMetaInformation $metaInformation
+        * @param string $claimGuid
+        *
+        * @return bool
+        */
+       public function isException( DumpMetaInformation $metaInformation,  
$claimGuid) {
+               Assert::parameterType( 'string', $claimGuid, '$claimGuid' );
+               $constraintId = $this->buildConstraintId( $metaInformation );
+               return $this->exceptionLookup->isException( $claimGuid, 
$constraintId );
+       }
+
+       /**
+        * Translates cross-check results to violations and inserts them into 
the violation table.
+        *
+        * @param Entity $entity
+        * @param CrossCheckResultList $checkResults
+        */
+       public function saveAsViolations( Entity $entity, CrossCheckResultList 
$checkResults ) {
+               $violations = $this->translateToViolation( $entity, 
$checkResults );
+               foreach( $violations as $violation ) {
+                       $this->violationStore->insert( $violation, true );
+               }
+       }
+
+       private function buildConstraintId( DumpMetaInformation 
$dumpMetaInformation ) {
+               $constraintId = md5( $dumpMetaInformation->getImportDate() . 
$dumpMetaInformation->getSourceItemId() );
+               $constraintId = WBQ_EXTERNAL_VALIDATION_ID . 
Violation::CONSTRAINT_ID_DELIMITER . $constraintId;
+               return $constraintId;
+       }
+
+       /**
+        * @param Entity $entity
+        * @param CrossCheckResultList $crossCheckResultList
+        *
+        * @return Violation[]
+        */
+       private function translateToViolation( Entity $entity, 
CrossCheckResultList $crossCheckResultList ) {
+
+               $violationArray = array();
+               foreach ( $crossCheckResultList as $crossCheckResult ) {
+                       if ( 
$crossCheckResult->getComparisonResult()->getStatus() !== 
ComparisonResult::STATUS_MISMATCH ) {
+                               continue;
+                       }
+
+
+                       $entityId = $entity->getId();
+                       $propertyId = $crossCheckResult->getPropertyId();
+                       $claimGuid = $crossCheckResult->getClaimGuid();
+                       //TODO: Use real ClaimGuid and TypeEntityId
+                       $constraintTypeEntityId = 
$crossCheckResult->getDumpMetaInformation()->getSourceItemId();
+                       $constraintId = $this->buildConstraintId( 
$crossCheckResult->getDumpMetaInformation() );
+                       $revisionId = 
$this->entityRevisionLookup->getLatestRevisionId( $entityId );
+                       $status = Violation::STATUS_VIOLATION;
+                       $additionalInformation = 
$this->buildAdditionalInformation( $crossCheckResult );
+
+                       $violationArray[] = new Violation( $entityId, 
$propertyId, $claimGuid, $constraintId, $constraintTypeEntityId, $revisionId, 
$status, $additionalInformation );
+               }
+
+               return $violationArray;
+       }
+
+       private function buildAdditionalInformation( CrossCheckResult 
$crossCheckResult ) {
+
+               $serializer = new DataValueSerializer();
+               $externalValues = 
$crossCheckResult->getComparisonResult()->getExternalValues();
+               $externalValuesSerialized = array();
+               foreach ( $externalValues as $externalValue ) {
+                       $externalValuesSerialized[] = $serializer->serialize( 
$externalValue );
+               }
+               $additionalInformation = array(
+                       'dump_id' => 
$crossCheckResult->getDumpMetaInformation()->getDumpId(),
+                       'external_values' => $externalValuesSerialized
+               );
+
+               return $additionalInformation;
+       }
+}
diff --git a/modules/ext.WikibaseExternalValidation.SpecialCrossCheckPage.css 
b/modules/ext.WikibaseExternalValidation.SpecialCrossCheckPage.css
index 418d64e..06c327b 100755
--- a/modules/ext.WikibaseExternalValidation.SpecialCrossCheckPage.css
+++ b/modules/ext.WikibaseExternalValidation.SpecialCrossCheckPage.css
@@ -1,44 +1,48 @@
 /* Entity id form */
 form {
-    margin-bottom: 20px;
-    width: 250px;
+       margin-bottom: 20px;
+       width: 250px;
 }
 
 .wbqev-crosscheck-form-entity-id {
-    width: 120px;
+       width: 120px;
 }
 
 /* Notices */
 .wbqev-crosscheck-notice {
-    font-style: italic;
+       font-style: italic;
 }
 
 .wbqev-crosscheck-notice-error {
-    font-weight: bold;
-    color: #BA0000;
+       font-weight: bold;
+       color: #BA0000;
 }
 
 /* Statuses */
 .wbqev-status {
-    font-weight: bold;
+       font-weight: bold;
 }
 
 .wbqev-status-match {
-    color: #008000;
+       color: #008000;
 }
 
 .wbqev-status-partial-match {
-    color: #6CB500;
+       color: #6CB500;
 }
 
 .wbqev-status-mismatch {
-    color: #BA0000;
+       color: #BA0000;
 }
 
 .wbqev-status-unknown {
-    color: #404040;
+       color: #404040;
+}
+
+.wbqev-status-exception {
+       color: #E6B800;
 }
 
 .wbqev-infobox {
-    width: 50%;
+       width: 50%;
 }
\ No newline at end of file
diff --git a/specials/SpecialCrossCheck.php b/specials/SpecialCrossCheck.php
index 98f95a8..c3f4fb1 100755
--- a/specials/SpecialCrossCheck.php
+++ b/specials/SpecialCrossCheck.php
@@ -25,15 +25,18 @@
 use Wikibase\Repo\EntityIdHtmlLinkFormatterFactory;
 use Wikibase\Repo\EntityIdLabelFormatterFactory;
 use Wikibase\Repo\WikibaseRepo;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
 use WikibaseQuality\ExternalValidation\CrossCheck\CrossCheckInteractor;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult;
 use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList;
 use WikibaseQuality\ExternalValidation\EvaluateCrossCheckJob;
 use WikibaseQuality\ExternalValidation\EvaluateCrossCheckJobService;
 use WikibaseQuality\ExternalValidation\ExternalValidationServices;
-use 
WikibaseQuality\ExternalValidation\Violations\CrossCheckResultToViolationTranslator;
+use WikibaseQuality\ExternalValidation\Violations\MagicalGateToBaseExtension;
 use WikibaseQuality\Html\HtmlTableBuilder;
 use WikibaseQuality\Html\HtmlTableCellBuilder;
 use WikibaseQuality\Html\HtmlTableHeaderBuilder;
+use WikibaseQuality\Violations\Violation;
 use WikibaseQuality\Violations\ViolationStore;
 use WikibaseQuality\WikibaseQualityFactory;
 
@@ -71,11 +74,6 @@
        private $crossCheckInteractor;
 
        /**
-        * @var CrossCheckResultToViolationTranslator
-        */
-       private $crossCheckResultToViolationTranslator;
-
-       /**
         * @var ViolationStore
         */
        private $violationStore;
@@ -97,7 +95,6 @@
                        $repo->getEntityIdParser(),
                        $repo->getValueFormatterFactory(),
                        $externalValidationServices->getCrossCheckInteractor(),
-                       
$externalValidationServices->getCrossCheckResultToViolationTranslator(),
                        $qualityServices->getViolationStore()
                );
        }
@@ -110,7 +107,6 @@
         * @param EntityIdParser $entityIdParser
         * @param OutputFormatValueFormatterFactory $valueFormatterFactory
         * @param CrossCheckInteractor $crossCheckInteractor
-        * @param CrossCheckResultToViolationTranslator 
$checkResultToViolationTranslator
         * @param ViolationStore $violationStore
         */
        public function __construct(
@@ -121,7 +117,6 @@
                EntityIdParser $entityIdParser,
                OutputFormatValueFormatterFactory $valueFormatterFactory,
                CrossCheckInteractor $crossCheckInteractor,
-               CrossCheckResultToViolationTranslator 
$checkResultToViolationTranslator,
                ViolationStore $violationStore
        ) {
                parent::__construct('CrossCheck');
@@ -139,7 +134,6 @@
                $this->entityIdLinkFormatter = 
$entityIdHtmlLinkFormatterFactory->getEntityIdFormater( $labelLookup );
 
                $this->crossCheckInteractor = $crossCheckInteractor;
-               $this->crossCheckResultToViolationTranslator = 
$checkResultToViolationTranslator;
                $this->violationStore = $violationStore;
        }
 
@@ -205,7 +199,6 @@
                        }
 
                        $results = 
$this->crossCheckInteractor->crossCheckEntity( $entity );
-                       $this->saveResultsInViolationsTable( $entity, $results 
);
 
                        if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
                                $this->doEvaluation( $entity, $results );
@@ -327,7 +320,7 @@
        private function buildSummary( $results ) {
                $statuses = array ();
                foreach ( $results as $result ) {
-                       $status = strtolower( 
$result->getComparisonResult()->getStatus() );
+                       $status = strtolower( $this->getStatus( $result ) );
                        if ( array_key_exists( $status, $statuses ) ) {
                                $statuses[ $status ]++;
                        } else {
@@ -374,6 +367,23 @@
                        );
 
                return $formattedStatus;
+       }
+
+       /**
+        * Check whether to return the actual status of the cross-check or if 
the comparison was marked as an
+        * exception before.
+        *
+        * @param CrossCheckResult $result
+        *
+        * @return string
+        */
+       private function getStatus( CrossCheckResult $result ) {
+               if ( $result->isException() ) {
+                       $status = Violation::STATUS_EXCEPTION;
+               } else {
+                       $status = $result->getComparisonResult()->getStatus();
+               }
+               return $status;
        }
 
        /**
@@ -449,7 +459,8 @@
                );
 
                foreach ( $results as $result ) {
-                       $status = $this->formatStatus( 
$result->getComparisonResult()->getStatus() );
+
+                       $status = $this->formatStatus( $this->getStatus( 
$result ) );
                        $propertyId = 
$this->entityIdLinkFormatter->formatEntityId( $result->getPropertyId() );
                        $localValue = $this->formatDataValues( 
$result->getComparisonResult()->getLocalValue() );
                        $externalValue = $this->formatDataValues( 
$result->getComparisonResult()->getExternalValues(), true, Html::element( 'br' 
) );
@@ -471,18 +482,6 @@
                return $table->toHtml();
        }
 
-
-       /**
-        * @param Entity $entity
-        * @param array $results
-        */
-       protected function saveResultsInViolationsTable( $entity, $results ) {
-               $violations = 
$this->crossCheckResultToViolationTranslator->translateToViolation( $entity, 
$results );
-               foreach( $violations as $violation ) {
-                       $this->violationStore->insert( $violation, true );
-               }
-       }
-
        private function doEvaluation( $entity, $results ) {
                $checkTimeStamp = wfTimestamp( TS_UNIX );
                $service = new EvaluateCrossCheckJobService();
@@ -491,6 +490,6 @@
                $jobs[] = EvaluateCrossCheckJob::newInsertNow( 
$entity->getId()->getSerialization(), $checkTimeStamp, $results );
                $jobs[] = EvaluateCrossCheckJob::newInsertDeferred( 
$entity->getId()->getSerialization(), $checkTimeStamp, 10*60 );
                $jobs[] = EvaluateCrossCheckJob::newInsertDeferred( 
$entity->getId()->getSerialization(), $checkTimeStamp, 60*60 );
-               JobQueueGroup::singleton()->push( $jobs );
+               //JobQueueGroup::singleton()->push( $jobs );
        }
 }
diff --git a/tests/phpunit/CrossCheck/CrossCheckerTest.php 
b/tests/phpunit/CrossCheck/CrossCheckerTest.php
index 72ee912..4f000e4 100755
--- a/tests/phpunit/CrossCheck/CrossCheckerTest.php
+++ b/tests/phpunit/CrossCheck/CrossCheckerTest.php
@@ -331,7 +331,8 @@
                        $dataValueComparer,
                        $referenceHandler,
                        $this->getDumpMetaInformationLookupMock(),
-                       $this->getExternalDataRepoMock()
+                       $this->getExternalDataRepoMock(),
+                       $this->getMagicalGateToOtherExtensionMock()
                );
        }
 
@@ -381,4 +382,14 @@
 
                return $externalDataRepo;
        }
+
+       private function getMagicalGateToOtherExtensionMock() {
+               $mock = 
$this->getMockBuilder('WikibaseQuality\ExternalValidation\Violations\MagicalGateToBaseExtension')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->expects( $this->any() )
+                       ->method( 'isException' )
+                       ->will( $this->returnValue( false ) );
+               return $mock;
+       }
 }
diff --git a/tests/phpunit/Serializer/CrossCheckResultSerializerTest.php 
b/tests/phpunit/Serializer/CrossCheckResultSerializerTest.php
index 80316f0..0555d21 100755
--- a/tests/phpunit/Serializer/CrossCheckResultSerializerTest.php
+++ b/tests/phpunit/Serializer/CrossCheckResultSerializerTest.php
@@ -37,7 +37,8 @@
                                        'foobar',
                                        $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation' ),
                                        $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult' ),
-                                       $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult' )
+                                       $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult' ),
+                                       false
                                )
                        )
                );
@@ -71,7 +72,8 @@
                                        'fubar',
                                        $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation' ),
                                        $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult' ),
-                                       $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult' )
+                                       $this->getMockWithoutConstructor( 
'WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult' ),
+                                       false
                                )
                        )
                );
diff --git a/tests/phpunit/Specials/SpecialCrossCheckTest.php 
b/tests/phpunit/Specials/SpecialCrossCheckTest.php
index e5b0c2a..858bc99 100755
--- a/tests/phpunit/Specials/SpecialCrossCheckTest.php
+++ b/tests/phpunit/Specials/SpecialCrossCheckTest.php
@@ -91,7 +91,6 @@
                        $wikibaseRepo->getEntityIdParser(),
                        $wikibaseRepo->getValueFormatterFactory(),
                        $externalValidationFactory->getCrossCheckInteractor(),
-                       
$externalValidationFactory->getCrossCheckResultToViolationTranslator(),
                        $wikibaseQuality->getViolationStore()
                );
        }
diff --git 
a/tests/phpunit/Violations/CrossCheckResultToViolationTranslatorTest.php 
b/tests/phpunit/Violations/CrossCheckResultToViolationTranslatorTest.php
deleted file mode 100755
index f2c014a..0000000
--- a/tests/phpunit/Violations/CrossCheckResultToViolationTranslatorTest.php
+++ /dev/null
@@ -1,168 +0,0 @@
-<?php
-
-namespace WikibaseQuality\ExternalValidation\Test\Violations;
-
-use DataValues\StringValue;
-use Wikibase\DataModel\Entity\Entity;
-use Wikibase\DataModel\Entity\EntityId;
-use Wikibase\DataModel\Entity\Item;
-use Wikibase\DataModel\Entity\PropertyId;
-use Wikibase\DataModel\Entity\ItemId;
-use Wikibase\Repo\WikibaseRepo;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList;
-use WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult;
-use WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation;
-use 
WikibaseQuality\ExternalValidation\Violations\CrossCheckResultToViolationTranslator;
-
-
-/**
- * @covers 
WikibaseQuality\ExternalValidation\Violations\CrossCheckResultToViolationTranslator
- *
- * @group WikibaseQualityExternalValidation
- * @group Database
- * @group medium
- *
- * @uses   
WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation
- * @uses   
WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult
- * @uses   WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult
- * @uses   
WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult
- * @uses   
WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList
- *
- * @author BP2014N1
- * @license GNU GPL v2+
- */
-class CrossCheckResultToViolationTranslatorTest extends \MediaWikiTestCase {
-
-       /**
-        * @var CrossCheckResultToViolationTranslator
-        */
-       private $translator;
-
-       /**
-        * @var PropertyId
-        */
-       private $propertyId;
-
-       /**
-        * @var string
-        */
-       private $claimGuid;
-
-       /**
-        * @var string
-        */
-       private $externalId;
-
-       /**
-        * @var Entity
-        */
-       private $entity;
-
-       /**
-        * @var DumpMetaInformation
-        */
-       private $dumpMetaInformation;
-
-       /**
-        * @var ReferenceResult
-        */
-       private $referenceResult;
-
-       /**
-        * @var EntityId[]
-        */
-       private static $idMap;
-
-       protected function setUp() {
-               parent::setUp();
-               $this->translator = new CrossCheckResultToViolationTranslator( 
$this->getEntityRevisionLookupMock() );
-
-               $this->propertyId = new PropertyId( 'P1' );
-               $this->entity = new Item();
-               $store = WikibaseRepo::getDefaultInstance()->getEntityStore();
-               $store->saveEntity( $this->entity, 'TestEntityQ1', 
$GLOBALS['wgUser'], EDIT_NEW );
-               self::$idMap['Q1'] = $this->entity->getId();
-               $this->claimGuid = self::$idMap['Q1'] . 
'$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
-               $this->externalId = 'foobar';
-
-               $this->dumpMetaInformation = new DumpMetaInformation(
-                       'foo',
-                       new ItemId( 'Q123456' ),
-                       array( new PropertyId( 'P227' ) ),
-                       '20150101000000',
-                       'en',
-                       'http://www.foo.bar',
-                       42,
-                       new ItemId( 'Q6938433' )
-               );
-
-               $this->referenceResult = new ReferenceResult(
-                       ReferenceResult::STATUS_REFERENCES_MISSING,
-                       $this->getReferenceMock()
-               );
-
-       }
-
-       protected function tearDown() {
-               parent::tearDown();
-               unset( $this->translator, $this->propertyId, $this->claimGuid, 
$this->entity, $this->dumpMetaInformation, $this->referenceResult );
-       }
-
-       public function testSingleComplianceResult() {
-               $comparisonResult = new ComparisonResult(
-                       $this->getDataValueMock(),
-                       array( $this->getDataValueMock() ),
-                       ComparisonResult::STATUS_MATCH
-               );
-
-               $crossCheckResultList = new CrossCheckResultList( array( new 
CrossCheckResult( $this->propertyId, $this->claimGuid, $this->externalId, 
$this->dumpMetaInformation, $comparisonResult, $this->referenceResult ) ) );
-               $violations = $this->translator->translateToViolation( 
$this->entity, $crossCheckResultList );
-               $this->assertEquals( array(), $violations );
-       }
-
-       public function testSingleViolationResult() {
-               $comparisonResult = new ComparisonResult(
-                       $this->getDataValueMock(),
-                       array( new StringValue( 'test' ) ),
-                       ComparisonResult::STATUS_MISMATCH
-               );
-
-               $crossCheckResultList = new CrossCheckResultList( array( new 
CrossCheckResult( $this->propertyId, $this->claimGuid, $this->externalId, 
$this->dumpMetaInformation, $comparisonResult, $this->referenceResult ) ) );
-               $violations = $this->translator->translateToViolation( 
$this->entity, $crossCheckResultList );
-               $this->assertEquals( 1, sizeof( $violations ) );
-
-               $violation = $violations[0];
-               $this->assertEquals( self::$idMap['Q1'], 
$violation->getEntityId() );
-               $this->assertEquals( 'P1', 
$violation->getPropertyId()->getSerialization() );
-               $this->assertEquals( $this->claimGuid, 
$violation->getClaimGuid() );
-               $this->assertEquals( 'wbqev|93346d9b0ea699c5387d1d2bf56322ff', 
$violation->getConstraintId() );
-               $this->assertEquals( 
$this->dumpMetaInformation->getSourceItemId(), 
$violation->getConstraintTypeEntityId() );
-               $this->assertEquals( array(
-                                                                
'external_values' => array( array( 'value' => 'test', 'type' => 'string' ) ),
-                                                                'dump_id' => 
'foo'
-                                                        ), 
$violation->getAdditionalInfo() );
-               $this->assertEquals( 42, $violation->getRevisionId() );
-
-       }
-
-       private function getReferenceMock() {
-               return $this->getMock( 'Wikibase\DataModel\Reference' );
-       }
-
-       private function getDataValueMock() {
-               return $this->getMock( 'DataValues\DataValue' );
-       }
-
-       private function getEntityRevisionLookupMock() {
-               $mock = $this->getMockBuilder( 
'Wikibase\Lib\Store\EntityRevisionLookup' )
-                                        ->setMethods( array( 
'getLatestRevisionId' ) )
-                                        ->getMockForAbstractClass();
-               $mock->expects( $this->any() )
-                        ->method( 'getLatestRevisionId' )
-                        ->will( $this->returnValue( 42 ) );
-
-               return $mock;
-       }
-}
diff --git a/tests/phpunit/Violations/MagicalGateToBaseExtensionTest.php 
b/tests/phpunit/Violations/MagicalGateToBaseExtensionTest.php
new file mode 100644
index 0000000..9976fab
--- /dev/null
+++ b/tests/phpunit/Violations/MagicalGateToBaseExtensionTest.php
@@ -0,0 +1,191 @@
+<?php
+
+namespace WikibaseQuality\ExternalValidation\Test\Violations;
+
+use DataValues\StringValue;
+use Wikibase\DataModel\Entity\Entity;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\Repo\WikibaseRepo;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList;
+use WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult;
+use WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation;
+use WikibaseQuality\ExternalValidation\Violations\MagicalGateToBaseExtension;
+use WikibaseQuality\Violations\Violation;
+
+
+/**
+ * @covers 
WikibaseQuality\ExternalValidation\Violations\MagicalGateToBaseExtension
+ *
+ * @group WikibaseQualityExternalValidation
+ * @group Database
+ * @group medium
+ *
+ * @uses   
WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation
+ * @uses   
WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult
+ * @uses   WikibaseQuality\ExternalValidation\CrossCheck\Result\ReferenceResult
+ * @uses   
WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResult
+ * @uses   
WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList
+ *
+ * @author BP2014N1
+ * @license GNU GPL v2+
+ */
+class MagicalGateToBaseExtensionTest extends \MediaWikiTestCase {
+
+       /**
+        * @var MagicalGateToBaseExtension
+        */
+       private $translator;
+
+       /**
+        * @var PropertyId
+        */
+       private $propertyId;
+
+       /**
+        * @var string
+        */
+       private $claimGuid;
+
+       /**
+        * @var string
+        */
+       private $externalId;
+
+       /**
+        * @var Entity
+        */
+       private $entity;
+
+       /**
+        * @var DumpMetaInformation
+        */
+       private $dumpMetaInformation;
+
+       /**
+        * @var ReferenceResult
+        */
+       private $referenceResult;
+
+       /**
+        * @var EntityId[]
+        */
+       private static $idMap;
+
+       protected function setUp() {
+               parent::setUp();
+               $this->translator = new MagicalGateToBaseExtension( 
$this->getEntityRevisionLookupMock(), $this->getViolationStoreMock(), 
$this->getExceptionLookupMock() );
+
+               $this->propertyId = new PropertyId( 'P1' );
+               $this->entity = new Item();
+               $store = WikibaseRepo::getDefaultInstance()->getEntityStore();
+               $store->saveEntity( $this->entity, 'TestEntityQ1', 
$GLOBALS['wgUser'], EDIT_NEW );
+               self::$idMap['Q1'] = $this->entity->getId();
+               $this->claimGuid = self::$idMap['Q1'] . 
'$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
+               $this->externalId = 'foobar';
+
+               $this->dumpMetaInformation = new DumpMetaInformation(
+                       'foo',
+                       new ItemId( 'Q123456' ),
+                       array( new PropertyId( 'P227' ) ),
+                       '20150101000000',
+                       'en',
+                       'http://www.foo.bar',
+                       42,
+                       new ItemId( 'Q6938433' )
+               );
+
+               $this->referenceResult = new ReferenceResult(
+                       ReferenceResult::STATUS_REFERENCES_MISSING,
+                       $this->getReferenceMock()
+               );
+
+       }
+
+       protected function tearDown() {
+               parent::tearDown();
+               unset( $this->translator, $this->propertyId, $this->claimGuid, 
$this->entity, $this->dumpMetaInformation, $this->referenceResult );
+       }
+
+       public function testSingleComplianceResult() {
+               $comparisonResult = new ComparisonResult(
+                       $this->getDataValueMock(),
+                       array( $this->getDataValueMock() ),
+                       ComparisonResult::STATUS_MATCH
+               );
+
+               $crossCheckResultList = new CrossCheckResultList( array( new 
CrossCheckResult( $this->propertyId, $this->claimGuid, $this->externalId, 
$this->dumpMetaInformation, $comparisonResult, $this->referenceResult, false ) 
) );
+               $violations = $this->translator->saveAsViolations( 
$this->entity, $crossCheckResultList );
+               $this->assertEquals( array(), $violations );
+       }
+
+       public function testSingleViolationResult() {
+               $comparisonResult = new ComparisonResult(
+                       $this->getDataValueMock(),
+                       array( new StringValue( 'test' ) ),
+                       ComparisonResult::STATUS_MISMATCH
+               );
+
+               $crossCheckResultList = new CrossCheckResultList( array( new 
CrossCheckResult( $this->propertyId, $this->claimGuid, $this->externalId, 
$this->dumpMetaInformation, $comparisonResult, $this->referenceResult, false ) 
) );
+               $violations = $this->translator->saveAsViolations( 
$this->entity, $crossCheckResultList );
+               $this->assertEquals( 1, sizeof( $violations ) );
+
+               $violation = $violations[0];
+               $this->assertEquals( self::$idMap['Q1'], 
$violation->getEntityId() );
+               $this->assertEquals( 'P1', 
$violation->getPropertyId()->getSerialization() );
+               $this->assertEquals( $this->claimGuid, 
$violation->getClaimGuid() );
+               $this->assertEquals( 'wbqev|93346d9b0ea699c5387d1d2bf56322ff', 
$violation->getConstraintId() );
+               $this->assertEquals( 
$this->dumpMetaInformation->getSourceItemId(), 
$violation->getConstraintTypeEntityId() );
+               $this->assertEquals( array(
+                                                                
'external_values' => array( array( 'value' => 'test', 'type' => 'string' ) ),
+                                                                'dump_id' => 
'foo'
+                                                        ), 
$violation->getAdditionalInfo() );
+               $this->assertEquals( 42, $violation->getRevisionId() );
+
+       }
+
+       private function getReferenceMock() {
+               return $this->getMock( 'Wikibase\DataModel\Reference' );
+       }
+
+       private function getDataValueMock() {
+               return $this->getMock( 'DataValues\DataValue' );
+       }
+
+       private function getEntityRevisionLookupMock() {
+               $mock = $this->getMockBuilder( 
'Wikibase\Lib\Store\EntityRevisionLookup' )
+                                        ->setMethods( array( 
'getLatestRevisionId' ) )
+                                        ->getMockForAbstractClass();
+               $mock->expects( $this->any() )
+                        ->method( 'getLatestRevisionId' )
+                        ->will( $this->returnValue( 42 ) );
+
+               return $mock;
+       }
+
+       private function getViolationStoreMock() {
+               $mock = $this->getMockBuilder( 
'WikibaseQuality\Violations\ViolationStore' )
+                       ->setMethods( array( 'insert') )
+                       ->disableOriginalConstructor()
+                       ->getMockForAbstractClass();
+               $mock->expects( $this->any() )
+                       ->method( 'insert' )
+                       ->with( $this->equalTo('something') );
+               return $mock;
+
+               function checkTranslation( Violation $violation, $someBoolean = 
false ) {
+                       return $violation;
+               }
+       }
+
+       private function getExceptionLookupMock() {
+               $mock = $this->getMockBuilder( 
'WikibaseQuality\Violations\ExceptionLookup' )
+                       ->disableOriginalConstructor()
+                       ->getMockForAbstractClass();
+               return $mock;
+       }
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I479e9b5720762d99d3fc9b04133f4652639099f8
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikibaseQualityExternalValidation
Gerrit-Branch: master
Gerrit-Owner: Tamslo <tamaraslosa...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to