mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-09 14:11:55 -04:00

* Add SSL verification configuration option - Add `verify_ssl` parameter to DownloadsConfig to control SSL certificate verification - Update client methods to use the new SSL verification setting - Add CLI option `--no-ssl-verify` to disable SSL verification - Implement SSL verification support across various clients and network requests - Add test suite to validate SSL verification configuration * Enhance SSL certificate handling with certifi support - Add new `ssl_utils.py` module for SSL certificate management - Implement optional certifi package support for improved certificate verification - Add utility functions for creating SSL contexts and handling connector kwargs - Update various clients to use new SSL utility functions - Add helpful error messaging for SSL certificate verification issues - Include optional certifi dependency in pyproject.toml * Enhance SSL verification tests and configuration support - Add comprehensive test suite for SSL verification utilities - Implement tests for SSL context creation and configuration - Update test configuration to include verify_ssl option - Add test coverage for SSL verification across different clients and methods - Improve error handling and testing for SSL-related configurations * run ruff format * Fix ruff checks --------- Co-authored-by: Nathan Thomas <nathanthomas707@gmail.com>
294 lines
8.8 KiB
Python
294 lines
8.8 KiB
Python
import os
|
|
import shutil
|
|
|
|
import pytest
|
|
import tomlkit
|
|
|
|
from streamrip.config import (
|
|
ArtworkConfig,
|
|
CliConfig,
|
|
Config,
|
|
ConfigData,
|
|
ConversionConfig,
|
|
DatabaseConfig,
|
|
DeezerConfig,
|
|
DownloadsConfig,
|
|
FilepathsConfig,
|
|
LastFmConfig,
|
|
MetadataConfig,
|
|
MiscConfig,
|
|
QobuzConfig,
|
|
QobuzDiscographyFilterConfig,
|
|
SoundcloudConfig,
|
|
TidalConfig,
|
|
YoutubeConfig,
|
|
_get_dict_keys_r,
|
|
_nested_set,
|
|
update_config,
|
|
)
|
|
|
|
SAMPLE_CONFIG = "tests/test_config.toml"
|
|
OLD_CONFIG = "tests/test_config_old.toml"
|
|
|
|
|
|
# Define a fixture to create a sample ConfigData instance for testing
|
|
@pytest.fixture()
|
|
def sample_config_data() -> ConfigData:
|
|
# Create a sample ConfigData instance here
|
|
# You can customize this to your specific needs for testing
|
|
with open(SAMPLE_CONFIG) as f:
|
|
config_data = ConfigData.from_toml(f.read())
|
|
return config_data
|
|
|
|
|
|
# Define a fixture to create a sample Config instance for testing
|
|
@pytest.fixture()
|
|
def sample_config() -> Config:
|
|
# Create a sample Config instance here
|
|
# You can customize this to your specific needs for testing
|
|
config = Config(SAMPLE_CONFIG)
|
|
return config
|
|
|
|
|
|
def test_get_keys_r():
|
|
d = {
|
|
"key1": {
|
|
"key2": {
|
|
"key3": 1,
|
|
"key4": 1,
|
|
},
|
|
"key6": [1, 2],
|
|
5: 1,
|
|
}
|
|
}
|
|
res = _get_dict_keys_r(d)
|
|
print(res)
|
|
assert res == {
|
|
("key1", "key2", "key3"),
|
|
("key1", "key2", "key4"),
|
|
("key1", "key6"),
|
|
("key1", 5),
|
|
}
|
|
|
|
|
|
def test_safe_set():
|
|
d = {
|
|
"key1": {
|
|
"key2": {
|
|
"key3": 1,
|
|
"key4": 1,
|
|
},
|
|
"key6": [1, 2],
|
|
5: 1,
|
|
}
|
|
}
|
|
_nested_set(d, "key1", "key2", "key3", val=5)
|
|
assert d == {
|
|
"key1": {
|
|
"key2": {
|
|
"key3": 5,
|
|
"key4": 1,
|
|
},
|
|
"key6": [1, 2],
|
|
5: 1,
|
|
}
|
|
}
|
|
|
|
|
|
def test_config_update():
|
|
old = {
|
|
"downloads": {"folder": "some_path", "use_service": True},
|
|
"qobuz": {"email": "asdf@gmail.com", "password": "test"},
|
|
"legacy_conf": {"something": 1, "other": 2},
|
|
}
|
|
new = {
|
|
"downloads": {"folder": "", "use_service": False, "keep_artwork": True},
|
|
"qobuz": {"email": "", "password": ""},
|
|
"tidal": {"email": "", "password": ""},
|
|
}
|
|
update_config(old, new)
|
|
assert new == {
|
|
"downloads": {"folder": "some_path", "use_service": True, "keep_artwork": True},
|
|
"qobuz": {"email": "asdf@gmail.com", "password": "test"},
|
|
"tidal": {"email": "", "password": ""},
|
|
}
|
|
|
|
|
|
def test_config_throws_outdated():
|
|
with pytest.raises(Exception, match="update"):
|
|
_ = Config(OLD_CONFIG)
|
|
|
|
|
|
def test_config_file_update():
|
|
tmp_conf = "tests/test_config_old2.toml"
|
|
shutil.copy("tests/test_config_old.toml", tmp_conf)
|
|
Config._update_file(tmp_conf, SAMPLE_CONFIG)
|
|
|
|
with open(tmp_conf) as f:
|
|
s = f.read()
|
|
toml = tomlkit.parse(s) # type: ignore
|
|
|
|
assert toml["downloads"]["folder"] == "old_value" # type: ignore
|
|
assert toml["downloads"]["source_subdirectories"] is True # type: ignore
|
|
assert toml["downloads"]["concurrency"] is True # type: ignore
|
|
assert toml["downloads"]["max_connections"] == 6 # type: ignore
|
|
assert toml["downloads"]["requests_per_minute"] == 60 # type: ignore
|
|
assert toml["cli"]["text_output"] is True # type: ignore
|
|
assert toml["cli"]["progress_bars"] is True # type: ignore
|
|
assert toml["cli"]["max_search_results"] == 100 # type: ignore
|
|
assert toml["misc"]["version"] == "2.0.6" # type: ignore
|
|
assert "YouTubeVideos" in str(toml["youtube"]["video_downloads_folder"])
|
|
# type: ignore
|
|
os.remove("tests/test_config_old2.toml")
|
|
|
|
|
|
def test_sample_config_data_properties(sample_config_data):
|
|
# Test the properties of ConfigData
|
|
assert sample_config_data.modified is False # Ensure initial state is not modified
|
|
|
|
|
|
def test_sample_config_data_modification(sample_config_data):
|
|
# Test modifying ConfigData and checking modified property
|
|
sample_config_data.set_modified()
|
|
assert sample_config_data._modified is True
|
|
|
|
|
|
def test_sample_config_data_fields(sample_config_data):
|
|
test_config = ConfigData(
|
|
toml=None, # type: ignore
|
|
downloads=DownloadsConfig(
|
|
folder="test_folder",
|
|
source_subdirectories=False,
|
|
disc_subdirectories=True,
|
|
concurrency=True,
|
|
max_connections=6,
|
|
requests_per_minute=60,
|
|
verify_ssl=True,
|
|
),
|
|
qobuz=QobuzConfig(
|
|
use_auth_token=False,
|
|
email_or_userid="test@gmail.com",
|
|
password_or_token="test_pwd",
|
|
app_id="12345",
|
|
quality=3,
|
|
download_booklets=True,
|
|
secrets=["secret1", "secret2"],
|
|
),
|
|
tidal=TidalConfig(
|
|
user_id="userid",
|
|
country_code="countrycode",
|
|
access_token="accesstoken",
|
|
refresh_token="refreshtoken",
|
|
token_expiry="tokenexpiry",
|
|
quality=3,
|
|
download_videos=True,
|
|
),
|
|
deezer=DeezerConfig(
|
|
arl="testarl",
|
|
quality=2,
|
|
use_deezloader=True,
|
|
deezloader_warnings=True,
|
|
),
|
|
soundcloud=SoundcloudConfig(
|
|
client_id="clientid",
|
|
app_version="appversion",
|
|
quality=0,
|
|
),
|
|
youtube=YoutubeConfig(
|
|
video_downloads_folder="videodownloadsfolder",
|
|
quality=0,
|
|
download_videos=False,
|
|
),
|
|
lastfm=LastFmConfig(source="qobuz", fallback_source=""),
|
|
filepaths=FilepathsConfig(
|
|
add_singles_to_folder=False,
|
|
folder_format="{albumartist} - {title} ({year}) [{container}] [{bit_depth}B-{sampling_rate}kHz]",
|
|
track_format="{tracknumber}. {artist} - {title}{explicit}",
|
|
restrict_characters=False,
|
|
truncate_to=120,
|
|
),
|
|
artwork=ArtworkConfig(
|
|
embed=True,
|
|
embed_size="large",
|
|
embed_max_width=-1,
|
|
save_artwork=True,
|
|
saved_max_width=-1,
|
|
),
|
|
metadata=MetadataConfig(
|
|
set_playlist_to_album=True,
|
|
renumber_playlist_tracks=True,
|
|
exclude=[],
|
|
),
|
|
qobuz_filters=QobuzDiscographyFilterConfig(
|
|
extras=False,
|
|
repeats=False,
|
|
non_albums=False,
|
|
features=False,
|
|
non_studio_albums=False,
|
|
non_remaster=False,
|
|
),
|
|
cli=CliConfig(
|
|
text_output=False,
|
|
progress_bars=False,
|
|
max_search_results=100,
|
|
),
|
|
database=DatabaseConfig(
|
|
downloads_enabled=True,
|
|
downloads_path="downloadspath",
|
|
failed_downloads_enabled=True,
|
|
failed_downloads_path="faileddownloadspath",
|
|
),
|
|
conversion=ConversionConfig(
|
|
enabled=False,
|
|
codec="ALAC",
|
|
sampling_rate=48000,
|
|
bit_depth=24,
|
|
lossy_bitrate=320,
|
|
),
|
|
misc=MiscConfig(version="2.0", check_for_updates=True),
|
|
_modified=False,
|
|
)
|
|
assert sample_config_data.downloads == test_config.downloads
|
|
assert sample_config_data.qobuz == test_config.qobuz
|
|
assert sample_config_data.tidal == test_config.tidal
|
|
assert sample_config_data.deezer == test_config.deezer
|
|
assert sample_config_data.soundcloud == test_config.soundcloud
|
|
assert sample_config_data.youtube == test_config.youtube
|
|
assert sample_config_data.lastfm == test_config.lastfm
|
|
assert sample_config_data.artwork == test_config.artwork
|
|
assert sample_config_data.filepaths == test_config.filepaths
|
|
assert sample_config_data.metadata == test_config.metadata
|
|
assert sample_config_data.qobuz_filters == test_config.qobuz_filters
|
|
assert sample_config_data.database == test_config.database
|
|
assert sample_config_data.conversion == test_config.conversion
|
|
|
|
|
|
def test_config_update_on_save():
|
|
tmp_config_path = "tests/config2.toml"
|
|
shutil.copy(SAMPLE_CONFIG, tmp_config_path)
|
|
conf = Config(tmp_config_path)
|
|
conf.file.downloads.folder = "new_folder"
|
|
conf.file.set_modified()
|
|
conf.save_file()
|
|
conf2 = Config(tmp_config_path)
|
|
os.remove(tmp_config_path)
|
|
|
|
assert conf2.session.downloads.folder == "new_folder"
|
|
|
|
|
|
def test_config_dont_update_without_set_modified():
|
|
tmp_config_path = "tests/config2.toml"
|
|
shutil.copy(SAMPLE_CONFIG, tmp_config_path)
|
|
conf = Config(tmp_config_path)
|
|
conf.file.downloads.folder = "new_folder"
|
|
del conf
|
|
conf2 = Config(tmp_config_path)
|
|
os.remove(tmp_config_path)
|
|
|
|
assert conf2.session.downloads.folder == "test_folder"
|
|
|
|
|
|
# Other tests for the Config class can be added as needed
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main()
|