Ladsgroup has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/339787 )
Change subject: Add LanguageChangeOpDeserializer ...................................................................... Add LanguageChangeOpDeserializer Bug: T155701 Change-Id: Ibda3e8b94a7f17637f4da5a5e54cd76369f1e003 --- A src/ChangeOp/Deserialization/LanguageChangeOpDeserializer.php A tests/phpunit/mediawiki/ChangeOp/Deserialization/LanguageChangeOpDeserializerTest.php 2 files changed, 218 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseLexeme refs/changes/87/339787/1 diff --git a/src/ChangeOp/Deserialization/LanguageChangeOpDeserializer.php b/src/ChangeOp/Deserialization/LanguageChangeOpDeserializer.php new file mode 100644 index 0000000..948fd7a --- /dev/null +++ b/src/ChangeOp/Deserialization/LanguageChangeOpDeserializer.php @@ -0,0 +1,107 @@ +<?php + +namespace Wikibase\Lexeme\ChangeOp\Deserialization; + +use InvalidArgumentException; +use ValueValidators\StringValidator; +use Wikibase\ChangeOp\ChangeOp; +use Wikibase\ChangeOp\ChangeOps; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\Lexeme\ChangeOp\ChangeOpLanguage; +use Wikibase\Lexeme\Validators\LexemeValidatorFactory; +use Wikibase\Repo\ChangeOp\ChangeOpDeserializer; +use Wikibase\Repo\ChangeOp\Deserialization\ChangeOpDeserializationException; +use Wikibase\StringNormalizer; + +/** + * Deserializer for language change request data. + * + * @see docs/change-op-serialization.wiki for a description of the serialization format. + * + * @license GPL-2.0+ + */ +class LanguageChangeOpDeserializer implements ChangeOpDeserializer{ + + /** + * @var LexemeValidatorFactory + */ + private $lexemeValidatorFactory; + + /** + * @var StringNormalizer + */ + private $stringNormalizer; + + /** + * @var StringValidator + */ + private $stringValidator; + + public function __construct( + LexemeValidatorFactory $lexemeValidatorFactory, + StringNormalizer $stringNormalizer + ) { + $this->lexemeValidatorFactory = $lexemeValidatorFactory; + $this->stringNormalizer = $stringNormalizer; + //XXX: Inject this? + $this->stringValidator = new StringValidator(); + } + + /** + * @see ChangeOpDeserializer::createEntityChangeOp + * + * @param array $changeRequest + * + * @throws ChangeOpDeserializationException + * + * @return ChangeOp + */ + public function createEntityChangeOp( array $changeRequest ) { + $changeOps = new ChangeOps(); + + $result = $this->stringValidator->validate( $changeRequest['language'] ); + if ( $result->isValid() !== true ) { + throw new ChangeOpDeserializationException( + 'language needs to be string', + 'invalid-language' + ); + } + $languageSerialization = $this->stringNormalizer->cleanupToNFC( $changeRequest['language'] ); + + if ( $languageSerialization === '' ) { + $changeOps->add( new ChangeOpLanguage( + null, + $this->lexemeValidatorFactory + ) ); + return $changeOps; + } + + $itemId = $this->validateItemId( $languageSerialization ); + // TODO: maybe move creating ChangeOpLanguage instance to some kind of factory? + $changeOps->add( new ChangeOpLanguage( + $itemId, + $this->lexemeValidatorFactory + ) ); + + return $changeOps; + } + + /** + * @param string $idSerialization + * @return ItemId + * @throws ChangeOpDeserializationException + */ + private function validateItemId( $idSerialization ) { + try { + $itemId = new ItemId( $idSerialization ); + } catch ( InvalidArgumentException $e ) { + throw new ChangeOpDeserializationException( + 'Item id can not be parsed', + 'invalid-item-id' + ); + } + + return $itemId; + } + +} diff --git a/tests/phpunit/mediawiki/ChangeOp/Deserialization/LanguageChangeOpDeserializerTest.php b/tests/phpunit/mediawiki/ChangeOp/Deserialization/LanguageChangeOpDeserializerTest.php new file mode 100644 index 0000000..26bae10 --- /dev/null +++ b/tests/phpunit/mediawiki/ChangeOp/Deserialization/LanguageChangeOpDeserializerTest.php @@ -0,0 +1,111 @@ +<?php + + +namespace Wikibase\Lexeme\Tests\ChangeOp\Deserialization; + +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\Lexeme\ChangeOp\Deserialization\LanguageChangeOpDeserializer; +use Wikibase\Lexeme\DataModel\Lexeme; +use Wikibase\Lexeme\DataModel\LexemeId; +use Wikibase\Lexeme\Validators\LexemeValidatorFactory; +use Wikibase\Repo\ChangeOp\Deserialization\ChangeOpDeserializationException; +use Wikibase\Repo\Tests\ChangeOp\ChangeOpTestMockProvider; +use Wikibase\StringNormalizer; + +/** + * @covers Wikibase\Lexeme\ChangeOp\Deserialiazation\LanguageChangeOpDeserializer + * + * @group WikibaseLexeme + * + * @license GPL-2.0+ + */ +class LanguageChangeOpDeserializerTest extends \PHPUnit_Framework_TestCase { + + private function newLanguageChangeOpDeserializer() { + $mockProvider = new ChangeOpTestMockProvider( $this ); + return new LanguageChangeOpDeserializer( + new LexemeValidatorFactory( 10, $mockProvider->getMockTermValidatorFactory() ), + new StringNormalizer() + ); + } + + public function testGivenLanguageSerializationIsNotString_exceptionIsThrown() { + $deserializer = $this->newLanguageChangeOpDeserializer(); + + $this->setExpectedException( ChangeOpDeserializationException::class ); + + $deserializer->createEntityChangeOp( [ 'language' => [] ] ); + } + + public function testGivenLanguageSerializationIsInvalid_exceptionIsThrown() { + + $lexemeValidatorFactory = $this->getMockBuilder( LexemeValidatorFactory::class ) + ->disableOriginalConstructor() + ->getMock(); + + $deserializer = new LanguageChangeOpDeserializer( + $lexemeValidatorFactory, + new StringNormalizer() + ); + + $this->setExpectedException( ChangeOpDeserializationException::class ); + + $deserializer->createEntityChangeOp( [ 'language' => 'invalid item id' ] ); + } + + // TODO: should case of ChangeOp with invalid Term (ie. throwing ChangeOpException + // when applied on Lexeme object) be also tested here? + + public function testGivenRequestWithLanguageAndNoLanguage_changeOpAddsTheLanguage() { + $lexeme = new Lexeme( new LexemeId( 'L100' ) ); + + $deserializer = $this->newLanguageChangeOpDeserializer(); + + $changeOp = $deserializer->createEntityChangeOp( + [ 'language' => 'q100' ] + ); + + $changeOp->apply( $lexeme ); + $this->assertSame( 'Q100', $lexeme->getLanguage()->getSerialization() ); + } + + public function testGivenRequestWithLanguageExists_changeOpSetsLanguageToNewValue() { + $lexeme = new Lexeme( new LexemeId( 'L100' ), null, null, new ItemId( 'Q100' ) ); + + $deserializer = $this->newLanguageChangeOpDeserializer(); + + $changeOp = $deserializer->createEntityChangeOp( + [ 'language' => 'q200' ] + ); + + $changeOp->apply( $lexeme ); + $this->assertSame( 'Q200', $lexeme->getLanguage()->getSerialization() ); + } + + public function testGivenRemoveRequestLanguageExists_changeOpRemovesLanguage() { + $lexeme = new Lexeme( new LexemeId( 'L100' ), null, null, new ItemId( 'Q100' ) ); + + $deserializer = $this->newLanguageChangeOpDeserializer(); + + $changeOp = $deserializer->createEntityChangeOp( + [ 'language' => '' ] + ); + + $changeOp->apply( $lexeme ); + $this->assertNull( $lexeme->getLanguage() ); + } + + public function testRequestRemoveLanguageDoesNotExist_changeOpDoesNothing() { + $lexeme = new Lexeme( new LexemeId( 'L100' ) ); + + $deserializer = $this->newLanguageChangeOpDeserializer(); + + $changeOp = $deserializer->createEntityChangeOp( + [ 'language' => '' ] + ); + + $changeOp->apply( $lexeme ); + $this->assertNull( $lexeme->getLanguage() ); + } + +} -- To view, visit https://gerrit.wikimedia.org/r/339787 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibda3e8b94a7f17637f4da5a5e54cd76369f1e003 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/WikibaseLexeme Gerrit-Branch: master Gerrit-Owner: Ladsgroup <ladsgr...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits