Implement enum filter

[MAILPOET-5187]
This commit is contained in:
Jan Jakes
2023-04-14 15:23:28 +02:00
committed by Aschepikov
parent de0199421c
commit 2da3e08c09
3 changed files with 145 additions and 0 deletions

View File

@@ -23,6 +23,7 @@ class CoreIntegration implements Integration {
$registry->addFilter(new Filters\NumberFilter());
$registry->addFilter(new Filters\IntegerFilter());
$registry->addFilter(new Filters\StringFilter());
$registry->addFilter(new Filters\EnumFilter());
$registry->addFilter(new Filters\EnumArrayFilter());
}
}

View File

@@ -0,0 +1,51 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\Core\Filters;
use MailPoet\Automation\Engine\Data\Field;
use MailPoet\Automation\Engine\Data\Filter as FilterData;
use MailPoet\Automation\Engine\Integration\Filter;
use MailPoet\Validator\Builder;
use MailPoet\Validator\Schema\ObjectSchema;
class EnumFilter implements Filter {
public const IS_ANY_OF = 'is-any-of';
public const IS_NONE_OF = 'is-none-of';
public function getFieldType(): string {
return Field::TYPE_ENUM;
}
public function getConditions(): array {
return [
self::IS_ANY_OF => __('is any of', 'mailpoet'),
self::IS_NONE_OF => __('is none of', 'mailpoet'),
];
}
public function getArgsSchema(): ObjectSchema {
return Builder::object([
'value' => Builder::oneOf([
Builder::array(Builder::string())->minItems(1),
Builder::array(Builder::integer())->minItems(1),
])->required(),
]);
}
public function matches(FilterData $data, $value): bool {
$filterValue = $data->getArgs()['value'] ?? null;
if (!is_scalar($value) || !is_array($filterValue)) {
return false;
}
$filterValue = array_unique($filterValue, SORT_REGULAR);
switch ($data->getCondition()) {
case self::IS_ANY_OF:
return in_array($value, $filterValue, true);
case self::IS_NONE_OF:
return !in_array($value, $filterValue, true);
default:
return false;
}
}
}

View File

@@ -0,0 +1,93 @@
<?php declare(strict_types = 1);
namespace MailPoet\Test\Automation\Integrations\Core\Filters;
use MailPoet\Automation\Engine\Data\Filter;
use MailPoet\Automation\Integrations\Core\Filters\EnumFilter;
use MailPoetUnitTest;
use stdClass;
class EnumFilterTest extends MailPoetUnitTest {
public function testItReturnsCorrectConfiguration(): void {
$filter = new EnumFilter();
$this->assertSame('enum', $filter->getFieldType());
$this->assertSame([
'is-any-of' => 'is any of',
'is-none-of' => 'is none of',
], $filter->getConditions());
$this->assertSame([
'type' => 'object',
'properties' => [
'value' => [
'oneOf' => [
['type' => 'array', 'items' => ['type' => 'string'], 'minItems' => 1],
['type' => 'array', 'items' => ['type' => 'integer'], 'minItems' => 1],
],
'required' => true,
],
],
], $filter->getArgsSchema()->toArray());
}
public function testInvalidValues(): void {
$this->assertNotMatches('is-any-of', [], null);
$this->assertNotMatches('is-any-of', [], 123);
$this->assertNotMatches('is-any-of', [], 'abc');
$this->assertNotMatches('is-any-of', [], new stdClass());
$this->assertNotMatches('is-any-of', [], true);
$this->assertNotMatches('is-any-of', [], false);
$this->assertNotMatches('is-any-of', [1], [1]);
$this->assertNotMatches('is-any-of', null, 1);
$this->assertNotMatches('is-any-of', 123, 1);
$this->assertNotMatches('is-any-of', 'abc', 1);
$this->assertNotMatches('is-any-of', new stdClass(), 1);
$this->assertNotMatches('is-any-of', true, 1);
$this->assertNotMatches('is-any-of', false, 1);
$this->assertNotMatches('is-any-of', 1, 1);
}
public function testMatchesAnyCondition(): void {
$this->assertMatches('is-any-of', [1], 1);
$this->assertMatches('is-any-of', [1, 1, 1], 1);
$this->assertMatches('is-any-of', [1, 2, 3], 1);
$this->assertMatches('is-any-of', [1, 2, 3], 3);
$this->assertMatches('is-any-of', ['abc', 'def'], 'abc');
$this->assertNotMatches('is-any-of', [], 1);
$this->assertNotMatches('is-any-of', [1], 0);
$this->assertNotMatches('is-any-of', [1, 2, 3], 7);
$this->assertNotMatches('is-any-of', ['abc', 'def'], 'xyz');
}
public function testMatchesNoneCondition(): void {
$this->assertMatches('is-none-of', [], 1);
$this->assertMatches('is-none-of', [1], 2);
$this->assertMatches('is-none-of', [1, 2, 3], 7);
$this->assertMatches('is-none-of', [1, 1, 1], 2);
$this->assertMatches('is-none-of', ['abc', 'def'], 'xyz');
$this->assertNotMatches('is-none-of', [1], 1);
$this->assertNotMatches('is-none-of', [1, 2, 3], 2);
$this->assertNotMatches('is-none-of', [1, 1, 1], 1);
$this->assertNotMatches('is-none-of', ['abc', 'def'], 'def');
}
public function testUnknownCondition(): void {
$this->assertNotMatches('unknown', [1], 1);
$this->assertNotMatches('unknown', [1], 1);
}
private function assertMatches(string $condition, $filterValue, $value): void {
$this->assertTrue($this->matchesFilter($condition, $filterValue, $value));
}
private function assertNotMatches(string $condition, $filterValue, $value): void {
$this->assertFalse($this->matchesFilter($condition, $filterValue, $value));
}
private function matchesFilter(string $condition, $filterValue, $value): bool {
$filter = new EnumFilter();
return $filter->matches(new Filter('f1', 'enum', '', $condition, ['value' => $filterValue]), $value);
}
}