jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/377742 )

Change subject: Add request object of AddForm API action and created it from 
API params
......................................................................


Add request object of AddForm API action and created it from API params

Change-Id: Ic593fcd9922f732036d7c5bdda4088887aa64928
---
A src/Api/AddFormRequest.php
A src/Api/AddFormRequestParser.php
A src/Api/AddFormRequestParserResult.php
A tests/phpunit/mediawiki/Api/AddFormRequestParserTest.php
A tests/phpunit/mediawiki/Api/AddFormRequestTest.php
5 files changed, 493 insertions(+), 0 deletions(-)

Approvals:
  Aleksey Bekh-Ivanov (WMDE): Looks good to me, approved
  jenkins-bot: Verified



diff --git a/src/Api/AddFormRequest.php b/src/Api/AddFormRequest.php
new file mode 100644
index 0000000..5a04c11
--- /dev/null
+++ b/src/Api/AddFormRequest.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Wikibase\Lexeme\Api;
+
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
+use Wikibase\Lexeme\ChangeOp\ChangeOpAddForm;
+use Wikibase\Lexeme\DataModel\LexemeId;
+use Wikimedia\Assert\Assert;
+
+/**
+ * @license GPL-2.0+
+ */
+class AddFormRequest {
+
+       /**
+        * @var LexemeId
+        */
+       private $lexemeId;
+
+       /**
+        * @var TermList
+        */
+       private $representations;
+
+       /**
+        * @var ItemId[]
+        */
+       private $grammaticalFeatures;
+
+       /**
+        * @param LexemeId $lexemeId
+        * @param TermList $representations
+        * @param ItemId[] $grammaticalFeatures
+        */
+       public function __construct(
+               LexemeId $lexemeId,
+               TermList $representations,
+               array $grammaticalFeatures
+       ) {
+               Assert::parameterElementType( ItemId::class, 
$grammaticalFeatures, '$grammaticalFeatures' );
+               Assert::parameter( !$representations->isEmpty(), 
'$representations', 'should not be empty' );
+
+               $this->lexemeId = $lexemeId;
+               $this->representations = $representations;
+               $this->grammaticalFeatures = $grammaticalFeatures;
+       }
+
+       /**
+        * @return ChangeOpAddForm
+        */
+       public function getChangeOp() {
+               return new ChangeOpAddForm( $this->representations, 
$this->grammaticalFeatures );
+       }
+
+       /**
+        * @return LexemeId
+        */
+       public function getLexemeId() {
+               return $this->lexemeId;
+       }
+
+}
diff --git a/src/Api/AddFormRequestParser.php b/src/Api/AddFormRequestParser.php
new file mode 100644
index 0000000..bb2a7aa
--- /dev/null
+++ b/src/Api/AddFormRequestParser.php
@@ -0,0 +1,168 @@
+<?php
+
+namespace Wikibase\Lexeme\Api;
+
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\EntityIdParsingException;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
+use Wikibase\Lexeme\DataModel\LexemeId;
+
+/**
+ * @license GPL-2.0+
+ */
+class AddFormRequestParser {
+
+       /**
+        * @var EntityIdParser
+        */
+       private $entityIdParser;
+
+       public function __construct( EntityIdParser $entityIdParser ) {
+               $this->entityIdParser = $entityIdParser;
+       }
+
+       /**
+        * @param array $params
+        * @return AddFormRequestParserResult
+        */
+       public function parse( array $params ) {
+               $errors = $this->validateRequiredFieldsPresent( $params );
+               if ( $errors ) {
+                       return AddFormRequestParserResult::newWithErrors( 
$errors );
+               }
+
+               $data = json_decode( $params['data'], true );
+               if ( $data === null ) {
+                       return AddFormRequestParserResult::newWithErrors( [ 
'data-invalid-json' ] );
+               }
+
+               $errors = $this->validateDataStructure( $data );
+               if ( $errors ) {
+                       return AddFormRequestParserResult::newWithErrors( 
$errors );
+               }
+
+               $lexemeId = $this->parseLexemeId( $params['lexemeId'], $errors 
);
+               $representations = $this->parseRepresentations( 
$data['representations'], $errors );
+               $grammaticalFeatures = $this->parseGrammaticalFeatures( 
$data['grammaticalFeatures'], $errors );
+
+               if ( $errors ) {
+                       return AddFormRequestParserResult::newWithErrors( 
$errors );
+               }
+
+               return AddFormRequestParserResult::newWithRequest(
+                       new AddFormRequest( $lexemeId, $representations, 
$grammaticalFeatures )
+               );
+       }
+
+       private function validateDataStructure( $data ) {
+               $errors = [];
+
+               if ( !is_array( $data ) ) {
+                       return [ 'data-not-array' ];
+               }
+
+               if ( !array_key_exists( 'representations', $data ) ) {
+                       $errors[] = 'data-representations-key-missing';
+               } elseif ( !is_array( $data['representations'] ) ) {
+                       $errors[] = 'data-representations-not-array';
+               }
+
+               if ( !array_key_exists( 'grammaticalFeatures', $data ) ) {
+                       $errors[] = 'data-grammatical-features-key-missing';
+               } elseif ( !is_array( $data['grammaticalFeatures'] ) ) {
+                       $errors[] = 'data-grammatical-features-not-array';
+               }
+
+               return $errors;
+       }
+
+       /**
+        * @param string $id
+        * @return LexemeId|null
+        */
+       private function parseLexemeId( $id, array &$errors ) {
+               try {
+                       $lexemeId = $this->entityIdParser->parse( $id );
+               } catch ( EntityIdParsingException $e ) {
+                       $errors[] = [ 'lexemeid-invalid', $id ];
+                       return null;
+               }
+
+               if ( $lexemeId->getEntityType() !== 'lexeme' ) {
+                       $errors[] = [ 'lexemeid-not-lexeme-id', $id ];
+                       return null;
+               }
+
+               return $lexemeId;
+       }
+
+       private function parseRepresentations( array $data, array &$errors ) {
+               $representations = [];
+
+               foreach ( $data as $index => $representationData ) {
+                       $incomplete = false;
+
+                       if ( !array_key_exists( 'representation', 
$representationData ) ) {
+                               $errors[] = [ 'representation-text-missing', 
$index ];
+                               $incomplete = true;
+                       }
+                       if ( !array_key_exists( 'language', $representationData 
) ) {
+                               $errors[] = [ 
'representation-language-missing', $index ];
+                               $incomplete = true;
+                       }
+
+                       if ( $incomplete ) {
+                               continue;
+                       }
+
+                       $representations[] = new Term(
+                               $representationData['language'],
+                               $representationData['representation']
+                       );
+               }
+
+               if ( empty( $representations ) ) {
+                       $errors[] = 'representations-empty';
+               }
+
+               return new TermList( $representations );
+       }
+
+       private function parseGrammaticalFeatures( $data, array &$errors ) {
+               $features = [];
+
+               foreach ( $data as $index => $featureId ) {
+                       try {
+                               $id = $this->entityIdParser->parse( $featureId 
);
+                       } catch ( EntityIdParsingException $e ) {
+                               $errors[] = [ 
'grammatical-feature-itemid-invalid', $featureId ];
+                               continue;
+                       }
+
+                       if ( $id->getEntityType() !== 'item' ) {
+                               $errors[] = [ 
'grammatical-feature-not-item-id', $featureId ];
+                               continue;
+                       }
+
+                       $features[] = $id;
+               }
+
+               return $features;
+       }
+
+       private function validateRequiredFieldsPresent( array $params ) {
+               $errors = [];
+
+               if ( !array_key_exists( 'lexemeId', $params ) ) {
+                       $errors[] = 'lexemeId-param-missing';
+               }
+
+               if ( !array_key_exists( 'data', $params ) ) {
+                       $errors[] = 'data-parame-missing';
+               }
+
+               return $errors;
+       }
+
+}
diff --git a/src/Api/AddFormRequestParserResult.php 
b/src/Api/AddFormRequestParserResult.php
new file mode 100644
index 0000000..ba18383
--- /dev/null
+++ b/src/Api/AddFormRequestParserResult.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Wikibase\Lexeme\Api;
+
+/**
+ * @license GPL-2.0+
+ */
+class AddFormRequestParserResult {
+
+       private $request;
+
+       private $errors;
+
+       /**
+        * @param AddFormRequest|null $request
+        * @param string[] $errors
+        */
+       public function __construct( AddFormRequest $request = null, array 
$errors ) {
+               $this->request = $request;
+               $this->errors = $errors;
+       }
+
+       public static function newWithRequest( AddFormRequest $request ) {
+               return new self( $request, [] );
+       }
+
+       public static function newWithErrors( array $errors ) {
+               return new self( null, $errors );
+       }
+
+       public function getRequest() {
+               return $this->request;
+       }
+
+       public function hasErrors() {
+               return !empty( $this->errors );
+       }
+
+       public function getErrors() {
+               return $this->errors;
+       }
+
+}
diff --git a/tests/phpunit/mediawiki/Api/AddFormRequestParserTest.php 
b/tests/phpunit/mediawiki/Api/AddFormRequestParserTest.php
new file mode 100644
index 0000000..9f44cb7
--- /dev/null
+++ b/tests/phpunit/mediawiki/Api/AddFormRequestParserTest.php
@@ -0,0 +1,152 @@
+<?php
+
+namespace Wikibase\Lexeme\Tests\MediaWiki\Api;
+
+use Wikibase\DataModel\Entity\DispatchingEntityIdParser;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
+use Wikibase\Lexeme\Api\AddFormRequest;
+use Wikibase\Lexeme\Api\AddFormRequestParser;
+use Wikibase\Lexeme\ChangeOp\ChangeOpAddForm;
+use Wikibase\Lexeme\DataModel\LexemeId;
+
+/**
+ * @covers Wikibase\Lexeme\Api\AddFormRequestParser
+ *
+ * @group WikibaseLexeme
+ *
+ * @license GPL-2.0+
+ */
+class AddFormRequestParserTest extends \PHPUnit_Framework_TestCase {
+
+       /**
+        * @dataProvider provideInvalidParamsAndErrors
+        */
+       public function testGivenInvalidParams_parseReturnsError( array $params 
) {
+               $parser = $this->newAddFormRequestParser();
+
+               $result = $parser->parse( $params );
+
+               $this->assertTrue( $result->hasErrors() );
+       }
+
+       public function provideInvalidParamsAndErrors() {
+               $noRepresentationsInDataParams = json_encode(
+                       [ 'grammaticalFeatures' => [] ]
+               );
+               $noGrammaticalFeaturesInDataParams = json_encode(
+                       [ 'representations' => [ 'language' => 'en', 
'representation' => 'goat' ] ]
+               );
+
+               return [
+                       'no lexemeId param' => [ [ 'data' => 
$this->getDataParam() ] ],
+                       'no data param' => [ [ 'lexemeId' => 'L1' ] ],
+                       'invalid lexeme ID (random string not ID)' => [ [
+                               'lexemeId' => 'foo', 'data' => 
$this->getDataParam()
+                       ] ],
+                       'invalid lexeme ID (not a lexeme ID)' => [ [
+                               'lexemeId' => 'Q11', 'data' => 
$this->getDataParam()
+                       ] ],
+                       'data not a well-formed JSON' => [ [ 'lexemeId' => 
'L1', 'data' => '{foo' ] ],
+                       'data not an array' => [ [ 'lexemeId' => 'L1', 'data' 
=> 'foo' ] ],
+                       'no representations in data' => [ [
+                               'lexemeId' => 'L1', 'data' => 
$noRepresentationsInDataParams
+                       ] ],
+                       'no grammatical features in data' => [ [
+                               'lexemeId' => 'L1', 'data' => 
$noGrammaticalFeaturesInDataParams
+                       ] ],
+                       'representations not an array' => [ [
+                               'lexemeId' => 'L1', 'data' => 
$this->getDataParam( [ 'representations' => 'foo' ] )
+                       ] ],
+                       'grammatical features not an array' => [ [
+                               'lexemeId' => 'L1', 'data' => 
$this->getDataParam( [ 'grammaticalFeatures' => 'Q1' ] )
+                       ] ],
+                       'empty representation list in data' => [ [
+                               'lexemeId' => 'L1',
+                               'data' => $this->getDataParam( [ 
'representations' => [] ] )
+                       ] ],
+                       'no representation string in data' => [ [
+                               'lexemeId' => 'L1',
+                               'data' => $this->getDataParam( [ 
'representations' => [ [ 'language' => 'en' ] ] ] )
+                       ] ],
+                       'no representation language in data' => [ [
+                               'lexemeId' => 'L1',
+                               'data' => $this->getDataParam( [ 
'representations' => [ [ 'representation' => 'foo' ] ] ] )
+                       ] ],
+                       'invalid item ID as grammatical feature (random string 
not ID)' => [ [
+                               'lexemeId' => 'L1',
+                               'data' => $this->getDataParam(
+                                       [ 'representations' => [ [ 
'grammaticalFeatures' => [ 'foo' ] ] ] ]
+                               )
+                       ] ],
+                       'invalid item ID as grammatical feature (not an item 
ID)' => [ [
+                               'lexemeId' => 'L1',
+                               'data' => $this->getDataParam(
+                                       [ 'representations' => [ [ 
'grammaticalFeatures' => [ 'L2' ] ] ] ]
+                               )
+                       ] ],
+               ];
+       }
+
+       public function testGivenValidData_parseReturnsRequestAndNoErrors() {
+               $parser = $this->newAddFormRequestParser();
+
+               $result = $parser->parse( [ 'lexemeId' => 'L1', 'data' => 
$this->getDataParam() ] );
+
+               $this->assertInstanceOf(
+                       AddFormRequest::class,
+                       $result->getRequest()
+               );
+               $this->assertFalse( $result->hasErrors() );
+       }
+
+       public function testLexemeIdPassedToRequestObject() {
+               $parser = $this->newAddFormRequestParser();
+
+               $result = $parser->parse( [ 'lexemeId' => 'L1', 'data' => 
$this->getDataParam() ] );
+               $request = $result->getRequest();
+
+               $this->assertEquals( new LexemeId( 'L1' ), 
$request->getLexemeId() );
+       }
+
+       public function testFormDataPassedToRequestObject() {
+               $parser = $this->newAddFormRequestParser();
+
+               $result = $parser->parse( [ 'lexemeId' => 'L1', 'data' => 
$this->getDataParam() ] );
+               $request = $result->getRequest();
+
+               $this->assertEquals(
+                       new ChangeOpAddForm( new TermList( [ new Term( 'en', 
'goat' ) ] ), [ new ItemId( 'Q17' ) ] ),
+                       $request->getChangeOp()
+               );
+       }
+
+       private function getDataParam( array $dataToUse = [] ) {
+               $simpleData = [
+                       'representations' => [
+                               [
+                                       'language' => 'en',
+                                       'representation' => 'goat'
+                               ]
+                       ],
+                       'grammaticalFeatures' => [ 'Q17' ],
+               ];
+
+               return json_encode( array_merge( $simpleData, $dataToUse ) );
+       }
+
+       private function newAddFormRequestParser() {
+               $idParser = new DispatchingEntityIdParser( [
+                       ItemId::PATTERN => function ( $id ) {
+                               return new ItemId( $id );
+                       },
+                       LexemeId::PATTERN => function ( $id ) {
+                               return new LexemeId( $id );
+                       }
+               ] );
+
+               return new AddFormRequestParser( $idParser );
+       }
+
+}
diff --git a/tests/phpunit/mediawiki/Api/AddFormRequestTest.php 
b/tests/phpunit/mediawiki/Api/AddFormRequestTest.php
new file mode 100644
index 0000000..b3c852b
--- /dev/null
+++ b/tests/phpunit/mediawiki/Api/AddFormRequestTest.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Wikibase\Lexeme\Tests\MediaWiki\Api;
+
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
+use Wikibase\Lexeme\Api\AddFormRequest;
+use Wikibase\Lexeme\DataModel\LexemeId;
+use Wikibase\Lexeme\Tests\DataModel\NewLexeme;
+
+/**
+ * @covers Wikibase\Lexeme\Api\AddFormRequest
+ *
+ * @group WikibaseLexeme
+ *
+ * @license GPL-2.0+
+ */
+class AddFormRequestTest extends \PHPUnit_Framework_TestCase {
+
+       public function testReturnsChangeOpThatAddsForm() {
+               $request = new AddFormRequest(
+                       new LexemeId( 'L1' ),
+                       new TermList( [ new Term( 'en', 'goat' ) ] ),
+                       [ new ItemId( 'Q1' ) ]
+               );
+
+               $changeOp = $request->getChangeOp();
+
+               $lexeme = NewLexeme::create()->build();
+
+               $changeOp->apply( $lexeme );
+
+               $forms = $lexeme->getForms();
+
+               $this->assertCount( 1, $forms );
+               $this->assertEquals( [ 'en' => 'goat' ], 
$forms[0]->getRepresentations()->toTextArray() );
+               $this->assertEquals( [ new ItemId( 'Q1' ) ], 
$forms[0]->getGrammaticalFeatures() );
+       }
+
+       public function 
testGivenNonItemsAsGrammaticalFeatures_constructorThrowsException() {
+               $this->setExpectedException( \InvalidArgumentException::class );
+
+               new AddFormRequest(
+                       new LexemeId( 'L1' ),
+                       new TermList( [ new Term( 'en', 'goat' ) ] ),
+                       [ 'foo' ]
+               );
+       }
+
+       public function 
testGivenEmptyRepresentationList_constructorThrowsException() {
+               $this->setExpectedException( \InvalidArgumentException::class );
+
+               new AddFormRequest( new LexemeId( 'L1' ), new TermList(), [] );
+       }
+
+       public function testGetLexemeId() {
+               $lexemeId = new LexemeId( 'L1' );
+
+               $request = new AddFormRequest( $lexemeId, new TermList( [ new 
Term( 'en', 'goat' ) ] ), [] );
+
+               $this->assertSame( $lexemeId, $request->getLexemeId() );
+       }
+
+}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic593fcd9922f732036d7c5bdda4088887aa64928
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/WikibaseLexeme
Gerrit-Branch: master
Gerrit-Owner: WMDE-leszek <[email protected]>
Gerrit-Reviewer: Aleksey Bekh-Ivanov (WMDE) <[email protected]>
Gerrit-Reviewer: WMDE-leszek <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to