Skip to content

Commit 1078673

Browse files
jenkins-botGerrit Code Review
authored andcommitted
Merge "GQL: Support EntityId value type"
2 parents a621add + f5315fa commit 1078673

File tree

6 files changed

+84
-3
lines changed

6 files changed

+84
-3
lines changed

repo/WikibaseRepo.datatypes.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,9 @@
494494
'search-index-data-formatter-callback' => function ( EntityIdValue $value ) {
495495
return $value->getEntityId()->getSerialization();
496496
},
497+
'graphql-value-type' => static function() {
498+
return WbReuse::getEntityValueType();
499+
},
497500
],
498501
'PT:wikibase-item' => [
499502
'expert-module' => 'wikibase.experts.Item',

repo/domains/reuse/src/Infrastructure/GraphQL/schema.graphql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ type PredicateProperty {
5252
label(languageCode: LanguageCode!): String
5353
}
5454

55-
union Value = StringValue | ItemValue | PropertyValue | GlobeCoordinateValue | MonolingualTextValue | QuantityValue | TimeValue
55+
union Value = StringValue | ItemValue | PropertyValue | GlobeCoordinateValue | MonolingualTextValue | QuantityValue | TimeValue | EntityValue
5656

5757
type StringValue {
5858
content: String!
@@ -96,6 +96,10 @@ type TimeValue {
9696
calendarModel: String!
9797
}
9898

99+
type EntityValue {
100+
id: String!
101+
}
102+
99103
enum ValueType {
100104
novalue
101105
somevalue

repo/domains/reuse/src/WbReuse.ServiceWiring.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
<?php declare( strict_types=1 );
22

3+
use GraphQL\Type\Definition\ObjectType;
4+
use GraphQL\Type\Definition\ResolveInfo;
5+
use GraphQL\Type\Definition\Type;
36
use MediaWiki\MediaWikiServices;
47
use Wikibase\Repo\Domains\Reuse\Application\UseCases\BatchGetItemLabels\BatchGetItemLabels;
58
use Wikibase\Repo\Domains\Reuse\Application\UseCases\BatchGetItems\BatchGetItems;
69
use Wikibase\Repo\Domains\Reuse\Application\UseCases\BatchGetPropertyLabels\BatchGetPropertyLabels;
10+
use Wikibase\Repo\Domains\Reuse\Domain\Model\PropertyValuePair;
11+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
712
use Wikibase\Repo\Domains\Reuse\Domain\Services\StatementReadModelConverter;
813
use Wikibase\Repo\Domains\Reuse\Infrastructure\DataAccess\EntityLookupItemsBatchRetriever;
914
use Wikibase\Repo\Domains\Reuse\Infrastructure\DataAccess\PrefetchingTermLookupBatchLabelsRetriever;
@@ -26,6 +31,17 @@
2631

2732
/** @phpcs-require-sorted-array */
2833
return [
34+
'WbReuse.EntityValueType' => function( MediaWikiServices $services ): ObjectType {
35+
return new ObjectType( [
36+
'name' => 'EntityValue',
37+
'fields' => [ 'id' => Type::nonNull( Type::string() ) ],
38+
'resolveField' => function( Statement|PropertyValuePair $valueProvider, $args, $context, ResolveInfo $info ) {
39+
40+
return $valueProvider->value->content
41+
->getArrayValue()[ $info->fieldName ] ?? null;
42+
},
43+
] );
44+
},
2945
'WbReuse.GraphQLSchema' => function( MediaWikiServices $services ): Schema {
3046
$languageCodeType = WbReuse::getLanguageCodeType( $services );
3147
$predicatePropertyType = new PredicatePropertyType(

repo/domains/reuse/src/WbReuse.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Wikibase\Repo\Domains\Reuse;
44

5+
use GraphQL\Type\Definition\ObjectType;
56
use MediaWiki\MediaWikiServices;
67
use Psr\Container\ContainerInterface;
78
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\GraphQLService;
@@ -44,4 +45,9 @@ public static function getStringValueType( ?ContainerInterface $services = null
4445
return ( $services ?: MediaWikiServices::getInstance() )
4546
->get( 'WbReuse.StringValueType' );
4647
}
48+
49+
public static function getEntityValueType( ?ContainerInterface $services = null ): ObjectType {
50+
return ( $services ?: MediaWikiServices::getInstance() )
51+
->get( 'WbReuse.EntityValueType' );
52+
}
4753
}

repo/domains/reuse/tests/phpunit/Infrastructure/GraphQL/GraphQLServiceTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use MediaWikiIntegrationTestCase;
1919
use Wikibase\DataAccess\PrefetchingTermLookup;
2020
use Wikibase\DataAccess\Tests\InMemoryPrefetchingTermLookup;
21+
use Wikibase\DataModel\Entity\EntityId;
2122
use Wikibase\DataModel\Entity\EntityIdValue;
2223
use Wikibase\DataModel\Entity\Item;
2324
use Wikibase\DataModel\Entity\ItemId;
@@ -60,8 +61,10 @@ class GraphQLServiceTest extends MediaWikiIntegrationTestCase {
6061
private static Property $propertyTypeProperty;
6162
private static Property $propertyUsedAsValue;
6263
private static Property $qualifierProperty;
64+
private static Property $customEntityIdProperty;
6365
private static MediaWikiSite $sitelinkSite;
6466
private const ALLOWED_SITELINK_SITES = [ 'examplewiki', 'otherwiki' ];
67+
private const CUSTOM_ENTITY_DATA_TYPE = 'test-type';
6568

6669
public static function setUpBeforeClass(): void {
6770
if ( !class_exists( GraphQL::class ) ) {
@@ -99,6 +102,7 @@ public function testQuery( string $query, array $expectedResult ): void {
99102
self::$quantityProperty,
100103
self::$timeProperty,
101104
self::$propertyTypeProperty,
105+
self::$customEntityIdProperty,
102106
] as $property ) {
103107
$dataTypeLookup->setDataTypeForProperty( $property->getId(), $property->getDataTypeId() );
104108
}
@@ -146,6 +150,7 @@ public function queryProvider(): Generator {
146150
$statementWithQuantityValuePropertyId = 'P8';
147151
$statementWithTimeValuePropertyId = 'P9';
148152
$statementWithPropertyValuePropertyId = 'P10';
153+
$statementWithCustomEntityIdValuePropertyId = 'P13';
149154
$statementWithItemValueQualifierPropertyId = $statementWithItemValuePropertyId; // also type wikibase-item so we can just reuse it.
150155
$statementReferencePropertyId = 'P11';
151156
$unusedPropertyId = 'P9999';
@@ -231,6 +236,16 @@ public function queryProvider(): Generator {
231236
->withSomeGuid()
232237
->build();
233238

239+
$customEntityId = $this->createMock( EntityId::class );
240+
$customEntityId->method( 'getSerialization' )
241+
->willReturn( 'T3' );
242+
$entityIdValue = new EntityIdValue( $customEntityId );
243+
$statementWithCustomEntityIdValue = NewStatement::forProperty( $statementWithCustomEntityIdValuePropertyId )
244+
->withSubject( $itemId )
245+
->withSomeGuid()
246+
->withValue( $entityIdValue )
247+
->build();
248+
234249
self::$sitelinkSite = new MediaWikiSite();
235250
self::$sitelinkSite->setLinkPath( 'https://wiki.example/wiki/$1' );
236251
$expectedSitelinkUrl = "https://wiki.example/wiki/$sitelinkTitle";
@@ -272,6 +287,11 @@ public function queryProvider(): Generator {
272287
new Fingerprint( new TermList( [ new Term( 'en', 'qualifier prop' ) ] ) ),
273288
'string',
274289
);
290+
self::$customEntityIdProperty = new Property(
291+
new NumericPropertyId( $statementWithCustomEntityIdValuePropertyId ),
292+
null,
293+
self::CUSTOM_ENTITY_DATA_TYPE
294+
);
275295

276296
self::$item1 = NewItem::withId( $itemId )
277297
->andLabel( 'en', $enLabel )
@@ -288,6 +308,7 @@ public function queryProvider(): Generator {
288308
->andStatement( $statementWithPropertyValue )
289309
->andStatement( $statementWithNoValue )
290310
->andStatement( $statementWithSomeValue )
311+
->andStatement( $statementWithCustomEntityIdValue )
291312
->build();
292313

293314
$item2Id = 'Q321';
@@ -704,6 +725,22 @@ public function queryProvider(): Generator {
704725
],
705726
],
706727
];
728+
yield 'entity id value for which there is no data type specific GraphQL type' => [
729+
"{ item(id: \"$itemId\") {
730+
statements(propertyId: \"{$statementWithCustomEntityIdValuePropertyId}\") {
731+
value {... on EntityValue { id } }
732+
}
733+
} }",
734+
[
735+
'data' => [
736+
'item' => [
737+
'statements' => [
738+
[ 'value' => [ 'id' => $entityIdValue->getEntityId()->getSerialization() ] ],
739+
],
740+
],
741+
],
742+
],
743+
];
707744
yield 'multiple items at once' => [
708745
"{
709746
item1: item(id: \"$itemId\") { label(languageCode: \"en\") }
@@ -804,6 +841,13 @@ private function newGraphQLService(
804841
$termLookup ?? $this->createStub( PrefetchingTermLookup::class ),
805842
);
806843

844+
$this->setTemporaryHook( 'WikibaseRepoDataTypes', function ( array &$dataTypes ): void {
845+
$dataTypes['PT:' . self::CUSTOM_ENTITY_DATA_TYPE] = [
846+
'value-type' => 'wikibase-entityid',
847+
];
848+
} );
849+
$this->resetServices();
850+
807851
return WbReuse::getGraphQLService();
808852
}
809853
}

repo/domains/reuse/tests/phpunit/Infrastructure/GraphQL/SchemaTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use GraphQL\GraphQL;
66
use GraphQL\Utils\SchemaPrinter;
7-
use PHPUnit\Framework\TestCase;
7+
use MediaWikiIntegrationTestCase;
88
use Wikibase\Repo\Domains\Reuse\WbReuse;
99

1010
/**
@@ -14,7 +14,7 @@
1414
*
1515
* @license GPL-2.0-or-later
1616
*/
17-
class SchemaTest extends TestCase {
17+
class SchemaTest extends MediaWikiIntegrationTestCase {
1818

1919
public static function setUpBeforeClass(): void {
2020
if ( !class_exists( GraphQL::class ) ) {
@@ -23,6 +23,14 @@ public static function setUpBeforeClass(): void {
2323
}
2424

2525
public function testSchemaIsUpToDate(): void {
26+
// This ensures that there is at least one data type using the generic EntityValue type to avoid generating different schemas
27+
// based on the available extensions on the test system.
28+
$this->setTemporaryHook( 'WikibaseRepoDataTypes', function ( array &$dataTypes ): void {
29+
$dataTypes[ 'PT:some-other-entity-type' ] = [
30+
'value-type' => 'wikibase-entityid',
31+
];
32+
} );
33+
2634
$this->assertSame(
2735
SchemaPrinter::doPrint( WbReuse::getGraphQLSchema() ),
2836
file_get_contents( __DIR__ . '/../../../../src/Infrastructure/GraphQL/schema.graphql' ),

0 commit comments

Comments
 (0)