async def test_username_with_colon(requests_mock):
    # FA doesn't allow usernames to have : in them
    username = "******"
    event = MockTelegramEvent.with_inline_query(query=f"gallery:{username}")
    inline = InlineFunctionality(MockExportAPI())
    # mock export api doesn't do non-existent users, so mocking with requests
    inline.api = FAExportAPI("http://example.com", ignore_status=True)
    requests_mock.get(f"http://example.com/user/{username}/gallery.json",
                      status_code=404)

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] is None
    assert event.answer.call_args[1]['gallery'] is False
    assert isinstance(args[0], list)
    assert len(args[0]) == 1
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlineArticle)
    assert args[0][0].kwargs == {
        "title": "User does not exist.",
        "description":
        f"FurAffinity user does not exist by the name: \"{username}\".",
        "text":
        f"FurAffinity user does not exist by the name: \"{username}\".",
    }
async def test_no_username_set(requests_mock):
    username = ""
    event = MockTelegramEvent.with_inline_query(query=f"gallery:{username}")
    inline = InlineFunctionality(MockExportAPI())
    # mock export api doesn't do non-existent users, so mocking with requests
    inline.api = FAExportAPI("http://example.com", ignore_status=True)
    requests_mock.get(
        f"http://example.com/user/{username}/gallery.json?page=1&full=1",
        json={
            "id": None,
            "name": "gallery",
            "profile": "https://www.furaffinity.net/user/gallery/"
        })

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] is None
    assert event.answer.call_args[1]['gallery'] is False
    assert isinstance(args[0], list)
    assert len(args[0]) == 1
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlineArticle)
    assert args[0][0].kwargs == {
        "title": "User does not exist.",
        "description":
        f"FurAffinity user does not exist by the name: \"{username}\".",
        "text":
        f"FurAffinity user does not exist by the name: \"{username}\".",
    }
async def test_second_page(mock_client):
    post_id = 234563
    username = "******"
    event = MockTelegramEvent.with_inline_query(query=f"scraps:{username}",
                                                offset="2")
    submission = MockSubmission(post_id)
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_user_folder(username, "scraps", [submission], page=2)

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == "3"
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 1
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlinePhoto)
    assert args[0][0].kwargs['file'] == submission.thumbnail_url
    assert args[0][0].kwargs['id'] == str(post_id)
    assert args[0][0].kwargs['text'] == submission.link
    assert len(args[0][0].kwargs['buttons']) == 1
    assert args[0][0].kwargs['buttons'][
        0].data == f"neaten_me:{submission.submission_id}".encode()
async def test_over_max_submissions_continue_end(mock_client):
    username = "******"
    posts = 72
    post_ids = list(range(123456, 123456 + posts))
    submissions = [MockSubmission(x) for x in post_ids]
    mock_api = MockExportAPI()
    mock_api.with_user_folder(username, "gallery", submissions)
    inline = InlineFunctionality(mock_api)
    skip = posts - inline.INLINE_MAX + 3
    event = MockTelegramEvent.with_inline_query(query=f"gallery:{username}",
                                                offset=f"1:{skip}")

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == "2"
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == inline.INLINE_MAX - 3
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlinePhoto)
    assert isinstance(args[0][1], _MockInlineBuilder._MockInlinePhoto)
    for x in range(inline.INLINE_MAX - 3):
        assert args[0][x].kwargs['file'] == submissions[x + skip].thumbnail_url
        assert args[0][x].kwargs['id'] == str(post_ids[x + skip])
        assert args[0][x].kwargs['text'] == submissions[x + skip].link
        assert len(args[0][x].kwargs['buttons']) == 1
        assert args[0][x].kwargs['buttons'][
            0].data == f"neaten_me:{submissions[x + skip].submission_id}".encode(
            )
async def test_search_with_offset(mock_client):
    post_id = 234563
    search_term = "YCH"
    offset = 2
    event = MockTelegramEvent.with_inline_query(query=search_term,
                                                offset=offset)
    submission = MockSubmission(post_id)
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_search_results(search_term, [submission], page=offset)

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert isinstance(args[0], list)
    assert len(args[0]) > 0
    for result in args[0]:
        assert isinstance(result, _MockInlineBuilder._MockInlinePhoto)
        assert result.kwargs['file'] == submission.thumbnail_url
        assert result.kwargs['id'] == str(post_id)
        assert result.kwargs['text'] == submission.link
        assert len(result.kwargs['buttons']) == 1
        assert result.kwargs['buttons'][
            0].data == f"neaten_me:{post_id}".encode()
async def test_get_user_gallery(mock_client):
    post_id1 = 234563
    post_id2 = 393282
    username = "******"
    event = MockTelegramEvent.with_inline_query(query=f"gallery:{username}")
    submission1 = MockSubmission(post_id1)
    submission2 = MockSubmission(post_id2)
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_user_folder(username, "gallery",
                                [submission1, submission2])

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == "2"
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 2
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlinePhoto)
    assert isinstance(args[0][1], _MockInlineBuilder._MockInlinePhoto)
    assert args[0][0].kwargs['file'] == submission1.thumbnail_url
    assert args[0][0].kwargs['id'] == str(post_id1)
    assert args[0][0].kwargs['text'] == submission1.link
    assert len(args[0][0].kwargs['buttons']) == 1
    assert args[0][0].kwargs['buttons'][
        0].data == f"neaten_me:{submission1.submission_id}".encode()
    assert args[0][1].kwargs['file'] == submission2.thumbnail_url
    assert args[0][1].kwargs['id'] == str(post_id2)
    assert args[0][1].kwargs['text'] == submission2.link
    assert len(args[0][1].kwargs['buttons']) == 1
    assert args[0][1].kwargs['buttons'][
        0].data == f"neaten_me:{submission2.submission_id}".encode()
