From 2641a370ae80fb26669d45f9f347d23331f970a1 Mon Sep 17 00:00:00 2001 From: 7x11x13 Date: Sun, 23 Jun 2024 18:47:40 -0400 Subject: [PATCH] Add tests --- .gitignore | 5 +- setup.py | 1 + tests/test_playlist.py | 130 ++++++++++++++++++++ tests/test_track.py | 273 +++++++++++++++++++++++++++++++++++++++++ tests/utils.py | 57 +++++++++ 5 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 tests/test_playlist.py create mode 100644 tests/test_track.py create mode 100644 tests/utils.py diff --git a/.gitignore b/.gitignore index af28267..bf8d894 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ dist/ *.pyc *.egg-info/ __pycache__/ -*.mp3 \ No newline at end of file +*.mp3 +.vscode +.venv +.env \ No newline at end of file diff --git a/setup.py b/setup.py index 64f2df2..4c28f66 100755 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ setup( "soundcloud-v2>=1.3.10", "filelock>=3.0.0", ], + extras_require={"test": ["coveralls", "pytest", "pytest-dotenv", "music-tag"]}, url="https://github.com/flyingrub/scdl", classifiers=[ "Programming Language :: Python", diff --git a/tests/test_playlist.py b/tests/test_playlist.py new file mode 100644 index 0000000..6bd4dd5 --- /dev/null +++ b/tests/test_playlist.py @@ -0,0 +1,130 @@ +import os +from pathlib import Path + +from tests.utils import assert_not_track, assert_track, call_scdl_with_auth + + +def assert_track_playlist_1( + tmp_path: Path, playlist_folder: str = "test playlist", check_metadata: bool = True +): + expected_name = "1_testing - test track.mp3" + assert_track( + tmp_path / playlist_folder, + expected_name, + expected_album="test playlist", + expected_albumartist="7x11x13-testing", + expected_tracknumber=1, + check_metadata=check_metadata, + ) + + +def assert_track_playlist_2( + tmp_path: Path, playlist_folder: str = "test playlist", check_metadata: bool = True +): + expected_name = "2_test track 2.mp3" + assert_track( + tmp_path / playlist_folder, + expected_name, + expected_title="test track 2", + expected_album="test playlist", + expected_albumartist="7x11x13-testing", + expected_tracknumber=2, + check_metadata=check_metadata, + ) + + +def test_playlist(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/sets/test-playlist/s-ZSLfNrbPoXR", + "--playlist-name-format", + "{playlist[tracknumber]}_{title}", + "--onlymp3", + ) + assert r.returncode == 0 + assert_track_playlist_1(tmp_path) + assert_track_playlist_2(tmp_path) + + +def test_n(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/sets/test-playlist/s-ZSLfNrbPoXR", + "--playlist-name-format", + "{playlist[tracknumber]}_{title}", + "--onlymp3", + "-n", + "1", + ) + assert r.returncode == 0 + assert_track(tmp_path / "test playlist", "1_test track 2.mp3", check_metadata=False) + assert_not_track(tmp_path / "test playlist", "2_testing - test track.mp3") + + +def test_offset(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/sets/test-playlist/s-ZSLfNrbPoXR", + "--playlist-name-format", + "{playlist[tracknumber]}_{title}", + "--onlymp3", + "-o", + "2", + ) + assert r.returncode == 0 + assert_not_track( + tmp_path / "test playlist", + "1_testing - test track.mp3", + ) + assert_track_playlist_2(tmp_path) + + +def test_no_playlist_folder(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/sets/test-playlist/s-ZSLfNrbPoXR", + "--playlist-name-format", + "{playlist[tracknumber]}_{title}", + "--onlymp3", + "--no-playlist-folder", + ) + assert r.returncode == 0 + assert_track_playlist_1(tmp_path, ".", False) + assert_track_playlist_2(tmp_path, ".", False) + assert_not_track(tmp_path / "test playlist", "1_testing - test track.mp3") + assert_not_track(tmp_path / "test playlist", "2_test track 2.mp3") + + +def test_no_strict_playlist(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/sets/test-playlist/s-ZSLfNrbPoXR", + "--playlist-name-format", + "{playlist[tracknumber]}_{title}", + "--onlymp3", + "--max-size=10kb", + ) + assert r.returncode == 0 + assert_not_track(tmp_path / "test playlist", "1_testing - test track.mp3") + assert_not_track(tmp_path / "test playlist", "2_test track 2.mp3") + + +def test_strict_playlist(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/sets/test-playlist/s-ZSLfNrbPoXR", + "--playlist-name-format", + "{playlist[tracknumber]}_{title}", + "--onlymp3", + "--max-size=10kb", + "--strict-playlist", + ) + assert r.returncode == 1 + assert_not_track(tmp_path / "test playlist", "1_testing - test track.mp3") + assert_not_track(tmp_path / "test playlist", "2_test track 2.mp3") diff --git a/tests/test_track.py b/tests/test_track.py new file mode 100644 index 0000000..f3846fa --- /dev/null +++ b/tests/test_track.py @@ -0,0 +1,273 @@ +import os +from pathlib import Path + +from tests.utils import assert_not_track, assert_track, call_scdl_with_auth + + +def test_original_download(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.wav") + + +def test_flac(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--flac", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.flac") + + +def test_opus(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--no-original", + "--opus", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.opus") + + +def test_mp3(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.mp3") + + +def test_unlisted_track(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track-2/s-fgLQFAzNIMP", + "--name-format", + "track", + "--onlymp3", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.mp3", "test track 2") + + +def test_original_art(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + "--original-art", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.mp3", expected_artwork_len=3409) + + +def test_original_name(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--original-name", + ) + assert r.returncode == 0 + assert_track(tmp_path, "original.wav", check_metadata=False) + + +def test_original_metadata(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--original-metadata", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.wav", "og title", "og artist", "og genre", False) + + +def test_force_metadata(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--original-metadata", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.wav", "og title", "og artist", "og genre", False) + + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--force-metadata", + ) + assert_track(tmp_path, "track.wav") + + +def test_addtimestamp(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--onlymp3", + "--addtimestamp", + ) + assert r.returncode == 0 + assert_track(tmp_path, "1719169486_testing - test track.mp3", check_metadata=False) + + +def test_addtofile(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track-2/s-fgLQFAzNIMP", + "--onlymp3", + "--addtofile", + ) + assert r.returncode == 0 + assert_track(tmp_path, "7x11x13-testing - test track 2.mp3", check_metadata=False) + + +def test_extract_artist(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--onlymp3", + "--name-format", + "track", + "--extract-artist", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.mp3", "test track", "testing") + + +def test_maxsize(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--onlymp3", + "--max-size=10kb", + ) + assert r.returncode == 1 + assert "not within --min-size and --max-size bounds" in r.stderr + + +def test_minsize(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--onlymp3", + "--min-size=1mb", + ) + assert r.returncode == 1 + assert "not within --min-size and --max-size bounds" in r.stderr + + +def test_only_original(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track-2/s-fgLQFAzNIMP", + "--only-original", + ) + assert r.returncode == 1 + assert "does not have original file available" in r.stderr + + +def test_overwrite(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + ) + assert r.returncode == 0 + + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + ) + assert r.returncode == 1 + assert "already exists" in r.stderr + + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + "--overwrite", + ) + assert r.returncode == 0 + + +def test_path(tmp_path: Path): + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + "--path", + str(tmp_path), + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.mp3", check_metadata=False) + + +def test_remove(tmp_path: Path): + os.chdir(tmp_path) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--onlymp3", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.mp3", check_metadata=False) + r = call_scdl_with_auth( + "-l", + "https://soundcloud.com/one-thousand-and-one/test-track", + "--name-format", + "track", + "--remove", + ) + assert r.returncode == 0 + assert_track(tmp_path, "track.wav", check_metadata=False) + assert_not_track(tmp_path, "track.mp3") diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..11a848f --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,57 @@ +import os +import subprocess +from pathlib import Path +from typing import Optional + +import music_tag +from soundcloud import SoundCloud + +client_id = SoundCloud().client_id + + +def call_scdl_with_auth(*args) -> subprocess.CompletedProcess[str]: + auth_token = os.getenv("AUTH_TOKEN") + assert auth_token + args = ( + ["scdl"] + + list(args) + + [f"--auth-token={auth_token}", f"--client-id={client_id}"] + ) + return subprocess.run(args, capture_output=True, encoding="utf-8") + + +def assert_track( + tmp_path: Path, + expected_name: str, + expected_title: str = "testing - test track", + expected_artist: str = "7x11x13-testing", + expected_genre: str = "Testing", + expected_artwork_len: int = 16136, + expected_album: Optional[str] = None, + expected_albumartist: Optional[str] = None, + expected_tracknumber: Optional[int] = None, + check_metadata: bool = True, +): + file = tmp_path / expected_name + assert file.exists() + + if check_metadata: + f = music_tag.load_file(file) + assert f["title"].value == expected_title + assert f["artist"].value == expected_artist + assert f["genre"].value == expected_genre + if expected_artwork_len: + assert len(f["artwork"].value.data) == expected_artwork_len + else: + assert not f["artwork"] + if expected_album: + assert f["album"].value == expected_album + if expected_albumartist: + assert f["albumartist"].value == expected_albumartist + if expected_tracknumber is not None: + assert f["tracknumber"].value == expected_tracknumber + + +def assert_not_track(tmp_path: Path, expected_name: str): + file = tmp_path / expected_name + assert not file.exists()