jenkins-bot has submitted this change and it was merged.

Change subject: Allow auto-creation of entities with custom ids.
......................................................................


Allow auto-creation of entities with custom ids.

Note that Icaf5f89f1a326 needs to be merged into WikibaseMediaInfo first
to avoid CI failures.

Depends-On: Icaf5f89f1a326e73a45b5227a0d9d49e4446fda4
Bug: T134259
Change-Id: Ia5f075eb3f1be9571a80fd4bfda5b5c914bbd39c
---
M lib/includes/Store/EntityStore.php
M lib/includes/Store/WikiPagePropertyOrderProvider.php
M lib/tests/phpunit/MockRepository.php
M repo/includes/Api/EditEntity.php
M repo/includes/Api/ModifyEntity.php
M repo/includes/Content/EntityHandler.php
M repo/includes/Store/Sql/WikiPageEntityStore.php
M repo/tests/phpunit/includes/Api/EditEntityTest.php
M repo/tests/phpunit/includes/Api/WikibaseApiTestCase.php
M repo/tests/phpunit/includes/Content/ItemHandlerTest.php
M repo/tests/phpunit/includes/Content/PropertyHandlerTest.php
M repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
12 files changed, 350 insertions(+), 44 deletions(-)

Approvals:
  Jonas Kress (WMDE): Looks good to me, approved
  Thiemo Mättig (WMDE): Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/includes/Store/EntityStore.php 
b/lib/includes/Store/EntityStore.php
index 71581d0..9e5461e 100644
--- a/lib/includes/Store/EntityStore.php
+++ b/lib/includes/Store/EntityStore.php
@@ -137,4 +137,20 @@
         */
        public function isWatching( User $user, EntityId $id );
 
+       /**
+        * Whether an entity with the given custom ID can exist.
+        *
+        * Implementations are not required to check if an entity with the 
given ID already exists.
+        * If this method returns true, this means that an entity with the 
given ID could be
+        * created (or already existed) at the time the method was called. 
There is no guarantee
+        * that this continues to be true after the method call returned. 
Callers must be careful
+        * to handle race conditions.
+        *
+        * @see EntityHandler::canCreateWithCustomId()
+        *
+        * @param EntityId $id
+        * @return bool
+        */
+       public function canCreateWithCustomId( EntityId $id );
+
 }
diff --git a/lib/includes/Store/WikiPagePropertyOrderProvider.php 
b/lib/includes/Store/WikiPagePropertyOrderProvider.php
index 38546f7..b57911d 100644
--- a/lib/includes/Store/WikiPagePropertyOrderProvider.php
+++ b/lib/includes/Store/WikiPagePropertyOrderProvider.php
@@ -21,6 +21,7 @@
 
        /**
         * Constructor of the WikiPageOrderProvider
+        *
         * @param Title $pageTitle page name the ordered property list is on
         */
        public function __construct( Title $pageTitle ) {
@@ -38,11 +39,13 @@
                        return null;
                }
                $parsedList = $this->parseList( $pageContent );
+
                return array_flip( $parsedList );
        }
 
        /**
         * Get Content of MediaWiki:Wikibase-SortedProperties
+        *
         * @return string|null
         * @throws PropertyOrderProviderException
         */
@@ -68,6 +71,7 @@
 
        /**
         * @param string $pageContent
+        *
         * @return string[]
         */
        private function parseList( $pageContent ) {
diff --git a/lib/tests/phpunit/MockRepository.php 
b/lib/tests/phpunit/MockRepository.php
index eb2b684..d374952 100644
--- a/lib/tests/phpunit/MockRepository.php
+++ b/lib/tests/phpunit/MockRepository.php
@@ -760,4 +760,16 @@
                throw new EntityRedirectLookupException( $entityId );
        }
 
+       /**
+        * Whether an entity with the given custom ID can be created.
+        *
+        * @see EntityHandler::canCreateWithCustomId()
+        *
+        * @param EntityId $id
+        * @return bool
+        */
+       public function canCreateWithCustomId( EntityId $id ) {
+               return false;
+       }
+
 }