async def test_search_with_spaces(mock_client):
    search_term = "deer YCH"
    event = MockTelegramEvent.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])

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == "2"
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 2
    for result in args[0]:
        assert isinstance(result, _MockInlineBuilder._MockInlinePhoto)
    assert args[0][0].kwargs['file'] == submission1.thumbnail_url
    assert args[0][0].kwargs['id'] == str(post_id1)
    assert args[0][0].kwargs['text'] == submission1.link
    assert len(args[0][0].kwargs['buttons']) == 1
    assert args[0][0].kwargs['buttons'][
        0].data == f"neaten_me:{submission1.submission_id}".encode()
    assert args[0][1].kwargs['file'] == submission2.thumbnail_url
    assert args[0][1].kwargs['id'] == str(post_id2)
    assert args[0][1].kwargs['text'] == submission2.link
    assert len(args[0][1].kwargs['buttons']) == 1
    assert args[0][1].kwargs['buttons'][
        0].data == f"neaten_me:{submission2.submission_id}".encode()
async def test_over_max_favs(mock_client):
    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)
    event = MockTelegramEvent.with_inline_query(query=f"favs:{username}")

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == submissions[
        inline.INLINE_MAX - 1].fav_id
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == inline.INLINE_MAX
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlinePhoto)
    assert isinstance(args[0][1], _MockInlineBuilder._MockInlinePhoto)
    for x in range(inline.INLINE_MAX):
        assert args[0][x].kwargs['file'] == submissions[x].thumbnail_url
        assert args[0][x].kwargs['id'] == str(post_ids[x])
        assert args[0][x].kwargs['text'] == submissions[x].link
        assert len(args[0][x].kwargs['buttons']) == 1
        assert args[0][x].kwargs['buttons'][
            0].data == f"neaten_me:{submissions[x].submission_id}".encode()
async def test_empty_query_no_results(mock_client):
    event = MockTelegramEvent.with_inline_query(query="")
    inline = InlineFunctionality(MockExportAPI())

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_with([])
示例#10
0
 def initialise_functionalities(self):
     return [
         BeepFunctionality(),
         WelcomeFunctionality(),
         ImageHashRecommendFunctionality(),
         NeatenFunctionality(self.api),
         InlineNeatenFunctionality(self.api),
         InlineFunctionality(self.api),
         InlineEditFunctionality(self.api, self.client),
         InlineEditButtonPress(self.api),
         SubscriptionFunctionality(self.subscription_watcher),
         BlocklistFunctionality(self.subscription_watcher),
         SupergroupUpgradeFunctionality(self.subscription_watcher),
         UnhandledMessageFunctionality(),
     ]
async def test_search_with_offset_no_more_results(mock_client):
    search_term = "YCH"
    offset = 2
    event = MockTelegramEvent.with_inline_query(query=search_term,
                                                offset=offset)
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_search_results(search_term, [], page=offset)

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] is None
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 0
async def test_over_max_submissions_continue_over_page(mock_client):
    username = "******"
    posts = 72
    post_ids = list(range(123456, 123456 + posts))
    skip = posts + 5
    submissions = [MockSubmission(x) for x in post_ids]
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_user_folder(username, "gallery", submissions)
    event = MockTelegramEvent.with_inline_query(query=f"gallery:{username}",
                                                offset=f"1:{skip}")

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == "2"
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 0
async def test_no_search_results(mock_client):
    search_term = "RareKeyword"
    event = MockTelegramEvent.with_inline_query(query=search_term)
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_search_results(search_term, [])

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] is None
    assert event.answer.call_args[1]['gallery'] is False
    assert isinstance(args[0], list)
    assert len(args[0]) == 1
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlineArticle)
    assert args[0][0].kwargs == {
        "title": "No results found.",
        "description": f"No results for search \"{search_term}\".",
        "text": f"No results for search \"{search_term}\".",
    }
async def test_empty_favs(mock_client):
    username = "******"
    event = MockTelegramEvent.with_inline_query(query=f"favs:{username}")
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_user_favs(username, [])

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] is None
    assert event.answer.call_args[1]['gallery'] is False
    assert isinstance(args[0], list)
    assert len(args[0]) == 1
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlineArticle)
    assert args[0][0].kwargs == {
        "title": "Nothing in favourites.",
        "description": f"There are no favourites for user \"{username}\".",
        "text": f"There are no favourites for user \"{username}\".",
    }
async def test_user_favourites_last_page(mock_client):
    # 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 = "******"
    event = MockTelegramEvent.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)

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] is None
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 0
async def test_search_with_combo_characters(mock_client):
    search_term = "(deer & !ych) | (dragon & !ych)"
    event = MockTelegramEvent.with_inline_query(query=search_term)
    post_id = 213231
    submission = MockSubmission(post_id)
    inline = InlineFunctionality(MockExportAPI())
    inline.api.with_search_results(search_term, [submission])

    with pytest.raises(StopPropagation):
        await inline.call(event)

    event.answer.assert_called_once()
    args = event.answer.call_args[0]
    assert event.answer.call_args[1]['next_offset'] == "2"
    assert event.answer.call_args[1]['gallery'] is True
    assert isinstance(args[0], list)
    assert len(args[0]) == 1
    assert isinstance(args[0][0], _MockInlineBuilder._MockInlinePhoto)
    assert args[0][0].kwargs['file'] == submission.thumbnail_url
    assert args[0][0].kwargs['id'] == str(post_id)
    assert args[0][0].kwargs['text'] == submission.link
    assert len(args[0][0].kwargs['buttons']) == 1
    assert args[0][0].kwargs['buttons'][
        0].data == f"neaten_me:{submission.submission_id}".encode()