Skip to content

Commit 160c3df

Browse files
committed
GQL: Handle invalid Item ID and Item not found
Bug: T400473 Change-Id: Iaafd19eb5cc067326862cd3cc0eef4e1ec657e60
1 parent ac0fa7c commit 160c3df

File tree

6 files changed

+85
-2
lines changed

6 files changed

+85
-2
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php declare( strict_types=1 );
2+
3+
namespace Wikibase\Repo\GraphQLPrototype;
4+
5+
use GraphQL\Error\ClientAware;
6+
7+
/**
8+
* @license GPL-2.0-or-later
9+
*/
10+
class InvalidItemId extends \Exception implements ClientAware {
11+
public function isClientSafe(): bool {
12+
return true;
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php declare( strict_types=1 );
2+
3+
namespace Wikibase\Repo\GraphQLPrototype;
4+
5+
use GraphQL\Error\ClientAware;
6+
7+
/**
8+
* @license GPL-2.0-or-later
9+
*/
10+
class ItemNotFound extends \Exception implements ClientAware {
11+
public function isClientSafe(): bool {
12+
return true;
13+
}
14+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php declare( strict_types=1 );
2+
3+
namespace Wikibase\Repo\GraphQLPrototype;
4+
5+
use InvalidArgumentException;
6+
use Wikibase\DataModel\Entity\ItemId;
7+
use Wikibase\DataModel\Services\Lookup\EntityLookup;
8+
9+
/**
10+
* @license GPL-2.0-or-later
11+
*/
12+
class ItemResolver {
13+
public function __construct( private EntityLookup $entityLookup ) {
14+
}
15+
16+
/**
17+
* @throws InvalidItemId
18+
* @throws ItemNotFound
19+
*/
20+
public function fetchItem( string $itemId ): array {
21+
try {
22+
$parsedId = new ItemId( $itemId );
23+
} catch ( InvalidArgumentException ) {
24+
throw new InvalidItemId( "Invalid Item ID: '$itemId'." );
25+
}
26+
27+
if ( !$this->entityLookup->hasEntity( $parsedId ) ) {
28+
throw new ItemNotFound( "Item '$parsedId' does not exist." );
29+
}
30+
31+
return [ 'id' => $parsedId->getSerialization() ];
32+
}
33+
}

repo/includes/GraphQLPrototype/Schema.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public function __construct(
1919
private ContentLanguages $labelLanguages,
2020
private LabelsResolver $labelsResolver,
2121
private StatementsResolver $statementsResolver,
22+
private ItemResolver $itemResolver,
2223
) {
2324
parent::__construct( [
2425
'query' => new ObjectType( [
@@ -29,7 +30,7 @@ public function __construct(
2930
'args' => [
3031
'id' => Type::nonNull( Type::string() ),
3132
],
32-
'resolve' => fn( $rootValue, array $args ) => [ 'id' => $args['id'] ],
33+
'resolve' => fn( $rootValue, array $args ) => $this->itemResolver->fetchItem( $args['id'] ),
3334
],
3435
],
3536
] ),

repo/includes/GraphQLPrototype/SpecialWikibaseGraphQL.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public function __construct(
2525
$termLanguages,
2626
new LabelsResolver( $termLookup ),
2727
new StatementsResolver( $entityLookup ),
28+
new ItemResolver( $entityLookup )
2829
) );
2930
}
3031

repo/tests/phpunit/includes/GraphQLPrototype/GraphQLQueryServiceTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Wikibase\DataModel\Tests\NewItem;
1414
use Wikibase\DataModel\Tests\NewStatement;
1515
use Wikibase\Repo\GraphQLPrototype\GraphQLQueryService;
16+
use Wikibase\Repo\GraphQLPrototype\ItemResolver;
1617
use Wikibase\Repo\GraphQLPrototype\LabelsResolver;
1718
use Wikibase\Repo\GraphQLPrototype\Schema;
1819
use Wikibase\Repo\GraphQLPrototype\StatementsResolver;
@@ -122,11 +123,30 @@ public function testStatementsQueryWithPropertyLabels(): void {
122123
);
123124
}
124125

126+
public function testInvalidItemId(): void {
127+
$result = $this->newGraphQLService()->query( 'query { item(id: "X123") { id } }' );
128+
$this->assertSame(
129+
"Invalid Item ID: 'X123'.",
130+
$result['errors'][0]['message']
131+
);
132+
}
133+
134+
public function testItemNotFound(): void {
135+
$result = $this->newGraphQLService()->query( 'query { item(id: "Q999999") { id } }' );
136+
$this->assertSame(
137+
"Item 'Q999999' does not exist.",
138+
$result['errors'][0]['message']
139+
);
140+
}
141+
125142
public function newGraphQLService(): GraphQLQueryService {
143+
$entityLookup = WikibaseRepo::getEntityLookup();
144+
126145
return new GraphQLQueryService( new Schema(
127146
WikibaseRepo::getTermsLanguages(),
128147
new LabelsResolver( WikibaseRepo::getPrefetchingTermLookup() ),
129-
new StatementsResolver( WikibaseRepo::getEntityLookup() )
148+
new StatementsResolver( $entityLookup ),
149+
new ItemResolver( $entityLookup ),
130150
) );
131151
}
132152

0 commit comments

Comments
 (0)