Format according to the black standard
This commit is contained in:
@@ -9,15 +9,21 @@ from bdfr.archive_entry.comment_archive_entry import CommentArchiveEntry
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_comment_id', 'expected_dict'), (
|
||||
('gstd4hk', {
|
||||
'author': 'james_pic',
|
||||
'subreddit': 'Python',
|
||||
'submission': 'mgi4op',
|
||||
'submission_title': '76% Faster CPython',
|
||||
'distinguished': None,
|
||||
}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_comment_id", "expected_dict"),
|
||||
(
|
||||
(
|
||||
"gstd4hk",
|
||||
{
|
||||
"author": "james_pic",
|
||||
"subreddit": "Python",
|
||||
"submission": "mgi4op",
|
||||
"submission_title": "76% Faster CPython",
|
||||
"distinguished": None,
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_get_comment_details(test_comment_id: str, expected_dict: dict, reddit_instance: praw.Reddit):
|
||||
comment = reddit_instance.comment(id=test_comment_id)
|
||||
test_entry = CommentArchiveEntry(comment)
|
||||
@@ -27,13 +33,16 @@ def test_get_comment_details(test_comment_id: str, expected_dict: dict, reddit_i
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_comment_id', 'expected_min_comments'), (
|
||||
('gstd4hk', 4),
|
||||
('gsvyste', 3),
|
||||
('gsxnvvb', 5),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_comment_id", "expected_min_comments"),
|
||||
(
|
||||
("gstd4hk", 4),
|
||||
("gsvyste", 3),
|
||||
("gsxnvvb", 5),
|
||||
),
|
||||
)
|
||||
def test_get_comment_replies(test_comment_id: str, expected_min_comments: int, reddit_instance: praw.Reddit):
|
||||
comment = reddit_instance.comment(id=test_comment_id)
|
||||
test_entry = CommentArchiveEntry(comment)
|
||||
result = test_entry.compile()
|
||||
assert len(result.get('replies')) >= expected_min_comments
|
||||
assert len(result.get("replies")) >= expected_min_comments
|
||||
|
||||
@@ -9,9 +9,7 @@ from bdfr.archive_entry.submission_archive_entry import SubmissionArchiveEntry
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'min_comments'), (
|
||||
('m3reby', 27),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "min_comments"), (("m3reby", 27),))
|
||||
def test_get_comments(test_submission_id: str, min_comments: int, reddit_instance: praw.Reddit):
|
||||
test_submission = reddit_instance.submission(id=test_submission_id)
|
||||
test_archive_entry = SubmissionArchiveEntry(test_submission)
|
||||
@@ -21,21 +19,27 @@ def test_get_comments(test_submission_id: str, min_comments: int, reddit_instanc
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'expected_dict'), (
|
||||
('m3reby', {
|
||||
'author': 'sinjen-tos',
|
||||
'id': 'm3reby',
|
||||
'link_flair_text': 'image',
|
||||
'pinned': False,
|
||||
'spoiler': False,
|
||||
'over_18': False,
|
||||
'locked': False,
|
||||
'distinguished': None,
|
||||
'created_utc': 1615583837,
|
||||
'permalink': '/r/australia/comments/m3reby/this_little_guy_fell_out_of_a_tree_and_in_front/'
|
||||
}),
|
||||
# TODO: add deleted user test case
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_submission_id", "expected_dict"),
|
||||
(
|
||||
(
|
||||
"m3reby",
|
||||
{
|
||||
"author": "sinjen-tos",
|
||||
"id": "m3reby",
|
||||
"link_flair_text": "image",
|
||||
"pinned": False,
|
||||
"spoiler": False,
|
||||
"over_18": False,
|
||||
"locked": False,
|
||||
"distinguished": None,
|
||||
"created_utc": 1615583837,
|
||||
"permalink": "/r/australia/comments/m3reby/this_little_guy_fell_out_of_a_tree_and_in_front/",
|
||||
},
|
||||
),
|
||||
# TODO: add deleted user test case
|
||||
),
|
||||
)
|
||||
def test_get_post_details(test_submission_id: str, expected_dict: dict, reddit_instance: praw.Reddit):
|
||||
test_submission = reddit_instance.submission(id=test_submission_id)
|
||||
test_archive_entry = SubmissionArchiveEntry(test_submission)
|
||||
|
||||
@@ -11,29 +11,29 @@ import pytest
|
||||
from bdfr.oauth2 import OAuth2TokenManager
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
@pytest.fixture(scope="session")
|
||||
def reddit_instance():
|
||||
rd = praw.Reddit(
|
||||
client_id='U-6gk4ZCh3IeNQ',
|
||||
client_secret='7CZHY6AmKweZME5s50SfDGylaPg',
|
||||
user_agent='test',
|
||||
client_id="U-6gk4ZCh3IeNQ",
|
||||
client_secret="7CZHY6AmKweZME5s50SfDGylaPg",
|
||||
user_agent="test",
|
||||
)
|
||||
return rd
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
@pytest.fixture(scope="session")
|
||||
def authenticated_reddit_instance():
|
||||
test_config_path = Path('./tests/test_config.cfg')
|
||||
test_config_path = Path("./tests/test_config.cfg")
|
||||
if not test_config_path.exists():
|
||||
pytest.skip('Refresh token must be provided to authenticate with OAuth2')
|
||||
pytest.skip("Refresh token must be provided to authenticate with OAuth2")
|
||||
cfg_parser = configparser.ConfigParser()
|
||||
cfg_parser.read(test_config_path)
|
||||
if not cfg_parser.has_option('DEFAULT', 'user_token'):
|
||||
pytest.skip('Refresh token must be provided to authenticate with OAuth2')
|
||||
if not cfg_parser.has_option("DEFAULT", "user_token"):
|
||||
pytest.skip("Refresh token must be provided to authenticate with OAuth2")
|
||||
token_manager = OAuth2TokenManager(cfg_parser, test_config_path)
|
||||
reddit_instance = praw.Reddit(
|
||||
client_id=cfg_parser.get('DEFAULT', 'client_id'),
|
||||
client_secret=cfg_parser.get('DEFAULT', 'client_secret'),
|
||||
client_id=cfg_parser.get("DEFAULT", "client_id"),
|
||||
client_secret=cfg_parser.get("DEFAULT", "client_secret"),
|
||||
user_agent=socket.gethostname(),
|
||||
token_manager=token_manager,
|
||||
)
|
||||
|
||||
@@ -10,67 +10,78 @@ from click.testing import CliRunner
|
||||
|
||||
from bdfr.__main__ import cli
|
||||
|
||||
does_test_config_exist = Path('./tests/test_config.cfg').exists()
|
||||
does_test_config_exist = Path("./tests/test_config.cfg").exists()
|
||||
|
||||
|
||||
def copy_test_config(run_path: Path):
|
||||
shutil.copy(Path('./tests/test_config.cfg'), Path(run_path, 'test_config.cfg'))
|
||||
shutil.copy(Path("./tests/test_config.cfg"), Path(run_path, "test_config.cfg"))
|
||||
|
||||
|
||||
def create_basic_args_for_archive_runner(test_args: list[str], run_path: Path):
|
||||
copy_test_config(run_path)
|
||||
out = [
|
||||
'archive',
|
||||
"archive",
|
||||
str(run_path),
|
||||
'-v',
|
||||
'--config', str(Path(run_path, 'test_config.cfg')),
|
||||
'--log', str(Path(run_path, 'test_log.txt')),
|
||||
"-v",
|
||||
"--config",
|
||||
str(Path(run_path, "test_config.cfg")),
|
||||
"--log",
|
||||
str(Path(run_path, "test_log.txt")),
|
||||
] + test_args
|
||||
return out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', 'gstd4hk'],
|
||||
['-l', 'm2601g', '-f', 'yaml'],
|
||||
['-l', 'n60t4c', '-f', 'xml'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "gstd4hk"],
|
||||
["-l", "m2601g", "-f", "yaml"],
|
||||
["-l", "n60t4c", "-f", "xml"],
|
||||
),
|
||||
)
|
||||
def test_cli_archive_single(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert re.search(r'Writing entry .*? to file in .*? format', result.output)
|
||||
assert re.search(r"Writing entry .*? to file in .*? format", result.output)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--subreddit', 'Mindustry', '-L', 25],
|
||||
['--subreddit', 'Mindustry', '-L', 25, '--format', 'xml'],
|
||||
['--subreddit', 'Mindustry', '-L', 25, '--format', 'yaml'],
|
||||
['--subreddit', 'Mindustry', '-L', 25, '--sort', 'new'],
|
||||
['--subreddit', 'Mindustry', '-L', 25, '--time', 'day'],
|
||||
['--subreddit', 'Mindustry', '-L', 25, '--time', 'day', '--sort', 'new'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--subreddit", "Mindustry", "-L", 25],
|
||||
["--subreddit", "Mindustry", "-L", 25, "--format", "xml"],
|
||||
["--subreddit", "Mindustry", "-L", 25, "--format", "yaml"],
|
||||
["--subreddit", "Mindustry", "-L", 25, "--sort", "new"],
|
||||
["--subreddit", "Mindustry", "-L", 25, "--time", "day"],
|
||||
["--subreddit", "Mindustry", "-L", 25, "--time", "day", "--sort", "new"],
|
||||
),
|
||||
)
|
||||
def test_cli_archive_subreddit(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert re.search(r'Writing entry .*? to file in .*? format', result.output)
|
||||
assert re.search(r"Writing entry .*? to file in .*? format", result.output)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--user', 'me', '--authenticate', '--all-comments', '-L', '10'],
|
||||
['--user', 'me', '--user', 'djnish', '--authenticate', '--all-comments', '-L', '10'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--user", "me", "--authenticate", "--all-comments", "-L", "10"],
|
||||
["--user", "me", "--user", "djnish", "--authenticate", "--all-comments", "-L", "10"],
|
||||
),
|
||||
)
|
||||
def test_cli_archive_all_user_comments(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
@@ -80,89 +91,88 @@ def test_cli_archive_all_user_comments(test_args: list[str], tmp_path: Path):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--comment-context', '--link', 'gxqapql'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--comment-context", "--link", "gxqapql"],))
|
||||
def test_cli_archive_full_context(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Converting comment' in result.output
|
||||
assert "Converting comment" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--subreddit', 'all', '-L', 100],
|
||||
['--subreddit', 'all', '-L', 100, '--sort', 'new'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--subreddit", "all", "-L", 100],
|
||||
["--subreddit", "all", "-L", 100, "--sort", "new"],
|
||||
),
|
||||
)
|
||||
def test_cli_archive_long(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert re.search(r'Writing entry .*? to file in .*? format', result.output)
|
||||
assert re.search(r"Writing entry .*? to file in .*? format", result.output)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--ignore-user', 'ArjanEgges', '-l', 'm3hxzd'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--ignore-user", "ArjanEgges", "-l", "m3hxzd"],))
|
||||
def test_cli_archive_ignore_user(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'being an ignored user' in result.output
|
||||
assert 'Attempting to archive submission' not in result.output
|
||||
assert "being an ignored user" in result.output
|
||||
assert "Attempting to archive submission" not in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--file-scheme', '{TITLE}', '-l', 'suy011'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--file-scheme", "{TITLE}", "-l", "suy011"],))
|
||||
def test_cli_archive_file_format(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Attempting to archive submission' in result.output
|
||||
assert re.search('format at /.+?/Judge says Trump and two adult', result.output)
|
||||
assert "Attempting to archive submission" in result.output
|
||||
assert re.search("format at /.+?/Judge says Trump and two adult", result.output)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', 'm2601g', '--exclude-id', 'm2601g'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["-l", "m2601g", "--exclude-id", "m2601g"],))
|
||||
def test_cli_archive_links_exclusion(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'in exclusion list' in result.output
|
||||
assert 'Attempting to archive' not in result.output
|
||||
assert "in exclusion list" in result.output
|
||||
assert "Attempting to archive" not in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', 'ijy4ch'], # user deleted post
|
||||
['-l', 'kw4wjm'], # post from banned subreddit
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "ijy4ch"], # user deleted post
|
||||
["-l", "kw4wjm"], # post from banned subreddit
|
||||
),
|
||||
)
|
||||
def test_cli_archive_soft_fail(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_archive_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'failed to be archived due to a PRAW exception' in result.output
|
||||
assert 'Attempting to archive' not in result.output
|
||||
assert "failed to be archived due to a PRAW exception" in result.output
|
||||
assert "Attempting to archive" not in result.output
|
||||
|
||||
@@ -9,54 +9,62 @@ from click.testing import CliRunner
|
||||
|
||||
from bdfr.__main__ import cli
|
||||
|
||||
does_test_config_exist = Path('./tests/test_config.cfg').exists()
|
||||
does_test_config_exist = Path("./tests/test_config.cfg").exists()
|
||||
|
||||
|
||||
def copy_test_config(run_path: Path):
|
||||
shutil.copy(Path('./tests/test_config.cfg'), Path(run_path, 'test_config.cfg'))
|
||||
shutil.copy(Path("./tests/test_config.cfg"), Path(run_path, "test_config.cfg"))
|
||||
|
||||
|
||||
def create_basic_args_for_cloner_runner(test_args: list[str], tmp_path: Path):
|
||||
copy_test_config(tmp_path)
|
||||
out = [
|
||||
'clone',
|
||||
"clone",
|
||||
str(tmp_path),
|
||||
'-v',
|
||||
'--config', str(Path(tmp_path, 'test_config.cfg')),
|
||||
'--log', str(Path(tmp_path, 'test_log.txt')),
|
||||
"-v",
|
||||
"--config",
|
||||
str(Path(tmp_path, "test_config.cfg")),
|
||||
"--log",
|
||||
str(Path(tmp_path, "test_log.txt")),
|
||||
] + test_args
|
||||
return out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', '6l7778'],
|
||||
['-s', 'TrollXChromosomes/', '-L', 1],
|
||||
['-l', 'eiajjw'],
|
||||
['-l', 'xl0lhi'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "6l7778"],
|
||||
["-s", "TrollXChromosomes/", "-L", 1],
|
||||
["-l", "eiajjw"],
|
||||
["-l", "xl0lhi"],
|
||||
),
|
||||
)
|
||||
def test_cli_scrape_general(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_cloner_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Downloaded submission' in result.output
|
||||
assert 'Record for entry item' in result.output
|
||||
assert "Downloaded submission" in result.output
|
||||
assert "Record for entry item" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', 'ijy4ch'], # user deleted post
|
||||
['-l', 'kw4wjm'], # post from banned subreddit
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "ijy4ch"], # user deleted post
|
||||
["-l", "kw4wjm"], # post from banned subreddit
|
||||
),
|
||||
)
|
||||
def test_cli_scrape_soft_fail(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_cloner_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Downloaded submission' not in result.output
|
||||
assert 'Record for entry item' not in result.output
|
||||
assert "Downloaded submission" not in result.output
|
||||
assert "Record for entry item" not in result.output
|
||||
|
||||
@@ -9,97 +9,107 @@ from click.testing import CliRunner
|
||||
|
||||
from bdfr.__main__ import cli
|
||||
|
||||
does_test_config_exist = Path('./tests/test_config.cfg').exists()
|
||||
does_test_config_exist = Path("./tests/test_config.cfg").exists()
|
||||
|
||||
|
||||
def copy_test_config(run_path: Path):
|
||||
shutil.copy(Path('./tests/test_config.cfg'), Path(run_path, './test_config.cfg'))
|
||||
shutil.copy(Path("./tests/test_config.cfg"), Path(run_path, "./test_config.cfg"))
|
||||
|
||||
|
||||
def create_basic_args_for_download_runner(test_args: list[str], run_path: Path):
|
||||
copy_test_config(run_path)
|
||||
out = [
|
||||
'download', str(run_path),
|
||||
'-v',
|
||||
'--config', str(Path(run_path, './test_config.cfg')),
|
||||
'--log', str(Path(run_path, 'test_log.txt')),
|
||||
"download",
|
||||
str(run_path),
|
||||
"-v",
|
||||
"--config",
|
||||
str(Path(run_path, "./test_config.cfg")),
|
||||
"--log",
|
||||
str(Path(run_path, "test_log.txt")),
|
||||
] + test_args
|
||||
return out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-s', 'Mindustry', '-L', 3],
|
||||
['-s', 'r/Mindustry', '-L', 3],
|
||||
['-s', 'r/mindustry', '-L', 3],
|
||||
['-s', 'mindustry', '-L', 3],
|
||||
['-s', 'https://www.reddit.com/r/TrollXChromosomes/', '-L', 3],
|
||||
['-s', 'r/TrollXChromosomes/', '-L', 3],
|
||||
['-s', 'TrollXChromosomes/', '-L', 3],
|
||||
['-s', 'trollxchromosomes', '-L', 3],
|
||||
['-s', 'trollxchromosomes,mindustry,python', '-L', 3],
|
||||
['-s', 'trollxchromosomes, mindustry, python', '-L', 3],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--time', 'day'],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--sort', 'new'],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--time', 'day', '--sort', 'new'],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--search', 'women'],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--time', 'day', '--search', 'women'],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--sort', 'new', '--search', 'women'],
|
||||
['-s', 'trollxchromosomes', '-L', 3, '--time', 'day', '--sort', 'new', '--search', 'women'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-s", "Mindustry", "-L", 3],
|
||||
["-s", "r/Mindustry", "-L", 3],
|
||||
["-s", "r/mindustry", "-L", 3],
|
||||
["-s", "mindustry", "-L", 3],
|
||||
["-s", "https://www.reddit.com/r/TrollXChromosomes/", "-L", 3],
|
||||
["-s", "r/TrollXChromosomes/", "-L", 3],
|
||||
["-s", "TrollXChromosomes/", "-L", 3],
|
||||
["-s", "trollxchromosomes", "-L", 3],
|
||||
["-s", "trollxchromosomes,mindustry,python", "-L", 3],
|
||||
["-s", "trollxchromosomes, mindustry, python", "-L", 3],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--time", "day"],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--sort", "new"],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--time", "day", "--sort", "new"],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--search", "women"],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--time", "day", "--search", "women"],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--sort", "new", "--search", "women"],
|
||||
["-s", "trollxchromosomes", "-L", 3, "--time", "day", "--sort", "new", "--search", "women"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_subreddits(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Added submissions from subreddit ' in result.output
|
||||
assert 'Downloaded submission' in result.output
|
||||
assert "Added submissions from subreddit " in result.output
|
||||
assert "Downloaded submission" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.authenticated
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-s', 'hentai', '-L', 10, '--search', 'red', '--authenticate'],
|
||||
['--authenticate', '--subscribed', '-L', 10],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-s", "hentai", "-L", 10, "--search", "red", "--authenticate"],
|
||||
["--authenticate", "--subscribed", "-L", 10],
|
||||
),
|
||||
)
|
||||
def test_cli_download_search_subreddits_authenticated(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Added submissions from subreddit ' in result.output
|
||||
assert 'Downloaded submission' in result.output
|
||||
assert "Added submissions from subreddit " in result.output
|
||||
assert "Downloaded submission" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.authenticated
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--subreddit', 'friends', '-L', 10, '--authenticate'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--subreddit", "friends", "-L", 10, "--authenticate"],))
|
||||
def test_cli_download_user_specific_subreddits(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Added submissions from subreddit ' in result.output
|
||||
assert "Added submissions from subreddit " in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', '6l7778'],
|
||||
['-l', 'https://reddit.com/r/EmpireDidNothingWrong/comments/6l7778/technically_true/'],
|
||||
['-l', 'm3hxzd'], # Really long title used to overflow filename limit
|
||||
['-l', 'm5bqkf'], # Resource leading to a 404
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "6l7778"],
|
||||
["-l", "https://reddit.com/r/EmpireDidNothingWrong/comments/6l7778/technically_true/"],
|
||||
["-l", "m3hxzd"], # Really long title used to overflow filename limit
|
||||
["-l", "m5bqkf"], # Resource leading to a 404
|
||||
),
|
||||
)
|
||||
def test_cli_download_links(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
@@ -109,64 +119,66 @@ def test_cli_download_links(test_args: list[str], tmp_path: Path):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--user', 'helen_darten', '-m', 'cuteanimalpics', '-L', 10],
|
||||
['--user', 'helen_darten', '-m', 'cuteanimalpics', '-L', 10, '--sort', 'rising'],
|
||||
['--user', 'helen_darten', '-m', 'cuteanimalpics', '-L', 10, '--time', 'week'],
|
||||
['--user', 'helen_darten', '-m', 'cuteanimalpics', '-L', 10, '--time', 'week', '--sort', 'rising'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--user", "helen_darten", "-m", "cuteanimalpics", "-L", 10],
|
||||
["--user", "helen_darten", "-m", "cuteanimalpics", "-L", 10, "--sort", "rising"],
|
||||
["--user", "helen_darten", "-m", "cuteanimalpics", "-L", 10, "--time", "week"],
|
||||
["--user", "helen_darten", "-m", "cuteanimalpics", "-L", 10, "--time", "week", "--sort", "rising"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_multireddit(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Added submissions from multireddit ' in result.output
|
||||
assert "Added submissions from multireddit " in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--user', 'helen_darten', '-m', 'xxyyzzqwerty', '-L', 10],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--user", "helen_darten", "-m", "xxyyzzqwerty", "-L", 10],))
|
||||
def test_cli_download_multireddit_nonexistent(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Failed to get submissions for multireddit' in result.output
|
||||
assert 'received 404 HTTP response' in result.output
|
||||
assert "Failed to get submissions for multireddit" in result.output
|
||||
assert "received 404 HTTP response" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.authenticated
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--user', 'djnish', '--submitted', '--user', 'FriesWithThat', '-L', 10],
|
||||
['--user', 'me', '--upvoted', '--authenticate', '-L', 10],
|
||||
['--user', 'me', '--saved', '--authenticate', '-L', 10],
|
||||
['--user', 'me', '--submitted', '--authenticate', '-L', 10],
|
||||
['--user', 'djnish', '--submitted', '-L', 10],
|
||||
['--user', 'djnish', '--submitted', '-L', 10, '--time', 'month'],
|
||||
['--user', 'djnish', '--submitted', '-L', 10, '--sort', 'controversial'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--user", "djnish", "--submitted", "--user", "FriesWithThat", "-L", 10],
|
||||
["--user", "me", "--upvoted", "--authenticate", "-L", 10],
|
||||
["--user", "me", "--saved", "--authenticate", "-L", 10],
|
||||
["--user", "me", "--submitted", "--authenticate", "-L", 10],
|
||||
["--user", "djnish", "--submitted", "-L", 10],
|
||||
["--user", "djnish", "--submitted", "-L", 10, "--time", "month"],
|
||||
["--user", "djnish", "--submitted", "-L", 10, "--sort", "controversial"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_user_data_good(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Downloaded submission ' in result.output
|
||||
assert "Downloaded submission " in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.authenticated
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--user', 'me', '-L', 10, '--folder-scheme', ''],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--user", "me", "-L", 10, "--folder-scheme", ""],))
|
||||
def test_cli_download_user_data_bad_me_unauthenticated(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
@@ -177,42 +189,41 @@ def test_cli_download_user_data_bad_me_unauthenticated(test_args: list[str], tmp
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--subreddit', 'python', '-L', 1, '--search-existing'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--subreddit", "python", "-L", 1, "--search-existing"],))
|
||||
def test_cli_download_search_existing(test_args: list[str], tmp_path: Path):
|
||||
Path(tmp_path, 'test.txt').touch()
|
||||
Path(tmp_path, "test.txt").touch()
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Calculating hashes for' in result.output
|
||||
assert "Calculating hashes for" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--subreddit', 'tumblr', '-L', '25', '--skip', 'png', '--skip', 'jpg'],
|
||||
['--subreddit', 'MaliciousCompliance', '-L', '25', '--skip', 'txt'],
|
||||
['--subreddit', 'tumblr', '-L', '10', '--skip-domain', 'i.redd.it'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--subreddit", "tumblr", "-L", "25", "--skip", "png", "--skip", "jpg"],
|
||||
["--subreddit", "MaliciousCompliance", "-L", "25", "--skip", "txt"],
|
||||
["--subreddit", "tumblr", "-L", "10", "--skip-domain", "i.redd.it"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_download_filters(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert any((string in result.output for string in ('Download filter removed ', 'filtered due to URL')))
|
||||
assert any((string in result.output for string in ("Download filter removed ", "filtered due to URL")))
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--subreddit', 'all', '-L', '100', '--sort', 'new'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--subreddit", "all", "-L", "100", "--sort", "new"],))
|
||||
def test_cli_download_long(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
@@ -223,34 +234,40 @@ def test_cli_download_long(test_args: list[str], tmp_path: Path):
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--user', 'sdclhgsolgjeroij', '--submitted', '-L', 10],
|
||||
['--user', 'me', '--upvoted', '-L', 10],
|
||||
['--user', 'sdclhgsolgjeroij', '--upvoted', '-L', 10],
|
||||
['--subreddit', 'submitters', '-L', 10], # Private subreddit
|
||||
['--subreddit', 'donaldtrump', '-L', 10], # Banned subreddit
|
||||
['--user', 'djnish', '--user', 'helen_darten', '-m', 'cuteanimalpics', '-L', 10],
|
||||
['--subreddit', 'friends', '-L', 10],
|
||||
['-l', 'ijy4ch'], # user deleted post
|
||||
['-l', 'kw4wjm'], # post from banned subreddit
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--user", "sdclhgsolgjeroij", "--submitted", "-L", 10],
|
||||
["--user", "me", "--upvoted", "-L", 10],
|
||||
["--user", "sdclhgsolgjeroij", "--upvoted", "-L", 10],
|
||||
["--subreddit", "submitters", "-L", 10], # Private subreddit
|
||||
["--subreddit", "donaldtrump", "-L", 10], # Banned subreddit
|
||||
["--user", "djnish", "--user", "helen_darten", "-m", "cuteanimalpics", "-L", 10],
|
||||
["--subreddit", "friends", "-L", 10],
|
||||
["-l", "ijy4ch"], # user deleted post
|
||||
["-l", "kw4wjm"], # post from banned subreddit
|
||||
),
|
||||
)
|
||||
def test_cli_download_soft_fail(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Downloaded' not in result.output
|
||||
assert "Downloaded" not in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--time', 'random'],
|
||||
['--sort', 'random'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--time", "random"],
|
||||
["--sort", "random"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_hard_fail(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
@@ -260,114 +277,122 @@ def test_cli_download_hard_fail(test_args: list[str], tmp_path: Path):
|
||||
|
||||
def test_cli_download_use_default_config(tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = ['download', '-vv', str(tmp_path)]
|
||||
test_args = ["download", "-vv", str(tmp_path)]
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', '6l7778', '--exclude-id', '6l7778'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["-l", "6l7778", "--exclude-id", "6l7778"],))
|
||||
def test_cli_download_links_exclusion(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'in exclusion list' in result.output
|
||||
assert 'Downloaded submission ' not in result.output
|
||||
assert "in exclusion list" in result.output
|
||||
assert "Downloaded submission " not in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', '6l7778', '--skip-subreddit', 'EmpireDidNothingWrong'],
|
||||
['-s', 'trollxchromosomes', '--skip-subreddit', 'trollxchromosomes', '-L', '3'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "6l7778", "--skip-subreddit", "EmpireDidNothingWrong"],
|
||||
["-s", "trollxchromosomes", "--skip-subreddit", "trollxchromosomes", "-L", "3"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_subreddit_exclusion(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'in skip list' in result.output
|
||||
assert 'Downloaded submission ' not in result.output
|
||||
assert "in skip list" in result.output
|
||||
assert "Downloaded submission " not in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--file-scheme', '{TITLE}'],
|
||||
['--file-scheme', '{TITLE}_test_{SUBREDDIT}'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["--file-scheme", "{TITLE}"],
|
||||
["--file-scheme", "{TITLE}_test_{SUBREDDIT}"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_file_scheme_warning(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Some files might not be downloaded due to name conflicts' in result.output
|
||||
assert "Some files might not be downloaded due to name conflicts" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['-l', 'n9w9fo', '--disable-module', 'SelfPost'],
|
||||
['-l', 'nnb9vs', '--disable-module', 'VReddit'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
"test_args",
|
||||
(
|
||||
["-l", "n9w9fo", "--disable-module", "SelfPost"],
|
||||
["-l", "nnb9vs", "--disable-module", "VReddit"],
|
||||
),
|
||||
)
|
||||
def test_cli_download_disable_modules(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'skipped due to disabled module' in result.output
|
||||
assert 'Downloaded submission' not in result.output
|
||||
assert "skipped due to disabled module" in result.output
|
||||
assert "Downloaded submission" not in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
def test_cli_download_include_id_file(tmp_path: Path):
|
||||
test_file = Path(tmp_path, 'include.txt')
|
||||
test_args = ['--include-id-file', str(test_file)]
|
||||
test_file.write_text('odr9wg\nody576')
|
||||
test_file = Path(tmp_path, "include.txt")
|
||||
test_args = ["--include-id-file", str(test_file)]
|
||||
test_file.write_text("odr9wg\nody576")
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Downloaded submission' in result.output
|
||||
assert "Downloaded submission" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize('test_args', (
|
||||
['--ignore-user', 'ArjanEgges', '-l', 'm3hxzd'],
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize("test_args", (["--ignore-user", "ArjanEgges", "-l", "m3hxzd"],))
|
||||
def test_cli_download_ignore_user(test_args: list[str], tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert 'Downloaded submission' not in result.output
|
||||
assert 'being an ignored user' in result.output
|
||||
assert "Downloaded submission" not in result.output
|
||||
assert "being an ignored user" in result.output
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason='A test config file is required for integration tests')
|
||||
@pytest.mark.parametrize(('test_args', 'was_filtered'), (
|
||||
(['-l', 'ljyy27', '--min-score', '50'], True),
|
||||
(['-l', 'ljyy27', '--min-score', '1'], False),
|
||||
(['-l', 'ljyy27', '--max-score', '1'], True),
|
||||
(['-l', 'ljyy27', '--max-score', '100'], False),
|
||||
))
|
||||
@pytest.mark.skipif(not does_test_config_exist, reason="A test config file is required for integration tests")
|
||||
@pytest.mark.parametrize(
|
||||
("test_args", "was_filtered"),
|
||||
(
|
||||
(["-l", "ljyy27", "--min-score", "50"], True),
|
||||
(["-l", "ljyy27", "--min-score", "1"], False),
|
||||
(["-l", "ljyy27", "--max-score", "1"], True),
|
||||
(["-l", "ljyy27", "--max-score", "100"], False),
|
||||
),
|
||||
)
|
||||
def test_cli_download_score_filter(test_args: list[str], was_filtered: bool, tmp_path: Path):
|
||||
runner = CliRunner()
|
||||
test_args = create_basic_args_for_download_runner(test_args, tmp_path)
|
||||
result = runner.invoke(cli, test_args)
|
||||
assert result.exit_code == 0
|
||||
assert ('filtered due to score' in result.output) == was_filtered
|
||||
assert ("filtered due to score" in result.output) == was_filtered
|
||||
|
||||
@@ -10,22 +10,23 @@ from bdfr.site_downloaders.fallback_downloaders.ytdlp_fallback import YtdlpFallb
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('https://www.reddit.com/r/specializedtools/comments/n2nw5m/bamboo_splitter/', True),
|
||||
('https://www.youtube.com/watch?v=P19nvJOmqCc', True),
|
||||
('https://www.example.com/test', False),
|
||||
('https://milesmatrix.bandcamp.com/album/la-boum/', False),
|
||||
('https://v.redd.it/dlr54z8p182a1', True),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("https://www.reddit.com/r/specializedtools/comments/n2nw5m/bamboo_splitter/", True),
|
||||
("https://www.youtube.com/watch?v=P19nvJOmqCc", True),
|
||||
("https://www.example.com/test", False),
|
||||
("https://milesmatrix.bandcamp.com/album/la-boum/", False),
|
||||
("https://v.redd.it/dlr54z8p182a1", True),
|
||||
),
|
||||
)
|
||||
def test_can_handle_link(test_url: str, expected: bool):
|
||||
result = YtdlpFallback.can_handle_link(test_url)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize('test_url', (
|
||||
'https://milesmatrix.bandcamp.com/album/la-boum/',
|
||||
))
|
||||
@pytest.mark.parametrize("test_url", ("https://milesmatrix.bandcamp.com/album/la-boum/",))
|
||||
def test_info_extraction_bad(test_url: str):
|
||||
with pytest.raises(NotADownloadableLinkError):
|
||||
YtdlpFallback.get_video_attributes(test_url)
|
||||
@@ -33,12 +34,18 @@ def test_info_extraction_bad(test_url: str):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://streamable.com/dt46y', 'b7e465adaade5f2b6d8c2b4b7d0a2878'),
|
||||
('https://streamable.com/t8sem', '49b2d1220c485455548f1edbc05d4ecf'),
|
||||
('https://www.reddit.com/r/specializedtools/comments/n2nw5m/bamboo_splitter/', '6c6ff46e04b4e33a755ae2a9b5a45ac5'),
|
||||
('https://v.redd.it/9z1dnk3xr5k61', '226cee353421c7aefb05c92424cc8cdd'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(
|
||||
("https://streamable.com/dt46y", "b7e465adaade5f2b6d8c2b4b7d0a2878"),
|
||||
("https://streamable.com/t8sem", "49b2d1220c485455548f1edbc05d4ecf"),
|
||||
(
|
||||
"https://www.reddit.com/r/specializedtools/comments/n2nw5m/bamboo_splitter/",
|
||||
"6c6ff46e04b4e33a755ae2a9b5a45ac5",
|
||||
),
|
||||
("https://v.redd.it/9z1dnk3xr5k61", "226cee353421c7aefb05c92424cc8cdd"),
|
||||
),
|
||||
)
|
||||
def test_find_resources(test_url: str, expected_hash: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
|
||||
@@ -10,10 +10,13 @@ from bdfr.site_downloaders.delay_for_reddit import DelayForReddit
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://www.delayforreddit.com/dfr/calvin6123/MjU1Njc5NQ==', '3300f28c2f9358d05667985c9c04210d'),
|
||||
('https://www.delayforreddit.com/dfr/RoXs_26/NDAwMzAyOQ==', '09b7b01719dff45ab197bdc08b90f78a'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(
|
||||
("https://www.delayforreddit.com/dfr/calvin6123/MjU1Njc5NQ==", "3300f28c2f9358d05667985c9c04210d"),
|
||||
("https://www.delayforreddit.com/dfr/RoXs_26/NDAwMzAyOQ==", "09b7b01719dff45ab197bdc08b90f78a"),
|
||||
),
|
||||
)
|
||||
def test_download_resource(test_url: str, expected_hash: str):
|
||||
mock_submission = Mock()
|
||||
mock_submission.url = test_url
|
||||
|
||||
@@ -10,10 +10,13 @@ from bdfr.site_downloaders.direct import Direct
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://giant.gfycat.com/DefinitiveCanineCrayfish.mp4', '48f9bd4dbec1556d7838885612b13b39'),
|
||||
('https://giant.gfycat.com/DazzlingSilkyIguana.mp4', '808941b48fc1e28713d36dd7ed9dc648'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(
|
||||
("https://giant.gfycat.com/DefinitiveCanineCrayfish.mp4", "48f9bd4dbec1556d7838885612b13b39"),
|
||||
("https://giant.gfycat.com/DazzlingSilkyIguana.mp4", "808941b48fc1e28713d36dd7ed9dc648"),
|
||||
),
|
||||
)
|
||||
def test_download_resource(test_url: str, expected_hash: str):
|
||||
mock_submission = Mock()
|
||||
mock_submission.url = test_url
|
||||
|
||||
@@ -21,67 +21,82 @@ from bdfr.site_downloaders.youtube import Youtube
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_submission_url', 'expected_class'), (
|
||||
('https://www.reddit.com/r/TwoXChromosomes/comments/lu29zn/i_refuse_to_live_my_life'
|
||||
'_in_anything_but_comfort/', SelfPost),
|
||||
('https://i.redd.it/affyv0axd5k61.png', Direct),
|
||||
('https://i.imgur.com/bZx1SJQ.jpg', Imgur),
|
||||
('https://imgur.com/BuzvZwb.gifv', Imgur),
|
||||
('https://imgur.com/a/MkxAzeg', Imgur),
|
||||
('https://m.imgur.com/a/py3RW0j', Imgur),
|
||||
('https://www.reddit.com/gallery/lu93m7', Gallery),
|
||||
('https://gfycat.com/concretecheerfulfinwhale', Gfycat),
|
||||
('https://www.erome.com/a/NWGw0F09', Erome),
|
||||
('https://youtube.com/watch?v=Gv8Wz74FjVA', Youtube),
|
||||
('https://redgifs.com/watch/courageousimpeccablecanvasback', Redgifs),
|
||||
('https://www.gifdeliverynetwork.com/repulsivefinishedandalusianhorse', Redgifs),
|
||||
('https://youtu.be/DevfjHOhuFc', Youtube),
|
||||
('https://m.youtube.com/watch?v=kr-FeojxzUM', Youtube),
|
||||
('https://dynasty-scans.com/system/images_images/000/017/819/original/80215103_p0.png?1612232781', Direct),
|
||||
('https://v.redd.it/9z1dnk3xr5k61', VReddit),
|
||||
('https://streamable.com/dt46y', YtdlpFallback),
|
||||
('https://vimeo.com/channels/31259/53576664', YtdlpFallback),
|
||||
('http://video.pbs.org/viralplayer/2365173446/', YtdlpFallback),
|
||||
('https://www.pornhub.com/view_video.php?viewkey=ph5a2ee0461a8d0', PornHub),
|
||||
('https://www.patreon.com/posts/minecart-track-59346560', Gallery),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_submission_url", "expected_class"),
|
||||
(
|
||||
(
|
||||
"https://www.reddit.com/r/TwoXChromosomes/comments/lu29zn/i_refuse_to_live_my_life"
|
||||
"_in_anything_but_comfort/",
|
||||
SelfPost,
|
||||
),
|
||||
("https://i.redd.it/affyv0axd5k61.png", Direct),
|
||||
("https://i.imgur.com/bZx1SJQ.jpg", Imgur),
|
||||
("https://imgur.com/BuzvZwb.gifv", Imgur),
|
||||
("https://imgur.com/a/MkxAzeg", Imgur),
|
||||
("https://m.imgur.com/a/py3RW0j", Imgur),
|
||||
("https://www.reddit.com/gallery/lu93m7", Gallery),
|
||||
("https://gfycat.com/concretecheerfulfinwhale", Gfycat),
|
||||
("https://www.erome.com/a/NWGw0F09", Erome),
|
||||
("https://youtube.com/watch?v=Gv8Wz74FjVA", Youtube),
|
||||
("https://redgifs.com/watch/courageousimpeccablecanvasback", Redgifs),
|
||||
("https://www.gifdeliverynetwork.com/repulsivefinishedandalusianhorse", Redgifs),
|
||||
("https://youtu.be/DevfjHOhuFc", Youtube),
|
||||
("https://m.youtube.com/watch?v=kr-FeojxzUM", Youtube),
|
||||
("https://dynasty-scans.com/system/images_images/000/017/819/original/80215103_p0.png?1612232781", Direct),
|
||||
("https://v.redd.it/9z1dnk3xr5k61", VReddit),
|
||||
("https://streamable.com/dt46y", YtdlpFallback),
|
||||
("https://vimeo.com/channels/31259/53576664", YtdlpFallback),
|
||||
("http://video.pbs.org/viralplayer/2365173446/", YtdlpFallback),
|
||||
("https://www.pornhub.com/view_video.php?viewkey=ph5a2ee0461a8d0", PornHub),
|
||||
("https://www.patreon.com/posts/minecart-track-59346560", Gallery),
|
||||
),
|
||||
)
|
||||
def test_factory_lever_good(test_submission_url: str, expected_class: BaseDownloader, reddit_instance: praw.Reddit):
|
||||
result = DownloadFactory.pull_lever(test_submission_url)
|
||||
assert result is expected_class
|
||||
|
||||
|
||||
@pytest.mark.parametrize('test_url', (
|
||||
'random.com',
|
||||
'bad',
|
||||
'https://www.google.com/',
|
||||
'https://www.google.com',
|
||||
'https://www.google.com/test',
|
||||
'https://www.google.com/test/',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_url",
|
||||
(
|
||||
"random.com",
|
||||
"bad",
|
||||
"https://www.google.com/",
|
||||
"https://www.google.com",
|
||||
"https://www.google.com/test",
|
||||
"https://www.google.com/test/",
|
||||
),
|
||||
)
|
||||
def test_factory_lever_bad(test_url: str):
|
||||
with pytest.raises(NotADownloadableLinkError):
|
||||
DownloadFactory.pull_lever(test_url)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('www.test.com/test.png', 'test.com/test.png'),
|
||||
('www.test.com/test.png?test_value=random', 'test.com/test.png'),
|
||||
('https://youtube.com/watch?v=Gv8Wz74FjVA', 'youtube.com/watch'),
|
||||
('https://i.imgur.com/BuzvZwb.gifv', 'i.imgur.com/BuzvZwb.gifv'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("www.test.com/test.png", "test.com/test.png"),
|
||||
("www.test.com/test.png?test_value=random", "test.com/test.png"),
|
||||
("https://youtube.com/watch?v=Gv8Wz74FjVA", "youtube.com/watch"),
|
||||
("https://i.imgur.com/BuzvZwb.gifv", "i.imgur.com/BuzvZwb.gifv"),
|
||||
),
|
||||
)
|
||||
def test_sanitise_url(test_url: str, expected: str):
|
||||
result = DownloadFactory.sanitise_url(test_url)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('www.example.com/test.asp', True),
|
||||
('www.example.com/test.html', True),
|
||||
('www.example.com/test.js', True),
|
||||
('www.example.com/test.xhtml', True),
|
||||
('www.example.com/test.mp4', False),
|
||||
('www.example.com/test.png', False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("www.example.com/test.asp", True),
|
||||
("www.example.com/test.html", True),
|
||||
("www.example.com/test.js", True),
|
||||
("www.example.com/test.xhtml", True),
|
||||
("www.example.com/test.mp4", False),
|
||||
("www.example.com/test.png", False),
|
||||
),
|
||||
)
|
||||
def test_is_web_resource(test_url: str, expected: bool):
|
||||
result = DownloadFactory.is_web_resource(test_url)
|
||||
assert result == expected
|
||||
|
||||
@@ -9,31 +9,38 @@ from bdfr.site_downloaders.erome import Erome
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_urls'), (
|
||||
('https://www.erome.com/a/vqtPuLXh', (
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/vqtPuLXh/KH2qBT99_480p.mp4',
|
||||
)),
|
||||
('https://www.erome.com/a/ORhX0FZz', (
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/9IYQocM9_480p.mp4',
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/9eEDc8xm_480p.mp4',
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/EvApC7Rp_480p.mp4',
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/LruobtMs_480p.mp4',
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/TJNmSUU5_480p.mp4',
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/X11Skh6Z_480p.mp4',
|
||||
r'https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/bjlTkpn7_480p.mp4'
|
||||
)),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_urls"),
|
||||
(
|
||||
("https://www.erome.com/a/vqtPuLXh", (r"https://[a-z]\d+.erome.com/\d{3}/vqtPuLXh/KH2qBT99_480p.mp4",)),
|
||||
(
|
||||
"https://www.erome.com/a/ORhX0FZz",
|
||||
(
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/9IYQocM9_480p.mp4",
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/9eEDc8xm_480p.mp4",
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/EvApC7Rp_480p.mp4",
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/LruobtMs_480p.mp4",
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/TJNmSUU5_480p.mp4",
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/X11Skh6Z_480p.mp4",
|
||||
r"https://[a-z]\d+.erome.com/\d{3}/ORhX0FZz/bjlTkpn7_480p.mp4",
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_get_link(test_url: str, expected_urls: tuple[str]):
|
||||
result = Erome. _get_links(test_url)
|
||||
result = Erome._get_links(test_url)
|
||||
assert all([any([re.match(p, r) for r in result]) for p in expected_urls])
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hashes_len'), (
|
||||
('https://www.erome.com/a/vqtPuLXh', 1),
|
||||
('https://www.erome.com/a/4tP3KI6F', 1),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hashes_len"),
|
||||
(
|
||||
("https://www.erome.com/a/vqtPuLXh", 1),
|
||||
("https://www.erome.com/a/4tP3KI6F", 1),
|
||||
),
|
||||
)
|
||||
def test_download_resource(test_url: str, expected_hashes_len: int):
|
||||
# Can't compare hashes for this test, Erome doesn't return the exact same file from request to request so the hash
|
||||
# will change back and forth randomly
|
||||
|
||||
@@ -9,30 +9,39 @@ from bdfr.site_downloaders.gallery import Gallery
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_ids', 'expected'), (
|
||||
([
|
||||
{'media_id': '18nzv9ch0hn61'},
|
||||
{'media_id': 'jqkizcch0hn61'},
|
||||
{'media_id': 'k0fnqzbh0hn61'},
|
||||
{'media_id': 'm3gamzbh0hn61'},
|
||||
], {
|
||||
'https://i.redd.it/18nzv9ch0hn61.jpg',
|
||||
'https://i.redd.it/jqkizcch0hn61.jpg',
|
||||
'https://i.redd.it/k0fnqzbh0hn61.jpg',
|
||||
'https://i.redd.it/m3gamzbh0hn61.jpg'
|
||||
}),
|
||||
([
|
||||
{'media_id': '04vxj25uqih61'},
|
||||
{'media_id': '0fnx83kpqih61'},
|
||||
{'media_id': '7zkmr1wqqih61'},
|
||||
{'media_id': 'u37k5gxrqih61'},
|
||||
], {
|
||||
'https://i.redd.it/04vxj25uqih61.png',
|
||||
'https://i.redd.it/0fnx83kpqih61.png',
|
||||
'https://i.redd.it/7zkmr1wqqih61.png',
|
||||
'https://i.redd.it/u37k5gxrqih61.png'
|
||||
}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_ids", "expected"),
|
||||
(
|
||||
(
|
||||
[
|
||||
{"media_id": "18nzv9ch0hn61"},
|
||||
{"media_id": "jqkizcch0hn61"},
|
||||
{"media_id": "k0fnqzbh0hn61"},
|
||||
{"media_id": "m3gamzbh0hn61"},
|
||||
],
|
||||
{
|
||||
"https://i.redd.it/18nzv9ch0hn61.jpg",
|
||||
"https://i.redd.it/jqkizcch0hn61.jpg",
|
||||
"https://i.redd.it/k0fnqzbh0hn61.jpg",
|
||||
"https://i.redd.it/m3gamzbh0hn61.jpg",
|
||||
},
|
||||
),
|
||||
(
|
||||
[
|
||||
{"media_id": "04vxj25uqih61"},
|
||||
{"media_id": "0fnx83kpqih61"},
|
||||
{"media_id": "7zkmr1wqqih61"},
|
||||
{"media_id": "u37k5gxrqih61"},
|
||||
],
|
||||
{
|
||||
"https://i.redd.it/04vxj25uqih61.png",
|
||||
"https://i.redd.it/0fnx83kpqih61.png",
|
||||
"https://i.redd.it/7zkmr1wqqih61.png",
|
||||
"https://i.redd.it/u37k5gxrqih61.png",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_gallery_get_links(test_ids: list[dict], expected: set[str]):
|
||||
results = Gallery._get_links(test_ids)
|
||||
assert set(results) == expected
|
||||
@@ -40,32 +49,47 @@ def test_gallery_get_links(test_ids: list[dict], expected: set[str]):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'expected_hashes'), (
|
||||
('m6lvrh', {
|
||||
'5c42b8341dd56eebef792e86f3981c6a',
|
||||
'8f38d76da46f4057bf2773a778e725ca',
|
||||
'f5776f8f90491c8b770b8e0a6bfa49b3',
|
||||
'fa1a43c94da30026ad19a9813a0ed2c2',
|
||||
}),
|
||||
('ljyy27', {
|
||||
'359c203ec81d0bc00e675f1023673238',
|
||||
'79262fd46bce5bfa550d878a3b898be4',
|
||||
'808c35267f44acb523ce03bfa5687404',
|
||||
'ec8b65bdb7f1279c4b3af0ea2bbb30c3',
|
||||
}),
|
||||
('obkflw', {
|
||||
'65163f685fb28c5b776e0e77122718be',
|
||||
'2a337eb5b13c34d3ca3f51b5db7c13e9',
|
||||
}),
|
||||
('rb3ub6', { # patreon post
|
||||
'748a976c6cedf7ea85b6f90e7cb685c7',
|
||||
'839796d7745e88ced6355504e1f74508',
|
||||
'bcdb740367d0f19f97a77e614b48a42d',
|
||||
'0f230b8c4e5d103d35a773fab9814ec3',
|
||||
'e5192d6cb4f84c4f4a658355310bf0f9',
|
||||
'91cbe172cd8ccbcf049fcea4204eb979',
|
||||
})
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_submission_id", "expected_hashes"),
|
||||
(
|
||||
(
|
||||
"m6lvrh",
|
||||
{
|
||||
"5c42b8341dd56eebef792e86f3981c6a",
|
||||
"8f38d76da46f4057bf2773a778e725ca",
|
||||
"f5776f8f90491c8b770b8e0a6bfa49b3",
|
||||
"fa1a43c94da30026ad19a9813a0ed2c2",
|
||||
},
|
||||
),
|
||||
(
|
||||
"ljyy27",
|
||||
{
|
||||
"359c203ec81d0bc00e675f1023673238",
|
||||
"79262fd46bce5bfa550d878a3b898be4",
|
||||
"808c35267f44acb523ce03bfa5687404",
|
||||
"ec8b65bdb7f1279c4b3af0ea2bbb30c3",
|
||||
},
|
||||
),
|
||||
(
|
||||
"obkflw",
|
||||
{
|
||||
"65163f685fb28c5b776e0e77122718be",
|
||||
"2a337eb5b13c34d3ca3f51b5db7c13e9",
|
||||
},
|
||||
),
|
||||
(
|
||||
"rb3ub6",
|
||||
{ # patreon post
|
||||
"748a976c6cedf7ea85b6f90e7cb685c7",
|
||||
"839796d7745e88ced6355504e1f74508",
|
||||
"bcdb740367d0f19f97a77e614b48a42d",
|
||||
"0f230b8c4e5d103d35a773fab9814ec3",
|
||||
"e5192d6cb4f84c4f4a658355310bf0f9",
|
||||
"91cbe172cd8ccbcf049fcea4204eb979",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_gallery_download(test_submission_id: str, expected_hashes: set[str], reddit_instance: praw.Reddit):
|
||||
test_submission = reddit_instance.submission(id=test_submission_id)
|
||||
gallery = Gallery(test_submission)
|
||||
@@ -75,10 +99,13 @@ def test_gallery_download(test_submission_id: str, expected_hashes: set[str], re
|
||||
assert set(hashes) == expected_hashes
|
||||
|
||||
|
||||
@pytest.mark.parametrize('test_id', (
|
||||
'n0pyzp',
|
||||
'nxyahw',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_id",
|
||||
(
|
||||
"n0pyzp",
|
||||
"nxyahw",
|
||||
),
|
||||
)
|
||||
def test_gallery_download_raises_right_error(test_id: str, reddit_instance: praw.Reddit):
|
||||
test_submission = reddit_instance.submission(id=test_id)
|
||||
gallery = Gallery(test_submission)
|
||||
|
||||
@@ -10,20 +10,26 @@ from bdfr.site_downloaders.gfycat import Gfycat
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_url'), (
|
||||
('https://gfycat.com/definitivecaninecrayfish', 'https://giant.gfycat.com/DefinitiveCanineCrayfish.mp4'),
|
||||
('https://gfycat.com/dazzlingsilkyiguana', 'https://giant.gfycat.com/DazzlingSilkyIguana.mp4'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_url"),
|
||||
(
|
||||
("https://gfycat.com/definitivecaninecrayfish", "https://giant.gfycat.com/DefinitiveCanineCrayfish.mp4"),
|
||||
("https://gfycat.com/dazzlingsilkyiguana", "https://giant.gfycat.com/DazzlingSilkyIguana.mp4"),
|
||||
),
|
||||
)
|
||||
def test_get_link(test_url: str, expected_url: str):
|
||||
result = Gfycat._get_link(test_url)
|
||||
assert result.pop() == expected_url
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://gfycat.com/definitivecaninecrayfish', '48f9bd4dbec1556d7838885612b13b39'),
|
||||
('https://gfycat.com/dazzlingsilkyiguana', '808941b48fc1e28713d36dd7ed9dc648'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(
|
||||
("https://gfycat.com/definitivecaninecrayfish", "48f9bd4dbec1556d7838885612b13b39"),
|
||||
("https://gfycat.com/dazzlingsilkyiguana", "808941b48fc1e28713d36dd7ed9dc648"),
|
||||
),
|
||||
)
|
||||
def test_download_resource(test_url: str, expected_hash: str):
|
||||
mock_submission = Mock()
|
||||
mock_submission.url = test_url
|
||||
|
||||
@@ -11,166 +11,167 @@ from bdfr.site_downloaders.imgur import Imgur
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_gen_dict', 'expected_image_dict'), (
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_gen_dict", "expected_image_dict"),
|
||||
(
|
||||
'https://imgur.com/a/xWZsDDP',
|
||||
{'num_images': '1', 'id': 'xWZsDDP', 'hash': 'xWZsDDP'},
|
||||
[
|
||||
{'hash': 'ypa8YfS', 'title': '', 'ext': '.png', 'animated': False}
|
||||
]
|
||||
(
|
||||
"https://imgur.com/a/xWZsDDP",
|
||||
{"num_images": "1", "id": "xWZsDDP", "hash": "xWZsDDP"},
|
||||
[{"hash": "ypa8YfS", "title": "", "ext": ".png", "animated": False}],
|
||||
),
|
||||
(
|
||||
"https://imgur.com/gallery/IjJJdlC",
|
||||
{"num_images": 1, "id": 384898055, "hash": "IjJJdlC"},
|
||||
[
|
||||
{
|
||||
"hash": "CbbScDt",
|
||||
"description": "watch when he gets it",
|
||||
"ext": ".gif",
|
||||
"animated": True,
|
||||
"has_sound": False,
|
||||
}
|
||||
],
|
||||
),
|
||||
(
|
||||
"https://imgur.com/a/dcc84Gt",
|
||||
{"num_images": "4", "id": "dcc84Gt", "hash": "dcc84Gt"},
|
||||
[
|
||||
{"hash": "ylx0Kle", "ext": ".jpg", "title": ""},
|
||||
{"hash": "TdYfKbK", "ext": ".jpg", "title": ""},
|
||||
{"hash": "pCxGbe8", "ext": ".jpg", "title": ""},
|
||||
{"hash": "TSAkikk", "ext": ".jpg", "title": ""},
|
||||
],
|
||||
),
|
||||
(
|
||||
"https://m.imgur.com/a/py3RW0j",
|
||||
{
|
||||
"num_images": "1",
|
||||
"id": "py3RW0j",
|
||||
"hash": "py3RW0j",
|
||||
},
|
||||
[{"hash": "K24eQmK", "has_sound": False, "ext": ".jpg"}],
|
||||
),
|
||||
),
|
||||
(
|
||||
'https://imgur.com/gallery/IjJJdlC',
|
||||
{'num_images': 1, 'id': 384898055, 'hash': 'IjJJdlC'},
|
||||
[
|
||||
{'hash': 'CbbScDt',
|
||||
'description': 'watch when he gets it',
|
||||
'ext': '.gif',
|
||||
'animated': True,
|
||||
'has_sound': False
|
||||
}
|
||||
],
|
||||
),
|
||||
(
|
||||
'https://imgur.com/a/dcc84Gt',
|
||||
{'num_images': '4', 'id': 'dcc84Gt', 'hash': 'dcc84Gt'},
|
||||
[
|
||||
{'hash': 'ylx0Kle', 'ext': '.jpg', 'title': ''},
|
||||
{'hash': 'TdYfKbK', 'ext': '.jpg', 'title': ''},
|
||||
{'hash': 'pCxGbe8', 'ext': '.jpg', 'title': ''},
|
||||
{'hash': 'TSAkikk', 'ext': '.jpg', 'title': ''},
|
||||
]
|
||||
),
|
||||
(
|
||||
'https://m.imgur.com/a/py3RW0j',
|
||||
{'num_images': '1', 'id': 'py3RW0j', 'hash': 'py3RW0j', },
|
||||
[
|
||||
{'hash': 'K24eQmK', 'has_sound': False, 'ext': '.jpg'}
|
||||
],
|
||||
),
|
||||
))
|
||||
)
|
||||
def test_get_data_album(test_url: str, expected_gen_dict: dict, expected_image_dict: list[dict]):
|
||||
result = Imgur._get_data(test_url)
|
||||
assert all([result.get(key) == expected_gen_dict[key] for key in expected_gen_dict.keys()])
|
||||
|
||||
# Check if all the keys from the test dict are correct in at least one of the album entries
|
||||
assert any([all([image.get(key) == image_dict[key] for key in image_dict.keys()])
|
||||
for image_dict in expected_image_dict for image in result['album_images']['images']])
|
||||
assert any(
|
||||
[
|
||||
all([image.get(key) == image_dict[key] for key in image_dict.keys()])
|
||||
for image_dict in expected_image_dict
|
||||
for image in result["album_images"]["images"]
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_image_dict'), (
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_image_dict"),
|
||||
(
|
||||
'https://i.imgur.com/dLk3FGY.gifv',
|
||||
{'hash': 'dLk3FGY', 'title': '', 'ext': '.mp4', 'animated': True}
|
||||
("https://i.imgur.com/dLk3FGY.gifv", {"hash": "dLk3FGY", "title": "", "ext": ".mp4", "animated": True}),
|
||||
(
|
||||
"https://imgur.com/65FqTpT.gifv",
|
||||
{"hash": "65FqTpT", "title": "", "description": "", "animated": True, "mimetype": "video/mp4"},
|
||||
),
|
||||
),
|
||||
(
|
||||
'https://imgur.com/65FqTpT.gifv',
|
||||
{
|
||||
'hash': '65FqTpT',
|
||||
'title': '',
|
||||
'description': '',
|
||||
'animated': True,
|
||||
'mimetype': 'video/mp4'
|
||||
},
|
||||
),
|
||||
))
|
||||
)
|
||||
def test_get_data_gif(test_url: str, expected_image_dict: dict):
|
||||
result = Imgur._get_data(test_url)
|
||||
assert all([result.get(key) == expected_image_dict[key] for key in expected_image_dict.keys()])
|
||||
|
||||
|
||||
@pytest.mark.parametrize('test_extension', (
|
||||
'.gif',
|
||||
'.png',
|
||||
'.jpg',
|
||||
'.mp4'
|
||||
))
|
||||
@pytest.mark.parametrize("test_extension", (".gif", ".png", ".jpg", ".mp4"))
|
||||
def test_imgur_extension_validation_good(test_extension: str):
|
||||
result = Imgur._validate_extension(test_extension)
|
||||
assert result == test_extension
|
||||
|
||||
|
||||
@pytest.mark.parametrize('test_extension', (
|
||||
'.jpeg',
|
||||
'bad',
|
||||
'.avi',
|
||||
'.test',
|
||||
'.flac',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_extension",
|
||||
(
|
||||
".jpeg",
|
||||
"bad",
|
||||
".avi",
|
||||
".test",
|
||||
".flac",
|
||||
),
|
||||
)
|
||||
def test_imgur_extension_validation_bad(test_extension: str):
|
||||
with pytest.raises(SiteDownloaderError):
|
||||
Imgur._validate_extension(test_extension)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hashes'), (
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hashes"),
|
||||
(
|
||||
'https://imgur.com/a/xWZsDDP',
|
||||
('f551d6e6b0fef2ce909767338612e31b',)
|
||||
),
|
||||
(
|
||||
'https://imgur.com/gallery/IjJJdlC',
|
||||
('740b006cf9ec9d6f734b6e8f5130bdab',),
|
||||
),
|
||||
(
|
||||
'https://imgur.com/a/dcc84Gt',
|
||||
("https://imgur.com/a/xWZsDDP", ("f551d6e6b0fef2ce909767338612e31b",)),
|
||||
(
|
||||
'cf1158e1de5c3c8993461383b96610cf',
|
||||
'28d6b791a2daef8aa363bf5a3198535d',
|
||||
'248ef8f2a6d03eeb2a80d0123dbaf9b6',
|
||||
'029c475ce01b58fdf1269d8771d33913',
|
||||
"https://imgur.com/gallery/IjJJdlC",
|
||||
("740b006cf9ec9d6f734b6e8f5130bdab",),
|
||||
),
|
||||
(
|
||||
"https://imgur.com/a/dcc84Gt",
|
||||
(
|
||||
"cf1158e1de5c3c8993461383b96610cf",
|
||||
"28d6b791a2daef8aa363bf5a3198535d",
|
||||
"248ef8f2a6d03eeb2a80d0123dbaf9b6",
|
||||
"029c475ce01b58fdf1269d8771d33913",
|
||||
),
|
||||
),
|
||||
(
|
||||
"https://imgur.com/a/eemHCCK",
|
||||
(
|
||||
"9cb757fd8f055e7ef7aa88addc9d9fa5",
|
||||
"b6cb6c918e2544e96fb7c07d828774b5",
|
||||
"fb6c913d721c0bbb96aa65d7f560d385",
|
||||
),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/lFJai6i.gifv",
|
||||
("01a6e79a30bec0e644e5da12365d5071",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/ywSyILa.gifv?",
|
||||
("56d4afc32d2966017c38d98568709b45",),
|
||||
),
|
||||
(
|
||||
"https://imgur.com/ubYwpbk.GIFV",
|
||||
("d4a774aac1667783f9ed3a1bd02fac0c",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/j1CNCZY.gifv",
|
||||
("58e7e6d972058c18b7ecde910ca147e3",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/uTvtQsw.gifv",
|
||||
("46c86533aa60fc0e09f2a758513e3ac2",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/OGeVuAe.giff",
|
||||
("77389679084d381336f168538793f218",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/OGeVuAe.gift",
|
||||
("77389679084d381336f168538793f218",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/3SKrQfK.jpg?1",
|
||||
("aa299e181b268578979cad176d1bd1d0",),
|
||||
),
|
||||
(
|
||||
"https://i.imgur.com/cbivYRW.jpg?3",
|
||||
("7ec6ceef5380cb163a1d498c359c51fd",),
|
||||
),
|
||||
(
|
||||
"http://i.imgur.com/s9uXxlq.jpg?5.jpg",
|
||||
("338de3c23ee21af056b3a7c154e2478f",),
|
||||
),
|
||||
),
|
||||
(
|
||||
'https://imgur.com/a/eemHCCK',
|
||||
(
|
||||
'9cb757fd8f055e7ef7aa88addc9d9fa5',
|
||||
'b6cb6c918e2544e96fb7c07d828774b5',
|
||||
'fb6c913d721c0bbb96aa65d7f560d385',
|
||||
),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/lFJai6i.gifv',
|
||||
('01a6e79a30bec0e644e5da12365d5071',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/ywSyILa.gifv?',
|
||||
('56d4afc32d2966017c38d98568709b45',),
|
||||
),
|
||||
(
|
||||
'https://imgur.com/ubYwpbk.GIFV',
|
||||
('d4a774aac1667783f9ed3a1bd02fac0c',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/j1CNCZY.gifv',
|
||||
('58e7e6d972058c18b7ecde910ca147e3',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/uTvtQsw.gifv',
|
||||
('46c86533aa60fc0e09f2a758513e3ac2',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/OGeVuAe.giff',
|
||||
('77389679084d381336f168538793f218',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/OGeVuAe.gift',
|
||||
('77389679084d381336f168538793f218',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/3SKrQfK.jpg?1',
|
||||
('aa299e181b268578979cad176d1bd1d0',),
|
||||
),
|
||||
(
|
||||
'https://i.imgur.com/cbivYRW.jpg?3',
|
||||
('7ec6ceef5380cb163a1d498c359c51fd',),
|
||||
),
|
||||
(
|
||||
'http://i.imgur.com/s9uXxlq.jpg?5.jpg',
|
||||
('338de3c23ee21af056b3a7c154e2478f',),
|
||||
),
|
||||
))
|
||||
)
|
||||
def test_find_resources(test_url: str, expected_hashes: list[str]):
|
||||
mock_download = Mock()
|
||||
mock_download.url = test_url
|
||||
|
||||
@@ -12,9 +12,10 @@ from bdfr.site_downloaders.pornhub import PornHub
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://www.pornhub.com/view_video.php?viewkey=ph6074c59798497', 'ad52a0f4fce8f99df0abed17de1d04c7'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(("https://www.pornhub.com/view_video.php?viewkey=ph6074c59798497", "ad52a0f4fce8f99df0abed17de1d04c7"),),
|
||||
)
|
||||
def test_hash_resources_good(test_url: str, expected_hash: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
@@ -27,9 +28,7 @@ def test_hash_resources_good(test_url: str, expected_hash: str):
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize('test_url', (
|
||||
'https://www.pornhub.com/view_video.php?viewkey=ph5ede121f0d3f8',
|
||||
))
|
||||
@pytest.mark.parametrize("test_url", ("https://www.pornhub.com/view_video.php?viewkey=ph5ede121f0d3f8",))
|
||||
def test_find_resources_good(test_url: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
|
||||
from unittest.mock import Mock
|
||||
import re
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -11,45 +11,55 @@ from bdfr.site_downloaders.redgifs import Redgifs
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('https://redgifs.com/watch/frighteningvictorioussalamander',
|
||||
{'FrighteningVictoriousSalamander.mp4'}),
|
||||
('https://redgifs.com/watch/springgreendecisivetaruca',
|
||||
{'SpringgreenDecisiveTaruca.mp4'}),
|
||||
('https://www.redgifs.com/watch/palegoldenrodrawhalibut',
|
||||
{'PalegoldenrodRawHalibut.mp4'}),
|
||||
('https://redgifs.com/watch/hollowintentsnowyowl',
|
||||
{'HollowIntentSnowyowl-large.jpg'}),
|
||||
('https://www.redgifs.com/watch/lustrousstickywaxwing',
|
||||
{'EntireEnchantingHypsilophodon-large.jpg',
|
||||
'FancyMagnificentAdamsstaghornedbeetle-large.jpg',
|
||||
'LustrousStickyWaxwing-large.jpg',
|
||||
'ParchedWindyArmyworm-large.jpg',
|
||||
'ThunderousColorlessErmine-large.jpg',
|
||||
'UnripeUnkemptWoodpecker-large.jpg'}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("https://redgifs.com/watch/frighteningvictorioussalamander", {"FrighteningVictoriousSalamander.mp4"}),
|
||||
("https://redgifs.com/watch/springgreendecisivetaruca", {"SpringgreenDecisiveTaruca.mp4"}),
|
||||
("https://www.redgifs.com/watch/palegoldenrodrawhalibut", {"PalegoldenrodRawHalibut.mp4"}),
|
||||
("https://redgifs.com/watch/hollowintentsnowyowl", {"HollowIntentSnowyowl-large.jpg"}),
|
||||
(
|
||||
"https://www.redgifs.com/watch/lustrousstickywaxwing",
|
||||
{
|
||||
"EntireEnchantingHypsilophodon-large.jpg",
|
||||
"FancyMagnificentAdamsstaghornedbeetle-large.jpg",
|
||||
"LustrousStickyWaxwing-large.jpg",
|
||||
"ParchedWindyArmyworm-large.jpg",
|
||||
"ThunderousColorlessErmine-large.jpg",
|
||||
"UnripeUnkemptWoodpecker-large.jpg",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_get_link(test_url: str, expected: set[str]):
|
||||
result = Redgifs._get_link(test_url)
|
||||
result = list(result)
|
||||
patterns = [r'https://thumbs\d\.redgifs\.com/' + e + r'.*' for e in expected]
|
||||
patterns = [r"https://thumbs\d\.redgifs\.com/" + e + r".*" for e in expected]
|
||||
assert all([re.match(p, r) for p in patterns] for r in result)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hashes'), (
|
||||
('https://redgifs.com/watch/frighteningvictorioussalamander', {'4007c35d9e1f4b67091b5f12cffda00a'}),
|
||||
('https://redgifs.com/watch/springgreendecisivetaruca', {'8dac487ac49a1f18cc1b4dabe23f0869'}),
|
||||
('https://redgifs.com/watch/leafysaltydungbeetle', {'076792c660b9c024c0471ef4759af8bd'}),
|
||||
('https://www.redgifs.com/watch/palegoldenrodrawhalibut', {'46d5aa77fe80c6407de1ecc92801c10e'}),
|
||||
('https://redgifs.com/watch/hollowintentsnowyowl', {'5ee51fa15e0a58e98f11dea6a6cca771'}),
|
||||
('https://www.redgifs.com/watch/lustrousstickywaxwing',
|
||||
{'b461e55664f07bed8d2f41d8586728fa',
|
||||
'30ba079a8ed7d7adf17929dc3064c10f',
|
||||
'0d4f149d170d29fc2f015c1121bab18b',
|
||||
'53987d99cfd77fd65b5fdade3718f9f1',
|
||||
'fb2e7d972846b83bf4016447d3060d60',
|
||||
'44fb28f72ec9a5cca63fa4369ab4f672'}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hashes"),
|
||||
(
|
||||
("https://redgifs.com/watch/frighteningvictorioussalamander", {"4007c35d9e1f4b67091b5f12cffda00a"}),
|
||||
("https://redgifs.com/watch/springgreendecisivetaruca", {"8dac487ac49a1f18cc1b4dabe23f0869"}),
|
||||
("https://redgifs.com/watch/leafysaltydungbeetle", {"076792c660b9c024c0471ef4759af8bd"}),
|
||||
("https://www.redgifs.com/watch/palegoldenrodrawhalibut", {"46d5aa77fe80c6407de1ecc92801c10e"}),
|
||||
("https://redgifs.com/watch/hollowintentsnowyowl", {"5ee51fa15e0a58e98f11dea6a6cca771"}),
|
||||
(
|
||||
"https://www.redgifs.com/watch/lustrousstickywaxwing",
|
||||
{
|
||||
"b461e55664f07bed8d2f41d8586728fa",
|
||||
"30ba079a8ed7d7adf17929dc3064c10f",
|
||||
"0d4f149d170d29fc2f015c1121bab18b",
|
||||
"53987d99cfd77fd65b5fdade3718f9f1",
|
||||
"fb2e7d972846b83bf4016447d3060d60",
|
||||
"44fb28f72ec9a5cca63fa4369ab4f672",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_download_resource(test_url: str, expected_hashes: set[str]):
|
||||
mock_submission = Mock()
|
||||
mock_submission.url = test_url
|
||||
@@ -62,18 +72,30 @@ def test_download_resource(test_url: str, expected_hashes: set[str]):
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_link', 'expected_hash'), (
|
||||
('https://redgifs.com/watch/flippantmemorablebaiji', {'FlippantMemorableBaiji-mobile.mp4'},
|
||||
{'41a5fb4865367ede9f65fc78736f497a'}),
|
||||
('https://redgifs.com/watch/thirstyunfortunatewaterdragons', {'thirstyunfortunatewaterdragons-mobile.mp4'},
|
||||
{'1a51dad8fedb594bdd84f027b3cbe8af'}),
|
||||
('https://redgifs.com/watch/conventionalplainxenopterygii', {'conventionalplainxenopterygii-mobile.mp4'},
|
||||
{'2e1786b3337da85b80b050e2c289daa4'})
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_link", "expected_hash"),
|
||||
(
|
||||
(
|
||||
"https://redgifs.com/watch/flippantmemorablebaiji",
|
||||
{"FlippantMemorableBaiji-mobile.mp4"},
|
||||
{"41a5fb4865367ede9f65fc78736f497a"},
|
||||
),
|
||||
(
|
||||
"https://redgifs.com/watch/thirstyunfortunatewaterdragons",
|
||||
{"thirstyunfortunatewaterdragons-mobile.mp4"},
|
||||
{"1a51dad8fedb594bdd84f027b3cbe8af"},
|
||||
),
|
||||
(
|
||||
"https://redgifs.com/watch/conventionalplainxenopterygii",
|
||||
{"conventionalplainxenopterygii-mobile.mp4"},
|
||||
{"2e1786b3337da85b80b050e2c289daa4"},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_hd_soft_fail(test_url: str, expected_link: set[str], expected_hash: set[str]):
|
||||
link = Redgifs._get_link(test_url)
|
||||
link = list(link)
|
||||
patterns = [r'https://thumbs\d\.redgifs\.com/' + e + r'.*' for e in expected_link]
|
||||
patterns = [r"https://thumbs\d\.redgifs\.com/" + e + r".*" for e in expected_link]
|
||||
assert all([re.match(p, r) for p in patterns] for r in link)
|
||||
mock_submission = Mock()
|
||||
mock_submission.url = test_url
|
||||
|
||||
@@ -10,11 +10,14 @@ from bdfr.site_downloaders.self_post import SelfPost
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'expected_hash'), (
|
||||
('ltmivt', '7d2c9e4e989e5cf2dca2e55a06b1c4f6'),
|
||||
('ltoaan', '221606386b614d6780c2585a59bd333f'),
|
||||
('d3sc8o', 'c1ff2b6bd3f6b91381dcd18dfc4ca35f'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_submission_id", "expected_hash"),
|
||||
(
|
||||
("ltmivt", "7d2c9e4e989e5cf2dca2e55a06b1c4f6"),
|
||||
("ltoaan", "221606386b614d6780c2585a59bd333f"),
|
||||
("d3sc8o", "c1ff2b6bd3f6b91381dcd18dfc4ca35f"),
|
||||
),
|
||||
)
|
||||
def test_find_resource(test_submission_id: str, expected_hash: str, reddit_instance: praw.Reddit):
|
||||
submission = reddit_instance.submission(id=test_submission_id)
|
||||
downloader = SelfPost(submission)
|
||||
|
||||
@@ -8,55 +8,83 @@ from bdfr.resource import Resource
|
||||
from bdfr.site_downloaders.vidble import Vidble
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('/RDFbznUvcN_med.jpg', '/RDFbznUvcN.jpg'),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_url", "expected"), (("/RDFbznUvcN_med.jpg", "/RDFbznUvcN.jpg"),))
|
||||
def test_change_med_url(test_url: str, expected: str):
|
||||
result = Vidble.change_med_url(test_url)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('https://www.vidble.com/show/UxsvAssYe5', {
|
||||
'https://www.vidble.com/UxsvAssYe5.gif',
|
||||
}),
|
||||
('https://vidble.com/show/RDFbznUvcN', {
|
||||
'https://www.vidble.com/RDFbznUvcN.jpg',
|
||||
}),
|
||||
('https://vidble.com/album/h0jTLs6B', {
|
||||
'https://www.vidble.com/XG4eAoJ5JZ.jpg',
|
||||
'https://www.vidble.com/IqF5UdH6Uq.jpg',
|
||||
'https://www.vidble.com/VWuNsnLJMD.jpg',
|
||||
'https://www.vidble.com/sMmM8O650W.jpg',
|
||||
}),
|
||||
('https://www.vidble.com/pHuwWkOcEb', {
|
||||
'https://www.vidble.com/pHuwWkOcEb.jpg',
|
||||
}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
(
|
||||
"https://www.vidble.com/show/UxsvAssYe5",
|
||||
{
|
||||
"https://www.vidble.com/UxsvAssYe5.gif",
|
||||
},
|
||||
),
|
||||
(
|
||||
"https://vidble.com/show/RDFbznUvcN",
|
||||
{
|
||||
"https://www.vidble.com/RDFbznUvcN.jpg",
|
||||
},
|
||||
),
|
||||
(
|
||||
"https://vidble.com/album/h0jTLs6B",
|
||||
{
|
||||
"https://www.vidble.com/XG4eAoJ5JZ.jpg",
|
||||
"https://www.vidble.com/IqF5UdH6Uq.jpg",
|
||||
"https://www.vidble.com/VWuNsnLJMD.jpg",
|
||||
"https://www.vidble.com/sMmM8O650W.jpg",
|
||||
},
|
||||
),
|
||||
(
|
||||
"https://www.vidble.com/pHuwWkOcEb",
|
||||
{
|
||||
"https://www.vidble.com/pHuwWkOcEb.jpg",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_get_links(test_url: str, expected: set[str]):
|
||||
results = Vidble.get_links(test_url)
|
||||
assert results == expected
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hashes'), (
|
||||
('https://www.vidble.com/show/UxsvAssYe5', {
|
||||
'0ef2f8e0e0b45936d2fb3e6fbdf67e28',
|
||||
}),
|
||||
('https://vidble.com/show/RDFbznUvcN', {
|
||||
'c2dd30a71e32369c50eed86f86efff58',
|
||||
}),
|
||||
('https://vidble.com/album/h0jTLs6B', {
|
||||
'3b3cba02e01c91f9858a95240b942c71',
|
||||
'dd6ecf5fc9e936f9fb614eb6a0537f99',
|
||||
'b31a942cd8cdda218ed547bbc04c3a27',
|
||||
'6f77c570b451eef4222804bd52267481',
|
||||
}),
|
||||
('https://www.vidble.com/pHuwWkOcEb', {
|
||||
'585f486dd0b2f23a57bddbd5bf185bc7',
|
||||
}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hashes"),
|
||||
(
|
||||
(
|
||||
"https://www.vidble.com/show/UxsvAssYe5",
|
||||
{
|
||||
"0ef2f8e0e0b45936d2fb3e6fbdf67e28",
|
||||
},
|
||||
),
|
||||
(
|
||||
"https://vidble.com/show/RDFbznUvcN",
|
||||
{
|
||||
"c2dd30a71e32369c50eed86f86efff58",
|
||||
},
|
||||
),
|
||||
(
|
||||
"https://vidble.com/album/h0jTLs6B",
|
||||
{
|
||||
"3b3cba02e01c91f9858a95240b942c71",
|
||||
"dd6ecf5fc9e936f9fb614eb6a0537f99",
|
||||
"b31a942cd8cdda218ed547bbc04c3a27",
|
||||
"6f77c570b451eef4222804bd52267481",
|
||||
},
|
||||
),
|
||||
(
|
||||
"https://www.vidble.com/pHuwWkOcEb",
|
||||
{
|
||||
"585f486dd0b2f23a57bddbd5bf185bc7",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_find_resources(test_url: str, expected_hashes: set[str]):
|
||||
mock_download = Mock()
|
||||
mock_download.url = test_url
|
||||
|
||||
@@ -12,9 +12,10 @@ from bdfr.site_downloaders.vreddit import VReddit
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://reddit.com/r/Unexpected/comments/z4xsuj/omg_thats_so_cute/', '1ffab5e5c0cc96db18108e4f37e8ca7f'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(("https://reddit.com/r/Unexpected/comments/z4xsuj/omg_thats_so_cute/", "1ffab5e5c0cc96db18108e4f37e8ca7f"),),
|
||||
)
|
||||
def test_find_resources_good(test_url: str, expected_hash: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
@@ -27,10 +28,13 @@ def test_find_resources_good(test_url: str, expected_hash: str):
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize('test_url', (
|
||||
'https://www.polygon.com/disney-plus/2020/5/14/21249881/gargoyles-animated-series-disney-plus-greg-weisman'
|
||||
'-interview-oj-simpson-goliath-chronicles',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_url",
|
||||
(
|
||||
"https://www.polygon.com/disney-plus/2020/5/14/21249881/gargoyles-animated-series-disney-plus-greg-weisman"
|
||||
"-interview-oj-simpson-goliath-chronicles",
|
||||
),
|
||||
)
|
||||
def test_find_resources_bad(test_url: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
|
||||
@@ -12,10 +12,13 @@ from bdfr.site_downloaders.youtube import Youtube
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://www.youtube.com/watch?v=uSm2VDgRIUs', '2d60b54582df5b95ec72bb00b580d2ff'),
|
||||
('https://www.youtube.com/watch?v=GcI7nxQj7HA', '5db0fc92a0a7fb9ac91e63505eea9cf0'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(
|
||||
("https://www.youtube.com/watch?v=uSm2VDgRIUs", "2d60b54582df5b95ec72bb00b580d2ff"),
|
||||
("https://www.youtube.com/watch?v=GcI7nxQj7HA", "5db0fc92a0a7fb9ac91e63505eea9cf0"),
|
||||
),
|
||||
)
|
||||
def test_find_resources_good(test_url: str, expected_hash: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
@@ -28,10 +31,13 @@ def test_find_resources_good(test_url: str, expected_hash: str):
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize('test_url', (
|
||||
'https://www.polygon.com/disney-plus/2020/5/14/21249881/gargoyles-animated-series-disney-plus-greg-weisman'
|
||||
'-interview-oj-simpson-goliath-chronicles',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_url",
|
||||
(
|
||||
"https://www.polygon.com/disney-plus/2020/5/14/21249881/gargoyles-animated-series-disney-plus-greg-weisman"
|
||||
"-interview-oj-simpson-goliath-chronicles",
|
||||
),
|
||||
)
|
||||
def test_find_resources_bad(test_url: str):
|
||||
test_submission = MagicMock()
|
||||
test_submission.url = test_url
|
||||
|
||||
@@ -12,15 +12,18 @@ from bdfr.archiver import Archiver
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'test_format'), (
|
||||
('m3reby', 'xml'),
|
||||
('m3reby', 'json'),
|
||||
('m3reby', 'yaml'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_submission_id", "test_format"),
|
||||
(
|
||||
("m3reby", "xml"),
|
||||
("m3reby", "json"),
|
||||
("m3reby", "yaml"),
|
||||
),
|
||||
)
|
||||
def test_write_submission_json(test_submission_id: str, tmp_path: Path, test_format: str, reddit_instance: praw.Reddit):
|
||||
archiver_mock = MagicMock()
|
||||
archiver_mock.args.format = test_format
|
||||
test_path = Path(tmp_path, 'test')
|
||||
test_path = Path(tmp_path, "test")
|
||||
test_submission = reddit_instance.submission(id=test_submission_id)
|
||||
archiver_mock.file_name_formatter.format_path.return_value = test_path
|
||||
Archiver.write_entry(archiver_mock, test_submission)
|
||||
|
||||
@@ -8,13 +8,16 @@ import pytest
|
||||
from bdfr.configuration import Configuration
|
||||
|
||||
|
||||
@pytest.mark.parametrize('arg_dict', (
|
||||
{'directory': 'test_dir'},
|
||||
{
|
||||
'directory': 'test_dir',
|
||||
'no_dupes': True,
|
||||
},
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"arg_dict",
|
||||
(
|
||||
{"directory": "test_dir"},
|
||||
{
|
||||
"directory": "test_dir",
|
||||
"no_dupes": True,
|
||||
},
|
||||
),
|
||||
)
|
||||
def test_process_click_context(arg_dict: dict):
|
||||
test_config = Configuration()
|
||||
test_context = MagicMock()
|
||||
@@ -25,9 +28,9 @@ def test_process_click_context(arg_dict: dict):
|
||||
|
||||
|
||||
def test_yaml_file_read():
|
||||
file = './tests/yaml_test_configuration.yaml'
|
||||
file = "./tests/yaml_test_configuration.yaml"
|
||||
test_config = Configuration()
|
||||
test_config.parse_yaml_options(file)
|
||||
assert test_config.subreddit == ['EarthPorn', 'TwoXChromosomes', 'Mindustry']
|
||||
assert test_config.sort == 'new'
|
||||
assert test_config.subreddit == ["EarthPorn", "TwoXChromosomes", "Mindustry"]
|
||||
assert test_config.sort == "new"
|
||||
assert test_config.limit == 10
|
||||
|
||||
@@ -20,7 +20,7 @@ from bdfr.site_authenticator import SiteAuthenticator
|
||||
@pytest.fixture()
|
||||
def args() -> Configuration:
|
||||
args = Configuration()
|
||||
args.time_format = 'ISO'
|
||||
args.time_format = "ISO"
|
||||
return args
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ def downloader_mock(args: Configuration):
|
||||
downloader_mock.args = args
|
||||
downloader_mock.sanitise_subreddit_name = RedditConnector.sanitise_subreddit_name
|
||||
downloader_mock.create_filtered_listing_generator = lambda x: RedditConnector.create_filtered_listing_generator(
|
||||
downloader_mock, x)
|
||||
downloader_mock, x
|
||||
)
|
||||
downloader_mock.split_args_input = RedditConnector.split_args_input
|
||||
downloader_mock.master_hash_list = {}
|
||||
return downloader_mock
|
||||
@@ -55,16 +56,22 @@ def assert_all_results_are_submissions_or_comments(result_limit: int, results: l
|
||||
|
||||
|
||||
def test_determine_directories(tmp_path: Path, downloader_mock: MagicMock):
|
||||
downloader_mock.args.directory = tmp_path / 'test'
|
||||
downloader_mock.args.directory = tmp_path / "test"
|
||||
downloader_mock.config_directories.user_config_dir = tmp_path
|
||||
RedditConnector.determine_directories(downloader_mock)
|
||||
assert Path(tmp_path / 'test').exists()
|
||||
assert Path(tmp_path / "test").exists()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('skip_extensions', 'skip_domains'), (
|
||||
([], []),
|
||||
(['.test'], ['test.com'],),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("skip_extensions", "skip_domains"),
|
||||
(
|
||||
([], []),
|
||||
(
|
||||
[".test"],
|
||||
["test.com"],
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_create_download_filter(skip_extensions: list[str], skip_domains: list[str], downloader_mock: MagicMock):
|
||||
downloader_mock.args.skip = skip_extensions
|
||||
downloader_mock.args.skip_domain = skip_domains
|
||||
@@ -75,14 +82,17 @@ def test_create_download_filter(skip_extensions: list[str], skip_domains: list[s
|
||||
assert result.excluded_extensions == skip_extensions
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_time', 'expected'), (
|
||||
('all', 'all'),
|
||||
('hour', 'hour'),
|
||||
('day', 'day'),
|
||||
('week', 'week'),
|
||||
('random', 'all'),
|
||||
('', 'all'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_time", "expected"),
|
||||
(
|
||||
("all", "all"),
|
||||
("hour", "hour"),
|
||||
("day", "day"),
|
||||
("week", "week"),
|
||||
("random", "all"),
|
||||
("", "all"),
|
||||
),
|
||||
)
|
||||
def test_create_time_filter(test_time: str, expected: str, downloader_mock: MagicMock):
|
||||
downloader_mock.args.time = test_time
|
||||
result = RedditConnector.create_time_filter(downloader_mock)
|
||||
@@ -91,12 +101,15 @@ def test_create_time_filter(test_time: str, expected: str, downloader_mock: Magi
|
||||
assert result.name.lower() == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_sort', 'expected'), (
|
||||
('', 'hot'),
|
||||
('hot', 'hot'),
|
||||
('controversial', 'controversial'),
|
||||
('new', 'new'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_sort", "expected"),
|
||||
(
|
||||
("", "hot"),
|
||||
("hot", "hot"),
|
||||
("controversial", "controversial"),
|
||||
("new", "new"),
|
||||
),
|
||||
)
|
||||
def test_create_sort_filter(test_sort: str, expected: str, downloader_mock: MagicMock):
|
||||
downloader_mock.args.sort = test_sort
|
||||
result = RedditConnector.create_sort_filter(downloader_mock)
|
||||
@@ -105,13 +118,16 @@ def test_create_sort_filter(test_sort: str, expected: str, downloader_mock: Magi
|
||||
assert result.name.lower() == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_file_scheme', 'test_folder_scheme'), (
|
||||
('{POSTID}', '{SUBREDDIT}'),
|
||||
('{REDDITOR}_{TITLE}_{POSTID}', '{SUBREDDIT}'),
|
||||
('{POSTID}', 'test'),
|
||||
('{POSTID}', ''),
|
||||
('{POSTID}', '{SUBREDDIT}/{REDDITOR}'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_file_scheme", "test_folder_scheme"),
|
||||
(
|
||||
("{POSTID}", "{SUBREDDIT}"),
|
||||
("{REDDITOR}_{TITLE}_{POSTID}", "{SUBREDDIT}"),
|
||||
("{POSTID}", "test"),
|
||||
("{POSTID}", ""),
|
||||
("{POSTID}", "{SUBREDDIT}/{REDDITOR}"),
|
||||
),
|
||||
)
|
||||
def test_create_file_name_formatter(test_file_scheme: str, test_folder_scheme: str, downloader_mock: MagicMock):
|
||||
downloader_mock.args.file_scheme = test_file_scheme
|
||||
downloader_mock.args.folder_scheme = test_folder_scheme
|
||||
@@ -119,14 +135,17 @@ def test_create_file_name_formatter(test_file_scheme: str, test_folder_scheme: s
|
||||
|
||||
assert isinstance(result, FileNameFormatter)
|
||||
assert result.file_format_string == test_file_scheme
|
||||
assert result.directory_format_string == test_folder_scheme.split('/')
|
||||
assert result.directory_format_string == test_folder_scheme.split("/")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_file_scheme', 'test_folder_scheme'), (
|
||||
('', ''),
|
||||
('', '{SUBREDDIT}'),
|
||||
('test', '{SUBREDDIT}'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_file_scheme", "test_folder_scheme"),
|
||||
(
|
||||
("", ""),
|
||||
("", "{SUBREDDIT}"),
|
||||
("test", "{SUBREDDIT}"),
|
||||
),
|
||||
)
|
||||
def test_create_file_name_formatter_bad(test_file_scheme: str, test_folder_scheme: str, downloader_mock: MagicMock):
|
||||
downloader_mock.args.file_scheme = test_file_scheme
|
||||
downloader_mock.args.folder_scheme = test_folder_scheme
|
||||
@@ -141,15 +160,17 @@ def test_create_authenticator(downloader_mock: MagicMock):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize('test_submission_ids', (
|
||||
('lvpf4l',),
|
||||
('lvpf4l', 'lvqnsn'),
|
||||
('lvpf4l', 'lvqnsn', 'lvl9kd'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_submission_ids",
|
||||
(
|
||||
("lvpf4l",),
|
||||
("lvpf4l", "lvqnsn"),
|
||||
("lvpf4l", "lvqnsn", "lvl9kd"),
|
||||
),
|
||||
)
|
||||
def test_get_submissions_from_link(
|
||||
test_submission_ids: list[str],
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock):
|
||||
test_submission_ids: list[str], reddit_instance: praw.Reddit, downloader_mock: MagicMock
|
||||
):
|
||||
downloader_mock.args.link = test_submission_ids
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
results = RedditConnector.get_submissions_from_link(downloader_mock)
|
||||
@@ -159,25 +180,28 @@ def test_get_submissions_from_link(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_subreddits', 'limit', 'sort_type', 'time_filter', 'max_expected_len'), (
|
||||
(('Futurology',), 10, 'hot', 'all', 10),
|
||||
(('Futurology', 'Mindustry, Python'), 10, 'hot', 'all', 30),
|
||||
(('Futurology',), 20, 'hot', 'all', 20),
|
||||
(('Futurology', 'Python'), 10, 'hot', 'all', 20),
|
||||
(('Futurology',), 100, 'hot', 'all', 100),
|
||||
(('Futurology',), 0, 'hot', 'all', 0),
|
||||
(('Futurology',), 10, 'top', 'all', 10),
|
||||
(('Futurology',), 10, 'top', 'week', 10),
|
||||
(('Futurology',), 10, 'hot', 'week', 10),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_subreddits", "limit", "sort_type", "time_filter", "max_expected_len"),
|
||||
(
|
||||
(("Futurology",), 10, "hot", "all", 10),
|
||||
(("Futurology", "Mindustry, Python"), 10, "hot", "all", 30),
|
||||
(("Futurology",), 20, "hot", "all", 20),
|
||||
(("Futurology", "Python"), 10, "hot", "all", 20),
|
||||
(("Futurology",), 100, "hot", "all", 100),
|
||||
(("Futurology",), 0, "hot", "all", 0),
|
||||
(("Futurology",), 10, "top", "all", 10),
|
||||
(("Futurology",), 10, "top", "week", 10),
|
||||
(("Futurology",), 10, "hot", "week", 10),
|
||||
),
|
||||
)
|
||||
def test_get_subreddit_normal(
|
||||
test_subreddits: list[str],
|
||||
limit: int,
|
||||
sort_type: str,
|
||||
time_filter: str,
|
||||
max_expected_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
test_subreddits: list[str],
|
||||
limit: int,
|
||||
sort_type: str,
|
||||
time_filter: str,
|
||||
max_expected_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
):
|
||||
downloader_mock.args.limit = limit
|
||||
downloader_mock.args.sort = sort_type
|
||||
@@ -197,26 +221,29 @@ def test_get_subreddit_normal(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_time', 'test_delta'), (
|
||||
('hour', timedelta(hours=1)),
|
||||
('day', timedelta(days=1)),
|
||||
('week', timedelta(days=7)),
|
||||
('month', timedelta(days=31)),
|
||||
('year', timedelta(days=365)),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_time", "test_delta"),
|
||||
(
|
||||
("hour", timedelta(hours=1)),
|
||||
("day", timedelta(days=1)),
|
||||
("week", timedelta(days=7)),
|
||||
("month", timedelta(days=31)),
|
||||
("year", timedelta(days=365)),
|
||||
),
|
||||
)
|
||||
def test_get_subreddit_time_verification(
|
||||
test_time: str,
|
||||
test_delta: timedelta,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
test_time: str,
|
||||
test_delta: timedelta,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
):
|
||||
downloader_mock.args.limit = 10
|
||||
downloader_mock.args.sort = 'top'
|
||||
downloader_mock.args.sort = "top"
|
||||
downloader_mock.args.time = test_time
|
||||
downloader_mock.time_filter = RedditConnector.create_time_filter(downloader_mock)
|
||||
downloader_mock.sort_filter = RedditConnector.create_sort_filter(downloader_mock)
|
||||
downloader_mock.determine_sort_function.return_value = RedditConnector.determine_sort_function(downloader_mock)
|
||||
downloader_mock.args.subreddit = ['all']
|
||||
downloader_mock.args.subreddit = ["all"]
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
results = RedditConnector.get_subreddits(downloader_mock)
|
||||
results = [sub for res1 in results for sub in res1]
|
||||
@@ -230,20 +257,23 @@ def test_get_subreddit_time_verification(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_subreddits', 'search_term', 'limit', 'time_filter', 'max_expected_len'), (
|
||||
(('Python',), 'scraper', 10, 'all', 10),
|
||||
(('Python',), '', 10, 'all', 0),
|
||||
(('Python',), 'djsdsgewef', 10, 'all', 0),
|
||||
(('Python',), 'scraper', 10, 'year', 10),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_subreddits", "search_term", "limit", "time_filter", "max_expected_len"),
|
||||
(
|
||||
(("Python",), "scraper", 10, "all", 10),
|
||||
(("Python",), "", 10, "all", 0),
|
||||
(("Python",), "djsdsgewef", 10, "all", 0),
|
||||
(("Python",), "scraper", 10, "year", 10),
|
||||
),
|
||||
)
|
||||
def test_get_subreddit_search(
|
||||
test_subreddits: list[str],
|
||||
search_term: str,
|
||||
time_filter: str,
|
||||
limit: int,
|
||||
max_expected_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
test_subreddits: list[str],
|
||||
search_term: str,
|
||||
time_filter: str,
|
||||
limit: int,
|
||||
max_expected_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
):
|
||||
downloader_mock._determine_sort_function.return_value = praw.models.Subreddit.hot
|
||||
downloader_mock.args.limit = limit
|
||||
@@ -265,17 +295,20 @@ def test_get_subreddit_search(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_user', 'test_multireddits', 'limit'), (
|
||||
('helen_darten', ('cuteanimalpics',), 10),
|
||||
('korfor', ('chess',), 100),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_user", "test_multireddits", "limit"),
|
||||
(
|
||||
("helen_darten", ("cuteanimalpics",), 10),
|
||||
("korfor", ("chess",), 100),
|
||||
),
|
||||
)
|
||||
# Good sources at https://www.reddit.com/r/multihub/
|
||||
def test_get_multireddits_public(
|
||||
test_user: str,
|
||||
test_multireddits: list[str],
|
||||
limit: int,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
test_user: str,
|
||||
test_multireddits: list[str],
|
||||
limit: int,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
):
|
||||
downloader_mock.determine_sort_function.return_value = praw.models.Subreddit.hot
|
||||
downloader_mock.sort_filter = RedditTypes.SortType.HOT
|
||||
@@ -283,11 +316,10 @@ def test_get_multireddits_public(
|
||||
downloader_mock.args.multireddit = test_multireddits
|
||||
downloader_mock.args.user = [test_user]
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.create_filtered_listing_generator.return_value = \
|
||||
RedditConnector.create_filtered_listing_generator(
|
||||
downloader_mock,
|
||||
reddit_instance.multireddit(redditor=test_user, name=test_multireddits[0]),
|
||||
)
|
||||
downloader_mock.create_filtered_listing_generator.return_value = RedditConnector.create_filtered_listing_generator(
|
||||
downloader_mock,
|
||||
reddit_instance.multireddit(redditor=test_user, name=test_multireddits[0]),
|
||||
)
|
||||
results = RedditConnector.get_multireddits(downloader_mock)
|
||||
results = [sub for res in results for sub in res]
|
||||
assert all([isinstance(res, praw.models.Submission) for res in results])
|
||||
@@ -297,11 +329,14 @@ def test_get_multireddits_public(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_user', 'limit'), (
|
||||
('danigirl3694', 10),
|
||||
('danigirl3694', 50),
|
||||
('CapitanHam', None),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_user", "limit"),
|
||||
(
|
||||
("danigirl3694", 10),
|
||||
("danigirl3694", 50),
|
||||
("CapitanHam", None),
|
||||
),
|
||||
)
|
||||
def test_get_user_submissions(test_user: str, limit: int, downloader_mock: MagicMock, reddit_instance: praw.Reddit):
|
||||
downloader_mock.args.limit = limit
|
||||
downloader_mock.determine_sort_function.return_value = praw.models.Subreddit.hot
|
||||
@@ -310,11 +345,10 @@ def test_get_user_submissions(test_user: str, limit: int, downloader_mock: Magic
|
||||
downloader_mock.args.user = [test_user]
|
||||
downloader_mock.authenticated = False
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.create_filtered_listing_generator.return_value = \
|
||||
RedditConnector.create_filtered_listing_generator(
|
||||
downloader_mock,
|
||||
reddit_instance.redditor(test_user).submissions,
|
||||
)
|
||||
downloader_mock.create_filtered_listing_generator.return_value = RedditConnector.create_filtered_listing_generator(
|
||||
downloader_mock,
|
||||
reddit_instance.redditor(test_user).submissions,
|
||||
)
|
||||
results = RedditConnector.get_user_data(downloader_mock)
|
||||
results = assert_all_results_are_submissions(limit, results)
|
||||
assert all([res.author.name == test_user for res in results])
|
||||
@@ -324,21 +358,24 @@ def test_get_user_submissions(test_user: str, limit: int, downloader_mock: Magic
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.authenticated
|
||||
@pytest.mark.parametrize('test_flag', (
|
||||
'upvoted',
|
||||
'saved',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_flag",
|
||||
(
|
||||
"upvoted",
|
||||
"saved",
|
||||
),
|
||||
)
|
||||
def test_get_user_authenticated_lists(
|
||||
test_flag: str,
|
||||
downloader_mock: MagicMock,
|
||||
authenticated_reddit_instance: praw.Reddit,
|
||||
test_flag: str,
|
||||
downloader_mock: MagicMock,
|
||||
authenticated_reddit_instance: praw.Reddit,
|
||||
):
|
||||
downloader_mock.args.__dict__[test_flag] = True
|
||||
downloader_mock.reddit_instance = authenticated_reddit_instance
|
||||
downloader_mock.args.limit = 10
|
||||
downloader_mock.determine_sort_function.return_value = praw.models.Subreddit.hot
|
||||
downloader_mock.sort_filter = RedditTypes.SortType.HOT
|
||||
downloader_mock.args.user = [RedditConnector.resolve_user_name(downloader_mock, 'me')]
|
||||
downloader_mock.args.user = [RedditConnector.resolve_user_name(downloader_mock, "me")]
|
||||
results = RedditConnector.get_user_data(downloader_mock)
|
||||
assert_all_results_are_submissions_or_comments(10, results)
|
||||
|
||||
@@ -359,54 +396,63 @@ def test_get_subscribed_subreddits(downloader_mock: MagicMock, authenticated_red
|
||||
assert results
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_name', 'expected'), (
|
||||
('Mindustry', 'Mindustry'),
|
||||
('Futurology', 'Futurology'),
|
||||
('r/Mindustry', 'Mindustry'),
|
||||
('TrollXChromosomes', 'TrollXChromosomes'),
|
||||
('r/TrollXChromosomes', 'TrollXChromosomes'),
|
||||
('https://www.reddit.com/r/TrollXChromosomes/', 'TrollXChromosomes'),
|
||||
('https://www.reddit.com/r/TrollXChromosomes', 'TrollXChromosomes'),
|
||||
('https://www.reddit.com/r/Futurology/', 'Futurology'),
|
||||
('https://www.reddit.com/r/Futurology', 'Futurology'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_name", "expected"),
|
||||
(
|
||||
("Mindustry", "Mindustry"),
|
||||
("Futurology", "Futurology"),
|
||||
("r/Mindustry", "Mindustry"),
|
||||
("TrollXChromosomes", "TrollXChromosomes"),
|
||||
("r/TrollXChromosomes", "TrollXChromosomes"),
|
||||
("https://www.reddit.com/r/TrollXChromosomes/", "TrollXChromosomes"),
|
||||
("https://www.reddit.com/r/TrollXChromosomes", "TrollXChromosomes"),
|
||||
("https://www.reddit.com/r/Futurology/", "Futurology"),
|
||||
("https://www.reddit.com/r/Futurology", "Futurology"),
|
||||
),
|
||||
)
|
||||
def test_sanitise_subreddit_name(test_name: str, expected: str):
|
||||
result = RedditConnector.sanitise_subreddit_name(test_name)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_subreddit_entries', 'expected'), (
|
||||
(['test1', 'test2', 'test3'], {'test1', 'test2', 'test3'}),
|
||||
(['test1,test2', 'test3'], {'test1', 'test2', 'test3'}),
|
||||
(['test1, test2', 'test3'], {'test1', 'test2', 'test3'}),
|
||||
(['test1; test2', 'test3'], {'test1', 'test2', 'test3'}),
|
||||
(['test1, test2', 'test1,test2,test3', 'test4'], {'test1', 'test2', 'test3', 'test4'}),
|
||||
([''], {''}),
|
||||
(['test'], {'test'}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_subreddit_entries", "expected"),
|
||||
(
|
||||
(["test1", "test2", "test3"], {"test1", "test2", "test3"}),
|
||||
(["test1,test2", "test3"], {"test1", "test2", "test3"}),
|
||||
(["test1, test2", "test3"], {"test1", "test2", "test3"}),
|
||||
(["test1; test2", "test3"], {"test1", "test2", "test3"}),
|
||||
(["test1, test2", "test1,test2,test3", "test4"], {"test1", "test2", "test3", "test4"}),
|
||||
([""], {""}),
|
||||
(["test"], {"test"}),
|
||||
),
|
||||
)
|
||||
def test_split_subreddit_entries(test_subreddit_entries: list[str], expected: set[str]):
|
||||
results = RedditConnector.split_args_input(test_subreddit_entries)
|
||||
assert results == expected
|
||||
|
||||
|
||||
def test_read_submission_ids_from_file(downloader_mock: MagicMock, tmp_path: Path):
|
||||
test_file = tmp_path / 'test.txt'
|
||||
test_file.write_text('aaaaaa\nbbbbbb')
|
||||
test_file = tmp_path / "test.txt"
|
||||
test_file.write_text("aaaaaa\nbbbbbb")
|
||||
results = RedditConnector.read_id_files([str(test_file)])
|
||||
assert results == {'aaaaaa', 'bbbbbb'}
|
||||
assert results == {"aaaaaa", "bbbbbb"}
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize('test_redditor_name', (
|
||||
'nasa',
|
||||
'crowdstrike',
|
||||
'HannibalGoddamnit',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_redditor_name",
|
||||
(
|
||||
"nasa",
|
||||
"crowdstrike",
|
||||
"HannibalGoddamnit",
|
||||
),
|
||||
)
|
||||
def test_check_user_existence_good(
|
||||
test_redditor_name: str,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
test_redditor_name: str,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
):
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
RedditConnector.check_user_existence(downloader_mock, test_redditor_name)
|
||||
@@ -414,42 +460,46 @@ def test_check_user_existence_good(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize('test_redditor_name', (
|
||||
'lhnhfkuhwreolo',
|
||||
'adlkfmnhglojh',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_redditor_name",
|
||||
(
|
||||
"lhnhfkuhwreolo",
|
||||
"adlkfmnhglojh",
|
||||
),
|
||||
)
|
||||
def test_check_user_existence_nonexistent(
|
||||
test_redditor_name: str,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
test_redditor_name: str,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
):
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
with pytest.raises(BulkDownloaderException, match='Could not find'):
|
||||
with pytest.raises(BulkDownloaderException, match="Could not find"):
|
||||
RedditConnector.check_user_existence(downloader_mock, test_redditor_name)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize('test_redditor_name', (
|
||||
'Bree-Boo',
|
||||
))
|
||||
@pytest.mark.parametrize("test_redditor_name", ("Bree-Boo",))
|
||||
def test_check_user_existence_banned(
|
||||
test_redditor_name: str,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
test_redditor_name: str,
|
||||
reddit_instance: praw.Reddit,
|
||||
downloader_mock: MagicMock,
|
||||
):
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
with pytest.raises(BulkDownloaderException, match='is banned'):
|
||||
with pytest.raises(BulkDownloaderException, match="is banned"):
|
||||
RedditConnector.check_user_existence(downloader_mock, test_redditor_name)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_subreddit_name', 'expected_message'), (
|
||||
('donaldtrump', 'cannot be found'),
|
||||
('submitters', 'private and cannot be scraped'),
|
||||
('lhnhfkuhwreolo', 'does not exist')
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_subreddit_name", "expected_message"),
|
||||
(
|
||||
("donaldtrump", "cannot be found"),
|
||||
("submitters", "private and cannot be scraped"),
|
||||
("lhnhfkuhwreolo", "does not exist"),
|
||||
),
|
||||
)
|
||||
def test_check_subreddit_status_bad(test_subreddit_name: str, expected_message: str, reddit_instance: praw.Reddit):
|
||||
test_subreddit = reddit_instance.subreddit(test_subreddit_name)
|
||||
with pytest.raises(BulkDownloaderException, match=expected_message):
|
||||
@@ -458,12 +508,15 @@ def test_check_subreddit_status_bad(test_subreddit_name: str, expected_message:
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize('test_subreddit_name', (
|
||||
'Python',
|
||||
'Mindustry',
|
||||
'TrollXChromosomes',
|
||||
'all',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_subreddit_name",
|
||||
(
|
||||
"Python",
|
||||
"Mindustry",
|
||||
"TrollXChromosomes",
|
||||
"all",
|
||||
),
|
||||
)
|
||||
def test_check_subreddit_status_good(test_subreddit_name: str, reddit_instance: praw.Reddit):
|
||||
test_subreddit = reddit_instance.subreddit(test_subreddit_name)
|
||||
RedditConnector.check_subreddit_status(test_subreddit)
|
||||
|
||||
@@ -11,55 +11,67 @@ from bdfr.resource import Resource
|
||||
|
||||
@pytest.fixture()
|
||||
def download_filter() -> DownloadFilter:
|
||||
return DownloadFilter(['mp4', 'mp3'], ['test.com', 'reddit.com', 'img.example.com'])
|
||||
return DownloadFilter(["mp4", "mp3"], ["test.com", "reddit.com", "img.example.com"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_extension', 'expected'), (
|
||||
('.mp4', False),
|
||||
('.avi', True),
|
||||
('.random.mp3', False),
|
||||
('mp4', False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_extension", "expected"),
|
||||
(
|
||||
(".mp4", False),
|
||||
(".avi", True),
|
||||
(".random.mp3", False),
|
||||
("mp4", False),
|
||||
),
|
||||
)
|
||||
def test_filter_extension(test_extension: str, expected: bool, download_filter: DownloadFilter):
|
||||
result = download_filter._check_extension(test_extension)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('test.mp4', True),
|
||||
('http://reddit.com/test.mp4', False),
|
||||
('http://reddit.com/test.gif', False),
|
||||
('https://www.example.com/test.mp4', True),
|
||||
('https://www.example.com/test.png', True),
|
||||
('https://i.example.com/test.png', True),
|
||||
('https://img.example.com/test.png', False),
|
||||
('https://i.test.com/test.png', False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("test.mp4", True),
|
||||
("http://reddit.com/test.mp4", False),
|
||||
("http://reddit.com/test.gif", False),
|
||||
("https://www.example.com/test.mp4", True),
|
||||
("https://www.example.com/test.png", True),
|
||||
("https://i.example.com/test.png", True),
|
||||
("https://img.example.com/test.png", False),
|
||||
("https://i.test.com/test.png", False),
|
||||
),
|
||||
)
|
||||
def test_filter_domain(test_url: str, expected: bool, download_filter: DownloadFilter):
|
||||
result = download_filter._check_domain(test_url)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('test.mp4', False),
|
||||
('test.gif', True),
|
||||
('https://www.example.com/test.mp4', False),
|
||||
('https://www.example.com/test.png', True),
|
||||
('http://reddit.com/test.mp4', False),
|
||||
('http://reddit.com/test.gif', False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("test.mp4", False),
|
||||
("test.gif", True),
|
||||
("https://www.example.com/test.mp4", False),
|
||||
("https://www.example.com/test.png", True),
|
||||
("http://reddit.com/test.mp4", False),
|
||||
("http://reddit.com/test.gif", False),
|
||||
),
|
||||
)
|
||||
def test_filter_all(test_url: str, expected: bool, download_filter: DownloadFilter):
|
||||
test_resource = Resource(MagicMock(), test_url, lambda: None)
|
||||
result = download_filter.check_resource(test_resource)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('test_url', (
|
||||
'test.mp3',
|
||||
'test.mp4',
|
||||
'http://reddit.com/test.mp4',
|
||||
't',
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_url",
|
||||
(
|
||||
"test.mp3",
|
||||
"test.mp4",
|
||||
"http://reddit.com/test.mp4",
|
||||
"t",
|
||||
),
|
||||
)
|
||||
def test_filter_empty_filter(test_url: str):
|
||||
download_filter = DownloadFilter()
|
||||
test_resource = Resource(MagicMock(), test_url, lambda: None)
|
||||
|
||||
@@ -18,7 +18,7 @@ from bdfr.downloader import RedditDownloader
|
||||
@pytest.fixture()
|
||||
def args() -> Configuration:
|
||||
args = Configuration()
|
||||
args.time_format = 'ISO'
|
||||
args.time_format = "ISO"
|
||||
return args
|
||||
|
||||
|
||||
@@ -32,29 +32,32 @@ def downloader_mock(args: Configuration):
|
||||
return downloader_mock
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_ids', 'test_excluded', 'expected_len'), (
|
||||
(('aaaaaa',), (), 1),
|
||||
(('aaaaaa',), ('aaaaaa',), 0),
|
||||
((), ('aaaaaa',), 0),
|
||||
(('aaaaaa', 'bbbbbb'), ('aaaaaa',), 1),
|
||||
(('aaaaaa', 'bbbbbb', 'cccccc'), ('aaaaaa',), 2),
|
||||
))
|
||||
@patch('bdfr.site_downloaders.download_factory.DownloadFactory.pull_lever')
|
||||
@pytest.mark.parametrize(
|
||||
("test_ids", "test_excluded", "expected_len"),
|
||||
(
|
||||
(("aaaaaa",), (), 1),
|
||||
(("aaaaaa",), ("aaaaaa",), 0),
|
||||
((), ("aaaaaa",), 0),
|
||||
(("aaaaaa", "bbbbbb"), ("aaaaaa",), 1),
|
||||
(("aaaaaa", "bbbbbb", "cccccc"), ("aaaaaa",), 2),
|
||||
),
|
||||
)
|
||||
@patch("bdfr.site_downloaders.download_factory.DownloadFactory.pull_lever")
|
||||
def test_excluded_ids(
|
||||
mock_function: MagicMock,
|
||||
test_ids: tuple[str],
|
||||
test_excluded: tuple[str],
|
||||
expected_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
mock_function: MagicMock,
|
||||
test_ids: tuple[str],
|
||||
test_excluded: tuple[str],
|
||||
expected_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
):
|
||||
downloader_mock.excluded_submission_ids = test_excluded
|
||||
mock_function.return_value = MagicMock()
|
||||
mock_function.return_value.__name__ = 'test'
|
||||
mock_function.return_value.__name__ = "test"
|
||||
test_submissions = []
|
||||
for test_id in test_ids:
|
||||
m = MagicMock()
|
||||
m.id = test_id
|
||||
m.subreddit.display_name.return_value = 'https://www.example.com/'
|
||||
m.subreddit.display_name.return_value = "https://www.example.com/"
|
||||
m.__class__ = praw.models.Submission
|
||||
test_submissions.append(m)
|
||||
downloader_mock.reddit_lists = [test_submissions]
|
||||
@@ -65,32 +68,27 @@ def test_excluded_ids(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize('test_submission_id', (
|
||||
'm1hqw6',
|
||||
))
|
||||
@pytest.mark.parametrize("test_submission_id", ("m1hqw6",))
|
||||
def test_mark_hard_link(
|
||||
test_submission_id: str,
|
||||
downloader_mock: MagicMock,
|
||||
tmp_path: Path,
|
||||
reddit_instance: praw.Reddit
|
||||
test_submission_id: str, downloader_mock: MagicMock, tmp_path: Path, reddit_instance: praw.Reddit
|
||||
):
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.args.make_hard_links = True
|
||||
downloader_mock.download_directory = tmp_path
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.file_scheme = '{POSTID}'
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.file_scheme = "{POSTID}"
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
original = Path(tmp_path, f'{test_submission_id}.png')
|
||||
original = Path(tmp_path, f"{test_submission_id}.png")
|
||||
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
assert original.exists()
|
||||
|
||||
downloader_mock.args.file_scheme = 'test2_{POSTID}'
|
||||
downloader_mock.args.file_scheme = "test2_{POSTID}"
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
test_file_1_stats = original.stat()
|
||||
test_file_2_inode = Path(tmp_path, f'test2_{test_submission_id}.png').stat().st_ino
|
||||
test_file_2_inode = Path(tmp_path, f"test2_{test_submission_id}.png").stat().st_ino
|
||||
|
||||
assert test_file_1_stats.st_nlink == 2
|
||||
assert test_file_1_stats.st_ino == test_file_2_inode
|
||||
@@ -98,20 +96,18 @@ def test_mark_hard_link(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'test_creation_date'), (
|
||||
('ndzz50', 1621204841.0),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "test_creation_date"), (("ndzz50", 1621204841.0),))
|
||||
def test_file_creation_date(
|
||||
test_submission_id: str,
|
||||
test_creation_date: float,
|
||||
downloader_mock: MagicMock,
|
||||
tmp_path: Path,
|
||||
reddit_instance: praw.Reddit
|
||||
test_submission_id: str,
|
||||
test_creation_date: float,
|
||||
downloader_mock: MagicMock,
|
||||
tmp_path: Path,
|
||||
reddit_instance: praw.Reddit,
|
||||
):
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_directory = tmp_path
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.file_scheme = '{POSTID}'
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.file_scheme = "{POSTID}"
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
|
||||
@@ -123,27 +119,25 @@ def test_file_creation_date(
|
||||
|
||||
|
||||
def test_search_existing_files():
|
||||
results = RedditDownloader.scan_existing_files(Path('.'))
|
||||
results = RedditDownloader.scan_existing_files(Path("."))
|
||||
assert len(results.keys()) != 0
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'test_hash'), (
|
||||
('m1hqw6', 'a912af8905ae468e0121e9940f797ad7'),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "test_hash"), (("m1hqw6", "a912af8905ae468e0121e9940f797ad7"),))
|
||||
def test_download_submission_hash_exists(
|
||||
test_submission_id: str,
|
||||
test_hash: str,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture
|
||||
test_submission_id: str,
|
||||
test_hash: str,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
):
|
||||
setup_logging(3)
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.no_dupes = True
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
@@ -153,47 +147,44 @@ def test_download_submission_hash_exists(
|
||||
folder_contents = list(tmp_path.iterdir())
|
||||
output = capsys.readouterr()
|
||||
assert not folder_contents
|
||||
assert re.search(r'Resource hash .*? downloaded elsewhere', output.out)
|
||||
assert re.search(r"Resource hash .*? downloaded elsewhere", output.out)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
def test_download_submission_file_exists(
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture
|
||||
downloader_mock: MagicMock, reddit_instance: praw.Reddit, tmp_path: Path, capsys: pytest.CaptureFixture
|
||||
):
|
||||
setup_logging(3)
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
submission = downloader_mock.reddit_instance.submission(id='m1hqw6')
|
||||
Path(tmp_path, 'Arneeman_Metagaming isn\'t always a bad thing_m1hqw6.png').touch()
|
||||
submission = downloader_mock.reddit_instance.submission(id="m1hqw6")
|
||||
Path(tmp_path, "Arneeman_Metagaming isn't always a bad thing_m1hqw6.png").touch()
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
folder_contents = list(tmp_path.iterdir())
|
||||
output = capsys.readouterr()
|
||||
assert len(folder_contents) == 1
|
||||
assert 'Arneeman_Metagaming isn\'t always a bad thing_m1hqw6.png'\
|
||||
' from submission m1hqw6 already exists' in output.out
|
||||
assert (
|
||||
"Arneeman_Metagaming isn't always a bad thing_m1hqw6.png" " from submission m1hqw6 already exists" in output.out
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'expected_files_len'), (
|
||||
('ljyy27', 4),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "expected_files_len"), (("ljyy27", 4),))
|
||||
def test_download_submission(
|
||||
test_submission_id: str,
|
||||
expected_files_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path):
|
||||
test_submission_id: str,
|
||||
expected_files_len: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
):
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
@@ -204,103 +195,95 @@ def test_download_submission(
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'min_score'), (
|
||||
('ljyy27', 1),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "min_score"), (("ljyy27", 1),))
|
||||
def test_download_submission_min_score_above(
|
||||
test_submission_id: str,
|
||||
min_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
test_submission_id: str,
|
||||
min_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
):
|
||||
setup_logging(3)
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.min_score = min_score
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
output = capsys.readouterr()
|
||||
assert 'filtered due to score' not in output.out
|
||||
assert "filtered due to score" not in output.out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'min_score'), (
|
||||
('ljyy27', 25),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "min_score"), (("ljyy27", 25),))
|
||||
def test_download_submission_min_score_below(
|
||||
test_submission_id: str,
|
||||
min_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
test_submission_id: str,
|
||||
min_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
):
|
||||
setup_logging(3)
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.min_score = min_score
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
output = capsys.readouterr()
|
||||
assert 'filtered due to score' in output.out
|
||||
assert "filtered due to score" in output.out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'max_score'), (
|
||||
('ljyy27', 25),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "max_score"), (("ljyy27", 25),))
|
||||
def test_download_submission_max_score_below(
|
||||
test_submission_id: str,
|
||||
max_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
test_submission_id: str,
|
||||
max_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
):
|
||||
setup_logging(3)
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.max_score = max_score
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
output = capsys.readouterr()
|
||||
assert 'filtered due to score' not in output.out
|
||||
assert "filtered due to score" not in output.out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'max_score'), (
|
||||
('ljyy27', 1),
|
||||
))
|
||||
@pytest.mark.parametrize(("test_submission_id", "max_score"), (("ljyy27", 1),))
|
||||
def test_download_submission_max_score_above(
|
||||
test_submission_id: str,
|
||||
max_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
test_submission_id: str,
|
||||
max_score: int,
|
||||
downloader_mock: MagicMock,
|
||||
reddit_instance: praw.Reddit,
|
||||
tmp_path: Path,
|
||||
capsys: pytest.CaptureFixture,
|
||||
):
|
||||
setup_logging(3)
|
||||
downloader_mock.reddit_instance = reddit_instance
|
||||
downloader_mock.download_filter.check_url.return_value = True
|
||||
downloader_mock.args.folder_scheme = ''
|
||||
downloader_mock.args.folder_scheme = ""
|
||||
downloader_mock.args.max_score = max_score
|
||||
downloader_mock.file_name_formatter = RedditConnector.create_file_name_formatter(downloader_mock)
|
||||
downloader_mock.download_directory = tmp_path
|
||||
submission = downloader_mock.reddit_instance.submission(id=test_submission_id)
|
||||
RedditDownloader._download_submission(downloader_mock, submission)
|
||||
output = capsys.readouterr()
|
||||
assert 'filtered due to score' in output.out
|
||||
assert "filtered due to score" in output.out
|
||||
|
||||
@@ -22,26 +22,26 @@ from bdfr.site_downloaders.self_post import SelfPost
|
||||
@pytest.fixture()
|
||||
def submission() -> MagicMock:
|
||||
test = MagicMock()
|
||||
test.title = 'name'
|
||||
test.subreddit.display_name = 'randomreddit'
|
||||
test.author.name = 'person'
|
||||
test.id = '12345'
|
||||
test.title = "name"
|
||||
test.subreddit.display_name = "randomreddit"
|
||||
test.author.name = "person"
|
||||
test.id = "12345"
|
||||
test.score = 1000
|
||||
test.link_flair_text = 'test_flair'
|
||||
test.link_flair_text = "test_flair"
|
||||
test.created_utc = datetime(2021, 4, 21, 9, 30, 0).timestamp()
|
||||
test.__class__ = praw.models.Submission
|
||||
return test
|
||||
|
||||
|
||||
def do_test_string_equality(result: Union[Path, str], expected: str) -> bool:
|
||||
if platform.system() == 'Windows':
|
||||
if platform.system() == "Windows":
|
||||
expected = FileNameFormatter._format_for_windows(expected)
|
||||
return str(result).endswith(expected)
|
||||
|
||||
|
||||
def do_test_path_equality(result: Path, expected: str) -> bool:
|
||||
if platform.system() == 'Windows':
|
||||
expected = expected.split('/')
|
||||
if platform.system() == "Windows":
|
||||
expected = expected.split("/")
|
||||
expected = [FileNameFormatter._format_for_windows(part) for part in expected]
|
||||
expected = Path(*expected)
|
||||
else:
|
||||
@@ -49,35 +49,41 @@ def do_test_path_equality(result: Path, expected: str) -> bool:
|
||||
return str(result).endswith(str(expected))
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
@pytest.fixture(scope="session")
|
||||
def reddit_submission(reddit_instance: praw.Reddit) -> praw.models.Submission:
|
||||
return reddit_instance.submission(id='w22m5l')
|
||||
return reddit_instance.submission(id="w22m5l")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_format_string', 'expected'), (
|
||||
('{SUBREDDIT}', 'randomreddit'),
|
||||
('{REDDITOR}', 'person'),
|
||||
('{POSTID}', '12345'),
|
||||
('{UPVOTES}', '1000'),
|
||||
('{FLAIR}', 'test_flair'),
|
||||
('{DATE}', '2021-04-21T09:30:00'),
|
||||
('{REDDITOR}_{TITLE}_{POSTID}', 'person_name_12345'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_format_string", "expected"),
|
||||
(
|
||||
("{SUBREDDIT}", "randomreddit"),
|
||||
("{REDDITOR}", "person"),
|
||||
("{POSTID}", "12345"),
|
||||
("{UPVOTES}", "1000"),
|
||||
("{FLAIR}", "test_flair"),
|
||||
("{DATE}", "2021-04-21T09:30:00"),
|
||||
("{REDDITOR}_{TITLE}_{POSTID}", "person_name_12345"),
|
||||
),
|
||||
)
|
||||
def test_format_name_mock(test_format_string: str, expected: str, submission: MagicMock):
|
||||
test_formatter = FileNameFormatter(test_format_string, '', 'ISO')
|
||||
test_formatter = FileNameFormatter(test_format_string, "", "ISO")
|
||||
result = test_formatter._format_name(submission, test_format_string)
|
||||
assert do_test_string_equality(result, expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_string', 'expected'), (
|
||||
('', False),
|
||||
('test', False),
|
||||
('{POSTID}', True),
|
||||
('POSTID', False),
|
||||
('{POSTID}_test', True),
|
||||
('test_{TITLE}', True),
|
||||
('TITLE_POSTID', False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_string", "expected"),
|
||||
(
|
||||
("", False),
|
||||
("test", False),
|
||||
("{POSTID}", True),
|
||||
("POSTID", False),
|
||||
("{POSTID}_test", True),
|
||||
("test_{TITLE}", True),
|
||||
("TITLE_POSTID", False),
|
||||
),
|
||||
)
|
||||
def test_check_format_string_validity(test_string: str, expected: bool):
|
||||
result = FileNameFormatter.validate_string(test_string)
|
||||
assert result == expected
|
||||
@@ -85,84 +91,98 @@ def test_check_format_string_validity(test_string: str, expected: bool):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_format_string', 'expected'), (
|
||||
('{SUBREDDIT}', 'formula1'),
|
||||
('{REDDITOR}', 'Kirsty-Blue'),
|
||||
('{POSTID}', 'w22m5l'),
|
||||
('{FLAIR}', 'Social Media rall'),
|
||||
('{SUBREDDIT}_{TITLE}', 'formula1_George Russel acknowledges the Twitter trend about him'),
|
||||
('{REDDITOR}_{TITLE}_{POSTID}', 'Kirsty-Blue_George Russel acknowledges the Twitter trend about him_w22m5l')
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_format_string", "expected"),
|
||||
(
|
||||
("{SUBREDDIT}", "formula1"),
|
||||
("{REDDITOR}", "Kirsty-Blue"),
|
||||
("{POSTID}", "w22m5l"),
|
||||
("{FLAIR}", "Social Media rall"),
|
||||
("{SUBREDDIT}_{TITLE}", "formula1_George Russel acknowledges the Twitter trend about him"),
|
||||
("{REDDITOR}_{TITLE}_{POSTID}", "Kirsty-Blue_George Russel acknowledges the Twitter trend about him_w22m5l"),
|
||||
),
|
||||
)
|
||||
def test_format_name_real(test_format_string: str, expected: str, reddit_submission: praw.models.Submission):
|
||||
test_formatter = FileNameFormatter(test_format_string, '', '')
|
||||
test_formatter = FileNameFormatter(test_format_string, "", "")
|
||||
result = test_formatter._format_name(reddit_submission, test_format_string)
|
||||
assert do_test_string_equality(result, expected)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('format_string_directory', 'format_string_file', 'expected'), (
|
||||
@pytest.mark.parametrize(
|
||||
("format_string_directory", "format_string_file", "expected"),
|
||||
(
|
||||
'{SUBREDDIT}',
|
||||
'{POSTID}',
|
||||
'test/formula1/w22m5l.png',
|
||||
(
|
||||
"{SUBREDDIT}",
|
||||
"{POSTID}",
|
||||
"test/formula1/w22m5l.png",
|
||||
),
|
||||
(
|
||||
"{SUBREDDIT}",
|
||||
"{TITLE}_{POSTID}",
|
||||
"test/formula1/George Russel acknowledges the Twitter trend about him_w22m5l.png",
|
||||
),
|
||||
(
|
||||
"{SUBREDDIT}",
|
||||
"{REDDITOR}_{TITLE}_{POSTID}",
|
||||
"test/formula1/Kirsty-Blue_George Russel acknowledges the Twitter trend about him_w22m5l.png",
|
||||
),
|
||||
),
|
||||
(
|
||||
'{SUBREDDIT}',
|
||||
'{TITLE}_{POSTID}',
|
||||
'test/formula1/George Russel acknowledges the Twitter trend about him_w22m5l.png',
|
||||
),
|
||||
(
|
||||
'{SUBREDDIT}',
|
||||
'{REDDITOR}_{TITLE}_{POSTID}',
|
||||
'test/formula1/Kirsty-Blue_George Russel acknowledges the Twitter trend about him_w22m5l.png',
|
||||
),
|
||||
))
|
||||
)
|
||||
def test_format_full(
|
||||
format_string_directory: str,
|
||||
format_string_file: str,
|
||||
expected: str,
|
||||
reddit_submission: praw.models.Submission):
|
||||
test_resource = Resource(reddit_submission, 'i.reddit.com/blabla.png', lambda: None)
|
||||
test_formatter = FileNameFormatter(format_string_file, format_string_directory, 'ISO')
|
||||
result = test_formatter.format_path(test_resource, Path('test'))
|
||||
format_string_directory: str, format_string_file: str, expected: str, reddit_submission: praw.models.Submission
|
||||
):
|
||||
test_resource = Resource(reddit_submission, "i.reddit.com/blabla.png", lambda: None)
|
||||
test_formatter = FileNameFormatter(format_string_file, format_string_directory, "ISO")
|
||||
result = test_formatter.format_path(test_resource, Path("test"))
|
||||
assert do_test_path_equality(result, expected)
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('format_string_directory', 'format_string_file'), (
|
||||
('{SUBREDDIT}', '{POSTID}'),
|
||||
('{SUBREDDIT}', '{UPVOTES}'),
|
||||
('{SUBREDDIT}', '{UPVOTES}{POSTID}'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("format_string_directory", "format_string_file"),
|
||||
(
|
||||
("{SUBREDDIT}", "{POSTID}"),
|
||||
("{SUBREDDIT}", "{UPVOTES}"),
|
||||
("{SUBREDDIT}", "{UPVOTES}{POSTID}"),
|
||||
),
|
||||
)
|
||||
def test_format_full_conform(
|
||||
format_string_directory: str,
|
||||
format_string_file: str,
|
||||
reddit_submission: praw.models.Submission):
|
||||
test_resource = Resource(reddit_submission, 'i.reddit.com/blabla.png', lambda: None)
|
||||
test_formatter = FileNameFormatter(format_string_file, format_string_directory, 'ISO')
|
||||
test_formatter.format_path(test_resource, Path('test'))
|
||||
format_string_directory: str, format_string_file: str, reddit_submission: praw.models.Submission
|
||||
):
|
||||
test_resource = Resource(reddit_submission, "i.reddit.com/blabla.png", lambda: None)
|
||||
test_formatter = FileNameFormatter(format_string_file, format_string_directory, "ISO")
|
||||
test_formatter.format_path(test_resource, Path("test"))
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('format_string_directory', 'format_string_file', 'index', 'expected'), (
|
||||
('{SUBREDDIT}', '{POSTID}', None, 'test/formula1/w22m5l.png'),
|
||||
('{SUBREDDIT}', '{POSTID}', 1, 'test/formula1/w22m5l_1.png'),
|
||||
('{SUBREDDIT}', '{POSTID}', 2, 'test/formula1/w22m5l_2.png'),
|
||||
('{SUBREDDIT}', '{TITLE}_{POSTID}', 2, 'test/formula1/George Russel acknowledges the Twitter trend about him_w22m5l_2.png'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("format_string_directory", "format_string_file", "index", "expected"),
|
||||
(
|
||||
("{SUBREDDIT}", "{POSTID}", None, "test/formula1/w22m5l.png"),
|
||||
("{SUBREDDIT}", "{POSTID}", 1, "test/formula1/w22m5l_1.png"),
|
||||
("{SUBREDDIT}", "{POSTID}", 2, "test/formula1/w22m5l_2.png"),
|
||||
(
|
||||
"{SUBREDDIT}",
|
||||
"{TITLE}_{POSTID}",
|
||||
2,
|
||||
"test/formula1/George Russel acknowledges the Twitter trend about him_w22m5l_2.png",
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_format_full_with_index_suffix(
|
||||
format_string_directory: str,
|
||||
format_string_file: str,
|
||||
index: Optional[int],
|
||||
expected: str,
|
||||
reddit_submission: praw.models.Submission,
|
||||
format_string_directory: str,
|
||||
format_string_file: str,
|
||||
index: Optional[int],
|
||||
expected: str,
|
||||
reddit_submission: praw.models.Submission,
|
||||
):
|
||||
test_resource = Resource(reddit_submission, 'i.reddit.com/blabla.png', lambda: None)
|
||||
test_formatter = FileNameFormatter(format_string_file, format_string_directory, 'ISO')
|
||||
result = test_formatter.format_path(test_resource, Path('test'), index)
|
||||
test_resource = Resource(reddit_submission, "i.reddit.com/blabla.png", lambda: None)
|
||||
test_formatter = FileNameFormatter(format_string_file, format_string_directory, "ISO")
|
||||
result = test_formatter.format_path(test_resource, Path("test"), index)
|
||||
assert do_test_path_equality(result, expected)
|
||||
|
||||
|
||||
@@ -170,99 +190,114 @@ def test_format_multiple_resources():
|
||||
mocks = []
|
||||
for i in range(1, 5):
|
||||
new_mock = MagicMock()
|
||||
new_mock.url = 'https://example.com/test.png'
|
||||
new_mock.extension = '.png'
|
||||
new_mock.source_submission.title = 'test'
|
||||
new_mock.url = "https://example.com/test.png"
|
||||
new_mock.extension = ".png"
|
||||
new_mock.source_submission.title = "test"
|
||||
new_mock.source_submission.__class__ = praw.models.Submission
|
||||
mocks.append(new_mock)
|
||||
test_formatter = FileNameFormatter('{TITLE}', '', 'ISO')
|
||||
results = test_formatter.format_resource_paths(mocks, Path('.'))
|
||||
test_formatter = FileNameFormatter("{TITLE}", "", "ISO")
|
||||
results = test_formatter.format_resource_paths(mocks, Path("."))
|
||||
results = set([str(res[0].name) for res in results])
|
||||
expected = {'test_1.png', 'test_2.png', 'test_3.png', 'test_4.png'}
|
||||
expected = {"test_1.png", "test_2.png", "test_3.png", "test_4.png"}
|
||||
assert results == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_filename', 'test_ending'), (
|
||||
('A' * 300, '.png'),
|
||||
('A' * 300, '_1.png'),
|
||||
('a' * 300, '_1000.jpeg'),
|
||||
('😍💕✨' * 100, '_1.png'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_filename", "test_ending"),
|
||||
(
|
||||
("A" * 300, ".png"),
|
||||
("A" * 300, "_1.png"),
|
||||
("a" * 300, "_1000.jpeg"),
|
||||
("😍💕✨" * 100, "_1.png"),
|
||||
),
|
||||
)
|
||||
def test_limit_filename_length(test_filename: str, test_ending: str):
|
||||
result = FileNameFormatter.limit_file_name_length(test_filename, test_ending, Path('.'))
|
||||
result = FileNameFormatter.limit_file_name_length(test_filename, test_ending, Path("."))
|
||||
assert len(result.name) <= 255
|
||||
assert len(result.name.encode('utf-8')) <= 255
|
||||
assert len(result.name.encode("utf-8")) <= 255
|
||||
assert len(str(result)) <= FileNameFormatter.find_max_path_length()
|
||||
assert isinstance(result, Path)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_filename', 'test_ending', 'expected_end'), (
|
||||
('test_aaaaaa', '_1.png', 'test_aaaaaa_1.png'),
|
||||
('test_aataaa', '_1.png', 'test_aataaa_1.png'),
|
||||
('test_abcdef', '_1.png', 'test_abcdef_1.png'),
|
||||
('test_aaaaaa', '.png', 'test_aaaaaa.png'),
|
||||
('test', '_1.png', 'test_1.png'),
|
||||
('test_m1hqw6', '_1.png', 'test_m1hqw6_1.png'),
|
||||
('A' * 300 + '_bbbccc', '.png', '_bbbccc.png'),
|
||||
('A' * 300 + '_bbbccc', '_1000.jpeg', '_bbbccc_1000.jpeg'),
|
||||
('😍💕✨' * 100 + '_aaa1aa', '_1.png', '_aaa1aa_1.png'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_filename", "test_ending", "expected_end"),
|
||||
(
|
||||
("test_aaaaaa", "_1.png", "test_aaaaaa_1.png"),
|
||||
("test_aataaa", "_1.png", "test_aataaa_1.png"),
|
||||
("test_abcdef", "_1.png", "test_abcdef_1.png"),
|
||||
("test_aaaaaa", ".png", "test_aaaaaa.png"),
|
||||
("test", "_1.png", "test_1.png"),
|
||||
("test_m1hqw6", "_1.png", "test_m1hqw6_1.png"),
|
||||
("A" * 300 + "_bbbccc", ".png", "_bbbccc.png"),
|
||||
("A" * 300 + "_bbbccc", "_1000.jpeg", "_bbbccc_1000.jpeg"),
|
||||
("😍💕✨" * 100 + "_aaa1aa", "_1.png", "_aaa1aa_1.png"),
|
||||
),
|
||||
)
|
||||
def test_preserve_id_append_when_shortening(test_filename: str, test_ending: str, expected_end: str):
|
||||
result = FileNameFormatter.limit_file_name_length(test_filename, test_ending, Path('.'))
|
||||
result = FileNameFormatter.limit_file_name_length(test_filename, test_ending, Path("."))
|
||||
assert len(result.name) <= 255
|
||||
assert len(result.name.encode('utf-8')) <= 255
|
||||
assert len(result.name.encode("utf-8")) <= 255
|
||||
assert result.name.endswith(expected_end)
|
||||
assert len(str(result)) <= FileNameFormatter.find_max_path_length()
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform == 'win32', reason='Test broken on windows github')
|
||||
@pytest.mark.skipif(sys.platform == "win32", reason="Test broken on windows github")
|
||||
def test_shorten_filename_real(submission: MagicMock, tmp_path: Path):
|
||||
submission.title = 'A' * 500
|
||||
submission.author.name = 'test'
|
||||
submission.subreddit.display_name = 'test'
|
||||
submission.id = 'BBBBBB'
|
||||
test_resource = Resource(submission, 'www.example.com/empty', lambda: None, '.jpeg')
|
||||
test_formatter = FileNameFormatter('{REDDITOR}_{TITLE}_{POSTID}', '{SUBREDDIT}', 'ISO')
|
||||
submission.title = "A" * 500
|
||||
submission.author.name = "test"
|
||||
submission.subreddit.display_name = "test"
|
||||
submission.id = "BBBBBB"
|
||||
test_resource = Resource(submission, "www.example.com/empty", lambda: None, ".jpeg")
|
||||
test_formatter = FileNameFormatter("{REDDITOR}_{TITLE}_{POSTID}", "{SUBREDDIT}", "ISO")
|
||||
result = test_formatter.format_path(test_resource, tmp_path)
|
||||
result.parent.mkdir(parents=True)
|
||||
result.touch()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_name', 'test_ending'), (
|
||||
('a', 'b'),
|
||||
('a', '_bbbbbb.jpg'),
|
||||
('a' * 20, '_bbbbbb.jpg'),
|
||||
('a' * 50, '_bbbbbb.jpg'),
|
||||
('a' * 500, '_bbbbbb.jpg'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_name", "test_ending"),
|
||||
(
|
||||
("a", "b"),
|
||||
("a", "_bbbbbb.jpg"),
|
||||
("a" * 20, "_bbbbbb.jpg"),
|
||||
("a" * 50, "_bbbbbb.jpg"),
|
||||
("a" * 500, "_bbbbbb.jpg"),
|
||||
),
|
||||
)
|
||||
def test_shorten_path(test_name: str, test_ending: str, tmp_path: Path):
|
||||
result = FileNameFormatter.limit_file_name_length(test_name, test_ending, tmp_path)
|
||||
assert len(str(result.name)) <= 255
|
||||
assert len(str(result.name).encode('UTF-8')) <= 255
|
||||
assert len(str(result.name).encode('cp1252')) <= 255
|
||||
assert len(str(result.name).encode("UTF-8")) <= 255
|
||||
assert len(str(result.name).encode("cp1252")) <= 255
|
||||
assert len(str(result)) <= FileNameFormatter.find_max_path_length()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_string', 'expected'), (
|
||||
('test', 'test'),
|
||||
('test😍', 'test'),
|
||||
('test.png', 'test.png'),
|
||||
('test*', 'test'),
|
||||
('test**', 'test'),
|
||||
('test?*', 'test'),
|
||||
('test_???.png', 'test_.png'),
|
||||
('test_???😍.png', 'test_.png'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_string", "expected"),
|
||||
(
|
||||
("test", "test"),
|
||||
("test😍", "test"),
|
||||
("test.png", "test.png"),
|
||||
("test*", "test"),
|
||||
("test**", "test"),
|
||||
("test?*", "test"),
|
||||
("test_???.png", "test_.png"),
|
||||
("test_???😍.png", "test_.png"),
|
||||
),
|
||||
)
|
||||
def test_format_file_name_for_windows(test_string: str, expected: str):
|
||||
result = FileNameFormatter._format_for_windows(test_string)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_string', 'expected'), (
|
||||
('test', 'test'),
|
||||
('test😍', 'test'),
|
||||
('😍', ''),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_string", "expected"),
|
||||
(
|
||||
("test", "test"),
|
||||
("test😍", "test"),
|
||||
("😍", ""),
|
||||
),
|
||||
)
|
||||
def test_strip_emojies(test_string: str, expected: str):
|
||||
result = FileNameFormatter._strip_emojis(test_string)
|
||||
assert result == expected
|
||||
@@ -270,121 +305,151 @@ def test_strip_emojies(test_string: str, expected: str):
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_submission_id', 'expected'), (
|
||||
('mfuteh', {
|
||||
'title': 'Why Do Interviewers Ask Linked List Questions?',
|
||||
'redditor': 'mjgardner',
|
||||
}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_submission_id", "expected"),
|
||||
(
|
||||
(
|
||||
"mfuteh",
|
||||
{
|
||||
"title": "Why Do Interviewers Ask Linked List Questions?",
|
||||
"redditor": "mjgardner",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_generate_dict_for_submission(test_submission_id: str, expected: dict, reddit_instance: praw.Reddit):
|
||||
test_submission = reddit_instance.submission(id=test_submission_id)
|
||||
test_formatter = FileNameFormatter('{TITLE}', '', 'ISO')
|
||||
test_formatter = FileNameFormatter("{TITLE}", "", "ISO")
|
||||
result = test_formatter._generate_name_dict_from_submission(test_submission)
|
||||
assert all([result.get(key) == expected[key] for key in expected.keys()])
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_comment_id', 'expected'), (
|
||||
('gsq0yuw', {
|
||||
'title': 'Why Do Interviewers Ask Linked List Questions?',
|
||||
'redditor': 'Doctor-Dapper',
|
||||
'postid': 'gsq0yuw',
|
||||
'flair': '',
|
||||
}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_comment_id", "expected"),
|
||||
(
|
||||
(
|
||||
"gsq0yuw",
|
||||
{
|
||||
"title": "Why Do Interviewers Ask Linked List Questions?",
|
||||
"redditor": "Doctor-Dapper",
|
||||
"postid": "gsq0yuw",
|
||||
"flair": "",
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_generate_dict_for_comment(test_comment_id: str, expected: dict, reddit_instance: praw.Reddit):
|
||||
test_comment = reddit_instance.comment(id=test_comment_id)
|
||||
test_formatter = FileNameFormatter('{TITLE}', '', 'ISO')
|
||||
test_formatter = FileNameFormatter("{TITLE}", "", "ISO")
|
||||
result = test_formatter._generate_name_dict_from_comment(test_comment)
|
||||
assert all([result.get(key) == expected[key] for key in expected.keys()])
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_file_scheme', 'test_folder_scheme', 'test_comment_id', 'expected_name'), (
|
||||
('{POSTID}', '', 'gsoubde', 'gsoubde.json'),
|
||||
('{REDDITOR}_{POSTID}', '', 'gsoubde', 'DELETED_gsoubde.json'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_file_scheme", "test_folder_scheme", "test_comment_id", "expected_name"),
|
||||
(
|
||||
("{POSTID}", "", "gsoubde", "gsoubde.json"),
|
||||
("{REDDITOR}_{POSTID}", "", "gsoubde", "DELETED_gsoubde.json"),
|
||||
),
|
||||
)
|
||||
def test_format_archive_entry_comment(
|
||||
test_file_scheme: str,
|
||||
test_folder_scheme: str,
|
||||
test_comment_id: str,
|
||||
expected_name: str,
|
||||
tmp_path: Path,
|
||||
reddit_instance: praw.Reddit,
|
||||
test_file_scheme: str,
|
||||
test_folder_scheme: str,
|
||||
test_comment_id: str,
|
||||
expected_name: str,
|
||||
tmp_path: Path,
|
||||
reddit_instance: praw.Reddit,
|
||||
):
|
||||
test_comment = reddit_instance.comment(id=test_comment_id)
|
||||
test_formatter = FileNameFormatter(test_file_scheme, test_folder_scheme, 'ISO')
|
||||
test_entry = Resource(test_comment, '', lambda: None, '.json')
|
||||
test_formatter = FileNameFormatter(test_file_scheme, test_folder_scheme, "ISO")
|
||||
test_entry = Resource(test_comment, "", lambda: None, ".json")
|
||||
result = test_formatter.format_path(test_entry, tmp_path)
|
||||
assert do_test_string_equality(result, expected_name)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_folder_scheme', 'expected'), (
|
||||
('{REDDITOR}/{SUBREDDIT}', 'person/randomreddit'),
|
||||
('{POSTID}/{SUBREDDIT}/{REDDITOR}', '12345/randomreddit/person'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_folder_scheme", "expected"),
|
||||
(
|
||||
("{REDDITOR}/{SUBREDDIT}", "person/randomreddit"),
|
||||
("{POSTID}/{SUBREDDIT}/{REDDITOR}", "12345/randomreddit/person"),
|
||||
),
|
||||
)
|
||||
def test_multilevel_folder_scheme(
|
||||
test_folder_scheme: str,
|
||||
expected: str,
|
||||
tmp_path: Path,
|
||||
submission: MagicMock,
|
||||
test_folder_scheme: str,
|
||||
expected: str,
|
||||
tmp_path: Path,
|
||||
submission: MagicMock,
|
||||
):
|
||||
test_formatter = FileNameFormatter('{POSTID}', test_folder_scheme, 'ISO')
|
||||
test_formatter = FileNameFormatter("{POSTID}", test_folder_scheme, "ISO")
|
||||
test_resource = MagicMock()
|
||||
test_resource.source_submission = submission
|
||||
test_resource.extension = '.png'
|
||||
test_resource.extension = ".png"
|
||||
result = test_formatter.format_path(test_resource, tmp_path)
|
||||
result = result.relative_to(tmp_path)
|
||||
assert do_test_path_equality(result.parent, expected)
|
||||
assert len(result.parents) == (len(expected.split('/')) + 1)
|
||||
assert len(result.parents) == (len(expected.split("/")) + 1)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_name_string', 'expected'), (
|
||||
('test', 'test'),
|
||||
('😍', '😍'),
|
||||
('test😍', 'test😍'),
|
||||
('test😍 ’', 'test😍 ’'),
|
||||
('test😍 \\u2019', 'test😍 ’'),
|
||||
('Using that real good [1\\4]', 'Using that real good [1\\4]'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_name_string", "expected"),
|
||||
(
|
||||
("test", "test"),
|
||||
("😍", "😍"),
|
||||
("test😍", "test😍"),
|
||||
("test😍 ’", "test😍 ’"),
|
||||
("test😍 \\u2019", "test😍 ’"),
|
||||
("Using that real good [1\\4]", "Using that real good [1\\4]"),
|
||||
),
|
||||
)
|
||||
def test_preserve_emojis(test_name_string: str, expected: str, submission: MagicMock):
|
||||
submission.title = test_name_string
|
||||
test_formatter = FileNameFormatter('{TITLE}', '', 'ISO')
|
||||
result = test_formatter._format_name(submission, '{TITLE}')
|
||||
test_formatter = FileNameFormatter("{TITLE}", "", "ISO")
|
||||
result = test_formatter._format_name(submission, "{TITLE}")
|
||||
assert do_test_string_equality(result, expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_string', 'expected'), (
|
||||
('test \\u2019', 'test ’'),
|
||||
('My cat\\u2019s paws are so cute', 'My cat’s paws are so cute'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_string", "expected"),
|
||||
(
|
||||
("test \\u2019", "test ’"),
|
||||
("My cat\\u2019s paws are so cute", "My cat’s paws are so cute"),
|
||||
),
|
||||
)
|
||||
def test_convert_unicode_escapes(test_string: str, expected: str):
|
||||
result = FileNameFormatter._convert_unicode_escapes(test_string)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_datetime', 'expected'), (
|
||||
(datetime(2020, 1, 1, 8, 0, 0), '2020-01-01T08:00:00'),
|
||||
(datetime(2020, 1, 1, 8, 0), '2020-01-01T08:00:00'),
|
||||
(datetime(2021, 4, 21, 8, 30, 21), '2021-04-21T08:30:21'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_datetime", "expected"),
|
||||
(
|
||||
(datetime(2020, 1, 1, 8, 0, 0), "2020-01-01T08:00:00"),
|
||||
(datetime(2020, 1, 1, 8, 0), "2020-01-01T08:00:00"),
|
||||
(datetime(2021, 4, 21, 8, 30, 21), "2021-04-21T08:30:21"),
|
||||
),
|
||||
)
|
||||
def test_convert_timestamp(test_datetime: datetime, expected: str):
|
||||
test_timestamp = test_datetime.timestamp()
|
||||
test_formatter = FileNameFormatter('{POSTID}', '', 'ISO')
|
||||
test_formatter = FileNameFormatter("{POSTID}", "", "ISO")
|
||||
result = test_formatter._convert_timestamp(test_timestamp)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_time_format', 'expected'), (
|
||||
('ISO', '2021-05-02T13:33:00'),
|
||||
('%Y_%m', '2021_05'),
|
||||
('%Y-%m-%d', '2021-05-02'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_time_format", "expected"),
|
||||
(
|
||||
("ISO", "2021-05-02T13:33:00"),
|
||||
("%Y_%m", "2021_05"),
|
||||
("%Y-%m-%d", "2021-05-02"),
|
||||
),
|
||||
)
|
||||
def test_time_string_formats(test_time_format: str, expected: str):
|
||||
test_time = datetime(2021, 5, 2, 13, 33)
|
||||
test_formatter = FileNameFormatter('{TITLE}', '', test_time_format)
|
||||
test_formatter = FileNameFormatter("{TITLE}", "", test_time_format)
|
||||
result = test_formatter._convert_timestamp(test_time.timestamp())
|
||||
assert result == expected
|
||||
|
||||
@@ -395,29 +460,32 @@ def test_get_max_path_length():
|
||||
|
||||
|
||||
def test_windows_max_path(tmp_path: Path):
|
||||
with unittest.mock.patch('platform.system', return_value='Windows'):
|
||||
with unittest.mock.patch('bdfr.file_name_formatter.FileNameFormatter.find_max_path_length', return_value=260):
|
||||
result = FileNameFormatter.limit_file_name_length('test' * 100, '_1.png', tmp_path)
|
||||
with unittest.mock.patch("platform.system", return_value="Windows"):
|
||||
with unittest.mock.patch("bdfr.file_name_formatter.FileNameFormatter.find_max_path_length", return_value=260):
|
||||
result = FileNameFormatter.limit_file_name_length("test" * 100, "_1.png", tmp_path)
|
||||
assert len(str(result)) <= 260
|
||||
assert len(result.name) <= (260 - len(str(tmp_path)))
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.reddit
|
||||
@pytest.mark.parametrize(('test_reddit_id', 'test_downloader', 'expected_names'), (
|
||||
('gphmnr', YtdlpFallback, {'He has a lot to say today.mp4'}),
|
||||
('d0oir2', YtdlpFallback, {"Crunk's finest moment. Welcome to the new subreddit!.mp4"}),
|
||||
('jiecu', SelfPost, {'[deleted by user].txt'}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_reddit_id", "test_downloader", "expected_names"),
|
||||
(
|
||||
("gphmnr", YtdlpFallback, {"He has a lot to say today.mp4"}),
|
||||
("d0oir2", YtdlpFallback, {"Crunk's finest moment. Welcome to the new subreddit!.mp4"}),
|
||||
("jiecu", SelfPost, {"[deleted by user].txt"}),
|
||||
),
|
||||
)
|
||||
def test_name_submission(
|
||||
test_reddit_id: str,
|
||||
test_downloader: Type[BaseDownloader],
|
||||
expected_names: set[str],
|
||||
reddit_instance: praw.reddit.Reddit,
|
||||
test_reddit_id: str,
|
||||
test_downloader: Type[BaseDownloader],
|
||||
expected_names: set[str],
|
||||
reddit_instance: praw.reddit.Reddit,
|
||||
):
|
||||
test_submission = reddit_instance.submission(id=test_reddit_id)
|
||||
test_resources = test_downloader(test_submission).find_resources()
|
||||
test_formatter = FileNameFormatter('{TITLE}', '', '')
|
||||
results = test_formatter.format_resource_paths(test_resources, Path('.'))
|
||||
test_formatter = FileNameFormatter("{TITLE}", "", "")
|
||||
results = test_formatter.format_resource_paths(test_resources, Path("."))
|
||||
results = set([r[0].name for r in results])
|
||||
assert results == expected_names
|
||||
|
||||
@@ -14,38 +14,58 @@ from bdfr.oauth2 import OAuth2Authenticator, OAuth2TokenManager
|
||||
@pytest.fixture()
|
||||
def example_config() -> configparser.ConfigParser:
|
||||
out = configparser.ConfigParser()
|
||||
config_dict = {'DEFAULT': {'user_token': 'example'}}
|
||||
config_dict = {"DEFAULT": {"user_token": "example"}}
|
||||
out.read_dict(config_dict)
|
||||
return out
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize('test_scopes', (
|
||||
{'history', },
|
||||
{'history', 'creddits'},
|
||||
{'account', 'flair'},
|
||||
{'*', },
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_scopes",
|
||||
(
|
||||
{
|
||||
"history",
|
||||
},
|
||||
{"history", "creddits"},
|
||||
{"account", "flair"},
|
||||
{
|
||||
"*",
|
||||
},
|
||||
),
|
||||
)
|
||||
def test_check_scopes(test_scopes: set[str]):
|
||||
OAuth2Authenticator._check_scopes(test_scopes)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_scopes', 'expected'), (
|
||||
('history', {'history', }),
|
||||
('history creddits', {'history', 'creddits'}),
|
||||
('history, creddits, account', {'history', 'creddits', 'account'}),
|
||||
('history,creddits,account,flair', {'history', 'creddits', 'account', 'flair'}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_scopes", "expected"),
|
||||
(
|
||||
(
|
||||
"history",
|
||||
{
|
||||
"history",
|
||||
},
|
||||
),
|
||||
("history creddits", {"history", "creddits"}),
|
||||
("history, creddits, account", {"history", "creddits", "account"}),
|
||||
("history,creddits,account,flair", {"history", "creddits", "account", "flair"}),
|
||||
),
|
||||
)
|
||||
def test_split_scopes(test_scopes: str, expected: set[str]):
|
||||
result = OAuth2Authenticator.split_scopes(test_scopes)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize('test_scopes', (
|
||||
{'random', },
|
||||
{'scope', 'another_scope'},
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"test_scopes",
|
||||
(
|
||||
{
|
||||
"random",
|
||||
},
|
||||
{"scope", "another_scope"},
|
||||
),
|
||||
)
|
||||
def test_check_scopes_bad(test_scopes: set[str]):
|
||||
with pytest.raises(BulkDownloaderException):
|
||||
OAuth2Authenticator._check_scopes(test_scopes)
|
||||
@@ -56,16 +76,16 @@ def test_token_manager_read(example_config: configparser.ConfigParser):
|
||||
mock_authoriser.refresh_token = None
|
||||
test_manager = OAuth2TokenManager(example_config, MagicMock())
|
||||
test_manager.pre_refresh_callback(mock_authoriser)
|
||||
assert mock_authoriser.refresh_token == example_config.get('DEFAULT', 'user_token')
|
||||
assert mock_authoriser.refresh_token == example_config.get("DEFAULT", "user_token")
|
||||
|
||||
|
||||
def test_token_manager_write(example_config: configparser.ConfigParser, tmp_path: Path):
|
||||
test_path = tmp_path / 'test.cfg'
|
||||
test_path = tmp_path / "test.cfg"
|
||||
mock_authoriser = MagicMock()
|
||||
mock_authoriser.refresh_token = 'changed_token'
|
||||
mock_authoriser.refresh_token = "changed_token"
|
||||
test_manager = OAuth2TokenManager(example_config, test_path)
|
||||
test_manager.post_refresh_callback(mock_authoriser)
|
||||
assert example_config.get('DEFAULT', 'user_token') == 'changed_token'
|
||||
with test_path.open('r') as file:
|
||||
assert example_config.get("DEFAULT", "user_token") == "changed_token"
|
||||
with test_path.open("r") as file:
|
||||
file_contents = file.read()
|
||||
assert 'user_token = changed_token' in file_contents
|
||||
assert "user_token = changed_token" in file_contents
|
||||
|
||||
@@ -8,18 +8,21 @@ import pytest
|
||||
from bdfr.resource import Resource
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('test_url', 'expected'), (
|
||||
('test.png', '.png'),
|
||||
('another.mp4', '.mp4'),
|
||||
('test.jpeg', '.jpeg'),
|
||||
('http://www.random.com/resource.png', '.png'),
|
||||
('https://www.resource.com/test/example.jpg', '.jpg'),
|
||||
('hard.png.mp4', '.mp4'),
|
||||
('https://preview.redd.it/7zkmr1wqqih61.png?width=237&format=png&auto=webp&s=19de214e634cbcad99', '.png'),
|
||||
('test.jpg#test', '.jpg'),
|
||||
('test.jpg?width=247#test', '.jpg'),
|
||||
('https://www.test.com/test/test2/example.png?random=test#thing', '.png'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected"),
|
||||
(
|
||||
("test.png", ".png"),
|
||||
("another.mp4", ".mp4"),
|
||||
("test.jpeg", ".jpeg"),
|
||||
("http://www.random.com/resource.png", ".png"),
|
||||
("https://www.resource.com/test/example.jpg", ".jpg"),
|
||||
("hard.png.mp4", ".mp4"),
|
||||
("https://preview.redd.it/7zkmr1wqqih61.png?width=237&format=png&auto=webp&s=19de214e634cbcad99", ".png"),
|
||||
("test.jpg#test", ".jpg"),
|
||||
("test.jpg?width=247#test", ".jpg"),
|
||||
("https://www.test.com/test/test2/example.png?random=test#thing", ".png"),
|
||||
),
|
||||
)
|
||||
def test_resource_get_extension(test_url: str, expected: str):
|
||||
test_resource = Resource(MagicMock(), test_url, lambda: None)
|
||||
result = test_resource._determine_extension()
|
||||
@@ -27,9 +30,10 @@ def test_resource_get_extension(test_url: str, expected: str):
|
||||
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.parametrize(('test_url', 'expected_hash'), (
|
||||
('https://www.iana.org/_img/2013.1/iana-logo-header.svg', '426b3ac01d3584c820f3b7f5985d6623'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
("test_url", "expected_hash"),
|
||||
(("https://www.iana.org/_img/2013.1/iana-logo-header.svg", "426b3ac01d3584c820f3b7f5985d6623"),),
|
||||
)
|
||||
def test_download_online_resource(test_url: str, expected_hash: str):
|
||||
test_resource = Resource(MagicMock(), test_url, Resource.retry_download(test_url))
|
||||
test_resource.download()
|
||||
|
||||
Reference in New Issue
Block a user