Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Fix background tasks blocking UI #797

Merged
Prev Previous commit
Next Next commit
Add tests
RisingOrange committed Nov 9, 2023
commit c32218c155c090a63b038c29c6b502c8696fb36a
111 changes: 110 additions & 1 deletion tests/addon/test_unit.py
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@
# has to be set before importing ankihub
os.environ["SKIP_INIT"] = "1"

from ankihub.addon_ankihub_client import AddonAnkiHubClient
from ankihub.ankihub_client import (
AnkiHubClient,
AnkiHubHTTPError,
@@ -59,7 +60,9 @@
_contains_path_to_this_addon,
_normalize_url,
_try_handle_exception,
upload_logs_in_background,
)
from ankihub.gui.media_sync import media_sync
from ankihub.gui.menu import AnkiHubLogin
from ankihub.gui.operations import deck_creation
from ankihub.gui.operations.deck_creation import (
@@ -107,7 +110,7 @@
mids_of_notes,
retain_nids_with_ah_note_type,
)
from ankihub.settings import ANKIWEB_ID
from ankihub.settings import ANKIWEB_ID, log_file_path


@pytest.fixture
@@ -161,6 +164,56 @@ def test_update_media_names_on_notes(
assert '<img src="will_not_replace.jpeg">' in " ".join(notes[2].fields)


class TestMediaSyncMediaDownload:
def test_with_exception(self, mock_function: MockFunction, qtbot: QtBot):
def raise_exception() -> None:
raise Exception("test")

update_and_download_mock = mock_function(
media_sync,
"_update_deck_media_and_download_missing_media",
side_effect=raise_exception,
)

with qtbot.captureExceptions() as exceptions:
media_sync.start_media_download()
qtbot.wait(500)

# Assert that _download_in_progress was set to False and the exception was raised
assert not media_sync._download_in_progress
assert len(exceptions) == 1
update_and_download_mock.assert_called_once() # sanity check


class TestMediaSyncMediaUpload:
def test_with_exception(
self,
anki_session_with_addon_data: AnkiSession,
mock_function: MockFunction,
qtbot: QtBot,
next_deterministic_uuid,
):
with anki_session_with_addon_data.profile_loaded():

def raise_exception() -> None:
raise Exception("test")

upload_media_mock = mock_function(
media_sync._client,
"upload_media",
side_effect=raise_exception,
)

with qtbot.captureExceptions() as exceptions:
media_sync.start_media_upload([], next_deterministic_uuid())
qtbot.wait(500)

# Assert that _amount_uploads_in_progress was was reset to 0 and the exception was raised
assert media_sync._amount_uploads_in_progress == 0
assert len(exceptions) == 1
upload_media_mock.assert_called_once() # sanity check


def test_lowest_level_common_ancestor_deck_name():

deck_names = [
@@ -1433,6 +1486,62 @@ def _mock_ask_user_to_return_false(
importlib.reload(errors)


class TestUploadLogs:
def test_basic(
self,
qtbot: QtBot,
mock_function: MockFunction,
):
on_done_mock = Mock()
upload_logs_mock = mock_function(AddonAnkiHubClient, "upload_logs")
upload_logs_in_background(on_done=on_done_mock)

qtbot.wait_until(lambda: on_done_mock.called)

upload_logs_mock.assert_called_once()
assert upload_logs_mock.call_args[1]["file"] == log_file_path()

@pytest.mark.parametrize(
"exception, expected_report_exception_called",
[
# The exception should not be reported for these two specific cases
(AnkiHubHTTPError(response=Mock(status_code=401)), False),
(
AnkiHubHTTPError(
response=Mock(status_code=406, reason=OUTDATED_CLIENT_ERROR_REASON)
),
False,
),
# The exception should be reported in all other cases
(AnkiHubHTTPError(response=Mock(status_code=500)), True),
(Exception("test"), True),
],
)
def test_with_exception(
self,
qtbot: QtBot,
mock_function: MockFunction,
exception: Exception,
expected_report_exception_called: bool,
):
def raise_exception(*args, **kwargs) -> None:
raise exception

on_done_mock = Mock()
upload_logs_mock = mock_function(
AddonAnkiHubClient, "upload_logs", side_effect=raise_exception
)
report_exception_mock = mock_function(errors, "_report_exception")
upload_logs_in_background(on_done=on_done_mock)

qtbot.wait(500)

upload_logs_mock.assert_called_once()
on_done_mock.assert_not_called()

assert report_exception_mock.called == expected_report_exception_called


class TestRateLimitedDecorator:
def test_rate_limited_decorator(self):
# Create a counter to keep track of how many times foo is executed