async def test_get_search_results_with_space(requests_mock): builder = SubmissionBuilder() search = "deer lion" search_safe = "deer%20lion" api = FAExportAPI("http://example.com/", ignore_status=True) requests_mock.get( f"http://example.com/search.json?full=1&perpage=48&q={search_safe}&page=1", json=[builder.build_search_json()]) results = await api.get_search_results(search) assert len(results) == 1 assert isinstance(results[0], FASubmissionShort) assert results[0].submission_id == builder.submission_id
async def test_convert_gif(): submission = SubmissionBuilder(file_ext="gif", file_size=47453).build_full_submission() mock_run = MockMethod("Test docker") mock_filesize = MockMethod(submission.SIZE_LIMIT_GIF - 10) submission._run_docker = mock_run.async_call with mock.patch("os.path.getsize", mock_filesize.call): output_path = await submission._convert_gif(submission.download_url) assert output_path is not None assert output_path.endswith(".mp4") assert mock_run.called assert mock_run.args[1].startswith(f"-i {submission.download_url}") assert mock_run.args[1].endswith(f" /{output_path}")
async def test_get_user_folder_specified_page(requests_mock): builder = SubmissionBuilder() username = "******" api = FAExportAPI("http://example.com/", ignore_status=True) requests_mock.get( f"http://example.com/user/{username}/gallery.json?page=2&full=1", json=[builder.build_search_json()]) results = await api.get_user_folder(username, "gallery", 2) assert len(results) == 1 assert isinstance(results[0], FASubmissionShort) assert results[0].submission_id == builder.submission_id assert results[0].link == builder.link assert results[0].thumbnail_url == builder.thumbnail_url
async def test_send_updates__blocked_pauses_other_subs(mock_client): api = MockExportAPI() watcher = SubscriptionWatcher(api, mock_client) subscription1 = Subscription("test", 12345) subscription2 = Subscription("other", 12345) subscription3 = Subscription("not me", 54321) watcher.subscriptions = {subscription1, subscription2, subscription3} submission = SubmissionBuilder().build_mock_submission() submission.send_message = lambda *args, **kwargs: (_ for _ in ()).throw( UserIsBlockedError(None)) await watcher._send_updates([subscription1], submission) assert subscription1.paused assert subscription2.paused assert not subscription3.paused
async def test_get_full_submission(requests_mock): builder = SubmissionBuilder(thumb_size=300) api = FAExportAPI("http://example.com/", ignore_status=True) requests_mock.get( f"http://example.com/submission/{builder.submission_id}.json", json=builder.build_submission_json()) submission = await api.get_full_submission(builder.submission_id) assert isinstance(submission, FASubmissionFull) assert submission.submission_id == builder.submission_id assert submission.link == builder.link assert submission.thumbnail_url == builder.thumbnail_url.replace( "@300-", "@1600-") assert submission.download_url == builder.download_url assert submission.full_image_url == builder.download_url
async def test_send_updates__gathers_subscriptions(mock_client): api = MockExportAPI() watcher = SubscriptionWatcher(api, mock_client) subscription1 = Subscription("test", 12345) subscription2 = Subscription("test2", 12345) subscription3 = Subscription("test", 54321) submission = SubmissionBuilder().build_mock_submission() await watcher._send_updates([subscription1, subscription2, subscription3], submission) assert submission._send_message.call_count == 2 call_list = submission._send_message.call_args_list # Indifferent to call order, so figure out the order here call1 = call_list[0] call2 = call_list[1] if call1[0][1] != 12345: call1 = call_list[1] call2 = call_list[0] args1, kwargs1 = call1 args2, kwargs2 = call2 # Check call matching two subscriptions assert args1[0] == mock_client assert args2[0] == mock_client assert args1[1] == 12345 assert args2[1] == 54321 assert "update" in kwargs1['prefix'].lower() assert "\"test\", \"test2\"" in kwargs1['prefix'] assert "subscriptions:" in kwargs1['prefix'].lower() # And check the one subscription call assert "update" in kwargs2['prefix'].lower() assert "\"test\"" in kwargs2['prefix'] assert "subscription:" in kwargs2['prefix'].lower()
async def test_get_user_folder_awkward_characters(requests_mock): builder = SubmissionBuilder() username = "******" safe_username = "******" api = FAExportAPI("http://example.com/", ignore_status=True) requests_mock.get( f"http://example.com/user/{safe_username}/gallery.json?page=1&full=1", json=[builder.build_search_json()]) results = await api.get_user_folder(username, "gallery") assert len(results) == 1 assert isinstance(results[0], FASubmissionShort) assert results[0].submission_id == builder.submission_id assert results[0].link == builder.link assert results[0].thumbnail_url == builder.thumbnail_url
async def test_auto_doc_just_over_size_limit(mock_client): title = "Example title" author = FAUser("A writer", "awriter") submission = SubmissionBuilder(file_ext="pdf", file_size=FASubmission.SIZE_LIMIT_DOCUMENT + 1, title=title, author=author).build_full_submission() chat = MockChat(-9327622) message_id = 2873292 await submission.send_message(mock_client, chat, reply_to=message_id) mock_client.send_message.assert_called_once() assert mock_client.send_message.call_args[1]['entity'] == chat assert mock_client.send_message.call_args[1][ 'file'] == submission.full_image_url assert mock_client.send_message.call_args[1]['reply_to'] == message_id assert mock_client.send_message.call_args[1]['parse_mode'] == 'html' sent_message = mock_client.send_message.call_args[1]['message'] assert sent_message.endswith( f"{submission.link}\n<a href=\"{submission.download_url}\">Direct download</a>" ) assert f"\"{title}\"" in sent_message assert author.name in sent_message assert author.link in sent_message
def test_matches_result__regex_matches_case_insensitive(): query = "d*taur" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="DeerTaur plays in woods").build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
def test_matches_result__suffix_doesnt_match_term(): query = "*taur" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="taur plays in woods").build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
async def test_send_updates__updates_latest(mock_client): api = MockExportAPI() watcher = SubscriptionWatcher(api, mock_client) subscription = Subscription("test", 12345) submission = SubmissionBuilder().build_mock_submission() await watcher._send_updates([subscription], submission) assert subscription.latest_update is not None
def test_matches_result__prefix_matches(): query = "deer*" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="deertaur plays in woods").build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
def test_matches_not_negative_rating(): query = "deer -rating:general" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Deer plays in woods", rating=Rating.GENERAL).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
async def test_swf_submission(mock_client): submission = SubmissionBuilder(file_ext="swf", file_size=47453).build_full_submission() chat = MockChat(-9327622) message_id = 2873292 try: await submission.send_message(mock_client, chat, reply_to=message_id) assert False, "Should have thrown exception." except CantSendFileType as e: assert str(e) == "I'm sorry, I can't neaten \".swf\" files."
def test_matches_result__two_words_in_description_matches(): query = "example submission" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="test", description="this submission is just an example", keywords=["example", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
def test_create_from_full_dict(self): builder = SubmissionBuilder() submission = FASubmission.from_full_dict( builder.build_submission_json()) assert isinstance(submission, FASubmissionFull) assert submission.submission_id == builder.submission_id assert submission.link == builder.link assert submission.thumbnail_url == builder.thumbnail_url assert submission.title == builder.title assert submission.author.profile_name == builder.author.profile_name assert submission.author.name == builder.author.name assert submission.author.link == builder.author.link assert submission.download_url == builder.download_url assert submission.full_image_url == builder.full_image_url assert submission.description == builder.description assert submission.keywords == builder.keywords
def test_matches_result__keywords_not_phrase(): query = "\"hello world\"" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description="this submission says hello to the world", keywords=["example", "hello", "world"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
async def test_convert_gif_failure(mock_client): submission = SubmissionBuilder(file_ext="gif", file_size=47453).build_full_submission() chat = MockChat(-9327622) message_id = 2873292 submission._convert_gif = lambda *args: (_ for _ in ()).throw(Exception) mock_bytes = b"hello world" with mock.patch.object(fa_submission, "_convert_gif_to_png", return_value=mock_bytes) as mock_convert: await submission.send_message(mock_client, chat, reply_to=message_id) mock_client.send_message.assert_called_once() assert mock_client.send_message.call_args[1]['entity'] == chat assert mock_client.send_message.call_args[1]['file'] == mock_bytes assert mock_client.send_message.call_args[1]['message'] == submission.link assert mock_client.send_message.call_args[1]['reply_to'] == message_id mock_convert.assert_called_once() assert mock_convert.call_args[0][0] == submission.download_url
def test_matches_result__case_insensitive_query(): query = "SUBMISSION" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="test submission", description="this submission is just an example", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
async def test_unknown_type_submission(mock_client): submission = SubmissionBuilder(file_ext="zzz", file_size=47453).build_full_submission() chat = MockChat(-9327622) message_id = 2873292 try: await submission.send_message(mock_client, chat, reply_to=message_id) assert False, "Should have thrown exception." except CantSendFileType as e: assert str( e) == "I'm sorry, I don't understand that file extension (zzz)."
def test_matches_result__doesnt_match_except_quote(): query = "taur except \"no taur\"" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description="this submission contains no taur", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
def test_matches_word_in_tag(): query = "deer" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description="this submission is <b>deer</b>", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
def test_matches_result__matches_query_with_hyphen(): query = "an-example" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description="this submission is just an-example", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
def test_matches_result__keyword_field(): query = "keywords:deer" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description="this submission has no deer and will not be tagged deer", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
def test_matches_result__substring_in_keywords_no_match(): query = "keyword" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="test submission", description="this submission is just an example", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
def test_matches_result__does_not_match_query_with_applicable_negated_query(): query = "test -example" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description="this submission is just an example", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
def test_matches_result__doesnt_match_except_bracket_clause(): query = "multi* except (multicol* or multitude)" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description= "this submission is just an example of a multitude of multicoloured things", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
def test_matches_result__doesnt_match_except_field(): query = "keywords:(multi* except (multitude multiple multicol*))" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description= "this submission is about multiplication but not tagged like that", keywords=["multitude", "multiple", "multicoloured", "multicolors"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match
def test_matches_result__except_matches_other_match(): query = "multi* except multitude" subscription = Subscription(query, 12432) submission = SubmissionBuilder( title="Test submission", description= "this submission is just an example of a multitude of multiple things", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert match
def test_matches_result__not_when_paused(): query = "test" subscription = Subscription(query, 12432) subscription.paused = True submission = SubmissionBuilder( title="test submission", description="this submission is just an example", keywords=["example", "submission", "keywords"]).build_full_submission() match = subscription.matches_result(submission, AndQuery([])) assert not match