Add IDs for filter groups and filter definitions

[MAILPOET-5257]
This commit is contained in:
Jan Jakes
2023-04-21 14:39:58 +02:00
committed by Aschepikov
parent 34ca96d007
commit f75620a7c1
10 changed files with 43 additions and 17 deletions

View File

@@ -5,6 +5,7 @@ export type NextStep = {
}; };
export type Filter = { export type Filter = {
id: string;
field_type: string; field_type: string;
field_key: string; field_key: string;
condition: string; condition: string;
@@ -12,6 +13,7 @@ export type Filter = {
}; };
export type FilterGroup = { export type FilterGroup = {
id: string;
operator: 'and' | 'or'; operator: 'and' | 'or';
filters: Filter[]; filters: Filter[];
}; };

View File

@@ -55,7 +55,7 @@ export function FiltersList(): JSX.Element | null {
{groups.map((group) => {groups.map((group) =>
group.filters.map((filter) => ( group.filters.map((filter) => (
<div <div
key={filter.field_key} key={filter.id}
className="mailpoet-automation-filters-list-item" className="mailpoet-automation-filters-list-item"
> >
<div className="mailpoet-automation-filters-list-item-content"> <div className="mailpoet-automation-filters-list-item-content">

View File

@@ -3,6 +3,9 @@
namespace MailPoet\Automation\Engine\Data; namespace MailPoet\Automation\Engine\Data;
class Filter { class Filter {
/** @var string */
private $id;
/** @var string */ /** @var string */
private $fieldType; private $fieldType;
@@ -16,17 +19,23 @@ class Filter {
private $args; private $args;
public function __construct( public function __construct(
string $id,
string $fieldType, string $fieldType,
string $fieldKey, string $fieldKey,
string $condition, string $condition,
array $args array $args
) { ) {
$this->id = $id;
$this->fieldType = $fieldType; $this->fieldType = $fieldType;
$this->fieldKey = $fieldKey; $this->fieldKey = $fieldKey;
$this->condition = $condition; $this->condition = $condition;
$this->args = $args; $this->args = $args;
} }
public function getId(): string {
return $this->id;
}
public function getFieldType(): string { public function getFieldType(): string {
return $this->fieldType; return $this->fieldType;
} }
@@ -45,6 +54,7 @@ class Filter {
public function toArray(): array { public function toArray(): array {
return [ return [
'id' => $this->id,
'field_type' => $this->fieldType, 'field_type' => $this->fieldType,
'field_key' => $this->fieldKey, 'field_key' => $this->fieldKey,
'condition' => $this->condition, 'condition' => $this->condition,
@@ -54,6 +64,7 @@ class Filter {
public static function fromArray(array $data): self { public static function fromArray(array $data): self {
return new self( return new self(
$data['id'],
$data['field_type'], $data['field_type'],
$data['field_key'], $data['field_key'],
$data['condition'], $data['condition'],

View File

@@ -6,6 +6,9 @@ class FilterGroup {
public const OPERATOR_AND = 'and'; public const OPERATOR_AND = 'and';
public const OPERATOR_OR = 'or'; public const OPERATOR_OR = 'or';
/** @var string */
private $id;
/** @var string */ /** @var string */
private $operator; private $operator;
@@ -13,13 +16,19 @@ class FilterGroup {
private $filters; private $filters;
public function __construct( public function __construct(
string $id,
string $operator, string $operator,
array $filters array $filters
) { ) {
$this->id = $id;
$this->operator = $operator; $this->operator = $operator;
$this->filters = $filters; $this->filters = $filters;
} }
public function getId(): string {
return $this->id;
}
public function getOperator(): string { public function getOperator(): string {
return $this->operator; return $this->operator;
} }
@@ -30,6 +39,7 @@ class FilterGroup {
public function toArray(): array { public function toArray(): array {
return [ return [
'id' => $this->id,
'operator' => $this->operator, 'operator' => $this->operator,
'filters' => array_map(function (Filter $filter): array { 'filters' => array_map(function (Filter $filter): array {
return $filter->toArray(); return $filter->toArray();
@@ -39,6 +49,7 @@ class FilterGroup {
public static function fromArray(array $data): self { public static function fromArray(array $data): self {
return new self( return new self(
$data['id'],
$data['operator'], $data['operator'],
array_map(function (array $filter) { array_map(function (array $filter) {
return Filter::fromArray($filter); return Filter::fromArray($filter);

View File

@@ -55,6 +55,7 @@ class AutomationSchema {
$operatorSchema = Builder::string()->pattern('^and|or$')->required(); $operatorSchema = Builder::string()->pattern('^and|or$')->required();
$filterSchema = Builder::object([ $filterSchema = Builder::object([
'id' => Builder::string()->required(),
'field_type' => Builder::string()->required(), 'field_type' => Builder::string()->required(),
'field_key' => Builder::string()->required(), 'field_key' => Builder::string()->required(),
'condition' => Builder::string()->required(), 'condition' => Builder::string()->required(),
@@ -62,6 +63,7 @@ class AutomationSchema {
]); ]);
$filterGroupSchema = Builder::object([ $filterGroupSchema = Builder::object([
'id' => Builder::string()->required(),
'operator' => $operatorSchema, 'operator' => $operatorSchema,
'filters' => Builder::array($filterSchema)->minItems(1)->required(), 'filters' => Builder::array($filterSchema)->minItems(1)->required(),
]); ]);

View File

@@ -173,8 +173,8 @@ class TriggerHandlerTest extends \MailPoetTest {
// automation that doesn't match segments filter // automation that doesn't match segments filter
$unknownId = $segment->getId() + 1; $unknownId = $segment->getId() + 1;
$filter = new Filter('enum_array', 'mailpoet:subscriber:segments', 'matches-any-of', ['value' => [$unknownId]]); $filter = new Filter('f1', 'enum_array', 'mailpoet:subscriber:segments', 'matches-any-of', ['value' => [$unknownId]]);
$filters = new Filters('and', [new FilterGroup('and', [$filter])]); $filters = new Filters('and', [new FilterGroup('g1', 'and', [$filter])]);
$automation = $this->tester->createAutomation( $automation = $this->tester->createAutomation(
'Will not run', 'Will not run',
new Step('trigger', Step::TYPE_TRIGGER, $trigger->getKey(), [], [], $filters) new Step('trigger', Step::TYPE_TRIGGER, $trigger->getKey(), [], [], $filters)
@@ -185,8 +185,8 @@ class TriggerHandlerTest extends \MailPoetTest {
$this->assertCount(0, $this->automationRunStorage->getAutomationRunsForAutomation($automation)); $this->assertCount(0, $this->automationRunStorage->getAutomationRunsForAutomation($automation));
// matches segments filter // matches segments filter
$filter = new Filter('enum_array', 'mailpoet:subscriber:segments', 'matches-any-of', ['value' => [$segment->getId()]]); $filter = new Filter('f1', 'enum_array', 'mailpoet:subscriber:segments', 'matches-any-of', ['value' => [$segment->getId()]]);
$filters = new Filters('and', [new FilterGroup('and', [$filter])]); $filters = new Filters('and', [new FilterGroup('g1', 'and', [$filter])]);
$automation = $this->tester->createAutomation( $automation = $this->tester->createAutomation(
'Will run', 'Will run',
new Step('trigger', Step::TYPE_TRIGGER, $trigger->getKey(), [], [], $filters) new Step('trigger', Step::TYPE_TRIGGER, $trigger->getKey(), [], [], $filters)

View File

@@ -25,7 +25,7 @@ use MailPoetUnitTest;
class FilterHandlerTest extends MailPoetUnitTest { class FilterHandlerTest extends MailPoetUnitTest {
/** @dataProvider dataForTestItFilters */ /** @dataProvider dataForTestItFilters */
public function testItFilters(array $stepFilters, bool $expectation): void { public function testItFilters(array $stepFilters, bool $expectation): void {
$filters = new Filters('and', [new FilterGroup('and', $stepFilters)]); $filters = new Filters('and', [new FilterGroup('g1', 'and', $stepFilters)]);
$step = new Step('step', Step::TYPE_TRIGGER, 'test:step', [], [], $filters); $step = new Step('step', Step::TYPE_TRIGGER, 'test:step', [], [], $filters);
$subject = $this->createSubject('subject', [ $subject = $this->createSubject('subject', [
new Field('test:field-string', Field::TYPE_STRING, 'Test field string', function () { new Field('test:field-string', Field::TYPE_STRING, 'Test field string', function () {
@@ -70,8 +70,8 @@ class FilterHandlerTest extends MailPoetUnitTest {
// matching // matching
[ [
[ [
new FilterData(Field::TYPE_STRING, 'test:field-string', '', ['value' => 'abc']), new FilterData('f1', Field::TYPE_STRING, 'test:field-string', '', ['value' => 'abc']),
new FilterData(Field::TYPE_INTEGER, 'test:field-integer', '', ['value' => 123]), new FilterData('f2', Field::TYPE_INTEGER, 'test:field-integer', '', ['value' => 123]),
], ],
true, true,
], ],
@@ -79,15 +79,15 @@ class FilterHandlerTest extends MailPoetUnitTest {
// not matching // not matching
[ [
[ [
new FilterData(Field::TYPE_INTEGER, 'test:field-integer', '', ['value' => 999]), new FilterData('f1', Field::TYPE_INTEGER, 'test:field-integer', '', ['value' => 999]),
], ],
false, false,
], ],
[ [
[ [
new FilterData(Field::TYPE_STRING, 'test:field-string', '', ['value' => 'abc']), new FilterData('f1', Field::TYPE_STRING, 'test:field-string', '', ['value' => 'abc']),
new FilterData(Field::TYPE_INTEGER, 'test:field-integer', '', ['value' => 999]), new FilterData('f2', Field::TYPE_INTEGER, 'test:field-integer', '', ['value' => 999]),
new FilterData(Field::TYPE_BOOLEAN, 'test:field-boolean', '', ['value' => true]), new FilterData('f3', Field::TYPE_BOOLEAN, 'test:field-boolean', '', ['value' => true]),
], ],
false, false,
], ],

View File

@@ -31,7 +31,7 @@ class ValidStepFiltersRuleTest extends AutomationRuleTest {
'validate' => Expected::once(), 'validate' => Expected::once(),
]); ]);
$filters = [new FilterData('string', 'test:key', 'is', ['value' => 'test'])]; $filters = [new FilterData('f1', 'string', 'test:key', 'is', ['value' => 'test'])];
$rule = new ValidStepFiltersRule($registry, $validator); $rule = new ValidStepFiltersRule($registry, $validator);
$automation = $this->getAutomation($filters); $automation = $this->getAutomation($filters);
(new AutomationWalker())->walk($automation, [$rule]); (new AutomationWalker())->walk($automation, [$rule]);
@@ -43,14 +43,14 @@ class ValidStepFiltersRuleTest extends AutomationRuleTest {
'validate' => Expected::never(), 'validate' => Expected::never(),
]); ]);
$filters = [new FilterData('string', 'test:key', 'is', ['value' => 'test'])]; $filters = [new FilterData('f1', 'string', 'test:key', 'is', ['value' => 'test'])];
$rule = new ValidStepFiltersRule($registry, $validator); $rule = new ValidStepFiltersRule($registry, $validator);
$automation = $this->getAutomation($filters); $automation = $this->getAutomation($filters);
(new AutomationWalker())->walk($automation, [$rule]); (new AutomationWalker())->walk($automation, [$rule]);
} }
private function getAutomation(array $filters): Automation { private function getAutomation(array $filters): Automation {
$filters = new Filters('and', [new FilterGroup('and', $filters)]); $filters = new Filters('and', [new FilterGroup('g1', 'and', $filters)]);
return $this->make(Automation::class, [ return $this->make(Automation::class, [
'getSteps' => [ 'getSteps' => [
'root' => new Step('root', 'root', 'core:root', [], [], $filters), 'root' => new Step('root', 'root', 'core:root', [], [], $filters),

View File

@@ -102,6 +102,6 @@ class EnumArrayFilterTest extends MailPoetUnitTest {
private function matchesFilter(string $condition, $filterValue, $value): bool { private function matchesFilter(string $condition, $filterValue, $value): bool {
$filter = new EnumArrayFilter(); $filter = new EnumArrayFilter();
return $filter->matches(new Filter('string', '', $condition, ['value' => $filterValue]), $value); return $filter->matches(new Filter('f1', 'string', '', $condition, ['value' => $filterValue]), $value);
} }
} }

View File

@@ -166,6 +166,6 @@ class StringFilterTest extends MailPoetUnitTest {
private function matchesFilter(string $condition, $filterValue, $value): bool { private function matchesFilter(string $condition, $filterValue, $value): bool {
$filter = new StringFilter(); $filter = new StringFilter();
return $filter->matches(new Filter('string', '', $condition, ['value' => $filterValue]), $value); return $filter->matches(new Filter('f1', 'string', '', $condition, ['value' => $filterValue]), $value);
} }
} }