Skip to content

Commit da95a99

Browse files
authored
fix Enum not resolved in first level input arguments (#561)
* fix enumtypemapper not handling enums passed as input via variables due to a missing ltrim not being carried over from the myclabsenumtypemapper the FQCN of the enum most of the time had a leading backslash resulting it not being found in the cache or duplication once with and once without leading backslash excluding of enums is not done on the NS getClassList method but reather later in the AbstractTypeMapper so EnumTypeMapper can actually find Enums (this whole implementation was previously working by accident) * remove php8.1 conditions
1 parent f3ce4c5 commit da95a99

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

src/Mappers/AbstractTypeMapper.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use TheCodingMachine\GraphQLite\Types\MutableObjectType;
3131
use TheCodingMachine\GraphQLite\Types\ResolvableMutableInputInterface;
3232

33+
use UnitEnum;
3334
use function assert;
3435

3536
/**
@@ -114,6 +115,10 @@ private function buildMap(): GlobTypeMapperCache
114115
$classes = $this->getClassList();
115116

116117
foreach ($classes as $className => $refClass) {
118+
// Enum's are not types
119+
if ($refClass->isEnum()) {
120+
continue;
121+
}
117122
$annotationsCache = $this->mapClassToAnnotationsCache->get($refClass, function () use ($refClass, $className) {
118123
$annotationsCache = new GlobAnnotationsCache();
119124

@@ -186,6 +191,10 @@ private function buildMapClassToExtendTypeArray(): GlobExtendTypeMapperCache
186191

187192
$classes = $this->getClassList();
188193
foreach ($classes as $refClass) {
194+
// Enum's are not types
195+
if ($refClass->isEnum()) {
196+
continue;
197+
}
189198
$annotationsCache = $this->mapClassToExtendAnnotationsCache->get($refClass, function () use ($refClass) {
190199
$extendAnnotationsCache = new GlobExtendAnnotationsCache();
191200

src/Mappers/Root/EnumTypeMapper.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use GraphQL\Type\Definition\NamedType;
99
use GraphQL\Type\Definition\OutputType;
1010
use GraphQL\Type\Definition\Type as GraphQLType;
11+
use MyCLabs\Enum\Enum;
1112
use phpDocumentor\Reflection\DocBlock;
1213
use phpDocumentor\Reflection\Type;
1314
use phpDocumentor\Reflection\Types\Object_;
@@ -94,13 +95,14 @@ private function map(Type $type): EnumType|null
9495
/** @param class-string $enumClass */
9596
private function mapByClassName(string $enumClass): EnumType|null
9697
{
97-
if (isset($this->cache[$enumClass])) {
98-
return $this->cache[$enumClass];
99-
}
100-
10198
if (! enum_exists($enumClass)) {
10299
return null;
103100
}
101+
/** @var class-string<Enum> $enumClass */
102+
$enumClass = ltrim($enumClass, '\\');
103+
if (isset($this->cache[$enumClass])) {
104+
return $this->cache[$enumClass];
105+
}
104106

105107
// phpcs:disable SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable
106108
/** @var class-string<UnitEnum> $enumClass */
@@ -119,7 +121,7 @@ private function mapByClassName(string $enumClass): EnumType|null
119121

120122
$type = new EnumType($enumClass, $typeName, $useValues);
121123

122-
return $this->cacheByName[$typeName] = $this->cache[$enumClass] = $type;
124+
return $this->cacheByName[$type->name] = $this->cache[$enumClass] = $type;
123125
}
124126

125127
private function getTypeName(ReflectionClass $reflectionClass): string
@@ -178,7 +180,6 @@ private function getNameToClassMapping(): array
178180
return $nameToClassMapping;
179181
});
180182
}
181-
182183
return $this->nameToClassMapping;
183184
}
184185
}

src/Utils/Namespaces/NS.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,6 @@ public function getClassList(): array
6161
}
6262

6363
$refClass = new ReflectionClass($className);
64-
// Enum's are not classes
65-
if (interface_exists(UnitEnum::class)) {
66-
// @phpstan-ignore-next-line - Remove this after minimum supported PHP version is >= 8.1
67-
if ($refClass->isEnum()) {
68-
continue;
69-
}
70-
}
7164

7265
$this->classes[$className] = $refClass;
7366
}

tests/Integration/EndToEndTest.php

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,62 @@ public function testEndToEndEnums3(): void
11751175
$this->assertSame(['echoProductType' => 'NON_FOOD'], $this->getSuccessResult($result));
11761176
}
11771177

1178-
/** @requires PHP >= 8.1 */
1178+
public function testEndToEndMutationNativeEnums(): void
1179+
{
1180+
$schema = $this->mainContainer->get(Schema::class);
1181+
assert($schema instanceof Schema);
1182+
1183+
$gql = '
1184+
mutation($size:Size!) {
1185+
singleEnum(size: $size)
1186+
}
1187+
';
1188+
$result = GraphQL::executeQuery(
1189+
$schema,
1190+
$gql,
1191+
variableValues: [
1192+
'size' => Size::L->name,
1193+
],
1194+
);
1195+
1196+
$this->assertSame([
1197+
'singleEnum' => 'L',
1198+
], $this->getSuccessResult($result));
1199+
}
1200+
1201+
public function testEndToEndInputVars(): void
1202+
{
1203+
$schema = $this->mainContainer->get(Schema::class);
1204+
assert($schema instanceof Schema);
1205+
1206+
$queryString = '
1207+
mutation ($contact: ContactInput!) {
1208+
saveContact(contact: $contact) {
1209+
name,
1210+
birthDate
1211+
}
1212+
}
1213+
';
1214+
1215+
$result = GraphQL::executeQuery(
1216+
$schema,
1217+
$queryString,
1218+
variableValues: [
1219+
'contact' => [
1220+
'name' => "foo",
1221+
'birthDate' => "1942-12-24T00:00:00+00:00"
1222+
]
1223+
]
1224+
);
1225+
1226+
$this->assertSame([
1227+
'saveContact' => [
1228+
'name' => 'foo',
1229+
'birthDate' => '1942-12-24T00:00:00+00:00'
1230+
],
1231+
], $this->getSuccessResult($result));
1232+
}
1233+
11791234
public function testEndToEndNativeEnums(): void
11801235
{
11811236
$schema = $this->mainContainer->get(Schema::class);

0 commit comments

Comments
 (0)