Clean json returned from server for keys with None values

Add testing
This commit is contained in:
Odd Stråbø 2020-08-21 15:09:34 +02:00
parent 8a3ca73d52
commit ed96dc8ad5
7 changed files with 188 additions and 4 deletions

66
.gitignore vendored
View file

@ -1,12 +1,72 @@
*.pyo
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
__local__/
machine_guid
/resources/media/Thumbs.db
Thumbs.db
.idea/
.DS_Store
.vscode/
pyinstrument/
pyinstrument_cext.so
# Now managed by templates
addon.xml
*.log

View file

@ -11,6 +11,7 @@ from six import string_types, ensure_str
from helper.utils import JsonDebugPrinter
from helper import LazyLogger
from helper.exceptions import HTTPException
from jellyfin.utils import clean_none_dict_values
#################################################################################################
@ -161,7 +162,7 @@ class HTTP(object):
LOG.debug("---<[ http ][%s ms]", elapsed)
LOG.debug(JsonDebugPrinter(response))
return response
return clean_none_dict_values(response)
except ValueError:
return

View file

@ -0,0 +1,43 @@
from six import string_types
from six.moves import collections_abc
def clean_none_dict_values(obj):
"""
Recursively remove keys with a value of None
"""
if not isinstance(obj, collections_abc.Iterable) or isinstance(obj, string_types):
return obj
queue = [obj]
while queue:
item = queue.pop()
if isinstance(item, collections_abc.Mapping):
mutable = isinstance(item, collections_abc.MutableMapping)
remove = []
for key, value in item.items():
if value is None and mutable:
remove.append(key)
elif isinstance(value, string_types):
continue
elif isinstance(value, collections_abc.Iterable):
queue.append(value)
if mutable:
# Remove keys with None value
for key in remove:
item.pop(key)
elif isinstance(item, collections_abc.Iterable):
for value in item:
if value is None or isinstance(value, string_types):
continue
elif isinstance(value, collections_abc.Iterable):
queue.append(value)
return obj

13
requirements-dev.txt Normal file
View file

@ -0,0 +1,13 @@
setuptools >= 44.1.1 # Old setuptools causes script.module.addon.signals to fail installing
six >= 1.13
python-dateutil >= 2.8.1
requests >= 2.22
futures >= 2.2; python_version < '3.0'
git+https://github.com/oddstr13/Kodistubs@python3 # Kodistubs >= 18
git+https://github.com/romanvm/kodi.six
git+https://github.com/ruuk/script.module.addon.signals
pytest >= 4.6.11
coverage >= 5.2
flake8 >= 3.8
flake8-import-order >= 0.18

0
tests/__init__.py Normal file
View file

View file

@ -0,0 +1,51 @@
import sys
import pytest
sys.path.insert(0, 'jellyfin_kodi')
from jellyfin.utils import clean_none_dict_values # noqa: E402
@pytest.mark.parametrize("obj,expected", [
(None, None),
([None, 1, 2, 3, None, 4], [None, 1, 2, 3, None, 4]),
({'foo': None, 'bar': 123}, {'bar': 123}),
({
'dict': {
'empty': None,
'string': "Hello, Woorld!",
},
'number': 123,
'list': [
None,
123,
"foo",
{
'empty': None,
'number': 123,
'string': "foo",
'list': [],
'dict': {},
}
]
}, {
'dict': {
'string': "Hello, Woorld!",
},
'number': 123,
'list': [
None,
123,
"foo",
{
'number': 123,
'string': "foo",
'list': [],
'dict': {},
}
]
}),
])
def test_clean_none_dict_values(obj, expected):
assert clean_none_dict_values(obj) == expected

16
tox.ini
View file

@ -6,3 +6,19 @@ extend-ignore =
I202
per-file-ignores =
*/__init__.py: F401
[pytest]
minversion = 4.6
testpaths =
tests
[coverage:run]
source =
jellyfin_kodi
context.py
context_play.py
default.py
service.py
.config/generate_xml.py
omit = tests/*
command_line = -m pytest