Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: rules() "required" is generated before "*_default" #22 #24

Merged
merged 12 commits into from
Feb 20, 2025
44 changes: 29 additions & 15 deletions src/lib/ValidationRulesBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,38 @@ public function build():array
$this->rules['trim'] = new ValidationRule($this->typeScope['trim'], 'trim');
}

foreach ($this->model->attributes as $attribute) {
if ($this->isIdColumn($attribute)) {
continue;
}
$this->defaultRule($attribute);
}

if (!empty($this->typeScope['required'])) {
$this->rules['required'] = new ValidationRule($this->typeScope['required'], 'required');
}
if (!empty($this->typeScope['ref'])) {
$this->addExistRules($this->typeScope['ref']);

foreach ($this->model->attributes as $attribute) {
if ($this->isIdColumn($attribute)) {
continue;
}
$this->resolveAttributeRules($attribute);
}

foreach ($this->model->indexes as $index) {
if ($index->isUnique) {
$this->addUniqueRule($index->columns);
}
}
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()`
if (in_array($attribute->columnName, ['id', $this->model->pkName]) ||
in_array($attribute->propertyName, ['id', $this->model->pkName])
) {
continue;
}
$this->resolveAttributeRules($attribute);

if (!empty($this->typeScope['ref'])) {
$this->addExistRules($this->typeScope['ref']);
}

if (!empty($this->typeScope['safe'])) {
$this->rules['safe'] = new ValidationRule($this->typeScope['safe'], 'safe');
}

return $this->rules;
}

Expand All @@ -93,7 +101,6 @@ private function resolveAttributeRules(Attribute $attribute):void
}
if ($attribute->phpType === 'bool' || $attribute->phpType === 'boolean') {
$this->rules[$attribute->columnName . '_boolean'] = new ValidationRule([$attribute->columnName], 'boolean');
$this->defaultRule($attribute);
return;
}

Expand All @@ -111,13 +118,11 @@ private function resolveAttributeRules(Attribute $attribute):void
}

$this->rules[$key] = new ValidationRule([$attribute->columnName], $attribute->dbType, $params);
$this->defaultRule($attribute);
return;
}

if (in_array($attribute->phpType, ['int', 'integer', 'double', 'float']) && !$attribute->isReference()) {
$this->addNumericRule($attribute);
$this->defaultRule($attribute);
return;
}
if ($attribute->phpType === 'string' && !$attribute->isReference()) {
Expand All @@ -127,10 +132,8 @@ private function resolveAttributeRules(Attribute $attribute):void
$key = $attribute->columnName . '_in';
$this->rules[$key] =
new ValidationRule([$attribute->columnName], 'in', ['range' => $attribute->enumValues]);
$this->defaultRule($attribute);
return;
}
$this->defaultRule($attribute);
$this->addRulesByAttributeName($attribute);
}

Expand Down Expand Up @@ -278,4 +281,15 @@ public function __toString()
}
};
}

private function isIdColumn(Attribute $attribute): bool
{
// 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])
) {
return true;
}
return false;
}
}
8 changes: 4 additions & 4 deletions tests/DbTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
namespace tests;

use cebe\yii2openapi\generator\ApiGenerator;
use SamIT\Yii2\MariaDb\Schema as MariaDbSchema;
use Yii;
use yii\db\IndexConstraint;
use yii\di\Container;
use yii\db\mysql\Schema as MySqlSchema;
use yii\db\pgsql\Schema as PgSqlSchema;
use \SamIT\Yii2\MariaDb\Schema as MariaDbSchema;
use yii\helpers\{ArrayHelper, VarDumper, StringHelper, Console};
use yii\di\Container;
use yii\helpers\{ArrayHelper, StringHelper};
use yii\helpers\FileHelper;

class DbTestCase extends \PHPUnit\Framework\TestCase
Expand Down Expand Up @@ -102,7 +102,6 @@ protected function compareFiles(array $actual, string $testFile)
foreach ($actual as $file) {
$expectedFile = str_replace('@app', substr($testFile, 0, -4), $file);
$actualFile = str_replace('@app', Yii::getAlias('@app'), $file);
// exec('cp '.$actualFile.' '.$expectedFile);
$this->checkFiles([$actualFile], [$expectedFile]);
}
}
Expand All @@ -128,6 +127,7 @@ protected function checkFiles(array $actual, array $expected)
);
}

// exec('cp '.$file.' '.$expectedFilePath);
$this->assertFileEquals($expectedFilePath, $file, "Failed asserting that file contents of\n$file\nare equal to file contents of\n$expectedFilePath \n\n cp $file $expectedFilePath \n\n ");
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/specs/blog/models/base/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ public function rules()
{
return [
'trim' => [['title'], 'trim'],
'active_default' => [['active'], 'default', 'value' => false],
'required' => [['title', 'active'], 'required'],
'title_unique' => [['title'], 'unique'],
'title_string' => [['title'], 'string', 'max' => 255],
'active_boolean' => [['active'], 'boolean'],
'active_default' => [['active'], 'default', 'value' => false],
'title_unique' => [['title'], 'unique'],
];
}

Expand Down
6 changes: 3 additions & 3 deletions tests/specs/blog/models/base/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ public function rules()
{
return [
'trim' => [['post_id'], 'trim'],
'message_default' => [['message'], 'default', 'value' => []],
'meta_data_default' => [['meta_data'], 'default', 'value' => []],
'required' => [['post_id', 'author_id', 'message', 'created_at'], 'required'],
'created_at_integer' => [['created_at'], 'integer'],
'post_id_string' => [['post_id'], 'string', 'max' => 128],
'post_id_exist' => [['post_id'], 'exist', 'targetRelation' => 'post'],
'author_id_integer' => [['author_id'], 'integer'],
'author_id_exist' => [['author_id'], 'exist', 'targetRelation' => 'author'],
'message_default' => [['message'], 'default', 'value' => []],
'meta_data_default' => [['meta_data'], 'default', 'value' => []],
'created_at_integer' => [['created_at'], 'integer'],
'safe' => [['message', 'meta_data'], 'safe'],
];
}
Expand Down
2 changes: 1 addition & 1 deletion tests/specs/blog/models/base/Fakerable.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public function rules()
{
return [
'trim' => [['str_text', 'str_varchar', 'str_date', 'str_datetime', 'str_country'], 'trim'],
'int_min_default' => [['int_min'], 'default', 'value' => 3],
'active_boolean' => [['active'], 'boolean'],
'floatval_double' => [['floatval'], 'double'],
'floatval_lim_double' => [['floatval_lim'], 'double', 'min' => 0, 'max' => 1],
'doubleval_double' => [['doubleval'], 'double'],
'int_min_integer' => [['int_min'], 'integer', 'min' => 5],
'int_min_default' => [['int_min'], 'default', 'value' => 3],
'int_max_integer' => [['int_max'], 'integer', 'max' => 5],
'int_minmax_integer' => [['int_minmax'], 'integer', 'min' => 5, 'max' => 25],
'int_created_at_integer' => [['int_created_at'], 'integer'],
Expand Down
14 changes: 7 additions & 7 deletions tests/specs/blog/models/base/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ public function rules()
{
return [
'trim' => [['title', 'slug', 'created_at'], 'trim'],
'active_default' => [['active'], 'default', 'value' => false],
'required' => [['title', 'category_id', 'active'], 'required'],
'category_id_integer' => [['category_id'], 'integer'],
'category_id_exist' => [['category_id'], 'exist', 'targetRelation' => 'category'],
'created_by_id_integer' => [['created_by_id'], 'integer'],
'created_by_id_exist' => [['created_by_id'], 'exist', 'targetRelation' => 'createdBy'],
'title_unique' => [['title'], 'unique'],
'slug_unique' => [['slug'], 'unique'],
'title_string' => [['title'], 'string', 'max' => 255],
'slug_string' => [['slug'], 'string', 'min' => 1, 'max' => 200],
'active_boolean' => [['active'], 'boolean'],
'active_default' => [['active'], 'default', 'value' => false],
'created_at_date' => [['created_at'], 'date', 'format' => 'php:Y-m-d'],
'title_unique' => [['title'], 'unique'],
'slug_unique' => [['slug'], 'unique'],
'category_id_integer' => [['category_id'], 'integer'],
'category_id_exist' => [['category_id'], 'exist', 'targetRelation' => 'category'],
'created_by_id_integer' => [['created_by_id'], 'integer'],
'created_by_id_exist' => [['created_by_id'], 'exist', 'targetRelation' => 'createdBy'],
];
}

Expand Down
10 changes: 5 additions & 5 deletions tests/specs/blog/models/base/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ public function rules()
{
return [
'trim' => [['username', 'email', 'password', 'role', 'created_at'], 'trim'],
'role_default' => [['role'], 'default', 'value' => 'reader'],
'flags_default' => [['flags'], 'default', 'value' => 0],
'created_at_default' => [['created_at'], 'default', 'value' => new \yii\db\Expression("(CURRENT_TIMESTAMP)")],
'required' => [['username', 'email', 'password'], 'required'],
'username_unique' => [['username'], 'unique'],
'email_unique' => [['email'], 'unique'],
'username_string' => [['username'], 'string', 'max' => 200],
'email_string' => [['email'], 'string', 'max' => 200],
'email_email' => [['email'], 'email'],
'password_string' => [['password'], 'string'],
'role_string' => [['role'], 'string', 'max' => 20],
'role_default' => [['role'], 'default', 'value' => 'reader'],
'flags_integer' => [['flags'], 'integer'],
'flags_default' => [['flags'], 'default', 'value' => 0],
'created_at_datetime' => [['created_at'], 'datetime', 'format' => 'php:Y-m-d H:i:s'],
'created_at_default' => [['created_at'], 'default', 'value' => new \yii\db\Expression("(CURRENT_TIMESTAMP)")],
'username_unique' => [['username'], 'unique'],
'email_unique' => [['email'], 'unique'],
];
}

Expand Down
8 changes: 4 additions & 4 deletions tests/specs/blog_v2/models/base/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public function rules()
{
return [
'trim' => [['message', 'meta_data', 'created_at'], 'trim'],
'meta_data_default' => [['meta_data'], 'default', 'value' => ''],
'required' => [['post_id', 'message', 'created_at'], 'required'],
'message_string' => [['message'], 'string'],
'meta_data_string' => [['meta_data'], 'string', 'min' => 1, 'max' => 300],
'created_at_datetime' => [['created_at'], 'datetime', 'format' => 'php:Y-m-d H:i:s'],
'post_id_integer' => [['post_id'], 'integer'],
'post_id_exist' => [['post_id'], 'exist', 'targetRelation' => 'post'],
'user_id_integer' => [['user_id'], 'integer'],
'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'user'],
'message_string' => [['message'], 'string'],
'meta_data_string' => [['meta_data'], 'string', 'min' => 1, 'max' => 300],
'meta_data_default' => [['meta_data'], 'default', 'value' => ''],
'created_at_datetime' => [['created_at'], 'datetime', 'format' => 'php:Y-m-d H:i:s'],
];
}

Expand Down
12 changes: 6 additions & 6 deletions tests/specs/blog_v2/models/base/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ public function rules()
{
return [
'trim' => [['title', 'slug', 'created_at'], 'trim'],
'lang_default' => [['lang'], 'default', 'value' => 'ru'],
'required' => [['title', 'category_id', 'active'], 'required'],
'category_id_integer' => [['category_id'], 'integer'],
'category_id_exist' => [['category_id'], 'exist', 'targetRelation' => 'category'],
'created_by_id_integer' => [['created_by_id'], 'integer'],
'created_by_id_exist' => [['created_by_id'], 'exist', 'targetRelation' => 'createdBy'],
'title_unique' => [['title'], 'unique'],
'title_string' => [['title'], 'string', 'max' => 255],
'slug_string' => [['slug'], 'string', 'min' => 1, 'max' => 200],
'lang_string' => [['lang'], 'string'],
'lang_in' => [['lang'], 'in', 'range' => [
'ru',
'eng',
]],
'lang_default' => [['lang'], 'default', 'value' => 'ru'],
'active_boolean' => [['active'], 'boolean'],
'created_at_date' => [['created_at'], 'date', 'format' => 'php:Y-m-d'],
'title_unique' => [['title'], 'unique'],
'category_id_integer' => [['category_id'], 'integer'],
'category_id_exist' => [['category_id'], 'exist', 'targetRelation' => 'category'],
'created_by_id_integer' => [['created_by_id'], 'integer'],
'created_by_id_exist' => [['created_by_id'], 'exist', 'targetRelation' => 'createdBy'],
];
}

Expand Down
2 changes: 1 addition & 1 deletion tests/specs/blog_v2/models/base/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ public function rules()
return [
'trim' => [['name'], 'trim'],
'required' => [['name', 'lang'], 'required'],
'name_unique' => [['name'], 'unique'],
'name_string' => [['name'], 'string', 'max' => 100],
'lang_string' => [['lang'], 'string'],
'lang_in' => [['lang'], 'in', 'range' => [
'ru',
'eng',
]],
'name_unique' => [['name'], 'unique'],
];
}

Expand Down
6 changes: 3 additions & 3 deletions tests/specs/blog_v2/models/base/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ public function rules()
{
return [
'trim' => [['login', 'email', 'password', 'created_at'], 'trim'],
'flags_default' => [['flags'], 'default', 'value' => 0],
'required' => [['login', 'email', 'password'], 'required'],
'login_unique' => [['login'], 'unique'],
'email_unique' => [['email'], 'unique'],
'login_string' => [['login'], 'string'],
'email_string' => [['email'], 'string', 'max' => 255],
'email_email' => [['email'], 'email'],
Expand All @@ -43,8 +42,9 @@ public function rules()
'reader',
]],
'flags_integer' => [['flags'], 'integer'],
'flags_default' => [['flags'], 'default', 'value' => 0],
'created_at_datetime' => [['created_at'], 'datetime', 'format' => 'php:Y-m-d H:i:s'],
'login_unique' => [['login'], 'unique'],
'email_unique' => [['email'], 'unique'],
];
}

Expand Down
2 changes: 1 addition & 1 deletion tests/specs/fk_col_name/app/models/base/Webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public function rules()
{
return [
'trim' => [['name'], 'trim'],
'name_string' => [['name'], 'string'],
'user_id_integer' => [['user_id'], 'integer'],
'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'user'],
'redelivery_of_integer' => [['redelivery_of'], 'integer'],
'redelivery_of_exist' => [['redelivery_of'], 'exist', 'targetRelation' => 'redeliveryOf'],
'name_string' => [['name'], 'string'],
];
}

Expand Down
14 changes: 7 additions & 7 deletions tests/specs/fk_col_name_index/app/models/base/Webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,7 @@ public function rules()
{
return [
'trim' => [['name'], 'trim'],
'user_id_integer' => [['user_id'], 'integer'],
'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'user'],
'redelivery_of_integer' => [['redelivery_of'], 'integer'],
'redelivery_of_exist' => [['redelivery_of'], 'exist', 'targetRelation' => 'redeliveryOf'],
'rd_abc_2_integer' => [['rd_abc_2'], 'integer'],
'rd_abc_2_exist' => [['rd_abc_2'], 'exist', 'targetRelation' => 'rd2'],
'name_string' => [['name'], 'string', 'max' => 255],
'user_id_name_unique' => [['user_id', 'name'], 'unique', 'targetAttribute' => [
'user_id',
'name',
Expand All @@ -48,7 +43,12 @@ public function rules()
'rd_abc_2',
'name',
]],
'name_string' => [['name'], 'string', 'max' => 255],
'user_id_integer' => [['user_id'], 'integer'],
'user_id_exist' => [['user_id'], 'exist', 'targetRelation' => 'user'],
'redelivery_of_integer' => [['redelivery_of'], 'integer'],
'redelivery_of_exist' => [['redelivery_of'], 'exist', 'targetRelation' => 'redeliveryOf'],
'rd_abc_2_integer' => [['rd_abc_2'], 'integer'],
'rd_abc_2_exist' => [['rd_abc_2'], 'exist', 'targetRelation' => 'rd2'],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function rules()
{
return [
'trim' => [['name', 'f'], 'trim'],
'size_default' => [['size'], 'default', 'value' => 'x-small'],
'name_string' => [['name'], 'string', 'max' => 150],
'size_string' => [['size'], 'string'],
'size_in' => [['size'], 'in', 'range' => [
Expand All @@ -39,7 +40,6 @@ public function rules()
'large',
'x-large',
]],
'size_default' => [['size'], 'default', 'value' => 'x-small'],
'd_integer' => [['d'], 'integer'],
'e_integer' => [['e'], 'integer'],
'f_string' => [['f'], 'string', 'max' => 12],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public static function tableName()
public function rules()
{
return [
'billing_factor_default' => [['billing_factor'], 'default', 'value' => 100],
'required' => [['billing_factor'], 'required'],
'billing_factor_integer' => [['billing_factor'], 'integer'],
'billing_factor_default' => [['billing_factor'], 'default', 'value' => 100],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public function rules()
{
return [
'trim' => [['nickname'], 'trim'],
'active_default' => [['active'], 'default', 'value' => false],
'required' => [['mailing_id'], 'required'],
'mailing_id_integer' => [['mailing_id'], 'integer'],
'mailing_id_exist' => [['mailing_id'], 'exist', 'targetRelation' => 'mailing'],
'active_boolean' => [['active'], 'boolean'],
'active_default' => [['active'], 'default', 'value' => false],
'nickname_string' => [['nickname'], 'string'],
'mailing_id_integer' => [['mailing_id'], 'integer'],
'mailing_id_exist' => [['mailing_id'], 'exist', 'targetRelation' => 'mailing'],
];
}

Expand Down
Loading