Skip to content

Commit 7223e96

Browse files
committed
feat(xml_rpc): add response serialization
1 parent f575a1e commit 7223e96

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

sipgate_e2e_test_utils/xml_rpc.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ def __repr__(self) -> str:
4545
def parse(body: str | bytes) -> 'XmlRpcResponse':
4646
return _parse_xml_rpc_response(body)
4747

48+
def serialize(self) -> str:
49+
return _serialize_xml_rpc_response(self)
50+
4851

4952
def _parse_xml_rpc_request(body: str | bytes) -> XmlRpcRequest:
5053
root = ElementTree.fromstring(body)
@@ -90,6 +93,23 @@ def _parse_xml_rpc_response(body: str | bytes) -> XmlRpcResponse:
9093
return XmlRpcResponse(int(members.pop('faultCode')), str(members.pop('faultString')), members)
9194

9295

96+
def _serialize_xml_rpc_response(response: XmlRpcResponse) -> str:
97+
params = dict(response.members, **{
98+
'faultCode': response.fault_code,
99+
'faultString': response.fault_string,
100+
})
101+
102+
if response.fault_code == 200:
103+
wrapper = '<params><param><value>{}</value></param></params>'
104+
else:
105+
wrapper = '<fault><value>{}</value></fault>'
106+
107+
return f"""<?xml version="1.0"?>
108+
<methodResponse>
109+
{wrapper.format(__serialize_struct(params))}
110+
</methodResponse>"""
111+
112+
93113
def __parse_member(node: Element) -> tuple[str, Any]:
94114
assert node.tag == 'member', f"expected 'member', but got {node.tag=}"
95115

tests/test_xml_rpc_response.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,77 @@ def test_call_has_string_representation(self) -> None:
141141

142142
parsed = XmlRpcResponse.parse(body)
143143
self.assertRegex(f"{parsed}", '^<XmlRpcResponse.*faultCode.*200.*>$')
144+
145+
def test_serialization_success_response(self) -> None:
146+
response = XmlRpcResponse(200, 'OK')
147+
148+
expected_body = """<?xml version="1.0"?>
149+
<methodResponse>
150+
<params>
151+
<param><value>
152+
<struct>
153+
<member><name>faultCode</name><value><i4>200</i4></value></member>
154+
<member><name>faultString</name><value><string>OK</string></value></member>
155+
</struct>
156+
</value></param>
157+
</params>
158+
</methodResponse>"""
159+
160+
# TODO: use better comparison
161+
# this would ignore spaces in values and does not ignore order of params
162+
self.assertEqual(''.join(expected_body.split()), ''.join(response.serialize().split()))
163+
164+
def test_serialization_fault_response(self) -> None:
165+
response = XmlRpcResponse(407, 'NOT SO OKAY')
166+
167+
expected_body = """<?xml version="1.0"?>
168+
<methodResponse>
169+
<fault><value>
170+
<struct>
171+
<member><name>faultCode</name><value><i4>407</i4></value></member>
172+
<member><name>faultString</name><value><string>NOT SO OKAY</string></value></member>
173+
</struct>
174+
</value></fault>
175+
</methodResponse>"""
176+
177+
# TODO: use better comparison
178+
# this would ignore spaces in values and does not ignore order of params
179+
self.assertEqual(''.join(expected_body.split()), ''.join(response.serialize().split()))
180+
181+
def test_serialization(self) -> None:
182+
response = XmlRpcResponse(200, 'OK', {
183+
'an_int': 42,
184+
'a_string': 'the_value',
185+
'a_struct': {
186+
'another_int': 23
187+
},
188+
'an_array': [{
189+
'another_str': 'the_other_value'
190+
}]
191+
})
192+
193+
expected_body = """<?xml version="1.0"?>
194+
<methodResponse>
195+
<params><param><value>
196+
<struct>
197+
<member><name>an_int</name><value><i4>42</i4></value></member>
198+
<member><name>a_string</name><value><string>the_value</string></value></member>
199+
<member><name>a_struct</name><value><struct>
200+
<member><name>another_int</name><value><i4>23</i4></value></member>
201+
</struct></value></member>
202+
<member><name>an_array</name><value><array>
203+
<data>
204+
<value><struct>
205+
<member><name>another_str</name><value><string>the_other_value</string></value></member>
206+
</struct></value>
207+
</data>
208+
</array></value></member>
209+
<member><name>faultCode</name><value><i4>200</i4></value></member>
210+
<member><name>faultString</name><value><string>OK</string></value></member>
211+
</struct>
212+
</value></param></params>
213+
</methodResponse>"""
214+
215+
# TODO: use better comparison
216+
# this would ignore spaces in values and does not ignore order of params
217+
self.assertEqual(''.join(expected_body.split()), ''.join(response.serialize().split()))

0 commit comments

Comments
 (0)