def test_check_user_existence_good( test_redditor_name: str, reddit_instance: praw.Reddit, downloader_mock: MagicMock, ): downloader_mock.reddit_instance = reddit_instance RedditDownloader._check_user_existence(downloader_mock, test_redditor_name)
def test_mark_hard_link(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.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') RedditDownloader._download_submission(downloader_mock, submission) assert original.exists() 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 assert test_file_1_stats.st_nlink == 2 assert test_file_1_stats.st_ino == test_file_2_inode
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 with pytest.raises(BulkDownloaderException): RedditDownloader._create_file_name_formatter(downloader_mock)
def test_check_user_existence_banned( test_redditor_name: str, reddit_instance: praw.Reddit, downloader_mock: MagicMock, ): downloader_mock.reddit_instance = reddit_instance with pytest.raises(BulkDownloaderException, match='is banned'): RedditDownloader._check_user_existence(downloader_mock, test_redditor_name)
def test_excluded_ids(test_ids: tuple[str], test_excluded: tuple[str], expected_len: int, downloader_mock: MagicMock): downloader_mock.excluded_submission_ids = test_excluded test_submissions = [] for test_id in test_ids: m = MagicMock() m.id = test_id test_submissions.append(m) downloader_mock.reddit_lists = [test_submissions] RedditDownloader.download(downloader_mock) assert downloader_mock._download_submission.call_count == expected_len
def cli_download(context: click.Context, **_): config = Configuration() config.process_click_arguments(context) setup_logging(config.verbose) try: reddit_downloader = RedditDownloader(config) reddit_downloader.download() except Exception: logger.exception('Downloader exited unexpectedly') raise else: logger.info('Program complete')
def test_download_submission(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.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) folder_contents = list(tmp_path.iterdir()) assert len(folder_contents) == expected_files_len
def test_get_user_authenticated_lists( 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.user = '******' downloader_mock.args.limit = 10 downloader_mock._determine_sort_function.return_value = praw.models.Subreddit.hot downloader_mock.sort_filter = RedditTypes.SortType.HOT RedditDownloader._resolve_user_name(downloader_mock) results = RedditDownloader._get_user_data(downloader_mock) assert_all_results_are_submissions(10, results)
def test_create_sort_filter(test_sort: str, expected: str, downloader_mock: MagicMock): downloader_mock.args.sort = test_sort result = RedditDownloader._create_sort_filter(downloader_mock) assert isinstance(result, RedditTypes.SortType) assert result.name.lower() == expected
def test_read_excluded_submission_ids_from_file(downloader_mock: MagicMock, tmp_path: Path): test_file = tmp_path / 'test.txt' test_file.write_text('aaaaaa\nbbbbbb') downloader_mock.args.exclude_id_file = [test_file] results = RedditDownloader._read_excluded_ids(downloader_mock) assert results == {'aaaaaa', 'bbbbbb'}
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 downloader_mock.sort_filter = RedditTypes.SortType.HOT downloader_mock.args.submitted = True downloader_mock.args.user = test_user downloader_mock.authenticated = False downloader_mock.reddit_instance = reddit_instance downloader_mock._create_filtered_listing_generator.return_value = \ RedditDownloader._create_filtered_listing_generator( downloader_mock, reddit_instance.redditor(test_user).submissions, ) results = RedditDownloader._get_user_data(downloader_mock) results = assert_all_results_are_submissions(limit, results) assert all([res.author.name == test_user for res in results])
def test_create_time_filter(test_time: str, expected: str, downloader_mock: MagicMock): downloader_mock.args.time = test_time result = RedditDownloader._create_time_filter(downloader_mock) assert isinstance(result, RedditTypes.TimeType) assert result.name.lower() == expected
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 result = RedditDownloader._create_download_filter(downloader_mock) assert isinstance(result, DownloadFilter) assert result.excluded_domains == skip_domains assert result.excluded_extensions == skip_extensions
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 result = RedditDownloader._create_file_name_formatter(downloader_mock) assert isinstance(result, FileNameFormatter) assert result.file_format_string == test_file_scheme assert result.directory_format_string == test_folder_scheme.split('/')
def test_file_creation_date(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.file_name_formatter = RedditConnector.create_file_name_formatter( downloader_mock) submission = downloader_mock.reddit_instance.submission( id=test_submission_id) RedditDownloader._download_submission(downloader_mock, submission) for file_path in Path(tmp_path).iterdir(): file_stats = os.stat(file_path) assert file_stats.st_mtime == test_creation_date
def test_get_submissions_from_link( 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 = RedditDownloader._get_submissions_from_link(downloader_mock) assert all([isinstance(sub, praw.models.Submission) for res in results for sub in res]) assert len(results[0]) == len(test_submission_ids)
def test_download_submission_file_exists( 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.file_name_formatter = RedditDownloader._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() 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 already exists' in output.out
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, ): downloader_mock._determine_sort_function.return_value = praw.models.Subreddit.hot downloader_mock.args.limit = limit downloader_mock.args.sort = sort_type downloader_mock.args.subreddit = test_subreddits downloader_mock.reddit_instance = reddit_instance downloader_mock.sort_filter = RedditDownloader._create_sort_filter(downloader_mock) results = RedditDownloader._get_subreddits(downloader_mock) test_subreddits = downloader_mock._split_args_input(test_subreddits) results = [sub for res1 in results for sub in res1] assert all([isinstance(res1, praw.models.Submission) for res1 in results]) assert all([res.subreddit.display_name in test_subreddits for res in results]) assert len(results) <= max_expected_len
def test_excluded_ids( 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' 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.__class__ = praw.models.Submission test_submissions.append(m) downloader_mock.reddit_lists = [test_submissions] for submission in test_submissions: RedditDownloader._download_submission(downloader_mock, submission) assert mock_function.call_count == expected_len
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 ): 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.no_dupes = True downloader_mock.file_name_formatter = RedditDownloader._create_file_name_formatter(downloader_mock) downloader_mock.download_directory = tmp_path downloader_mock.master_hash_list = {test_hash: None} submission = downloader_mock.reddit_instance.submission(id=test_submission_id) RedditDownloader._download_submission(downloader_mock, submission) folder_contents = list(tmp_path.iterdir()) output = capsys.readouterr() assert len(folder_contents) == 0 assert re.search(r'Resource hash .*? downloaded elsewhere', output.out)
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, ): downloader_mock._determine_sort_function.return_value = praw.models.Subreddit.hot downloader_mock.args.limit = limit downloader_mock.args.search = search_term downloader_mock.args.subreddit = test_subreddits downloader_mock.reddit_instance = reddit_instance downloader_mock.sort_filter = RedditTypes.SortType.HOT downloader_mock.args.time = time_filter downloader_mock.time_filter = RedditDownloader._create_time_filter(downloader_mock) results = RedditDownloader._get_subreddits(downloader_mock) results = [sub for res in results for sub in res] assert all([isinstance(res, praw.models.Submission) for res in results]) assert all([res.subreddit.display_name in test_subreddits for res in results]) assert len(results) <= max_expected_len
def test_get_multireddits_public( 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 downloader_mock.args.limit = limit 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 = \ RedditDownloader._create_filtered_listing_generator( downloader_mock, reddit_instance.multireddit(test_user, test_multireddits[0]), ) results = RedditDownloader._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]) assert len(results) == limit
def test_create_authenticator(downloader_mock: MagicMock): result = RedditDownloader._create_authenticator(downloader_mock) assert isinstance(result, SiteAuthenticator)
def test_check_subreddit_status_good(test_subreddit_name: str, reddit_instance: praw.Reddit): test_subreddit = reddit_instance.subreddit(test_subreddit_name) RedditDownloader._check_subreddit_status(test_subreddit)
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): RedditDownloader._check_subreddit_status(test_subreddit)
def test_determine_directories(tmp_path: Path, downloader_mock: MagicMock): downloader_mock.args.directory = tmp_path / 'test' downloader_mock.config_directories.user_config_dir = tmp_path RedditDownloader._determine_directories(downloader_mock) assert Path(tmp_path / 'test').exists()
def test_sanitise_subreddit_name(test_name: str, expected: str): result = RedditDownloader._sanitise_subreddit_name(test_name) assert result == expected
def test_split_subreddit_entries(test_subreddit_entries: list[str], expected: set[str]): results = RedditDownloader._split_args_input(test_subreddit_entries) assert results == expected
def test_search_existing_files(): results = RedditDownloader.scan_existing_files(Path('.')) assert len(results.keys()) >= 40