def common_tests(class_, xml_, dict_, parent_id, helpers): """Common tests for the MS classes.""" xml_content = XML.fromstring(xml_.encode("utf8")) # MusicServiceItem.from_xml and MusicServiceItem.to_dict item_from_xml = class_.from_xml(xml_content, FAKE_MUSIC_SERVICE, parent_id) assert item_from_xml.to_dict == dict_ # MusicServiceItem.from_dict and MusicServiceItem.to_dict item_from_dict = class_.from_dict(dict_) assert item_from_dict.to_dict == dict_ # MusicServiceItem.didl_metadata # NOTE! These tests is reliant on the attributes being put in the same # order by ElementTree and so it might fail if that changes if item_from_xml.can_play: dict_encoded = {} for key, value in dict_.items(): try: is_str = isinstance(value, unicode) except NameError: is_str = isinstance(value, str) if is_str: 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_call(): """Calling a command should result in an http request.""" s = SoapMessage( endpoint='http://endpoint.example.com', method='getData', parameters=[('one', '1')], http_headers={'user-agent': 'sonos'}, soap_action='ACTION', soap_header="<a_header>data</a_header>", 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_call(): """Calling a command should result in an http request.""" s = SoapMessage( endpoint="http://endpoint.example.com", method="getData", parameters=[("one", "1")], http_headers={"user-agent": "sonos"}, soap_action="ACTION", soap_header="<a_header>data</a_header>", 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_wrong_element(self): # Using the wrong element elt = XML.fromstring("""<res>URI</res>""") with pytest.raises(DIDLMetadataError) as excinfo: didl_object = data_structures.DidlObject.from_element(elt) assert "Wrong element. Expected <item> or <container>, " "got <res> for class object" in str(excinfo.value)
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'<res bitrate="3" protocolInfo="a:protocol:info:xx">a%20uri</res>') assert data_structures.DidlResource.from_element(elt) == res
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': '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"></DIDL-Lite>', '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), ('RequestedCount', 1), ('SortCriteria', '') ]) moco.avTransport.AddURIToSavedQueue.assert_called_once_with([ ('InstanceID', 0), ('UpdateID', update_id), ('ObjectID', playlist.item_id), ('EnqueuedURI', track.uri), ('EnqueuedURIMetaData', to_didl_string(track)), ('AddAtIndex', 4294967295) ])
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( '<dummy xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" ' + 'xmlns:dc="http://purl.org/dc/elements/1.1/" ' + 'xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">' + '<item id="iid" parentID="pid" restricted="true">' + '<dc:title>a_title</dc:title>' + '<dc:creator>a_creator</dc:creator>' + '<upnp:class>object</upnp:class><desc id="cdudn" ' + 'nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">' + 'RINCON_AssociatedZPUDN</desc></item></dummy>')[0] assert_xml_equal(elt2, elt)
def test_didl_object_from_element_unoff_subelement(self): """Test that for a DidlObject created from an element with an unofficial .# specified sub class, that the sub class is completely ignored """ elt = XML.fromstring(self.didl_xml.replace("object", "object.#SubClass")) didl_object = data_structures.DidlObject.from_element(elt) assert didl_object.item_class == "object"
def test_didl_object_from_element(self): elt = XML.fromstring(self.didl_xml) didl_object = data_structures.DidlObject.from_element(elt) assert didl_object.title == "the_title" assert didl_object.parent_id == "pid" assert didl_object.item_id == "iid" assert didl_object.creator == "a_creator" assert didl_object.desc == "DUMMY" assert didl_object.item_class == "object"
def test_didl_object_from_element(self): elt = XML.fromstring(self.didl_xml) didl_object = data_structures.DidlObject.from_element(elt) assert didl_object.title == 'the_title' assert didl_object.parent_id == 'pid' assert didl_object.item_id == 'iid' assert didl_object.creator == 'a_creator' assert didl_object.desc == 'DUMMY' assert didl_object.item_class == 'object'
def test_create_didl_resource_to_from_element(self, helpers): res = data_structures.DidlResource("a%20uri", "a:protocol:info:xx", bitrate=3) elt = res.to_element() assert helpers.compare_xml( elt, XML.fromstring( b'<res bitrate="3" ' b'protocolInfo="a:protocol:info:xx">a%20uri</res>' ), ) assert data_structures.DidlResource.from_element(elt) == res
def test_didl_object_from_wrong_class(self): # mismatched upnp class bad_elt1 = XML.fromstring( """<item xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" id="iid" parentID="pid" restricted="true"> <dc:title>the_title</dc:title> <upnp:class>object.item</upnp:class> <dc:creator>a_creator</dc:creator> <desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/"> RINCON_AssociatedZPUDN </desc> </item> """) with pytest.raises(DIDLMetadataError) as excinfo: didl_object = data_structures.DidlObject.from_element(bad_elt1) assert ("UPnP class is incorrect. Expected 'object', got 'object.item'" ) in str(excinfo.value)