From 4f74394e8fb24eee10ebeedadfa6f58b661967aa Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 22 Apr 2026 15:21:41 +0530 Subject: [PATCH] Fix spec enum name validation --- src/Appwrite/Platform/Tasks/Specs.php | 6 +- src/Appwrite/SDK/Specification/Format.php | 9 +++ tests/unit/Platform/Tasks/SpecsTest.php | 67 +++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Specs.php b/src/Appwrite/Platform/Tasks/Specs.php index e9fa15e6c7..31fb69460f 100644 --- a/src/Appwrite/Platform/Tasks/Specs.php +++ b/src/Appwrite/Platform/Tasks/Specs.php @@ -370,12 +370,12 @@ class Specs extends Action } $explicitEnumName = $this->getExplicitSpecEnumName($node); - if (!\is_null($explicitEnumName)) { + if (!\is_null($explicitEnumName) && !isset($node['enum'])) { $this->addSpecEnumName($enums, $explicitEnumName); } foreach ($node as $key => $value) { - if (!\is_array($value)) { + if ($key === 'items' || !\is_array($value)) { continue; } @@ -420,7 +420,7 @@ class Specs extends Action return $this->getFallbackSpecEnumName($parent, $fallbackName); } - if (\is_string($key) && !\in_array($key, ['components', 'content', 'definitions', 'parameters', 'paths', 'properties', 'responses'], true)) { + if (\is_string($key) && !\in_array($key, ['components', 'content', 'definitions', 'delete', 'get', 'head', 'options', 'parameters', 'patch', 'paths', 'post', 'properties', 'put', 'responses'], true)) { return $key; } diff --git a/src/Appwrite/SDK/Specification/Format.php b/src/Appwrite/SDK/Specification/Format.php index e68e9438ca..0c28384db1 100644 --- a/src/Appwrite/SDK/Specification/Format.php +++ b/src/Appwrite/SDK/Specification/Format.php @@ -751,6 +751,15 @@ abstract class Format break; case 'project': switch ($method) { + case 'getEmailTemplate': + case 'updateEmailTemplate': + switch ($param) { + case 'templateId': + return 'EmailTemplateType'; + case 'locale': + return 'EmailTemplateLocale'; + } + break; case 'getUsage': switch ($param) { case 'period': diff --git a/tests/unit/Platform/Tasks/SpecsTest.php b/tests/unit/Platform/Tasks/SpecsTest.php index a10c66bf81..6cb11b310e 100644 --- a/tests/unit/Platform/Tasks/SpecsTest.php +++ b/tests/unit/Platform/Tasks/SpecsTest.php @@ -11,6 +11,18 @@ class TestSpecs extends Specs { $this->verifyParsedSpec($spec); } + + public function collectEnums(array $spec): array + { + $collect = \Closure::bind(function (array $spec): array { + $enums = []; + $this->collectSpecEnumNames($spec, $enums); + + return $enums; + }, $this, Specs::class); + + return $collect($spec); + } } class SpecsTest extends TestCase @@ -119,4 +131,59 @@ class SpecsTest extends TestCase $this->addToAssertionCount(1); } + + public function testCollectSpecEnumNamesDoesNotDoubleRegisterExplicitNames(): void + { + $enums = $this->specs->collectEnums([ + 'schema' => [ + 'type' => 'string', + 'enum' => ['en'], + 'x-enum-name' => 'Locale', + ], + ]); + + $this->assertSame(['Locale'], $enums['locale']); + } + + public function testCollectSpecEnumNamesDoesNotDoubleRegisterItemsEnums(): void + { + $enums = $this->specs->collectEnums([ + 'name' => 'Locale', + 'type' => 'array', + 'items' => [ + 'type' => 'string', + 'enum' => ['en'], + ], + ]); + + $this->assertSame(['Locale'], $enums['locale']); + } + + public function testVerifyParsedSpecIgnoresHttpMethodFallbackNames(): void + { + $this->specs->verify([ + 'tags' => [ + [ + 'name' => 'patch', + 'description' => 'Patch APIs', + ], + ], + 'paths' => [ + '/example' => [ + 'patch' => [ + 'parameters' => [ + [ + 'schema' => [ + 'type' => 'string', + 'enum' => ['enabled'], + ], + ], + ], + ], + ], + ], + ]); + + $this->addToAssertionCount(1); + } }