Allow query without value.

This commit is contained in:
Jakub Zdroik 2020-12-03 17:31:30 +01:00 committed by Jakub Gocławski
parent 9da9c530ac
commit 7fb2ab6410
No known key found for this signature in database
GPG key ID: DB23479BBC13E2A3
6 changed files with 42 additions and 8 deletions

View file

@ -236,7 +236,7 @@ Now, let's use `count-only`.
CLI: `/ip/dhcp-server/lease/print count-only` (returns 13)
```python
>>> api.get_resource('/ip/dhcp-server/lease').call('print', {'count-only': ''}).done_message
>>> api.get_resource('/ip/dhcp-server/lease').call('print', {'count-only': None}).done_message
{'ret': '13'}
```
@ -246,7 +246,7 @@ Now, let's use `count-only` and `where`.
CLI: `/ip/dhcp-server/lease/print count-only where server=developers` (returns 4)
```python
>>> api.get_resource('/ip/dhcp-server/lease').call('print', {'count-only': ''}, {'server': 'developers'}).done_message
>>> api.get_resource('/ip/dhcp-server/lease').call('print', {'count-only': None}, {'server': 'developers'}).done_message
{'ret': '4'}
```
@ -256,7 +256,7 @@ Now, let's use `count-only` and `where` with boolean value.
CLI: `/ip/route/pri count-only where static` (returns 1)
```python
>>> api.get_resource('/ip/route').call('print', {'count-only': ''}, {'static': 'yes'}).done_message
>>> api.get_resource('/ip/route').call('print', {'count-only': None}, {'static': 'yes'}).done_message
{'ret': '1'}
```
@ -281,7 +281,7 @@ True
CLI command: `/interface/ethernet/poe/monitor numbers=0 once`
```python
>>> response = api.get_resource('/interface/ether/poe').call('monitor', {'numbers': '0', 'once': ''})
>>> response = api.get_resource('/interface/ether/poe').call('monitor', {'numbers': '0', 'once': None})
>>> response
[{'name': 'ether10', 'poe-out': 'auto-on', 'poe-out-status': 'waiting-for-load'}]
```

View file

@ -21,7 +21,7 @@ class EncodingApiCommunicator(object):
def transform_item(self, item):
key, value = item
if not isinstance(value, bytes):
if value is not None and not isinstance(value, bytes):
logger.warning(
'Non-bytes value passed as item value ({}). You should probably use api.get_resource() instead of '
'api.get_binary_resource() or encode arguments yourself.'.format(value))

View file

@ -66,7 +66,10 @@ class RouterOsResource(RouterOsBinaryResource):
def transform_item(self, item):
key, value = item
return (key, self.structure[key].get_mikrotik_value(value))
if value is None:
return (key, None)
else:
return (key, self.structure[key].get_mikrotik_value(value))
def decorate_promise(self, promise):
return TypedPromiseDecorator(promise, self.structure)
@ -89,7 +92,10 @@ class TypedPromiseDecorator(object):
def transform_item(self, item):
key, value = item
return (key, self.structure[key].get_python_value(value))
if value is None:
return (key, None)
else:
return (key, self.structure[key].get_python_value(value))
def clean_path(path):

View file

@ -54,7 +54,10 @@ class CommandSentence(object):
def get_api_format(self):
formated = [self.path + self.command]
for key, value in self.attributes.items():
formated.append(b'=' + key + b'=' + value)
formatted_attribute = b'=' + key
if value:
formatted_attribute += b'=' + value
formated.append(formatted_attribute)
for _query in self.queries:
formated.extend(_query.get_api_format())
if self.tag is not None:

View file

@ -73,6 +73,22 @@ class TestCommunicator(TestCase):
base.send_sentence.assert_called_once_with(
[b'/interface/set', b'=x=y', b'.tag=1'])
def test_call_with_arguments(self):
base = mock.Mock()
base.receive_sentence.return_value = [b'!done', b'.tag=1']
communicator = api_communicator.ApiCommunicator(base)
communicator.call('/interface/monitor-traffic/', 'monitor', {'interface': 'ether1'})
base.send_sentence.assert_called_once_with(
[b'/interface/monitor-traffic/monitor', b'=interface=ether1', b'.tag=1'])
def test_call_without_arguments(self):
base = mock.Mock()
base.receive_sentence.return_value = [b'!done', b'.tag=1']
communicator = api_communicator.ApiCommunicator(base)
communicator.call('/interface/monitor-traffic/', 'monitor', {'once': None})
base.send_sentence.assert_called_once_with(
[b'/interface/monitor-traffic/monitor', b'=once', b'.tag=1'])
def test_async_error_raises_when_synchronizing(self):
base = mock.Mock()
base.receive_sentence.side_effect = [

View file

@ -33,6 +33,15 @@ class TestTypedResource(unittest.TestCase):
'/unknown/', 'set', arguments={'x': b'y'}, queries={},
additional_queries=())
def test_unknown_resource_set_with_no_value(self):
communicator = mock.Mock()
some_resource = resource.RouterOsResource(communicator, '/unknown',
structure.default_structure)
some_resource.set(x=None)
communicator.call.assert_called_with(
'/unknown/', 'set', arguments={'x': None}, queries={},
additional_queries=())
def test_string_resource_get(self):
communicator = mock.Mock()
response = base.AsynchronousResponse([{'string': b's'}], command='')