diff --git a/CHANGELOG.md b/CHANGELOG.md index 93a01ad..17347c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - model: replace regexp-based ISO datetime parsing with `datetime.fromisoformat` for `Edm.DateTime` and `Edm.DateTimeOffset` - Petr Hanak +- model: fix stripping single-quotes from string values - Petr Hanak - service: guard against cross-origin __next URL redirection - Petr Hanak + ### Removed - Python 3.9 is no longer supported by pyodata. Python 3.10 is now the minimal supported version. diff --git a/pyodata/v2/model.py b/pyodata/v2/model.py index 9a8e60b..7312b01 100644 --- a/pyodata/v2/model.py +++ b/pyodata/v2/model.py @@ -574,10 +574,12 @@ def to_literal(self, value): # pylint: disable=no-self-use def from_json(self, value): - return value.strip('\'') + return value def from_literal(self, value): - return value.strip('\'') + if len(value) >= 2 and value[0] == "'" and value[-1] == "'": + return value[1:-1] + return value class EdmBooleanTypTraits(TypTraits): diff --git a/tests/test_model_v2.py b/tests/test_model_v2.py index d2e9bc5..32aa207 100644 --- a/tests/test_model_v2.py +++ b/tests/test_model_v2.py @@ -412,6 +412,24 @@ def test_traits(): assert typ.traits.to_literal('Foo Foo') == "'Foo Foo'" assert typ.traits.from_literal("'Alice Bob'") == 'Alice Bob' + # EdmStringTypTraits.from_json — must return value unchanged + assert typ.traits.from_json('hello') == 'hello' + assert typ.traits.from_json("'A' crew") == "'A' crew" + assert typ.traits.from_json("Eng Department'") == "Eng Department'" + assert typ.traits.from_json("'wrapped'") == "'wrapped'" + + # EdmStringTypTraits.from_literal — must remove exactly one wrapping pair + assert typ.traits.from_literal("''A' crew'") == "'A' crew" + assert typ.traits.from_literal("'Eng Department''") == "Eng Department'" + assert typ.traits.from_literal("''") == '' + assert typ.traits.from_literal('') == '' + + # EdmStringTypTraits.from_literal — guard conditions quotes around the value + assert typ.traits.from_literal('no quotes') == 'no quotes' + assert typ.traits.from_literal("'only left") == "'only left" + assert typ.traits.from_literal("only right'") == "only right'" + assert typ.traits.from_literal("'") == "'" + # bool typ = Types.from_name('Edm.Boolean') assert repr(typ.traits) == 'EdmBooleanTypTraits' @@ -941,7 +959,7 @@ def test_complex_serializer(schema): # entity with properties of ODATA primitive types entity_type = schema.entity_type('TemperatureMeasurement') assert srl.to_literal(entity_type, {'ignored-key': 'ignored-value', 'Sensor': 'x'}) == {'Sensor': "'x'"} - assert srl.from_json(entity_type, {'ignored-key': 'ignored-value', 'Sensor': "'x'"}) == {'Sensor': 'x'} + assert srl.from_json(entity_type, {'ignored-key': 'ignored-value', 'Sensor': 'x'}) == {'Sensor': 'x'} @patch('logging.Logger.warning') diff --git a/tests/test_model_v2_EdmStructTypeSerializer.py b/tests/test_model_v2_EdmStructTypeSerializer.py index 9b6eee7..d1dc41c 100644 --- a/tests/test_model_v2_EdmStructTypeSerializer.py +++ b/tests/test_model_v2_EdmStructTypeSerializer.py @@ -9,7 +9,7 @@ @pytest.fixture def complex_type_property_declarations(): return { - 'TestString': (Types.parse_type_name('Edm.String'), "'FooBar'", "'FooBar'", 'FooBar'), + 'TestString': (Types.parse_type_name('Edm.String'), 'FooBar', "'FooBar'", 'FooBar'), 'TestBoolean': (Types.parse_type_name('Edm.Boolean'), False, 'false', False), 'TestInt64': (Types.parse_type_name('Edm.Int64'), '123L', '123L', 123), 'TestDateTime': (Types.parse_type_name('Edm.DateTime'), "/Date(2147483647000)/", "datetime'2038-01-19T03:14:07'",