jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/403449 )
Change subject: Added tests for classes related to EditFormElements API
......................................................................
Added tests for classes related to EditFormElements API
Bug: T184409
Change-Id: I947034388daaea34129d62a5fcc035c361587f0a
---
A tests/phpunit/mediawiki/Api/EditFormElementsRequestParserResultTest.php
A tests/phpunit/mediawiki/Api/EditFormElementsRequestParserTest.php
A tests/phpunit/mediawiki/Api/EditFormElementsRequestTest.php
A tests/phpunit/mediawiki/ChangeOp/ChangeOpEditFormElementsTest.php
4 files changed, 482 insertions(+), 0 deletions(-)
Approvals:
WMDE-leszek: Looks good to me, approved
jenkins-bot: Verified
diff --git
a/tests/phpunit/mediawiki/Api/EditFormElementsRequestParserResultTest.php
b/tests/phpunit/mediawiki/Api/EditFormElementsRequestParserResultTest.php
new file mode 100644
index 0000000..ee38c97
--- /dev/null
+++ b/tests/phpunit/mediawiki/Api/EditFormElementsRequestParserResultTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Wikibase\Lexeme\Tests\MediaWiki\Api;
+
+use Wikibase\Lexeme\Api\EditFormElementsRequest;
+use Wikibase\Lexeme\Api\EditFormElementsRequestParserResult;
+use Wikibase\Lexeme\Api\Error\ApiError;
+
+/**
+ * @covers \Wikibase\Lexeme\Api\EditFormElementsRequestParserResult
+ *
+ * @license GPL-2.0+
+ */
+class EditFormElementsRequestParserResultTest extends
\PHPUnit_Framework_TestCase {
+
+ public function testGivenThereAreErrors_getRequestThrowsException() {
+ $result = EditFormElementsRequestParserResult::newWithErrors( [
$this->newApiError() ] );
+
+ $this->setExpectedException( \Exception::class );
+
+ $result->getRequest();
+ }
+
+ public function
testGivenResultIsSuccessful_asFatalStatusThrowsException() {
+ $result = EditFormElementsRequestParserResult::newWithRequest(
$this->newRequest() );
+
+ $this->setExpectedException( \Exception::class );
+ $result->asFatalStatus();
+ }
+
+ public function
testGivenThereAreErrors_asFatalStatusReturnsFatalStatusWithTheErrorMessages() {
+ $error1 = $this->newApiError();
+ $error2 = $this->newApiError();
+ $result = EditFormElementsRequestParserResult::newWithErrors( [
$error1, $error2 ] );
+
+ $status = $result->asFatalStatus();
+
+ $this->assertTrue( !$status->isGood(), "Status is not fatal" );
+ $gotErrors = $status->getErrors();
+ assertThat( $gotErrors, hasItem( hasKeyValuePair( 'message',
$error1->asApiMessage() ) ) );
+ assertThat( $gotErrors, hasItem( hasKeyValuePair( 'message',
$error2->asApiMessage() ) ) );
+ }
+
+ public function
testCanNotCreateOnlyWithArrayContainingNotAnApiErrorInstance() {
+ $this->setExpectedException( \InvalidArgumentException::class );
+ EditFormElementsRequestParserResult::newWithErrors( [ 'error' ]
);
+ }
+
+ /**
+ * @return ApiError
+ */
+ public function newApiError() {
+ /** @var ApiError|\Prophecy\Prophecy\ObjectProphecy $error */
+ $error = $this->prophesize( ApiError::class );
+ $error->asApiMessage()
+ ->willReturn( $this->prophesize( \ApiMessage::class
)->reveal() );
+
+ return $error->reveal();
+ }
+
+ /**
+ * @return EditFormElementsRequest
+ */
+ private function newRequest() {
+ return $this->prophesize( EditFormElementsRequest::class
)->reveal();
+ }
+
+}
diff --git a/tests/phpunit/mediawiki/Api/EditFormElementsRequestParserTest.php
b/tests/phpunit/mediawiki/Api/EditFormElementsRequestParserTest.php
new file mode 100644
index 0000000..f6cfd72
--- /dev/null
+++ b/tests/phpunit/mediawiki/Api/EditFormElementsRequestParserTest.php
@@ -0,0 +1,316 @@
+<?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\EditFormElementsRequestParser;
+use Wikibase\Lexeme\Api\EditFormElementsRequestParserResult;
+use Wikibase\Lexeme\Api\Error\ApiError;
+use Wikibase\Lexeme\Api\Error\FormMustHaveAtLeastOneRepresentation;
+use Wikibase\Lexeme\Api\Error\JsonFieldHasWrongType;
+use Wikibase\Lexeme\Api\Error\JsonFieldIsNotAnItemId;
+use Wikibase\Lexeme\Api\Error\JsonFieldIsRequired;
+use Wikibase\Lexeme\Api\Error\ParameterIsNotAJsonObject;
+use Wikibase\Lexeme\Api\Error\ParameterIsNotFormId;
+use Wikibase\Lexeme\Api\Error\ParameterIsRequired;
+use Wikibase\Lexeme\Api\Error\RepresentationLanguageCanNotBeEmpty;
+use Wikibase\Lexeme\Api\Error\RepresentationsMustHaveUniqueLanguage;
+use Wikibase\Lexeme\Api\Error\RepresentationTextCanNotBeEmpty;
+use Wikibase\Lexeme\ChangeOp\ChangeOpEditFormElements;
+use Wikibase\Lexeme\DataModel\FormId;
+
+/**
+ * @covers \Wikibase\Lexeme\Api\EditFormElementsRequestParser
+ *
+ * @license GPL-2.0+
+ */
+class EditFormElementsRequestParserTest extends \PHPUnit_Framework_TestCase {
+
+ const DEFAULT_REPRESENTATION = 'colour';
+ const DEFAULT_REPRESENTATION_LANGUAGE = 'en';
+ const DEFAULT_GRAMMATICAL_FEATURE = 'Q17';
+ const DEFAULT_FORM_ID = 'L1-F1';
+
+ /**
+ * @dataProvider provideInvalidParamsAndRespectiveErrors
+ */
+ public function testGivenInvalidParams_parseReturnsError(
+ array $params,
+ array $expectedErrors
+ ) {
+ $parser = $this->newRequestParser();
+
+ $result = $parser->parse( $params );
+
+ $this->assertTrue( $result->hasErrors(), 'Result doesn not
contain errors, but should' );
+ foreach ( $expectedErrors as $expectedError ) {
+ $this->assertResultContainsError( $result,
$expectedError );
+ }
+ }
+
+ public function provideInvalidParamsAndRespectiveErrors() {
+ $noRepresentationsInDataParams = json_encode(
+ [ 'grammaticalFeatures' => [] ]
+ );
+ $noGrammaticalFeaturesInDataParams = json_encode(
+ [ 'representations' => [ 'language' => 'en',
'representation' => 'goat' ] ]
+ );
+
+ return [
+ 'no formId param' => [
+ [ 'data' => $this->getDataParam() ],
+ [ new ParameterIsRequired( 'formId' ) ]
+ ],
+ 'no data param' => [
+ [ 'formId' => self::DEFAULT_FORM_ID ],
+ [ new ParameterIsRequired( 'data' ) ]
+ ],
+ 'invalid form ID (random string not ID)' => [
+ [ 'formId' => 'foo', 'data' =>
$this->getDataParam() ],
+ [ new ParameterIsNotFormId( 'formId', 'foo' ) ]
+ ],
+ 'invalid form ID (not a form ID)' => [
+ [ 'formId' => 'Q11', 'data' =>
$this->getDataParam() ],
+ [ new ParameterIsNotFormId( 'formId', 'Q11' ) ]
+ ],
+ 'invalid form ID (no lexeme part in the ID)' => [
+ [ 'formId' => 'F1', 'data' =>
$this->getDataParam() ],
+ [ new ParameterIsNotFormId( 'formId', 'F1' ) ]
+ ],
+ 'data not a well-formed JSON' => [
+ [ 'formId' => self::DEFAULT_FORM_ID, 'data' =>
'{foo' ],
+ [ new ParameterIsNotAJsonObject( 'data', '{foo'
) ]
+ ],
+ 'data not an object - string given' => [
+ [ 'formId' => self::DEFAULT_FORM_ID, 'data' =>
'"foo"' ],
+ [ new ParameterIsNotAJsonObject( 'data',
'"foo"' ) ]
+ ],
+ 'data not an object - array given' => [
+ [ 'formId' => self::DEFAULT_FORM_ID, 'data' =>
'[]' ],
+ [ new ParameterIsNotAJsonObject( 'data', '[]' )
]
+ ],
+ 'no representations in data' => [
+ [ 'formId' => self::DEFAULT_FORM_ID, 'data' =>
$noRepresentationsInDataParams ],
+ [ new JsonFieldIsRequired( 'data', [
'representations' ] ) ]
+ ],
+ 'no grammatical features in data' => [
+ [ 'formId' => self::DEFAULT_FORM_ID, 'data' =>
$noGrammaticalFeaturesInDataParams ],
+ [ new JsonFieldIsRequired( 'data', [
'grammaticalFeatures' ] ) ]
+ ],
+ 'representations is a string' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam( [
'representations' => 'foo' ] )
+ ],
+ [ new JsonFieldHasWrongType( 'data', [
'representations' ], 'array', 'string' ) ]
+ ],
+ 'representations is an object' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam( [
'representations' => [ 'foo' => 'bar' ] ] )
+ ],
+ [ new JsonFieldHasWrongType( 'data', [
'representations' ], 'array', 'object' ) ]
+ ],
+ 'grammatical features not an array' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam( [
'grammaticalFeatures' => 'Q1' ] )
+ ],
+ [ new JsonFieldHasWrongType(
+ 'data', [ 'grammaticalFeatures' ],
'array', 'string'
+ ) ]
+ ],
+ 'empty representation list in data' => [
+ [ 'formId' => self::DEFAULT_FORM_ID, 'data' =>
$this->getDataParam(
+ [ 'representations' => [] ]
+ ) ],
+ [ new FormMustHaveAtLeastOneRepresentation(
'data', [ 'representations' ] ) ]
+ ],
+ 'representation list contains only single empty
representation' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'representations' => [ [
'representation' => '', 'language' => 'en' ] ] ]
+ )
+ ],
+ [ new RepresentationTextCanNotBeEmpty( 'data',
[ 'representations', 0, 'representation' ] ) ]
+ ],
+ 'representation list contains only representation with
empty language' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'representations' => [ [
'representation' => 'goat', 'language' => '' ] ] ]
+ )
+ ],
+ [ new RepresentationLanguageCanNotBeEmpty(
'data', [ 'representations', 0, 'language' ] ) ]
+ ],
+ 'no representation string in data' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'representations' => [ [
'language' => 'en' ] ] ]
+ )
+ ],
+ [ new JsonFieldIsRequired( 'data', [
'representations', 0, 'representation' ] ) ]
+ ],
+ 'no representation language in data' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'representations' => [ [
'representation' => 'foo' ] ] ]
+ )
+ ],
+ [ new JsonFieldIsRequired( 'data', [
'representations', 0, 'language' ] ) ]
+ ],
+ 'two representations with the same language' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'representations' => [
+ [ 'representation' =>
'r1', 'language' => 'en' ],
+ [ 'representation' =>
'r2', 'language' => 'fr' ],
+ [ 'representation' =>
'r3', 'language' => 'en' ],
+ ] ]
+ )
+ ],
+ [ new RepresentationsMustHaveUniqueLanguage(
+ 'data',
+ [ 'representations', 2, 'language' ],
+ 'en'
+ ) ]
+ ],
+ 'invalid item ID as grammatical feature (random string
not ID)' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'grammaticalFeatures' => [
'foo' ] ]
+ )
+ ],
+ [ new JsonFieldIsNotAnItemId(
+ 'data',
+ [ 'grammaticalFeatures', 0 ],
+ 'foo'
+ ) ]
+ ],
+ 'invalid item ID as grammatical feature (not an item
ID)' => [
+ [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam(
+ [ 'grammaticalFeatures' => [
'L2' ] ]
+ )
+ ] ,
+ [ new JsonFieldIsNotAnItemId(
+ 'data',
+ [ 'grammaticalFeatures', 0 ],
+ 'L2'
+ ) ] ],
+ ];
+ }
+
+ public function
testGivenOneRepresentationMissingText_parseReturnsRequestWithOnlyThisError() {
+ $data = [
+ 'representations' => [
+ [
+ 'language' =>
self::DEFAULT_REPRESENTATION_LANGUAGE,
+ 'representation' => ''
+ ]
+ ],
+ 'grammaticalFeatures' => [],
+ ];
+
+ $parser = $this->newRequestParser();
+ $result = $parser->parse( [ 'formId' => self::DEFAULT_FORM_ID,
'data' => json_encode( $data ) ] );
+
+ $errors = $result->asFatalStatus()->getErrors();
+ $this->assertCount( 1, $errors );
+ $expectedError = new RepresentationTextCanNotBeEmpty(
+ 'data',
+ [ 'representations', 0, 'representation' ]
+ );
+ $this->assertResultContainsError( $result, $expectedError );
+ }
+
+ public function testGivenValidData_parseReturnsRequestAndNoErrors() {
+ $parser = $this->newRequestParser();
+
+ $result = $parser->parse( [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam()
+ ] );
+
+ $this->assertFalse( $result->hasErrors() );
+ }
+
+ public function testFormIdGetsPassedToRequestObject() {
+ $parser = $this->newRequestParser();
+
+ $result = $parser->parse( [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam()
+ ] );
+ $request = $result->getRequest();
+
+ $this->assertEquals( new FormId( self::DEFAULT_FORM_ID ),
$request->getFormId() );
+ }
+
+ public function testFormDataGetsPassedToRequestObject() {
+ $parser = $this->newRequestParser();
+
+ $result = $parser->parse( [
+ 'formId' => self::DEFAULT_FORM_ID,
+ 'data' => $this->getDataParam()
+ ] );
+ $request = $result->getRequest();
+
+ $this->assertEquals(
+ new ChangeOpEditFormElements(
+ new TermList(
+ [ new Term(
self::DEFAULT_REPRESENTATION_LANGUAGE, self::DEFAULT_REPRESENTATION ) ]
+ ),
+ [ new ItemId( self::DEFAULT_GRAMMATICAL_FEATURE
) ]
+ ),
+ $request->getChangeOp()
+ );
+ }
+
+ private function getDataParam( array $dataToUse = [] ) {
+ $simpleData = [
+ 'representations' => [
+ [
+ 'language' =>
self::DEFAULT_REPRESENTATION_LANGUAGE,
+ 'representation' =>
self::DEFAULT_REPRESENTATION,
+ ]
+ ],
+ 'grammaticalFeatures' => [
self::DEFAULT_GRAMMATICAL_FEATURE ],
+ ];
+
+ return json_encode( array_merge( $simpleData, $dataToUse ) );
+ }
+
+ private function newRequestParser() {
+ $idParser = new DispatchingEntityIdParser( [
+ FormId::PATTERN => function ( $id ) {
+ return new FormId( $id );
+ }
+ ] );
+
+ return new EditFormElementsRequestParser( $idParser );
+ }
+
+ private function assertResultContainsError(
+ EditFormElementsRequestParserResult $result,
+ ApiError $expectedError
+ ) {
+ $status = $result->asFatalStatus();
+ $errors = $status->getErrors();
+
+ assertThat(
+ $errors,
+ hasItem( hasKeyValuePair( 'message',
$expectedError->asApiMessage() ) )
+ );
+ }
+
+}
diff --git a/tests/phpunit/mediawiki/Api/EditFormElementsRequestTest.php
b/tests/phpunit/mediawiki/Api/EditFormElementsRequestTest.php
new file mode 100644
index 0000000..7771fa6
--- /dev/null
+++ b/tests/phpunit/mediawiki/Api/EditFormElementsRequestTest.php
@@ -0,0 +1,42 @@
+<?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\EditFormElementsRequest;
+use Wikibase\Lexeme\DataModel\Form;
+use Wikibase\Lexeme\DataModel\FormId;
+
+/**
+ * @covers \Wikibase\Lexeme\Api\EditFormElementsRequest
+ *
+ * @license GPL-2.0+
+ */
+class EditFormElementsRequestTest extends \PHPUnit_Framework_TestCase {
+
+ public function testReturnsChangeOpThatChangesFormElements() {
+ $formId = new FormId( 'L1-F1' );
+ $colorWithoutU = new Term( 'en', 'color' );
+ $colorWithU = new Term( 'en', 'colour' );
+ $featureOne = new ItemId( 'Q1' );
+ $featureTwo = new ItemId( 'Q2' );
+
+ $form = new Form( $formId, new TermList( [ $colorWithoutU ] ),
[ $featureOne ] );
+
+ $request = new EditFormElementsRequest(
+ new FormId( 'L1-F1' ),
+ new TermList( [ $colorWithU ] ),
+ [ $featureTwo ]
+ );
+
+ $changeOp = $request->getChangeOp();
+
+ $changeOp->apply( $form );
+
+ $this->assertEquals( $colorWithU,
$form->getRepresentations()->getByLanguage( 'en' ) );
+ $this->assertEquals( [ $featureTwo ],
$form->getGrammaticalFeatures() );
+ }
+
+}
diff --git a/tests/phpunit/mediawiki/ChangeOp/ChangeOpEditFormElementsTest.php
b/tests/phpunit/mediawiki/ChangeOp/ChangeOpEditFormElementsTest.php
new file mode 100644
index 0000000..0f87588
--- /dev/null
+++ b/tests/phpunit/mediawiki/ChangeOp/ChangeOpEditFormElementsTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Wikibase\Lexeme\Tests\MediaWiki\ChangeOp;
+
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
+use Wikibase\Lexeme\ChangeOp\ChangeOpEditFormElements;
+use Wikibase\Lexeme\Tests\DataModel\NewForm;
+use Wikibase\Repo\Tests\NewItem;
+
+/**
+ * @covers \Wikibase\Lexeme\ChangeOp\ChangeOpEditFormElements
+ *
+ * @license GPL-2.0+
+ */
+class ChangeOpEditFormElementsTest extends \PHPUnit_Framework_TestCase {
+
+ public function test_validateFailsIfProvidedEntityIsNotAForm() {
+ $changeOp = new ChangeOpEditFormElements( new TermList(), [] );
+
+ $this->setExpectedException( \InvalidArgumentException::class );
+ $changeOp->validate( NewItem::withId( 'Q1' )->build() );
+ }
+
+ public function test_validatePassesIfProvidedEntityIsAForm() {
+ $changeOp = new ChangeOpEditFormElements( new TermList(), [] );
+
+ $result = $changeOp->validate( NewForm::any()->build() );
+
+ $this->assertTrue( $result->isValid() );
+ }
+
+ public function test_applyFailsIfProvidedEntityIsNotAForm() {
+ $changeOp = new ChangeOpEditFormElements( new TermList(), [] );
+
+ $this->setExpectedException( \InvalidArgumentException::class );
+ $changeOp->apply( NewItem::withId( 'Q1' )->build() );
+ }
+
+ // TODO: Probably might be preferred to have this split to
add/change/remove cases?
+ public function test_applyChangesFormElements() {
+ $representations = new TermList( [ new Term( 'en', 'goat' ) ] );
+ $changeOp = new ChangeOpEditFormElements( $representations, [
new ItemId( 'Q1000' ) ] );
+ $form = NewForm::havingRepresentation( 'en', 'cat' )
+ ->andGrammaticalFeature( 'Q1' )
+ ->build();
+
+ $changeOp->apply( $form );
+
+ $this->assertEquals( $representations,
$form->getRepresentations() );
+ $this->assertEquals( [ new ItemId( 'Q1000' ) ],
$form->getGrammaticalFeatures() );
+ }
+
+ // TODO: Test the summary is set as specified, once specified
+}
--
To view, visit https://gerrit.wikimedia.org/r/403449
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I947034388daaea34129d62a5fcc035c361587f0a
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/WikibaseLexeme
Gerrit-Branch: master
Gerrit-Owner: WMDE-leszek <[email protected]>
Gerrit-Reviewer: Ladsgroup <[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