Skip to content

Commit 903207e

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

File tree

2 files changed

+158
-7
lines changed

2 files changed

+158
-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: 154 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
/*
46
* This file is part of the MassiveSearchBundle
57
*
@@ -14,24 +16,30 @@
1416
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Expression;
1517
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Field;
1618
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Property;
19+
use Massive\Bundle\SearchBundle\Search\Metadata\Field\Value;
1720
use Massive\Bundle\SearchBundle\Search\Metadata\FieldEvaluator;
1821
use Massive\Bundle\SearchBundle\Search\Metadata\FieldInterface;
19-
use Massive\Bundle\SearchBundle\Search\ObjectToDocumentConverter;
2022
use Massive\Bundle\SearchBundle\Tests\Resources\TestBundle\Product;
2123
use PHPUnit\Framework\TestCase;
2224
use Prophecy\Argument;
2325
use Prophecy\PhpUnit\ProphecyTrait;
26+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
2427

2528
class FieldEvaluatorTest extends TestCase
2629
{
2730
use ProphecyTrait;
2831

2932
/**
30-
* @var ObjectToDocumentConverter
33+
* @var FieldEvaluator
3134
*/
3235
private $fieldEvaluator;
3336

34-
public function setUp()
37+
/**
38+
* @var ExpressionLanguage
39+
*/
40+
private $expressionLanguage;
41+
42+
protected function setUp()
3543
{
3644
parent::setUp();
3745
$this->expressionLanguage = $this->prophesize('Symfony\Component\ExpressionLanguage\ExpressionLanguage');
@@ -43,27 +51,62 @@ public function setUp()
4351
public function provideGetValue()
4452
{
4553
return [
46-
[
54+
'Field with string value' => [
4755
new Field('title'),
4856
[
4957
'title' => 'My product',
5058
],
5159
'My product',
5260
],
53-
[
61+
'Property with string value' => [
5462
new Property('title'),
5563
[
5664
'title' => 'My product',
5765
],
5866
'My product',
5967
],
60-
[
68+
'Expression' => [
6169
new Expression('object.title'),
6270
[
6371
'title' => 'My product',
6472
],
6573
'this_was_evaluated',
6674
],
75+
'Field with integer value' => [
76+
new Field('price'),
77+
[
78+
'price' => 1999,
79+
],
80+
1999,
81+
],
82+
'Property with boolean value' => [
83+
new Property('isActive'),
84+
[
85+
'isActive' => true,
86+
],
87+
true,
88+
],
89+
'Field with array value' => [
90+
new Field('tags'),
91+
[
92+
'tags' => ['tag1', 'tag2'],
93+
],
94+
['tag1', 'tag2'],
95+
],
96+
'Property with null value' => [
97+
new Property('description'),
98+
[
99+
'description' => null,
100+
],
101+
null,
102+
],
103+
'Field with object value' => [
104+
new Field('category'),
105+
[
106+
'category' => 'Electronics',
107+
],
108+
'Electronics',
109+
],
67110
];
68111
}
69112

@@ -78,6 +121,110 @@ public function testGetValue(FieldInterface $field, $data, $expectedValue)
78121
}
79122

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

0 commit comments

Comments
 (0)