From ba770ca1b1d0d67135f0cc8c852c87faf42465b3 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 16:13:00 +0530 Subject: [PATCH 1/7] Add sub-tasks --- TODO.taskpaper | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 TODO.taskpaper diff --git a/TODO.taskpaper b/TODO.taskpaper new file mode 100644 index 00000000..e5485208 --- /dev/null +++ b/TODO.taskpaper @@ -0,0 +1,9 @@ +TODO.taskpaper + +### Add validation rules by attribute name or pattern #30 + ☐ create failing test + ☐ implement the solution + ☐ fix failing tests if any + ☐ resolve TODOs if any + ☐ review PR + ☐ delete this file and submit PR From 34459ade05ee81da513e0bf6d9150fe6b685bd85 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 18:14:00 +0530 Subject: [PATCH 2/7] Contains implementation --- TODO.taskpaper | 8 ++-- src/lib/ValidationRulesBuilder.php | 28 +++++++++--- .../index.php | 14 ++++++ .../index.yaml | 45 +++++++++++++++++++ tests/unit/IssueFixTest.php | 14 ++++++ 5 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php create mode 100644 tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.yaml diff --git a/TODO.taskpaper b/TODO.taskpaper index e5485208..617c3c2f 100644 --- a/TODO.taskpaper +++ b/TODO.taskpaper @@ -1,9 +1,9 @@ TODO.taskpaper ### Add validation rules by attribute name or pattern #30 - ☐ create failing test - ☐ implement the solution - ☐ fix failing tests if any - ☐ resolve TODOs if any + ✔ create failing test @done (24-08-26 18:13) + ✔ implement the solution @done (24-08-26 18:13) + ✔ fix failing tests if any @done (24-08-26 18:13) + ✔ resolve TODOs if any @done (24-08-26 18:13) ☐ review PR ☐ delete this file and submit PR diff --git a/src/lib/ValidationRulesBuilder.php b/src/lib/ValidationRulesBuilder.php index 3f3c1398..1e9c3188 100644 --- a/src/lib/ValidationRulesBuilder.php +++ b/src/lib/ValidationRulesBuilder.php @@ -10,8 +10,6 @@ use cebe\yii2openapi\lib\items\Attribute; use cebe\yii2openapi\lib\items\DbModel; use cebe\yii2openapi\lib\items\ValidationRule; -use yii\helpers\VarDumper; -use yii\validators\DateValidator; use function count; use function implode; use function in_array; @@ -65,7 +63,7 @@ public function build():array } } foreach ($this->model->attributes as $attribute) { - // column/field/property with name `id` is considered as Primary Key by this library and it is automatically handled by DB/Yii; so remove it from validation `rules()` + // column/field/property with name `id` is considered as Primary Key by this library, and it is automatically handled by DB/Yii; so remove it from validation `rules()` if (in_array($attribute->columnName, ['id', $this->model->pkName]) || in_array($attribute->propertyName, ['id', $this->model->pkName]) ) { @@ -140,12 +138,30 @@ private function addRulesByAttributeName(Attribute $attribute):void $patterns = [ '~e?mail~i' => 'email', '~(url|site|website|href|link)~i' => 'url', + + # below patters will only work if `format: binary` (file) is present in OpenAPI spec + # also `string` validation rule will be removed + '~(image|photo|picture)~i' => 'image', + '~(file|pdf|audio|video|document|json|yml|yaml|zip|tar|7z)~i' => 'file', ]; + $addRule = function (Attribute $attribute, string $validator): void { + $key = $attribute->columnName . '_' . $validator; + $this->rules[$key] = new ValidationRule([$attribute->columnName], $validator); + }; foreach ($patterns as $pattern => $validator) { if (empty($attribute->reference) # ignore column name based rules in case of reference/relation # https://github.com/cebe/yii2-openapi/issues/159 && preg_match($pattern, strtolower($attribute->columnName))) { - $key = $attribute->columnName . '_' . $validator; - $this->rules[$key] = new ValidationRule([$attribute->columnName], $validator); + + if (in_array($validator, ['image', 'file'], true)) { + if ($attribute->dbType === 'binary') { + $addRule($attribute, $validator); + // for files, we don't need `string` validation + $key = $attribute->columnName . '_string'; + unset($this->rules[$key]); + } + } else { + $addRule($attribute, $validator); + } return; } } @@ -223,7 +239,7 @@ private function prepareTypeScope():void if ($attribute->isReadOnly()) { continue; } - // column/field/property with name `id` is considered as Primary Key by this library and it is automatically handled by DB/Yii; so remove it from validation `rules()` + // column/field/property with name `id` is considered as Primary Key by this library, and it is automatically handled by DB/Yii; so remove it from validation `rules()` if (in_array($attribute->columnName, ['id', $this->model->pkName]) || in_array($attribute->propertyName, ['id', $this->model->pkName]) ) { diff --git a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php new file mode 100644 index 00000000..ded72814 --- /dev/null +++ b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php @@ -0,0 +1,14 @@ + '@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.yaml', + 'generateUrls' => false, + 'generateModels' => true, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => false, + 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` +]; + diff --git a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.yaml b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.yaml new file mode 100644 index 00000000..4561070f --- /dev/null +++ b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.yaml @@ -0,0 +1,45 @@ + +openapi: 3.0.3 + +info: + title: Add validation rules by attribute name or pattern \#30 + version: 1.0.0 + +components: + schemas: + User: + type: object + required: + - id + - name + properties: + id: + type: integer + readOnly: true + name: + description: name + type: string + maxLength: 128 + photo: + type: string + format: binary + profile_photo: + type: string + format: binary + pdf: + type: string + format: binary + a_file: + type: string + format: binary + profile: + type: string + +paths: + '/': + get: + operationId: opId + summary: summary + responses: + '200': + description: OK diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index b6c7abdb..a105928c 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -360,4 +360,18 @@ public function test158BugGiiapiGeneratedRulesEnumWithTrim() ]); $this->checkFiles($actualFiles, $expectedFiles); } + + // https://github.com/php-openapi/yii2-openapi/issues/30 + public function test30AddValidationRulesByAttributeNameOrPattern() + { + $testFile = Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php"); + $this->runGenerator($testFile); +// $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ +// 'recursive' => true, +// ]); +// $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql"), [ +// 'recursive' => true, +// ]); +// $this->checkFiles($actualFiles, $expectedFiles); + } } From c978bd7107d2028ae567a3619deae2c8b3ce0ed3 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 18:16:02 +0530 Subject: [PATCH 3/7] Cleanup --- src/lib/ValidationRulesBuilder.php | 1 - .../index.php | 2 +- .../mysql/models/User.php | 10 +++++ .../mysql/models/base/User.php | 37 +++++++++++++++++++ tests/unit/IssueFixTest.php | 14 +++---- 5 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/User.php create mode 100644 tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/base/User.php diff --git a/src/lib/ValidationRulesBuilder.php b/src/lib/ValidationRulesBuilder.php index 1e9c3188..8e9a5ed5 100644 --- a/src/lib/ValidationRulesBuilder.php +++ b/src/lib/ValidationRulesBuilder.php @@ -151,7 +151,6 @@ private function addRulesByAttributeName(Attribute $attribute):void foreach ($patterns as $pattern => $validator) { if (empty($attribute->reference) # ignore column name based rules in case of reference/relation # https://github.com/cebe/yii2-openapi/issues/159 && preg_match($pattern, strtolower($attribute->columnName))) { - if (in_array($validator, ['image', 'file'], true)) { if ($attribute->dbType === 'binary') { $addRule($attribute, $validator); diff --git a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php index ded72814..4415beda 100644 --- a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php +++ b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php @@ -9,6 +9,6 @@ ], 'generateControllers' => false, 'generateMigrations' => false, - 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` + 'generateModelFaker' => false, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/User.php b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/User.php new file mode 100644 index 00000000..9b837d6e --- /dev/null +++ b/tests/specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql/models/User.php @@ -0,0 +1,10 @@ + [['name', 'photo', 'profile_photo', 'pdf', 'a_file', 'profile'], 'trim'], + 'required' => [['name'], 'required'], + 'name_string' => [['name'], 'string', 'max' => 128], + 'photo_image' => [['photo'], 'image'], + 'profile_photo_image' => [['profile_photo'], 'image'], + 'pdf_file' => [['pdf'], 'file'], + 'a_file_file' => [['a_file'], 'file'], + 'profile_string' => [['profile'], 'string'], + ]; + } +} diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index a105928c..1a7d17b8 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -366,12 +366,12 @@ public function test30AddValidationRulesByAttributeNameOrPattern() { $testFile = Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php"); $this->runGenerator($testFile); -// $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ -// 'recursive' => true, -// ]); -// $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql"), [ -// 'recursive' => true, -// ]); -// $this->checkFiles($actualFiles, $expectedFiles); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); } } From 0dcf9b6b38b73d6b6c362b930dbe7141efe58a98 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 18:17:08 +0530 Subject: [PATCH 4/7] Format --- tests/unit/IssueFixTest.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 1a7d17b8..e08e6b2b 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -366,12 +366,12 @@ public function test30AddValidationRulesByAttributeNameOrPattern() { $testFile = Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php"); $this->runGenerator($testFile); - $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ - 'recursive' => true, - ]); - $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql"), [ - 'recursive' => true, - ]); - $this->checkFiles($actualFiles, $expectedFiles); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); } } From acfe0aff1ec1f594fb3ad8a294a0e9886608330f Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 18:18:17 +0530 Subject: [PATCH 5/7] Resolve TODO.taskpaper --- TODO.taskpaper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.taskpaper b/TODO.taskpaper index 617c3c2f..821b0e7f 100644 --- a/TODO.taskpaper +++ b/TODO.taskpaper @@ -5,5 +5,5 @@ TODO.taskpaper ✔ implement the solution @done (24-08-26 18:13) ✔ fix failing tests if any @done (24-08-26 18:13) ✔ resolve TODOs if any @done (24-08-26 18:13) - ☐ review PR + ✔ review PR @done (24-08-26 18:17) ☐ delete this file and submit PR From 04e3780e377e94babab2fa41a48eb09c6d1948e2 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 18:18:45 +0530 Subject: [PATCH 6/7] Apply --- TODO.taskpaper | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 TODO.taskpaper diff --git a/TODO.taskpaper b/TODO.taskpaper deleted file mode 100644 index 821b0e7f..00000000 --- a/TODO.taskpaper +++ /dev/null @@ -1,9 +0,0 @@ -TODO.taskpaper - -### Add validation rules by attribute name or pattern #30 - ✔ create failing test @done (24-08-26 18:13) - ✔ implement the solution @done (24-08-26 18:13) - ✔ fix failing tests if any @done (24-08-26 18:13) - ✔ resolve TODOs if any @done (24-08-26 18:13) - ✔ review PR @done (24-08-26 18:17) - ☐ delete this file and submit PR From 42674b7be60515f056ddc1ddb2d44cf88115f0d1 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 26 Aug 2024 18:20:39 +0530 Subject: [PATCH 7/7] Resolve TODO --- src/lib/ValidationRulesBuilder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/ValidationRulesBuilder.php b/src/lib/ValidationRulesBuilder.php index 8e9a5ed5..75f07be5 100644 --- a/src/lib/ValidationRulesBuilder.php +++ b/src/lib/ValidationRulesBuilder.php @@ -134,7 +134,6 @@ private function resolveAttributeRules(Attribute $attribute):void private function addRulesByAttributeName(Attribute $attribute):void { - //@TODO: probably also patterns for file, image $patterns = [ '~e?mail~i' => 'email', '~(url|site|website|href|link)~i' => 'url',