diff --git a/repo/includes/Api/EditEntity.php b/repo/includes/Api/EditEntity.php
index 2ece96e..d615e8b 100644
--- a/repo/includes/Api/EditEntity.php
+++ b/repo/includes/Api/EditEntity.php
@@ -176,24 +176,48 @@
        }
 
        /**
-        * @see ModifyEntity::createEntity
+        * Create an empty entity.
         *
-        * @param string $entityType
+        * @since 0.1
+        *
+        * @param string|null $entityType The type of entity to be created 
(ignored if $id is given)
+        * @param EntityId|null $id The ID of the entity to be created 
(optional if $entityType is
+        *        given)
         *
         * @throws UsageException
         * @throws LogicException
-        * @return EntityDocument
+        * @return EntityDocument Newly created entity
         */
-       protected function createEntity( $entityType ) {
-               $this->flags |= EDIT_NEW;
+       protected function createEntity( $entityType, EntityId $id = null ) {
+               // TODO: pull this up into ModifyEntity.
 
-               try {
-                       return $this->entityFactory->newEmpty( $entityType );
-               } catch ( InvalidArgumentException $ex ) {
-                       $this->errorReporter->dieError( "No such entity type: 
'$entityType'", 'no-such-entity-type' );
+               if ( $id ) {
+                       $entityType = $id->getEntityType();
+               } elseif ( !$entityType ) {
+                       $this->errorReporter->dieError( "No entity type 
provided for creation!", 'no-entity-type' );
+                       throw new LogicException( 'ApiErrorReporter::dieError 
did not throw an exception' );
                }
 
-               throw new LogicException( 'ApiErrorReporter::dieError did not 
throw an exception' );
+               try {
+                       $entity = $this->entityFactory->newEmpty( $entityType );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->errorReporter->dieError( "No such entity type: 
'$entityType'", 'no-such-entity-type' );
+                       throw new LogicException( 'ApiErrorReporter::dieError 
did not throw an exception' );
+               }
+
+               if ( $id !== null ) {
+                       if ( !$this->entityStore->canCreateWithCustomId( $id ) 
) {
+                               $this->errorReporter->dieError( "Cannot create 
entity with ID: '$id'", 'bad-entity-id' );
+                               throw new LogicException( 
'ApiErrorReporter::dieError did not throw an exception' );
+                       }
+
+                       $entity->setId( $id );
+               } else {
+                       // NOTE: We need to assign an ID early, for things like 
the ClaimIdGenerator.
+                       $this->entityStore->assignFreshId( $entity );
+               }
+
+               return $entity;
        }
 
        /**
diff --git a/repo/includes/Api/ModifyEntity.php 
b/repo/includes/Api/ModifyEntity.php
index f93d709..2b31b1d 100644
--- a/repo/includes/Api/ModifyEntity.php
+++ b/repo/includes/Api/ModifyEntity.php
@@ -65,7 +65,7 @@
        /**
         * @var EntityStore
         */
-       private $entityStore;
+       protected $entityStore;
 
        /**
         * @since 0.5
@@ -184,11 +184,12 @@
        }
 
        /**
-        * Get the entity using the id, site and title params passed to the api
+        * Get an EntityRevision using the id, site and title params as well as 
the
+        * baserevid passed to the api.
         *
         * @param array $params
         *
-        * @return EntityRevision Found existing entity
+        * @return EntityRevision|null Found existing entity
         */
        protected function getEntityRevisionFromApiParams( array $params ) {
                $entityRevision = null;
@@ -211,11 +212,6 @@
                                // is a subclass of StorageException, so we 
still have some inconsistency
                                // and need to check both.
                                $this->errorReporter->dieException( $ex, 
'no-such-entity' );
-                       }
-
-                       if ( $entityRevision === null ) {
-                               $this->errorReporter->dieError( "Can't access 
entity " . $entityId
-                                       . ', revision may have been deleted.', 
'no-such-entity' );
                        }
                }
 
@@ -318,15 +314,19 @@
        }
 
        /**
-        * Create the entity.
+        * Create an empty entity.
         *
         * @since 0.1
         *
-        * @param string $entityType
+        * @param string|null $entityType The type of entity to be created 
(ignored if $id is given)
+        * @param EntityId|null $id The ID of the entity to be created 
(optional if $entityType is
+        *        given)
         *
+        * @throws UsageException
+        * @throws LogicException
         * @return EntityDocument Newly created entity
         */
-       protected function createEntity( $entityType ) {
+       protected function createEntity( $entityType, EntityId $id = null ) {
                $this->errorReporter->dieError( 'Could not find an existing 
entity', 'no-such-entity' );
        }
 
@@ -417,13 +417,26 @@
                // Try to find the entity or fail and create it, or die in the 
process
                $entityRev = $this->getEntityRevisionFromApiParams( $params );
                if ( is_null( $entityRev ) ) {
-                       $entity = $this->createEntity( $params['new'] );
-                       $entityRevId = 0;
+                       $entityId = $this->getEntityIdFromParams( $params );
 
-                       // HACK: We need to assign an ID early, for things like 
the ClaimIdGenerator.
-                       if ( $entity->getId() === null ) {
-                               $this->entityStore->assignFreshId( $entity );
+                       if ( !$params['new'] ) {
+                               if ( !$entityId ) {
+                                       $this->errorReporter->dieError(
+                                               'No entity was identified, nor 
was creation requested',
+                                               'param-illegal'
+                                       );
+                               } elseif ( 
!$this->entityStore->canCreateWithCustomId( $entityId ) ) {
+                                       $this->errorReporter->dieError(
+                                               'Could not find entity ' . 
$entityId,
+                                               'no-such-entity'
+                                       );
+                               }
                        }
+
+                       $entity = $this->createEntity( $params['new'], 
$entityId );
+
+                       $this->flags |= EDIT_NEW;
+                       $entityRevId = 0;
                } else {
                        $entity = $entityRev->getEntity();
                        $entityRevId = $entityRev->getRevisionId();
diff --git a/repo/includes/Content/EntityHandler.php 
b/repo/includes/Content/EntityHandler.php
index 9d0a8b4..e223953 100644
--- a/repo/includes/Content/EntityHandler.php
+++ b/repo/includes/Content/EntityHandler.php
@@ -739,4 +739,37 @@
                return $updates;
        }
 
+       /**
+        * Whether IDs can automatically be assigned to entities
+        * of the kind supported by this EntityHandler.
+        *
+        * @return bool
+        */
+       public function allowAutomaticIds() {
+               return true;
+       }
+
+       /**
+        * Whether the given custom ID is valid for creating a new entity
+        * of the kind supported by this EntityHandler.
+        *
+        * Implementations are not required to check if an entity with the 
given ID already exists.
+        * If this method returns true, this means that an entity with the 
given ID could be
+        * created (or already existed) at the time the method was called. 
There is no guarantee
+        * that this continues to be true after the method call returned. 
Callers must be careful
+        * to handle race conditions.
+        *
+        * @note For entity types that cannot be created with custom IDs (that 
is,
+        * entity types that are defined to use automatic IDs), this should 
always
+        * return false.
+        *
+        * @see EntityStore::canCreateWithCustomId()
+        *
+        * @param EntityId $id
+        * @return bool
+        */
+       public function canCreateWithCustomId( EntityId $id ) {
+               return false;
+       }
+
 }
diff --git a/repo/includes/Store/Sql/WikiPageEntityStore.php 
b/repo/includes/Store/Sql/WikiPageEntityStore.php
index a821c42..d1e9f93 100644
--- a/repo/includes/Store/Sql/WikiPageEntityStore.php
+++ b/repo/includes/Store/Sql/WikiPageEntityStore.php
@@ -71,17 +71,40 @@
         */
        public function assignFreshId( EntityDocument $entity ) {
                if ( $entity->getId() !== null ) {
-                       throw new StorageException( 'This entity already has an 
ID!' );
+                       throw new StorageException( 'This entity already has an 
ID: ' . $entity->getId() . ' !' );
                }
 
-               $contentModelId = 
$this->contentFactory->getContentModelForType( $entity->getType() );
+               $type = $entity->getType();
+               $handler = $this->contentFactory->getContentHandlerForType( 
$type );
+
+               if ( !$handler->allowAutomaticIds() ) {
+                       throw new StorageException( $type . ' entities do not 
support automatic IDs!' );
+               }
+
+               // TODO: move this into EntityHandler!
+               $contentModelId = $handler->getModelID();
                $numericId = $this->idGenerator->getNewId( $contentModelId );
 
-               //FIXME: this relies on setId() accepting numeric IDs!
+               // FIXME: this relies on setId() accepting numeric IDs! Use an 
EntityIdComposer instead.
                $entity->setId( $numericId );
        }
 
        /**
+        * @see EntityStore::canCreateWithId()
+        *
+        * @param EntityId $id
+        *
+        * @return bool
+        * @throws StorageException
+        */
+       public function canCreateWithCustomId( EntityId $id ) {
+               $type = $id->getEntityType();
+               $handler = $this->contentFactory->getContentHandlerForType( 
$type );
+
+               return $handler->canCreateWithCustomId( $id );
+       }
+
+       /**
         * Registers a watcher that will be notified whenever an entity is
         * updated or deleted.
         *
diff --git a/repo/tests/phpunit/includes/Api/EditEntityTest.php 
b/repo/tests/phpunit/includes/Api/EditEntityTest.php
index 60cc7ae..8b88a7d 100644
--- a/repo/tests/phpunit/includes/Api/EditEntityTest.php
+++ b/repo/tests/phpunit/includes/Api/EditEntityTest.php
@@ -5,6 +5,10 @@
 use UsageException;
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\Property;
+use Wikibase\Lib\Store\EntityStore;
+use Wikibase\Lib\Store\StorageException;
+use Wikibase\MediaInfo\DataModel\MediaInfo;
+use Wikibase\MediaInfo\DataModel\MediaInfoId;
 use Wikibase\Repo\WikibaseRepo;
 
 /**
@@ -76,6 +80,14 @@
                                self::$idMap['%Q149%'] => '',
                                'Q99999' => '', // Just in case we have a wrong 
config
                        ) );
+
+                       // Create a file page for which we can later create a 
MediaInfo entity.
+                       // XXX It's ugly to have knowledge about MediaInfo 
here. But since we currently can't
+                       // inject mock handlers for a mock media type, this is 
the only way to test automatic
+                       // creation.
+
+                       $titleInfo = $this->insertPage( 
'File:EditEntityTest.jpg' );
+                       self::$idMap['%M11%'] = 'M' . $titleInfo['id'];
                }
                self::$hasSetup = true;
        }
@@ -100,6 +112,11 @@
                                                . '"datatype":"string"}'
                                ),
                                'e' => array( 'type' => 'property' ) ),
+                       'new mediainfo from id' => array(
+                               'p' => array( 'id' => '%M11%', 'data' => '{}' ),
+                               'e' => array( 'type' => 'mediainfo' ),
+                               't' => 'mediainfo', // skip if MediaInfo is not 
configured
+                       ),
                        'add a sitelink..' => array( // make sure if we pass in 
a valid id it is accepted
                                'p' => array(
                                        'data' => 
'{"sitelinks":{"dewiki":{"site":"dewiki",'
@@ -383,9 +400,27 @@
        }
 
        /**
+        * Skips a test of the given entity type is not enabled.
+        *
+        * @param string $needed the required entity type
+        */
+       private function skipIfEntityTypeNotKnown( $needed ) {
+               if ( $needed === null ) {
+                       return;
+               }
+
+               $enabledTypes = 
WikibaseRepo::getDefaultInstance()->getEnabledEntityTypes();
+               if ( !in_array( $needed, $enabledTypes ) ) {
+                       $this->markTestSkipped( 'Entity type not enabled: ' . 
$needed );
+               }
+       }
+
+       /**
         * @dataProvider provideData
         */
-       public function testEditEntity( $params, $expected ) {
+       public function testEditEntity( $params, $expected, $needed = null ) {
+               $this->skipIfEntityTypeNotKnown( $needed );
+
                $this->injectIds( $params );
                $this->injectIds( $expected );
 
@@ -480,6 +515,12 @@
                                'e' => array( 'exception' => array(
                                        'type' => UsageException::class,
                                        'code' => 'no-such-entity-id'
+                               ) ) ),
+                       'unknown id' => array(
+                               'p' => array( 'id' => 'Q1234567', 'data' => 
'{}' ),
+                               'e' => array( 'exception' => array(
+                                       'type' => UsageException::class,
+                                       'code' => 'no-such-entity'
                                ) ) ),
                        'invalid explicit id' => array(
                                'p' => array( 'id' => '1234', 'data' => '{}' ),
@@ -778,13 +819,41 @@
                                        'code' => 'not-supported',
                                        'message' => 'Non Items cannot have 
sitelinks'
                                ) ) ),
+                       'create mediainfo with automatic id' => array(
+                               'p' => array( 'new' => 'mediainfo', 'data' => 
'{}' ),
+                               'e' => array( 'exception' => array(
+                                       'type' => StorageException::class,
+                                       'message' => 'mediainfo entities do not 
support automatic IDs'
+                               ) ),
+                               't' => 'mediainfo' // skip if MediaInfo is not 
configured
+                       ),
+                       'create mediainfo with malformed id' => array(
+                               'p' => array( 'id' => 'M123X', 'data' => '{}' ),
+                               'e' => array( 'exception' => array(
+                                       'type' => UsageException::class,
+                                       'code' => 'no-such-entity-id',
+                                       'message' => 'Could not find such an 
entity ID'
+                               ) ),
+                               't' => 'mediainfo' // skip if MediaInfo is not 
configured
+                       ),
+                       'create mediainfo with bad id' => array(
+                               'p' => array( 'id' => 'M12734569', 'data' => 
'{}' ),
+                               'e' => array( 'exception' => array(
+                                       'type' => UsageException::class,
+                                       'code' => 'no-such-entity',
+                                       'message' => 'Could not find such an 
entity'
+                               ) ),
+                               't' => 'mediainfo' // skip if MediaInfo is not 
configured
+                       ),
                );
        }
 
        /**
         * @dataProvider provideExceptionData
         */
-       public function testEditEntityExceptions( $params, $expected ) {
+       public function testEditEntityExceptions( $params, $expected, $needed = 
null ) {
+               $this->skipIfEntityTypeNotKnown( $needed );
+
                $this->injectIds( $params );
                $this->injectIds( $expected );
 
diff --git a/repo/tests/phpunit/includes/Api/WikibaseApiTestCase.php 
b/repo/tests/phpunit/includes/Api/WikibaseApiTestCase.php
index 2dac777..ef8bb37 100644
--- a/repo/tests/phpunit/includes/Api/WikibaseApiTestCase.php
+++ b/repo/tests/phpunit/includes/Api/WikibaseApiTestCase.php
@@ -3,6 +3,7 @@
 namespace Wikibase\Test\Repo\Api;
 
 use ApiTestCase;
+use Exception;
 use OutOfBoundsException;
 use Revision;
 use TestSites;
@@ -186,6 +187,13 @@
                        if ( array_key_exists( 'message', $exception ) ) {
                                $this->assertContains( $exception['message'], 
$e->getMessage() );
                        }
+               } catch ( Exception $e ) {
+                       if ( array_key_exists( 'type', $exception ) ) {
+                               $this->assertInstanceOf( $exception['type'], $e 
);
+                       }
+                       if ( array_key_exists( 'message', $exception ) ) {
+                               $this->assertContains( $exception['message'], 
$e->getMessage() );
+                       }
                }
        }
 
diff --git a/repo/tests/phpunit/includes/Content/ItemHandlerTest.php 
b/repo/tests/phpunit/includes/Content/ItemHandlerTest.php
index 0e37dd4..7d8007b 100644
--- a/repo/tests/phpunit/includes/Content/ItemHandlerTest.php
+++ b/repo/tests/phpunit/includes/Content/ItemHandlerTest.php
@@ -146,4 +146,15 @@
                return $this->getWikibaseRepo( $settings )->newItemHandler();
        }
 
+       public function testAllowAutomaticIds() {
+               $handler = $this->getHandler();
+               $this->assertTrue( $handler->allowAutomaticIds() );
+       }
+
+       public function testCanCreateWithCustomId() {
+               $handler = $this->getHandler();
+               $id = new ItemId( 'Q7' );
+               $this->assertFalse( $handler->canCreateWithCustomId( $id ) );
+       }
+
 }
diff --git a/repo/tests/phpunit/includes/Content/PropertyHandlerTest.php 
b/repo/tests/phpunit/includes/Content/PropertyHandlerTest.php
index eff02cf..c6c4517 100644
--- a/repo/tests/phpunit/includes/Content/PropertyHandlerTest.php
+++ b/repo/tests/phpunit/includes/Content/PropertyHandlerTest.php
@@ -103,4 +103,15 @@
                return $this->getWikibaseRepo( $settings 
)->newPropertyHandler();
        }
 
+       public function testAllowAutomaticIds() {
+               $handler = $this->getHandler();
+               $this->assertTrue( $handler->allowAutomaticIds() );
+       }
+
+       public function testCanCreateWithCustomId() {
+               $handler = $this->getHandler();
+               $id = new PropertyId( 'P7' );
+               $this->assertFalse( $handler->canCreateWithCustomId( $id ) );
+       }
+
 }
diff --git a/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php 
b/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
index 499a5bd..fbcf90c 100644
--- a/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
+++ b/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
@@ -3,6 +3,7 @@
 namespace Wikibase\Test;
 
 use MediaWikiTestCase;
+use RawMessage;
 use Revision;
 use Status;
 use User;
@@ -19,6 +20,7 @@
 use Wikibase\Lib\Store\StorageException;
 use Wikibase\Lib\Store\WikiPageEntityRevisionLookup;
 use Wikibase\Repo\Content\EntityContentFactory;
+use Wikibase\Repo\Content\EntityHandler;
 use Wikibase\Repo\Store\WikiPageEntityStore;
 use Wikibase\Repo\WikibaseRepo;
 use Wikibase\SqlIdGenerator;
@@ -34,6 +36,42 @@
  * @author Daniel Kinzler
  */
 class WikiPageEntityStoreTest extends MediaWikiTestCase {
+
+       /**
+        * @return EntityHandler
+        */
+       private function newFrobHandler() {
+               $handler = $this->getMockBuilder( EntityHandler::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $handler->expects( $this->any() )
+                       ->method( 'canCreateWithCustomId' )
+                       ->will( $this->returnValue( true ) );
+
+               return $handler;
+       }
+
+       /**
+        * @param string $text
+        *
+        * @return EntityId
+        */
+       private function newFrobId( $text ) {
+               $id = $this->getMockBuilder( EntityId::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $id->expects( $this->any() )
+                       ->method( 'getSerialization' )
+                       ->will( $this->returnValue( $text ) );
+
+               $id->expects( $this->any() )
+                       ->method( 'getEntityType' )
+                       ->will( $this->returnValue( 'frob' ) );
+
+               return $id;
+       }
 
        /**
         * @see EntityLookupTest::newEntityLoader()
@@ -58,7 +96,8 @@
                        new EntityContentFactory(
                                array(
                                        'item' => CONTENT_MODEL_WIKIBASE_ITEM,
-                                       'property' => 
CONTENT_MODEL_WIKIBASE_PROPERTY
+                                       'property' => 
CONTENT_MODEL_WIKIBASE_PROPERTY,
+                                       'frob' => 'FROB',
                                ),
                                array(
                                        'item' => function() use ( 
$wikibaseRepo ) {
@@ -66,7 +105,10 @@
                                        },
                                        'property' => function() use ( 
$wikibaseRepo ) {
                                                return 
$wikibaseRepo->newPropertyHandler();
-                                       }
+                                       },
+                                       'frob' => function() use ( 
$wikibaseRepo ) {
+                                               return $this->newFrobHandler();
+                                       },
                                )
                        ),
                        new SqlIdGenerator( wfGetLB() )
@@ -393,11 +435,22 @@
                        $status = $ex->getStatus();
 
                        if ( !$status ) {
-                               $status = Status::newFatal( 'boohoo' );
+                               $status = Status::newFatal( new RawMessage( 
$ex->getMessage() ) );
                        }
                }
 
                return $status;
+       }
+
+       private function getStatusLine( Status $status ) {
+               if ( $status->isGood() ) {
+                       return '';
+               } elseif ( $status->isOK() ) {
+                       $warnings = $status->getErrorsByType( 'warning' );
+                       return "\nStatus (OK): Warnings: " . var_dump( 
$warnings );
+               } else {
+                       return $status->getWikiText();
+               }
        }
 
        public function testSaveFlags() {
@@ -430,9 +483,10 @@
                $status = $this->saveEntity( $store, $entity, 'create item', 
null, EDIT_NEW );
                $this->assertTrue(
                        $status->isOK(),
-                       'create with EDIT_NEW flag for ' .
-                       $entity->getId()->getSerialization()
+                       'create with EDIT_NEW flag for ' . $entity->getId() .
+                       $this->getStatusLine( $status )
                );
+               $this->assertNotNull( $entity->getId(), 'getEntityId() after 
save' );
 
                // ok, the item exists now in the database.
 
@@ -450,13 +504,16 @@
                $status = $this->saveEntity( $store, $entity, 'create item', 
null, EDIT_UPDATE );
                $this->assertTrue(
                        $status->isOK(),
-                       'try to save with EDIT_UPDATE flag, save failed'
+                       'try to save with EDIT_UPDATE flag, save failed' . 
$this->getStatusLine( $status )
                );
 
                // try to save without flags
                $entity->setLabel( 'en', $prefix . 'six' );
                $status = $this->saveEntity( $store, $entity, 'create item' );
-               $this->assertTrue( $status->isOK(), 'try to save without flags, 
save failed' );
+               $this->assertTrue(
+                       $status->isOK(),
+                       'try to save without flags, save failed' . 
$this->getStatusLine( $status )
+               );
        }
 
        public function testRepeatedSave() {
@@ -469,15 +526,18 @@
                // create
                $entity->setLabel( 'en', $prefix . "First" );
                $status = $this->saveEntity( $store, $entity, 'create item', 
null, EDIT_NEW );
-               $this->assertTrue( $status->isOK(), 'create, save failed, 
status ok' );
-               $this->assertTrue( $status->isGood(), 'create, status is good' 
);
+               $this->assertTrue(
+                       $status->isOK(),
+                       'create, save failed, status ok' . 
$this->getStatusLine( $status )
+               );
+               $this->assertTrue( $status->isGood(), 'create, status is good' 
. $this->getStatusLine( $status ) );
 
                // change
                $prev_id = $store->getWikiPageForEntity( $entity->getId() 
)->getLatest();
                $entity->setLabel( 'en', $prefix . "Second" );
                $status = $this->saveEntity( $store, $entity, 'modify item', 
null, EDIT_UPDATE );
-               $this->assertTrue( $status->isOK(), 'change, status ok' );
-               $this->assertTrue( $status->isGood(), 'change, status good' );
+               $this->assertTrue( $status->isOK(), 'change, status ok' . 
$this->getStatusLine( $status ) );
+               $this->assertTrue( $status->isGood(), 'change, status good' . 
$this->getStatusLine( $status ) );
 
                $rev_id = $store->getWikiPageForEntity( $entity->getId() 
)->getLatest();
                $this->assertNotEquals( $prev_id, $rev_id, "revision ID should 
change on edit" );
@@ -486,7 +546,7 @@
                $prev_id = $store->getWikiPageForEntity( $entity->getId() 
)->getLatest();
                $entity->setLabel( 'en', $prefix . "Third" );
                $status = $this->saveEntity( $store, $entity, 'modify item 
again', null, EDIT_UPDATE );
-               $this->assertTrue( $status->isOK(), 'change again, status ok' );
+               $this->assertTrue( $status->isOK(), 'change again, status ok' . 
$this->getStatusLine( $status ) );
                $this->assertTrue( $status->isGood(), 'change again, status 
good' );
 
                $rev_id = $store->getWikiPageForEntity( $entity->getId() 
)->getLatest();
@@ -495,7 +555,11 @@
                // save unchanged
                $prev_id = $store->getWikiPageForEntity( $entity->getId() 
)->getLatest();
                $status = $this->saveEntity( $store, $entity, 'save 
unmodified', null, EDIT_UPDATE );
-               $this->assertTrue( $status->isOK(), 'save unchanged, save 
failed, status ok' );
+               $this->assertTrue(
+                       $status->isOK(),
+                       'save unchanged, save failed, status ok'
+                       . $this->getStatusLine( $status )
+               );
 
                $rev_id = $store->getWikiPageForEntity( $entity->getId() 
)->getLatest();
                $this->assertEquals( $prev_id, $rev_id, "revision ID should 
stay the same if no change was made" );
@@ -573,4 +637,22 @@
                return $pageId = (int)$row->epp_page_id;
        }
 
+       public function provideCanCreateWithCustomId() {
+               return [
+                       'no custom id allowed' => [ new ItemId( 'Q7' ), false ],
+                       'custom id allowed' => [ $this->newFrobId( 'F7' ), true 
],
+               ];
+       }
+
+       /**
+        * @dataProvider provideCanCreateWithCustomId
+        * @covers WikiPageEntityStore::canCreateWithCustomId()
+        */
+       public function testCanCreateWithCustomId( EntityId $id, $expected ) {
+               /* @var WikiPageEntityStore $store */
+               list( $store, ) = $this->createStoreAndLookup();
+
+               $this->assertSame( $expected, $store->canCreateWithCustomId( 
$id ), $id->getSerialization() );
+       }
+
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia5f075eb3f1be9571a80fd4bfda5b5c914bbd39c
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Adrian Heine <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: Jonas Kress (WMDE) <[email protected]>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to