Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed
- Escape slashes in entity keys when they appear in the URL path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: if you see the changelog entries, we add also author names for important changes. So feel free to add yourself to this line :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding my name for the fame and fortune!


### Removed
- Python 3.7 (long after its EOL) is no longer supported by pyodata. Python 3.8 is now minimal supported version. - Petr Hanak
Expand Down
6 changes: 3 additions & 3 deletions pyodata/v2/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def expand(self, expand):

def get_path(self):
if self.get_encode_path():
return quote(self._entity_set_proxy.last_segment + self._entity_key.to_key_string())
return quote(self._entity_set_proxy.last_segment) + quote(self._entity_key.to_key_string(), safe='')
return self._entity_set_proxy.last_segment + self._entity_key.to_key_string()

def get_default_headers(self):
Expand Down Expand Up @@ -563,7 +563,7 @@ def __init__(self, url, connection, handler, entity_set, entity_key, encode_path

def get_path(self):
if self.get_encode_path():
return quote(self._entity_set.name + self._entity_key.to_key_string())
return quote(self._entity_set.name) + quote(self._entity_key.to_key_string(), safe='')
return self._entity_set.name + self._entity_key.to_key_string()

def get_encode_path(self):
Expand Down Expand Up @@ -607,7 +607,7 @@ def __init__(self, url, connection, handler, entity_set, entity_key, method="PAT

def get_path(self):
if self.get_encode_path():
return quote(self._entity_set.name + self._entity_key.to_key_string())
return quote(self._entity_set.name) + quote(self._entity_key.to_key_string(), safe='')
return self._entity_set.name + self._entity_key.to_key_string()

def get_method(self):
Expand Down
17 changes: 17 additions & 0 deletions tests/test_service_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,22 @@ def test_entity_url(service):
entity = service.entity_sets.MasterEntities.get_entity('12345').execute()
assert entity.url == URL_ROOT + "/MasterEntities('12345')"

@responses.activate
def test_entity_url_with_slashes(service):
"""Test correct build of entity url"""

# pylint: disable=redefined-outer-name
path = quote("MasterEntities('FOO/BAR')", safe='')
responses.add(
responses.GET,
f"{service.url}/{path}",
headers={'Content-type': 'application/json'},
json={'d': {'Key': 'FOO/BAR'}},
status=200)

entity = service.entity_sets.MasterEntities.get_entity('FOO/BAR').execute()
assert entity.url == URL_ROOT + "/MasterEntities('FOO/BAR')"


@responses.activate
def test_entity_entity_set_name(service):
Expand Down Expand Up @@ -631,6 +647,7 @@ def test_delete_entity(service):
assert isinstance(request, pyodata.v2.service.EntityDeleteRequest)
assert request.execute() is None


@responses.activate
def test_delete_entity_not_encoded_path(service):
"""Check deleting of entity"""
Expand Down