1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
import os.path
import unittest
from unittest import mock
import vcr
import mopidy_soundcloud
from mopidy.models import Track
from mopidy_soundcloud import Extension
from mopidy_soundcloud.soundcloud import SoundCloudClient, readable_url
local_path = os.path.abspath(os.path.dirname(__file__))
my_vcr = vcr.VCR(
serializer="yaml",
cassette_library_dir=local_path + "/fixtures",
record_mode="once",
match_on=["uri", "method"],
decode_compressed_response=True,
filter_headers=["Authorization"],
)
class ApiTest(unittest.TestCase):
@my_vcr.use_cassette("sc-login.yaml")
def setUp(self):
config = Extension().get_config_schema()
config["auth_token"] = "3-35204-970067440-lVY4FovkEcKrEGw"
config["explore_songs"] = 10
self.api = SoundCloudClient({"soundcloud": config, "proxy": {}})
def test_sets_user_agent(self):
agent = "Mopidy-SoundCloud/%s Mopidy/" % mopidy_soundcloud.__version__
assert agent in self.api.http_client.headers["user-agent"]
def test_public_client_no_token(self):
token_key = "authorization"
assert token_key not in self.api.public_stream_client.headers._store
def test_resolves_string(self):
_id = self.api.parse_track_uri("soundcloud:song.38720262")
assert _id == "38720262"
@my_vcr.use_cassette("sc-login-error.yaml")
def test_responds_with_error(self):
with mock.patch("mopidy_soundcloud.soundcloud.logger.error") as d:
config = Extension().get_config_schema()
config["auth_token"] = "1-fake-token"
SoundCloudClient({"soundcloud": config, "proxy": {}}).user
d.assert_called_once_with(
'Invalid "auth_token" used for SoundCloud authentication!'
)
@my_vcr.use_cassette("sc-login.yaml")
def test_returns_username(self):
user = self.api.user.get("username")
assert user == "Nick Steel 3"
@my_vcr.use_cassette("sc-resolve-track.yaml")
def test_resolves_object(self):
trackc = {}
trackc["uri"] = "soundcloud:song.38720262"
track = Track(**trackc)
id = self.api.parse_track_uri(track)
assert id == "38720262"
@my_vcr.use_cassette("sc-resolve-track-none.yaml")
def test_resolves_unknown_track_to_none(self):
track = self.api.get_track("s38720262")
assert track is None
@my_vcr.use_cassette("sc-resolve-track.yaml")
def test_resolves_track(self):
track = self.api.get_track("13158665")
assert isinstance(track, Track)
assert track.uri == "soundcloud:song/Munching at Tiannas house.13158665"
@my_vcr.use_cassette("sc-resolve-http.yaml")
def test_resolves_http_url(self):
track = self.api.resolve_url(
"https://soundcloud.com/bbc-radio-4/m-w-cloud"
)[0]
assert isinstance(track, Track)
assert (
track.uri
== "soundcloud:song/That Mitchell and Webb Sound The Cloud.122889665"
)
@my_vcr.use_cassette("sc-resolve-set.yaml")
def test_resolves_set_url(self):
expected_tracks = [
"01 Dash And Blast",
"02 We Flood Empty Lakes",
"03 A Song For Starlit Beaches",
"04 Illuminate My Heart, My Darling",
]
tracks = self.api.resolve_url(
"https://soundcloud.com/yndihalda/sets/dash-and-blast"
)
assert len(tracks) == 4
for i, _ in enumerate(expected_tracks):
assert isinstance(tracks[i], Track)
assert tracks[i].name == expected_tracks[i]
assert tracks[i].length > 500
assert len(tracks[i].artists) == 1
assert list(tracks[i].artists)[0].name == "yndi halda"
@my_vcr.use_cassette("sc-liked.yaml")
def test_get_user_likes(self):
tracks = self.api.get_likes()
assert len(tracks) == 3
assert isinstance(tracks[0], Track)
assert tracks[1].name == "Pelican - Deny The Absolute"
@my_vcr.use_cassette("sc-stream.yaml")
def test_get_user_stream(self):
tracks = self.api.get_user_stream()
assert len(tracks) == 10
assert isinstance(tracks[0], Track)
assert tracks[2].name == "JW Ep 20- Jeremiah Watkins"
@my_vcr.use_cassette("sc-following.yaml")
def test_get_followings(self):
users = self.api.get_followings()
assert len(users) == 10
assert users[0] == ("Young Legionnaire", "992503")
assert users[1] == ("Tall Ships", "1710483")
assert users[8] == ("Pelican Song", "27945548")
assert users[9] == ("sleepmakeswaves", "1739693")
@my_vcr.use_cassette("sc-user-tracks.yaml")
def test_get_user_tracks(self):
expected_tracks = [
"The Wait",
"The Cliff (Palms Remix)",
"The Cliff (Justin Broadrick Remix)",
"The Cliff (Vocal Version)",
"Pelican - The Creeper",
"Pelican - Lathe Biosas",
"Pelican - Ephemeral",
"Pelican - Deny the Absolute",
"Pelican - Immutable Dusk",
"Pelican - Strung Up From The Sky",
]
tracks = self.api.get_tracks(27945548)
for i, _ in enumerate(expected_tracks):
assert isinstance(tracks[i], Track)
assert tracks[i].name == expected_tracks[i]
assert tracks[i].length > 500
assert len(tracks[i].artists) == 1
@my_vcr.use_cassette("sc-set.yaml")
def test_get_set(self):
tracks = self.api.get_set("10961826")
assert len(tracks) == 1
assert isinstance(tracks[0], dict)
@my_vcr.use_cassette("sc-set-invalid.yaml")
def test_get_invalid_set(self):
tracks = self.api.get_set("blahblahrubbosh")
assert tracks == []
@my_vcr.use_cassette("sc-sets.yaml")
def test_get_sets(self):
sets = self.api.get_sets()
assert len(sets) == 2
name, set_id, tracks = sets[1]
assert name == "Pelican"
assert set_id == "10961826"
assert len(tracks) == 1
def test_readeble_url(self):
assert "Barsuk Records" == readable_url('"@"Barsuk Records')
assert "_Barsuk Records" == readable_url("_Barsuk 'Records'")
@my_vcr.use_cassette("sc-resolve-track-id.yaml")
def test_resolves_stream_track(self):
self.api._update_public_client_id = mock.Mock()
track = self.api.get_track("13158665", True)
assert isinstance(track, Track)
assert track.uri == (
"https://cf-media.sndcdn.com/fxguEjG4ax6B.128.mp3?Policy="
"eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNu"
"ZGNkbi5jb20vZnhndUVqRzRheDZCLjEyOC5tcDMqIiwiQ29uZGl0aW9u"
"Ijp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjUxNzky"
"Mzg1fX19XX0_&Signature=OGBst0oQOjHEf3TnH7IJbKipFi3zmWB9b"
"PSjTld5weixfAW6K3z4xglDCbDyt0YRn6fdq6WKIdZR93ngRB2OyBIuP"
"777YhM45uRxYBZkJMr1KC3NleHmNjVror1XBE-Zsp2Lz6EDOGvYPMno9"
"nYM0MLiSjStYtMHKu101vhrdn2DpgJf-xLdQW-2UAY-Ls-trnQRfA038"
"40ebzbNVepPAzum3EeX2CIaislknlEwM40BUD4CVU-4maTCo9QdWOYuq"
"xXODjJkjSff9M9-OZ49EDzZoPD506pmY8omwqPgeDQ2X5l5I9Y9v7-3b"
"nmmqF~EkK4ojoX3I1fp89BrOMhTkw__&Key-Pair-Id=APKAI6TU7MMX"
"M5DG6EPQ"
)
@my_vcr.use_cassette("sc-resolve-track-id.yaml")
def test_unstreamable_track(self):
track = self.api._get("tracks/13158665")
track["streamable"] = False
track = self.api.parse_track(track)
assert track is None
def test_parse_fail_reason(self):
test_reason = "Unknown"
reason_res = self.api.parse_fail_reason(test_reason)
assert reason_res == ""
@my_vcr.use_cassette("sc-search.yaml")
def test_search(self):
tracks = self.api.search("the great descent")
assert len(tracks) == 10
assert isinstance(tracks[0], Track)
assert tracks[0].name == "Turn Around (Mix1)"
|