def test_user_favourites(context): post_id1 = 234563 post_id2 = 393282 username = "******" update = MockTelegramUpdate.with_inline_query( query=f"favourites:{username}") submission1 = MockSubmission(post_id1) submission2 = MockSubmission(post_id2) inline = InlineFunctionality(MockExportAPI()) inline.api.with_user_favs(username, [submission1, submission2]) inline.call(update, context) context.bot.answer_inline_query.assert_called_once() args = context.bot.answer_inline_query.call_args[0] assert context.bot.answer_inline_query.call_args[1][ 'next_offset'] == submission2.fav_id assert args[0] == update.inline_query.id assert isinstance(args[1], list) assert len(args[1]) == 2 assert isinstance(args[1][0], InlineQueryResultPhoto) assert isinstance(args[1][1], InlineQueryResultPhoto) assert args[1][0].id == str(post_id1) assert args[1][1].id == str(post_id2) assert args[1][0].photo_url == submission1.thumbnail_url assert args[1][1].photo_url == submission2.thumbnail_url assert args[1][0].thumb_url == FASubmission.make_thumbnail_smaller( submission1.thumbnail_url) assert args[1][1].thumb_url == FASubmission.make_thumbnail_smaller( submission2.thumbnail_url) assert args[1][0].caption == submission1.link assert args[1][1].caption == submission2.link
def test_direct_no_match_groupchat(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id), chat_type=Chat.GROUP ) neaten = NeatenFunctionality(MockExportAPI()) for folder in ['gallery', 'scraps']: neaten.api.with_user_folder(username, folder, [ MockSubmission(post_id, image_id=image_id + 4), MockSubmission(post_id - 1, image_id=image_id - 15) ]) neaten.call(update, context) context.bot.send_photo.assert_not_called() context.bot.send_message.assert_called_with( chat_id=update.message.chat_id, text="⏳ Neatening image link", reply_to_message_id=update.message.message_id ) context.bot.delete_message.assert_called_with( update.message.chat_id, context._sent_message_ids[0] )
def test_search_with_spaces(context): search_term = "deer YCH" update = MockTelegramUpdate.with_inline_query(query=search_term) post_id1 = 213231 post_id2 = 84331 submission1 = MockSubmission(post_id1) submission2 = MockSubmission(post_id2) inline = InlineFunctionality(MockExportAPI()) inline.api.with_search_results(search_term, [submission1, submission2]) inline.call(update, context) context.bot.answer_inline_query.assert_called_once() args = context.bot.answer_inline_query.call_args[0] assert context.bot.answer_inline_query.call_args[1]['next_offset'] == 2 assert args[0] == update.inline_query.id assert isinstance(args[1], list) assert len(args[1]) == 2 for result in args[1]: assert isinstance(result, InlineQueryResultPhoto) assert args[1][0].id == str(post_id1) assert args[1][1].id == str(post_id2) assert args[1][0].photo_url == submission1.thumbnail_url assert args[1][1].photo_url == submission2.thumbnail_url assert args[1][0].thumb_url == FASubmission.make_thumbnail_smaller( submission1.thumbnail_url) assert args[1][1].thumb_url == FASubmission.make_thumbnail_smaller( submission2.thumbnail_url) assert args[1][0].caption == submission1.link assert args[1][1].caption == submission2.link
def test_submission_link_and_different_direct_link(context): username = "******" image_id1 = 1560331512 image_id2 = image_id1 + 300 post_id1 = 232347 post_id2 = 233447 update = MockTelegramUpdate.with_message( text="https://furaffinity.net/view/{2}/ http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format( username, image_id1, post_id2 ) ) submission1 = MockSubmission(post_id1, image_id=image_id1) submission2 = MockSubmission(post_id2, image_id=image_id2) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_user_folder(username, "gallery", [ submission2, submission1, MockSubmission(post_id1 - 1, image_id=image_id1 - 15) ]) neaten.call(update, context) context.bot.send_photo.assert_called() calls = [call( chat_id=update.message.chat_id, photo=submission.download_url, caption=submission.link, reply_to_message_id=update.message.message_id ) for submission in [submission2, submission1]] context.bot.send_photo.assert_has_calls(calls)
def test_result_missing_between_pages(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id) ) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_user_folder(username, "gallery", [ MockSubmission(post_id + 1, image_id=image_id + 16), MockSubmission(post_id, image_id=image_id + 3) ], page=1) neaten.api.with_user_folder(username, "gallery", [ MockSubmission(post_id - 2, image_id=image_id - 27), MockSubmission(post_id - 3, image_id=image_id - 34) ], page=2) neaten.call(update, context) context.bot.send_photo.assert_not_called() context.bot.send_message.assert_called_with( chat_id=update.message.chat_id, text="Could not locate the image by {} with image id {}.".format(username, image_id), reply_to_message_id=update.message.message_id )
def test_direct_in_progress_message(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id) ) goal_submission = MockSubmission(post_id, image_id=image_id) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_user_folder(username, "gallery", [ goal_submission, MockSubmission(post_id - 1, image_id=image_id - 15) ]) neaten.call(update, context) context.bot.send_message.assert_called_with( chat_id=update.message.chat_id, text="⏳ Neatening image link", reply_to_message_id=update.message.message_id ) context.bot.delete_message.assert_called_with( update.message.chat_id, context._sent_message_ids[0] )
def test_result_in_scraps(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id) ) submission = MockSubmission(post_id, image_id=image_id) neaten = NeatenFunctionality(MockExportAPI()) for page in [1, 2]: neaten.api.with_user_folder(username, "gallery", [ MockSubmission(post_id + 1 + (3 - page) * 5, image_id=image_id + 16 + (3 - page) * 56), MockSubmission(post_id + (3 - page) * 5, image_id=image_id + (3 - page) * 56), MockSubmission(post_id - 2 + (3 - page) * 5, image_id=image_id - 27 + (3 - page) * 56), MockSubmission(post_id - 3 + (3 - page) * 5, image_id=image_id - 34 + (3 - page) * 56) ], page=page) neaten.api.with_user_folder(username, "gallery", [], page=3) neaten.api.with_user_folder(username, "scraps", [ MockSubmission(post_id + 1, image_id=image_id + 16), submission, MockSubmission(post_id - 2, image_id=image_id - 27), MockSubmission(post_id - 3, image_id=image_id - 34) ], page=1) neaten.call(update, context) context.bot.send_photo.assert_called_once() assert context.bot.send_photo.call_args[1]['chat_id'] == update.message.chat_id assert context.bot.send_photo.call_args[1]['photo'] == submission.download_url assert context.bot.send_photo.call_args[1]['caption'] == submission.link assert context.bot.send_photo.call_args[1]['reply_to_message_id'] == update.message.message_id
def test_over_48_favs(context): username = "******" post_ids = list(range(123456, 123456 + 72)) submissions = [MockSubmission(x) for x in post_ids] inline = InlineFunctionality(MockExportAPI()) inline.api.with_user_favs(username, submissions) update = MockTelegramUpdate.with_inline_query(query=f"favs:{username}") inline.call(update, context) context.bot.answer_inline_query.assert_called_once() args = context.bot.answer_inline_query.call_args[0] assert context.bot.answer_inline_query.call_args[1][ 'next_offset'] == submissions[47].fav_id assert args[0] == update.inline_query.id assert isinstance(args[1], list) assert len(args[1]) == 48 assert isinstance(args[1][0], InlineQueryResultPhoto) assert isinstance(args[1][1], InlineQueryResultPhoto) for x in range(48): assert args[1][x].id == str(post_ids[x]) assert args[1][x].photo_url == submissions[x].thumbnail_url assert args[1][x].thumb_url == FASubmission.make_thumbnail_smaller( submissions[x].thumbnail_url) assert args[1][x].caption == submissions[x].link
def test_continue_from_fav_id(context): post_id = 234563 fav_id = "354233" username = "******" update = MockTelegramUpdate.with_inline_query(query=f"favs:{username}", offset=fav_id) submission = MockSubmission(post_id) inline = InlineFunctionality(MockExportAPI()) inline.api.with_user_favs(username, [submission], next_id=fav_id) inline.call(update, context) context.bot.answer_inline_query.assert_called_once() args = context.bot.answer_inline_query.call_args[0] assert context.bot.answer_inline_query.call_args[1][ 'next_offset'] == submission.fav_id assert args[0] == update.inline_query.id assert isinstance(args[1], list) assert len(args[1]) == 1 assert isinstance(args[1][0], InlineQueryResultPhoto) assert args[1][0].id == str(post_id) assert args[1][0].photo_url == submission.thumbnail_url assert args[1][0].thumb_url == FASubmission.make_thumbnail_smaller( submission.thumbnail_url) assert args[1][0].caption == submission.link
def test_get_new_results__returns_new_results(self, bot): api = MockExportAPI() api.with_browse_results([ MockSubmission("1223"), MockSubmission("1222"), MockSubmission("1220") ]) watcher = SubscriptionWatcher(api, bot) watcher.latest_ids.append("1220") watcher.running = True results = watcher._get_new_results() assert len(results) == 2 assert results[0].submission_id == "1222" assert results[1].submission_id == "1223"
def test_run__passes_correct_blocklists_to_subscriptions(self, bot): submission = MockSubmission("12322") api = MockExportAPI().with_submission(submission) watcher = SubscriptionWatcher(api, bot) method_called = MockMethod([submission]) watcher._get_new_results = method_called.call watcher.BACK_OFF = 1 watcher.blocklists = {156: {"test", "ych"}, -200: {"example"}} sub1 = MockSubscription("deer", 156) sub2 = MockSubscription("dog", -232) watcher.subscriptions = [sub1, sub2] thread = Thread(target=lambda: self.watcher_killer(watcher)) thread.start() # Run watcher watcher.run() thread.join() assert submission in sub1.submissions_checked assert len(sub1.blocklists) == 1 assert len(sub1.blocklists[0]) == 2 assert "test" in sub1.blocklists[0] assert "ych" in sub1.blocklists[0] assert submission in sub2.submissions_checked assert len(sub2.blocklists) == 1 assert len(sub2.blocklists[0]) == 0 assert method_called.called
def test_get_new_results__handles_empty_latest_ids(self, bot): api = MockExportAPI() api.with_browse_results([ MockSubmission("1223"), MockSubmission("1222"), MockSubmission("1220") ]) watcher = SubscriptionWatcher(api, bot) watcher.running = True results = watcher._get_new_results() assert len(results) == 0 assert len(watcher.latest_ids) == 3 assert watcher.latest_ids[0] == "1220" assert watcher.latest_ids[1] == "1222" assert watcher.latest_ids[2] == "1223"
def test_run__calls_update_latest_ids(self, bot): submission1 = MockSubmission("12322") submission2 = MockSubmission("12324") api = MockExportAPI().with_submissions([submission1, submission2]) watcher = SubscriptionWatcher(api, bot) mock_new_results = MockMethod([submission1, submission2]) watcher._get_new_results = mock_new_results.call mock_update_latest = MockMethod() watcher._update_latest_ids = mock_update_latest.call # Shorten the wait watcher.BACK_OFF = 1 thread = Thread(target=lambda: self.watcher_killer(watcher)) thread.start() # Run watcher watcher.run() thread.join() assert mock_update_latest.called assert mock_update_latest.args[0] == [submission2]
def test_run__checks_all_new_results(self, bot): submission1 = MockSubmission("12322") submission2 = MockSubmission("12324") api = MockExportAPI().with_submissions([submission1, submission2]) watcher = SubscriptionWatcher(api, bot) method_called = MockMethod([submission1, submission2]) watcher._get_new_results = method_called.call watcher.BACK_OFF = 1 sub = MockSubscription("deer", 0) watcher.subscriptions = [sub] thread = Thread(target=lambda: self.watcher_killer(watcher)) thread.start() # Run watcher watcher.run() thread.join() assert submission1 in sub.submissions_checked assert submission2 in sub.submissions_checked assert method_called.called
def test_update_latest_ids(self, bot): api = MockExportAPI() watcher = SubscriptionWatcher(api, bot) id_list = ["1234", "1233", "1230", "1229"] submissions = [MockSubmission(x) for x in id_list] mock_save_json = MockMethod() watcher.save_to_json = mock_save_json.call watcher._update_latest_ids(submissions) assert list(watcher.latest_ids) == id_list assert mock_save_json.called
def test_duplicate_direct_link(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png ".format(username, image_id) * 2 ) submission = MockSubmission(post_id, image_id=image_id) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_user_folder(username, "gallery", [ submission, MockSubmission(post_id - 1, image_id=image_id - 15) ]) neaten.call(update, context) context.bot.send_photo.assert_called_once() assert context.bot.send_photo.call_args[1]['chat_id'] == update.message.chat_id assert context.bot.send_photo.call_args[1]['photo'] == submission.download_url assert context.bot.send_photo.call_args[1]['caption'] == submission.link assert context.bot.send_photo.call_args[1]['reply_to_message_id'] == update.message.message_id
def test_user_favourites_last_page(context): # On the last page of favourites, if you specify "next", it repeats the same page, this simulates that. post_id1 = 234563 post_id2 = 393282 submission1 = MockSubmission(post_id1) submission2 = MockSubmission(post_id2) username = "******" update = MockTelegramUpdate.with_inline_query( query=f"favourites:{username}", offset=submission2.fav_id) inline = InlineFunctionality(MockExportAPI()) inline.api.with_user_favs(username, [submission1, submission2], next_id=submission2.fav_id) inline.call(update, context) context.bot.answer_inline_query.assert_called_once() args = context.bot.answer_inline_query.call_args[0] assert context.bot.answer_inline_query.call_args[1]['next_offset'] == "" assert args[0] == update.inline_query.id assert isinstance(args[1], list) assert len(args[1]) == 0
def test_get_new_results__goes_to_another_page(self, bot): api = MockExportAPI() api.with_browse_results([ MockSubmission("1227"), MockSubmission("1225"), MockSubmission("1224") ], page=1) api.with_browse_results([ MockSubmission("1223"), MockSubmission("1222"), MockSubmission("1220") ], page=2) watcher = SubscriptionWatcher(api, bot) watcher.latest_ids = collections.deque(maxlen=4) watcher.latest_ids.append("1220") watcher.running = True results = watcher._get_new_results() assert len(results) == 5 assert results[0].submission_id == "1222" assert results[1].submission_id == "1223" assert results[2].submission_id == "1224" assert results[3].submission_id == "1225" assert results[4].submission_id == "1227"
def test_result_first_on_page(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id) ) submission = MockSubmission(post_id, image_id=image_id) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_user_folder(username, "gallery", [ MockSubmission(post_id + 3, image_id=image_id + 16), MockSubmission(post_id + 2, image_id=image_id + 8) ], page=1) neaten.api.with_user_folder(username, "gallery", [ submission, MockSubmission(post_id - 2, image_id=image_id - 2), MockSubmission(post_id - 7, image_id=image_id - 4), MockSubmission(post_id - 9, image_id=image_id - 10) ], page=2) neaten.call(update, context) context.bot.send_photo.assert_called_once() assert context.bot.send_photo.call_args[1]['chat_id'] == update.message.chat_id assert context.bot.send_photo.call_args[1]['photo'] == submission.download_url assert context.bot.send_photo.call_args[1]['caption'] == submission.link assert context.bot.send_photo.call_args[1]['reply_to_message_id'] == update.message.message_id
def test_direct_link(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id) ) goal_submission = MockSubmission(post_id, image_id=image_id) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_user_folder(username, "gallery", [ goal_submission, MockSubmission(post_id - 1, image_id=image_id - 15) ]) neaten.call(update, context) context.bot.send_photo.assert_called_with( chat_id=update.message.chat_id, photo=goal_submission.download_url, caption=goal_submission.link, reply_to_message_id=update.message.message_id )
def test_two_submission_links(context): post_id1 = 23636984 post_id2 = 23636996 update = MockTelegramUpdate.with_message( text="furaffinity.net/view/{}\nfuraffinity.net/view/{}".format( post_id1, post_id2)) submission1 = MockSubmission(post_id1) submission2 = MockSubmission(post_id2) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submissions([submission1, submission2]) neaten.call(update, context) context.bot.send_photo.assert_called() calls = [ call(chat_id=update.message.chat_id, photo=submission.download_url, caption=submission.link, reply_to_message_id=update.message.message_id) for submission in [submission1, submission2] ] context.bot.send_photo.assert_has_calls(calls)
def test_direct_no_match(context): username = "******" image_id = 1560331512 post_id = 232347 update = MockTelegramUpdate.with_message( text="http://d.facdn.net/art/{0}/{1}/{1}.pic_of_me.png".format(username, image_id) ) neaten = NeatenFunctionality(MockExportAPI()) for folder in ['gallery', 'scraps']: neaten.api.with_user_folder(username, folder, [ MockSubmission(post_id, image_id=image_id + 4), MockSubmission(post_id - 1, image_id=image_id - 15) ]) neaten.call(update, context) context.bot.send_photo.assert_not_called() context.bot.send_message.assert_called() context.bot.send_message.assert_called_with( chat_id=update.message.chat_id, text="Could not locate the image by {} with image id {}.".format(username, image_id), reply_to_message_id=update.message.message_id )
def test_thumb_and_different_submission_link(context): post_id1 = 382632 post_id2 = 382672 update = MockTelegramUpdate.with_message( text= f"https://t.facdn.net/{post_id1}@1600-1562445328.jpg\nhttps://furaffinity.net/view/{post_id2}" ) submission1 = MockSubmission(post_id1) submission2 = MockSubmission(post_id2) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submissions([submission1, submission2]) neaten.call(update, context) context.bot.send_photo.assert_called() calls = [ call(chat_id=update.message.chat_id, photo=submission.download_url, caption=submission.link, reply_to_message_id=update.message.message_id) for submission in [submission1, submission2] ] context.bot.send_photo.assert_has_calls(calls)
def test_mp3_submission(context): post_id = 23636984 update = MockTelegramUpdate.with_message( text="https://www.furaffinity.net/view/{}/".format(post_id)) submission = MockSubmission(post_id, file_ext="mp3") neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submission(submission) neaten.call(update, context) context.bot.send_audio.assert_called_with( chat_id=update.message.chat_id, audio=submission.download_url, caption=submission.link, reply_to_message_id=update.message.message_id)
def test_txt_submission(context): post_id = 23636984 update = MockTelegramUpdate.with_message( text="https://www.furaffinity.net/view/{}/".format(post_id)) submission = MockSubmission(post_id, file_ext="txt") neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submission(submission) neaten.call(update, context) context.bot.send_photo.assert_called_with( chat_id=update.message.chat_id, photo=submission.full_image_url, caption= f"{submission.link}\n[Direct download]({submission.download_url})", reply_to_message_id=update.message.message_id, parse_mode=telegram.ParseMode.MARKDOWN)
def test_unknown_type_submission(context): post_id = 23636984 update = MockTelegramUpdate.with_message( text="https://www.furaffinity.net/view/{}/".format(post_id), chat_type=Chat.PRIVATE) submission = MockSubmission(post_id, file_ext="zzz") neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submission(submission) neaten.call(update, context) context.bot.send_photo.assert_not_called() context.bot.send_document.assert_not_called() context.bot.send_message.assert_called_with( chat_id=update.message.chat_id, text="I'm sorry, I don't understand that file extension (zzz).", reply_to_message_id=update.message.message_id)
def test_run__failed_to_send_doesnt_kill_watcher(self, bot): submission = MockSubmission("12322") api = MockExportAPI().with_browse_results([submission], 1) watcher = SubscriptionWatcher(api, bot) watcher._send_update = lambda *args: (_ for _ in ()).throw(Exception) watcher.BACK_OFF = 3 sub1 = MockSubscription("deer", 0) watcher.subscriptions = [sub1] api.call_after_x_browse = (lambda: watcher.stop(), 2) # Run watcher start_time = datetime.datetime.now() watcher.run() end_time = datetime.datetime.now() time_waited = end_time - start_time assert 3 <= time_waited.seconds <= 5
def build_mock_submission(self): sub = MockSubmission( self.submission_id, username=self.author.profile_name, image_id=self._image_id, file_size=14852 if self._download_file_size is None else self._download_file_size, file_ext=self._file_ext, fav_id=self.fav_id, title=self.title, author=self.author, description=self.description, keywords=self.keywords, thumbnail_url=self.thumbnail_url, download_url=self.download_url, full_image_url=self.full_image_url, ) return sub
def test_submission_link_no_http(context): post_id = 23636984 update = MockTelegramUpdate.with_message( text="furaffinity.net/view/{}".format(post_id)) submission = MockSubmission(post_id) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submission(submission) neaten.call(update, context) context.bot.send_photo.assert_called_once() assert context.bot.send_photo.call_args[1][ 'chat_id'] == update.message.chat_id assert context.bot.send_photo.call_args[1][ 'photo'] == submission.download_url assert context.bot.send_photo.call_args[1]['caption'] == submission.link assert context.bot.send_photo.call_args[1][ 'reply_to_message_id'] == update.message.message_id
def test_thumbnail_link(context): post_id = 382632 update = MockTelegramUpdate.with_message( text=f"https://t.facdn.net/{post_id}@400-1562445328.jpg") submission = MockSubmission(post_id) neaten = NeatenFunctionality(MockExportAPI()) neaten.api.with_submission(submission) neaten.call(update, context) context.bot.send_photo.assert_called_once() assert context.bot.send_photo.call_args[1][ 'chat_id'] == update.message.chat_id assert context.bot.send_photo.call_args[1][ 'photo'] == submission.download_url assert context.bot.send_photo.call_args[1]['caption'] == submission.link assert context.bot.send_photo.call_args[1][ 'reply_to_message_id'] == update.message.message_id