Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
dict_encoded[key] = escape(value).\
encode('ascii', 'xmlcharrefreplace').decode('ascii')
else:
dict_encoded[key] = value
didl = DIDL_TEMPLATE.format(item_class=class_.item_class,
**dict_encoded)
assert helpers.compare_xml(
item_from_xml.didl_metadata, XML.fromstring(didl)
)
assert helpers.compare_xml(
item_from_dict.didl_metadata, XML.fromstring(didl)
)
else:
with pytest.raises(DIDLMetadataError):
# pylint: disable=pointless-statement
item_from_xml.didl_metadata
# Text attributes with mandatory content
for name in ['item_id', 'extended_id', 'title', 'service_id']:
getter_attributes_test(name, item_from_xml, item_from_dict,
dict_[name])
# Text attributes with voluntary content
for name in ['parent_id', 'album_art_uri']:
getter_attributes_test(name, item_from_xml, item_from_dict,
dict_.get(name))
# Boolean attribute
getter_attributes_test('can_play', item_from_xml, item_from_dict,
bool(dict_.get('can_play')))
return item_from_xml, item_from_dict
def test_remove_playlist_bad_id(self, soco):
"""Test attempting to remove a Sonos playlist using a bad id."""
# junky bad
with pytest.raises(SoCoUPnPException):
soco.remove_sonos_playlist('SQ:-7')
# realistic non-existing
hpl_i = max([int(x.item_id.split(':')[1])
for x in soco.get_sonos_playlists()])
with pytest.raises(SoCoUPnPException):
soco.remove_sonos_playlist('SQ:{}'.format(hpl_i + 1))
def moco():
""" A mock soco with fake services.
Allows calls to services to be tracked. Should not cause any network access
"""
services = (
'AVTransport', 'RenderingControl', 'DeviceProperties',
'ContentDirectory', 'ZoneGroupTopology')
patchers = [mock.patch('soco.core.{0}'.format(service))
for service in services]
for patch in patchers:
patch.start()
yield SoCo(IP_ADDR)
for patch in reversed(patchers):
patch.stop()
assert sock.sendto.call_count == 9
# select called with the relevant timeout
select.select.assert_called_with(
[sock, sock, sock], [], [], min(TIMEOUT, 0.1))
# SoCo should be created with the IP address received
config.SOCO_CLASS.assert_called_with(IP_ADDR)
# Now test include_visible parameter. include_invisible=True should
# result in calling SoCo.all_zones etc
# Reset gethostbyname, to always return the same value
monkeypatch.setattr('socket.gethostbyname',
Mock(return_value='192.168.1.15'))
config.SOCO_CLASS.return_value = Mock(
all_zones='ALL', visible_zones='VISIBLE')
assert discover(include_invisible=True) == 'ALL'
assert discover(include_invisible=False) == 'VISIBLE'
# if select does not return within timeout SoCo should not be called
# at all
# simulate no data being returned within timeout
select.select.return_value = (0, 1, 1)
discover(timeout=1)
# Check no SoCo instance created
config.SOCO_CLASS.assert_not_called
def test_add_item_to_sonos_playlist(self, moco):
moco.contentDirectory.reset_mock()
playlist = mock.Mock()
playlist.item_id = 7
ressource = mock.Mock()
ressource.uri = 'fake_uri'
track = mock.Mock()
track.resources = [ressource]
track.uri = 'fake_uri'
track.to_element.return_value = XML.Element('a')
update_id = 100
moco.contentDirectory.Browse.return_value = {
'NumberReturned': '0',
'Result': '',
'TotalMatches': '0',
'UpdateID': update_id
}
moco.add_item_to_sonos_playlist(track, playlist)
moco.contentDirectory.Browse.assert_called_once_with([
('ObjectID', playlist.item_id),
('BrowseFlag', 'BrowseDirectChildren'),
('Filter', '*'),
('StartingIndex', 0),
def test_didl_object_to_element(self):
didl_object = data_structures.DidlObject(title='a_title',
parent_id='pid', item_id='iid', creator='a_creator')
# we seem to have to go through this to get ElementTree to deal
# with namespaces properly!
elt = XML.fromstring(XML.tostring(didl_object.to_element(True)))
elt2 = XML.fromstring('' +
'' +
'a_title' +
'a_creator' +
'object')[0]
assert_xml_equal(elt2, elt)
def test_create_didl_resource_to_from_element(self):
res = data_structures.DidlResource('a%20uri', 'a:protocol:info:xx',
bitrate=3)
elt = res.to_element()
assert XML.tostring(elt) == (
b'a%20uri')
assert data_structures.DidlResource.from_element(elt).__dict__ == \
res.__dict__
endpoint='http://endpoint.example.com',
method='getData',
parameters=[('one', '1')],
http_headers={'user-agent': 'sonos'},
soap_action='ACTION',
soap_header="data",
namespace="http://namespace.com",
other_arg=4)
response = mock.MagicMock()
response.headers = {}
response.status_code = 200
response.content = DUMMY_VALID_RESPONSE
with mock.patch('requests.post', return_value=response) as fake_post:
result = s.call()
assert XML.tostring(result)
fake_post.assert_called_once_with(
'http://endpoint.example.com',
headers={'SOAPACTION': '"ACTION"',
'Content-Type': 'text/xml; charset="utf-8"', 'user-agent':
'sonos'},
data=mock.ANY, other_arg=4)
def test_didl_object_from_dict(self):
didl_object = data_structures.DidlObject(
title='a_title',
parent_id='pid',
item_id='iid',
creator='a_creator',
desc='dummy')
the_dict = {
'title': 'a_title',
'parent_id': 'pid',
'item_id': 'iid',
'creator': 'a_creator',
'restricted': True,
'desc': 'dummy'
}
assert data_structures.DidlObject.from_dict(the_dict) == didl_object
# adding in an attibute not in _translation should make no difference
the_dict['creator'] = 'another_creator'
def test_didl_object_from_dict(self):
didl_object = data_structures.DidlObject(title='a_title',
parent_id='pid', item_id='iid', creator='a_creator', desc='dummy')
the_dict = {
'title': 'a_title',
'parent_id': 'pid',
'item_id': 'iid',
'creator': 'a_creator',
'restricted': True,
'desc': 'dummy'
}
assert data_structures.DidlObject.from_dict(the_dict) == didl_object
# adding in an attibute not in _translation should make no difference
the_dict['creator'] = 'another_creator'
assert data_structures.DidlObject.from_dict(the_dict) != didl_object
# round trip
assert data_structures.DidlObject.from_dict(the_dict).to_dict() == \
the_dict