# Path: soco/data_structures.py
# class DidlMusicTrack(DidlAudioItem):
# 
#     """Class that represents a music library track."""
# 
#     # the DIDL Lite class for this object.
#     item_class = "object.item.audioItem.musicTrack"
#     # name: (ns, tag)
#     _translation = DidlAudioItem._translation.copy()
#     _translation.update(
#         {
#             "artist": ("upnp", "artist"),
#             "album": ("upnp", "album"),
#             "original_track_number": ("upnp", "originalTrackNumber"),
#             "playlist": ("upnp", "playlist"),
#             "contributor": ("dc", "contributor"),
#             "date": ("dc", "date"),
#         }
#     )
# 
# class DidlPlaylistContainer(DidlContainer):
# 
#     """Class that represents a music library play list."""
# 
#     # (str) The DIDL Lite class for this object
#     item_class = "object.container.playlistContainer"
#     # Yes, really. Sonos uses the item tag, not the container tag. But
#     # sometimes it uses the container tag, eg:
#     # >>> s=soco.SoCo('192.168.1.102')
#     # >>> s.get_playlists()
#     # See https://github.com/SoCo/SoCo/issues/353
#     tag = "item"
#     # name: (ns, tag)
#     _translation = DidlContainer._translation.copy()
#     _translation.update(
#         {
#             "artist": ("upnp", "artist"),
#             "genre": ("upnp", "genre"),
#             "long_description": ("upnp", "longDescription"),
#             "producer": ("dc", "producer"),
#             "contributor": ("dc", "contributor"),
#             "description": ("dc", "description"),
#             "date": ("dc", "date"),
#             "language": ("dc", "language"),
#             "rights": ("dc", "rights"),
#         }
#     )
# 
# class SearchResult(ListOfMusicInfoItems):
# 
#     """Container class that represents a search or browse result.
# 
#     Browse is just a special case of search.
#     """
# 
#     def __init__(self, items, search_type, number_returned, total_matches, update_id):
#         super().__init__(items, number_returned, total_matches, update_id)
#         self._metadata["search_type"] = search_type
# 
#     def __repr__(self):
#         return "{}(items={}, search_type='{}')".format(
#             self.__class__.__name__,
#             super().__repr__(),
#             self.search_type,
#         )
# 
#     @property
#     def search_type(self):
#         """str: the search type."""
#         return self._metadata["search_type"]
# 
# Path: soco/exceptions.py
# class SoCoUPnPException(SoCoException):
# 
#     """A UPnP Fault Code, raised in response to actions sent over the
#     network.
# 
#     """
# 
#     def __init__(self, message, error_code, error_xml, error_description=""):
#         """
#         Args:
#             message (str): The message from the server.
#             error_code (str): The UPnP Error Code as a string.
#             error_xml (str): The xml containing the error, as a utf-8
#                 encoded string.
#             error_description (str): A description of the error. Default is ""
#         """
#         super().__init__()
#         self.message = message
#         self.error_code = error_code
#         self.error_description = error_description
#         self.error_xml = error_xml
# 
#     def __str__(self):
#         return self.message


import time
import pytest
import soco as soco_module
from soco.data_structures import (
    DidlMusicTrack,
    DidlPlaylistContainer,
    SearchResult,
)
from soco.music_library import MusicLibrary
from soco.exceptions import SoCoUPnPException
    def test_remove_playlist(self, soco):
        """Test removing a Sonos playlist."""
        # a place holder, remove_sonos_playlist is exercised in the
        # 'restore_sonos_playlists'
        pass

    def test_remove_playlist_itemid(self, soco):
        """Test removing a Sonos playlist by item_id."""
        new_playlist = soco.create_sonos_playlist(title=self.playlist_name)
        assert type(new_playlist) is DidlPlaylistContainer
        assert soco.remove_sonos_playlist(new_playlist.item_id)
        found = False
        for sonos_playlist in soco.get_sonos_playlists():
            if sonos_playlist.title == self.playlist_name:
                found = True
                break
        assert found is False, "new_playlist was not removed by item_id"

    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
        playlists = soco.get_sonos_playlists()
        # Accommodate the case of no existing playlists
        if len(playlists) == 0:
            hpl_i = 0
        else:
            hpl_i = max([int(x.item_id.split(":")[1]) for x in playlists])

