Skip to content

Commit e10c933

Browse files
add check for non array in field-evaluator
1 parent 7e127de commit e10c933

File tree

2 files changed

+156
-7
lines changed

2 files changed

+156
-7
lines changed

Search/Metadata/FieldEvaluator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ public function getValue($object, FieldInterface $field)
7272

7373
public function evaluateCondition($object, string $condition)
7474
{
75+
if (!\is_array($object)) {
76+
return false;
77+
}
78+
7579
try {
7680
return $this->expressionLanguage->evaluate($condition, $object);
7781
} catch (\Exception $e) {

Tests/Unit/Search/Metadata/FieldEvaluatorTest.php

Lines changed: 152 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,30 @@
1414
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Expression;
1515
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Field;
1616
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Property;
17+
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Value;
1718
use Massive\Bundle\SearchBundle\Search\Metadata\FieldEvaluator;
1819
use Massive\Bundle\SearchBundle\Search\Metadata\FieldInterface;
19-
use Massive\Bundle\SearchBundle\Search\ObjectToDocumentConverter;
2020
use Massive\Bundle\SearchBundle\Tests\Resources\TestBundle\Product;
2121
use PHPUnit\Framework\TestCase;
2222
use Prophecy\Argument;
2323
use Prophecy\PhpUnit\ProphecyTrait;
24+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
2425

2526
class FieldEvaluatorTest extends TestCase
2627
{
2728
use ProphecyTrait;
2829

2930
/**
30-
* @var ObjectToDocumentConverter
31+
* @var FieldEvaluator
3132
*/
3233
private $fieldEvaluator;
3334

34-
public function setUp()
35+
/**
36+
* @var ExpressionLanguage
37+
*/
38+
private $expressionLanguage;
39+
40+
protected function setUp()
3541
{
3642
parent::setUp();
3743
$this->expressionLanguage = $this->prophesize('Symfony\Component\ExpressionLanguage\ExpressionLanguage');
@@ -43,27 +49,62 @@ public function setUp()
4349
public function provideGetValue()
4450
{
4551
return [
46-
[
52+
'Field with string value' => [
4753
new Field('title'),
4854
[
4955
'title' => 'My product',
5056
],
5157
'My product',
5258
],
53-
[
59+
'Property with string value' => [
5460
new Property('title'),
5561
[
5662
'title' => 'My product',
5763
],
5864
'My product',
5965
],
60-
[
66+
'Expression' => [
6167
new Expression('object.title'),
6268
[
6369
'title' => 'My product',
6470
],
6571
'this_was_evaluated',
6672
],
73+
'Field with integer value' => [
74+
new Field('price'),
75+
[
76+
'price' => 1999,
77+
],
78+
1999,
79+
],
80+
'Property with boolean value' => [
81+
new Property('isActive'),
82+
[
83+
'isActive' => true,
84+
],
85+
true,
86+
],
87+
'Field with array value' => [
88+
new Field('tags'),
89+
[
90+
'tags' => ['tag1', 'tag2'],
91+
],
92+
['tag1', 'tag2'],
93+
],
94+
'Property with null value' => [
95+
new Property('description'),
96+
[
97+
'description' => null,
98+
],
99+
null,
100+
],
101+
'Field with object value' => [
102+
new Field('category'),
103+
[
104+
'category' => 'Electronics',
105+
],
106+
'Electronics',
107+
],
67108
];
68109
}
69110

@@ -78,6 +119,110 @@ public function testGetValue(FieldInterface $field, $data, $expectedValue)
78119
}
79120

80121
$result = $this->fieldEvaluator->getValue($product, $field);
81-
$this->assertEquals($expectedValue, $result);
122+
$this->assertSame($expectedValue, $result);
123+
}
124+
125+
public function testGetValueWithValue()
126+
{
127+
// Create a real Value instance instead of a mock
128+
$valueField = new Value('static value');
129+
130+
$result = $this->fieldEvaluator->getValue(new Product(), $valueField);
131+
$this->assertSame('static value', $result);
132+
}
133+
134+
public function testGetValueWithArrayAndField()
135+
{
136+
$field = new Field('name');
137+
$data = ['name' => 'Array value'];
138+
139+
$result = $this->fieldEvaluator->getValue($data, $field);
140+
$this->assertSame('Array value', $result);
141+
}
142+
143+
public function testGetValueWithInvalidFieldType()
144+
{
145+
$this->expectException(\RuntimeException::class);
146+
$this->expectExceptionMessage('Unknown field type');
147+
148+
$invalidField = $this->prophesize(FieldInterface::class)->reveal();
149+
$this->fieldEvaluator->getValue(new Product(), $invalidField);
150+
}
151+
152+
public function testGetValueWithInvalidPropertyAccess()
153+
{
154+
$this->expectException(\Exception::class);
155+
$this->expectExceptionMessage('Error encountered when trying to determine value');
156+
157+
$product = new Product();
158+
$field = new Property('nonexistentProperty');
159+
160+
$this->fieldEvaluator->getValue($product, $field);
161+
}
162+
163+
public function testGetExpressionValueWithError()
164+
{
165+
$this->expectException(\Exception::class);
166+
$this->expectExceptionMessage('Error encountered when trying to determine value');
167+
168+
$this->expressionLanguage->evaluate(Argument::any(), Argument::any())
169+
->willThrow(new \Exception('Expression error'));
170+
171+
$product = new Product();
172+
$field = new Expression('object.something');
173+
174+
$this->fieldEvaluator->getValue($product, $field);
175+
}
176+
177+
public function provideEvaluateCondition()
178+
{
179+
return [
180+
'True condition' => [
181+
['age' => 25, 'active' => true],
182+
'age > 18 and active == true',
183+
true,
184+
],
185+
'False condition' => [
186+
['age' => 15, 'active' => true],
187+
'age > 18 and active == true',
188+
false,
189+
],
190+
'Complex condition' => [
191+
['price' => 100, 'discount' => 20, 'stock' => 5],
192+
'price > 50 and (discount > 10 or stock > 10)',
193+
true,
194+
],
195+
];
196+
}
197+
198+
/**
199+
* @dataProvider provideEvaluateCondition
200+
*/
201+
public function testEvaluateCondition(array $object, string $condition, bool $expected)
202+
{
203+
$expressionLanguage = new ExpressionLanguage();
204+
$fieldEvaluator = new FieldEvaluator($expressionLanguage);
205+
206+
$result = $fieldEvaluator->evaluateCondition($object, $condition);
207+
$this->assertSame($expected, $result);
208+
}
209+
210+
public function testEvaluateConditionWithNonArrayObject()
211+
{
212+
$product = new Product();
213+
$result = $this->fieldEvaluator->evaluateCondition($product, 'whatever');
214+
215+
$this->assertFalse($result);
216+
}
217+
218+
public function testEvaluateConditionWithError()
219+
{
220+
$this->expectException(\RuntimeException::class);
221+
$this->expectExceptionMessage('Error encountered when evaluating expression');
222+
223+
$this->expressionLanguage->evaluate(Argument::any(), Argument::any())
224+
->willThrow(new \Exception('Expression error'));
225+
226+
$this->fieldEvaluator->evaluateCondition(['test' => true], 'invalid_syntax');
82227
}
83228
}

0 commit comments

Comments
 (0)