Skip to content

Commit

Permalink
feat: add Null value which stands in for a forced XML nil value
Browse files Browse the repository at this point in the history
This allows things to be specifically unset, which was not previously possible.
At present the reverse path for decoding this has not been implemented.
  • Loading branch information
nigelm committed Jun 26, 2022
1 parent 2467b8f commit 4701ec5
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
24 changes: 15 additions & 9 deletions broadworks_ocip/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import attr
from lxml import etree
from null_object import Null

from broadworks_ocip.exceptions import OCIErrorAPISetup
from broadworks_ocip.exceptions import OCIErrorAttributeMissing
Expand Down Expand Up @@ -73,7 +74,10 @@ def __init__(self, **kwargs):
raise OCIErrorAttributeMissing(
message=f"{cname}: Required attribute {elem.name} is missing",
)
if elem.is_array:
if value is Null:
# always allowed
pass
elif elem.is_array:
if not isinstance(value, list):
raise TypeError(
f"{cname}: Expected {elem.name} to be a list but it is {type(value)}",
Expand Down Expand Up @@ -212,14 +216,16 @@ def etree_sub_element_(
Returns:
etree: etree.Element() for this class
"""
if value is None:
if sub_element.is_required:
etree.SubElement(
element,
sub_element.xmlname,
{"{http://www.w3.org/2001/XMLSchema-instance}nil": "true"},
nsmap=self._default_nsmap(),
)
# if value is Null or (value is None and sub_element.is_required):
if value is Null or (value is None and sub_element.is_required):
etree.SubElement(
element,
sub_element.xmlname,
{"{http://www.w3.org/2001/XMLSchema-instance}nil": "true"},
nsmap=self._default_nsmap(),
)
elif value is None:
pass
elif sub_element.is_table:
# any table should be a list of namedtuple elements
if type(value) is list and len(value) > 0:
Expand Down
13 changes: 12 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ exclude = [
python = ">=3.6.2,<4.0"
lxml = "^4.7.1"
attrs = "^21.4.0"
null-object = "^0.1.0"

[tool.poetry.dev-dependencies]
pytest = "^6.2.5"
Expand Down
16 changes: 9 additions & 7 deletions tests/test_basic_command_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest # noqa: F401
from lxml import etree
from null_object import Null

from broadworks_ocip import BroadworksAPI

Expand Down Expand Up @@ -425,13 +426,14 @@ def test_nested_elements():
phone_number="123456789",
extension="1219",
# sip_alias_list=api.get_type_object("ReplacementSIPAliasList",sip_alias=[]),
sip_alias_list=Null,
endpoint=dict(
trunk_addressing=api.get_type_object(
"TrunkAddressingMultipleContactModify",
# trunk_group_device_endpoint=None,
trunk_group_device_endpoint=Null,
enterprise_trunk_name="ET02",
# alternate_trunk_identity=None,
# physical_location=None,
alternate_trunk_identity=Null,
physical_location=Null,
),
),
)
Expand All @@ -444,13 +446,13 @@ def test_nested_elements():
b"<userId>user@example.com</userId>"
b"<phoneNumber>123456789</phoneNumber>"
b"<extension>1219</extension>"
# b'<sipAliasList xsi:nil="true"/>'
b'<sipAliasList xsi:nil="true"/>'
b"<endpoint>"
b"<trunkAddressing>"
# b'<trunkGroupDeviceEndpoint xsi:nil="true"/>'
b'<trunkGroupDeviceEndpoint xsi:nil="true"/>'
b"<enterpriseTrunkName>ET02</enterpriseTrunkName>"
# b'<alternateTrunkIdentity xsi:nil="true"/>'
# b'<physicalLocation xsi:nil="true"/>'
b'<alternateTrunkIdentity xsi:nil="true"/>'
b'<physicalLocation xsi:nil="true"/>'
b"</trunkAddressing>"
b"</endpoint>"
b"</command>"
Expand Down

0 comments on commit 4701ec5

Please sign in to comment.