Skip to content

Commit b3b8c5b

Browse files
authored
Serialize valid \BackedEnum values in GraphQL\Type\Definition\PhpEnumType
1 parent 738132c commit b3b8c5b

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ You can find and compare releases at the [GitHub release page](https://github.co
99

1010
## Unreleased
1111

12+
## v15.13.0
13+
14+
### Added
15+
16+
- Serialize valid `\BackedEnum` values in `GraphQL\Type\Definition\PhpEnumType` https://github.com/webonyx/graphql-php/pull/1604
17+
1218
## v15.12.5
1319

1420
### Fixed

src/Type/Definition/PhpEnumType.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
use GraphQL\Utils\PhpDoc;
77
use GraphQL\Utils\Utils;
88

9-
/**
10-
* @phpstan-import-type PartialEnumValueConfig from EnumType
11-
*/
9+
/** @phpstan-import-type PartialEnumValueConfig from EnumType */
1210
class PhpEnumType extends EnumType
1311
{
1412
public const MULTIPLE_DESCRIPTIONS_DISALLOWED = 'Using more than 1 Description attribute is not supported.';
@@ -47,12 +45,23 @@ public function __construct(string $enum, ?string $name = null)
4745

4846
public function serialize($value): string
4947
{
50-
if (! ($value instanceof $this->enumClass)) {
51-
$notEnum = Utils::printSafe($value);
52-
throw new SerializationError("Cannot serialize value as enum: {$notEnum}, expected instance of {$this->enumClass}.");
48+
if ($value instanceof $this->enumClass) {
49+
return $value->name;
50+
}
51+
52+
if (is_a($this->enumClass, \BackedEnum::class, true)) {
53+
try {
54+
$instance = $this->enumClass::from($value);
55+
} catch (\ValueError|\TypeError $_) {
56+
$notEnumInstanceOrValue = Utils::printSafe($value);
57+
throw new SerializationError("Cannot serialize value as enum: {$notEnumInstanceOrValue}, expected instance or valid value of {$this->enumClass}.");
58+
}
59+
60+
return $instance->name;
5361
}
5462

55-
return $value->name;
63+
$notEnum = Utils::printSafe($value);
64+
throw new SerializationError("Cannot serialize value as enum: {$notEnum}, expected instance of {$this->enumClass}.");
5665
}
5766

5867
public function parseValue($value)

tests/Type/PhpEnumTypeTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,28 @@ public function testExecutesWithEnumTypeFromPhpEnum(): void
136136
], GraphQL::executeQuery($schema, '{ foo(bar: A) }')->toArray());
137137
}
138138

139+
public function testSerializesBackedEnumsByValue(): void
140+
{
141+
$enumType = new PhpEnumType(IntPhpEnum::class);
142+
$schema = new Schema([
143+
'query' => new ObjectType([
144+
'name' => 'Query',
145+
'fields' => [
146+
'foo' => [
147+
'type' => Type::nonNull($enumType),
148+
'resolve' => static fn (): int => 1,
149+
],
150+
],
151+
]),
152+
]);
153+
154+
self::assertSame([
155+
'data' => [
156+
'foo' => 'A',
157+
],
158+
], GraphQL::executeQuery($schema, '{ foo }')->toArray());
159+
}
160+
139161
public function testAcceptsEnumFromVariableValues(): void
140162
{
141163
$enumType = new PhpEnumType(PhpEnum::class);
@@ -212,4 +234,25 @@ public function testFailsToSerializeNonEnum(): void
212234
self::expectExceptionObject(new SerializationError('Cannot serialize value as enum: "A", expected instance of GraphQL\\Tests\\Type\\PhpEnumType\\PhpEnum.'));
213235
$result->toArray(DebugFlag::RETHROW_INTERNAL_EXCEPTIONS);
214236
}
237+
238+
public function testFailsToSerializeNonEnumValue(): void
239+
{
240+
$enumType = new PhpEnumType(IntPhpEnum::class);
241+
$schema = new Schema([
242+
'query' => new ObjectType([
243+
'name' => 'Query',
244+
'fields' => [
245+
'foo' => [
246+
'type' => Type::nonNull($enumType),
247+
'resolve' => static fn (): string => 'A',
248+
],
249+
],
250+
]),
251+
]);
252+
253+
$result = GraphQL::executeQuery($schema, '{ foo }');
254+
255+
self::expectExceptionObject(new SerializationError('Cannot serialize value as enum: "A", expected instance or valid value of GraphQL\\Tests\\Type\\PhpEnumType\\IntPhpEnum.'));
256+
$result->toArray(DebugFlag::RETHROW_INTERNAL_EXCEPTIONS);
257+
}
215258
}

0 commit comments

Comments
 (0)