Skip to content

Commit 8fdf834

Browse files
Support 'in' syntax for test query predicates (#105)
Co-authored-by: David Weterings <d.weterings@labdigital.nl>
1 parent d932312 commit 8fdf834

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

src/commercetools/testing/predicates.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import operator
1010
import re
1111
import typing
12+
from functools import partial
1213

1314
import marshmallow
1415

@@ -419,6 +420,7 @@ class PredicateFilter:
419420
"!=": operator.ne,
420421
"<>": operator.ne,
421422
"is not": operator.is_not,
423+
"in": operator.contains,
422424
}
423425

424426
def __init__(self, predicate, schema):
@@ -481,6 +483,8 @@ def filter_field(
481483
for child_doc in obj
482484
)
483485

486+
is_sequence_value = False
487+
484488
if isinstance(schema_field, marshmallow.fields.Dict):
485489
obj = schema_field._deserialize(obj, None, None)
486490
assert len(path) == 1
@@ -489,15 +493,27 @@ def filter_field(
489493
if obj is not None:
490494
obj = schema_field._deserialize(obj, None, None)
491495
if value is not None:
492-
value = schema_field._deserialize(value, None, None)
496+
is_sequence_value = isinstance(value, tuple) or isinstance(value, list)
497+
if is_sequence_value:
498+
deserialize = partial(
499+
schema_field._deserialize, attr=None, data=None
500+
)
501+
value = list(map(deserialize, value))
502+
else:
503+
value = schema_field._deserialize(value, None, None)
493504

494-
# Case insensitve comparison for strings
505+
op = self.operators[operator_value]
506+
507+
# Case insensitive comparison for strings
495508
if isinstance(obj, str):
496509
obj = obj.lower()
497510
if isinstance(value, str):
498511
value = value.lower()
512+
elif is_sequence_value:
513+
value = [x.lower() if isinstance(x, str) else x for x in value]
514+
if operator_value == "in":
515+
return op(value, obj)
499516

500-
op = self.operators[operator_value]
501517
return op(obj, value)
502518

503519
def case_insensitive_get(sef, dict, key, default=None):

tests/test_testing_predicates.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import ast
2-
import re
3-
41
import pytest
52

63
from commercetools._schemas._product import ProductDataSchema
@@ -58,3 +55,27 @@ def mock_filter_field(obj, path, operator, value):
5855
pf.filter_field = mock_filter_field
5956
pf.match({"slug": {"nl-BE": "test-categorie"}})
6057
assert paths == found_paths
58+
59+
60+
def test_in_filter():
61+
skus = '("1337", "1338")'
62+
predicate = f"masterVariant(sku in {skus}) or variants(sku in {skus})"
63+
pf = predicates.PredicateFilter(predicate, schema=ProductDataSchema)
64+
65+
product_data = {
66+
"masterVariant": {"sku": "1337"},
67+
"variants": [{"sku": "1338"}, {"sku": "1339"}],
68+
}
69+
assert pf.match(product_data) is True
70+
71+
product_data = {
72+
"masterVariant": {"sku": "1444"},
73+
"variants": [{"sku": "1338"}, {"sku": "1339"}],
74+
}
75+
assert pf.match(product_data) is True
76+
77+
product_data = {
78+
"masterVariant": {"sku": "1444"},
79+
"variants": [{"sku": "1438"}, {"sku": "1139"}],
80+
}
81+
assert pf.match(product_data) is False

0 commit comments

Comments
 (0)