# Path: soco/data_structures.py
# class DidlMusicTrack(DidlAudioItem):
# 
#     """Class that represents a music library track."""
# 
#     # the DIDL Lite class for this object.
#     item_class = "object.item.audioItem.musicTrack"
#     # name: (ns, tag)
#     _translation = DidlAudioItem._translation.copy()
#     _translation.update(
#         {
#             "artist": ("upnp", "artist"),
#             "album": ("upnp", "album"),
#             "original_track_number": ("upnp", "originalTrackNumber"),
#             "playlist": ("upnp", "playlist"),
#             "contributor": ("dc", "contributor"),
#             "date": ("dc", "date"),
#         }
#     )
# 
# class DidlPlaylistContainer(DidlContainer):
# 
#     """Class that represents a music library play list."""
# 
#     # (str) The DIDL Lite class for this object
#     item_class = "object.container.playlistContainer"
#     # Yes, really. Sonos uses the item tag, not the container tag. But
#     # sometimes it uses the container tag, eg:
#     # >>> s=soco.SoCo('192.168.1.102')
#     # >>> s.get_playlists()
#     # See https://github.com/SoCo/SoCo/issues/353
#     tag = "item"
#     # name: (ns, tag)
#     _translation = DidlContainer._translation.copy()
#     _translation.update(
#         {
#             "artist": ("upnp", "artist"),
#             "genre": ("upnp", "genre"),
#             "long_description": ("upnp", "longDescription"),
#             "producer": ("dc", "producer"),
#             "contributor": ("dc", "contributor"),
#             "description": ("dc", "description"),
#             "date": ("dc", "date"),
#             "language": ("dc", "language"),
#             "rights": ("dc", "rights"),
#         }
#     )
# 
# class SearchResult(ListOfMusicInfoItems):
# 
#     """Container class that represents a search or browse result.
# 
#     Browse is just a special case of search.
#     """
# 
#     def __init__(self, items, search_type, number_returned, total_matches, update_id):
#         super().__init__(items, number_returned, total_matches, update_id)
#         self._metadata["search_type"] = search_type
# 
#     def __repr__(self):
#         return "{}(items={}, search_type='{}')".format(
#             self.__class__.__name__,
#             super().__repr__(),
#             self.search_type,
#         )
# 
#     @property
#     def search_type(self):
#         """str: the search type."""
#         return self._metadata["search_type"]
# 
# Path: soco/exceptions.py
# class SoCoUPnPException(SoCoException):
# 
#     """A UPnP Fault Code, raised in response to actions sent over the
#     network.
# 
#     """
# 
#     def __init__(self, message, error_code, error_xml, error_description=""):
#         """
#         Args:
#             message (str): The message from the server.
#             error_code (str): The UPnP Error Code as a string.
#             error_xml (str): The xml containing the error, as a utf-8
#                 encoded string.
#             error_description (str): A description of the error. Default is ""
#         """
#         super().__init__()
#         self.message = message
#         self.error_code = error_code
#         self.error_description = error_description
#         self.error_xml = error_xml
# 
#     def __str__(self):
#         return self.message


# Path: tests/test_integration.py
import time
import pytest
import soco as soco_module
from soco.data_structures import (
    DidlMusicTrack,
    DidlPlaylistContainer,
    SearchResult,
)
from soco.music_library import MusicLibrary
from soco.exceptions import SoCoUPnPException

    def test_remove_playlist(self, soco):
        """Test removing a Sonos playlist."""
        # a place holder, remove_sonos_playlist is exercised in the
        # 'restore_sonos_playlists'
        pass

    def test_remove_playlist_itemid(self, soco):
        """Test removing a Sonos playlist by item_id."""
        new_playlist = soco.create_sonos_playlist(title=self.playlist_name)
        assert type(new_playlist) is DidlPlaylistContainer
        assert soco.remove_sonos_playlist(new_playlist.item_id)
        found = False
        for sonos_playlist in soco.get_sonos_playlists():
            if sonos_playlist.title == self.playlist_name:
                found = True
                break
        assert found is False, "new_playlist was not removed by item_id"

    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
        playlists = soco.get_sonos_playlists()
        # Accommodate the case of no existing playlists
        if len(playlists) == 0:
            hpl_i = 0
        else:
            hpl_i = max([int(x.item_id.split(":")[1]) for x in playlists])

        with pytest.raises(SoCoUPnPException):