diff --git a/app_src/tests/test_download_apk_screen.py b/app_src/tests/test_download_apk_screen.py index 24f13e1..3e86b3a 100644 --- a/app_src/tests/test_download_apk_screen.py +++ b/app_src/tests/test_download_apk_screen.py @@ -46,6 +46,12 @@ def test_apk_is_valid_rejects_wrong_size(tmp_path): class _FakeResponse: def __init__(self, content): + """ + Initialize a response with content and its byte length. + + Parameters: + content: The response content. + """ self.content = content self.headers = {"content-length": str(len(content))} @@ -53,11 +59,22 @@ def raise_for_status(self): return None def iter_content(self, _): + """Yield the response content as a single chunk.""" yield self.content @pytest.fixture def fake_download_dir(tmp_path, monkeypatch): + """ + Configure APK downloads to use a temporary directory. + + Parameters: + tmp_path: Temporary directory used as the APK download location. + monkeypatch: Fixture used to replace the APK directory resolver. + + Returns: + The configured temporary directory. + """ monkeypatch.setattr(d, "get_apk_directory", lambda: str(tmp_path)) return tmp_path @@ -106,6 +123,7 @@ def unbind(self, *_, **__): class _FakeUpdateButton: def __init__(self): + """Initialize the fake button with an unclicked state and a fake streak.""" self.clicked = False self.streak = _FakeStreak() @@ -118,6 +136,7 @@ class _FakeLaterButton: def _instantiate_screen(): + """Create a download screen with mocked application dependencies for testing.""" from kivy.event import EventDispatcher from kivy.properties import StringProperty from kivymd.app import MDApp @@ -148,9 +167,17 @@ def test_start_download_uses_versioned_url_and_filename(): class _FakeThread: def __init__(self, target=None, daemon=None): + """ + Capture the callable provided as the thread target. + + Parameters: + target (callable, optional): Callable assigned as the thread target. + daemon (bool, optional): Thread daemon setting. + """ captured["target"] = target def start(self): + """Run the captured target function.""" captured["target"]() with mock.patch("threading.Thread", _FakeThread), \ diff --git a/app_src/ui/screens/download_apk_screen.py b/app_src/ui/screens/download_apk_screen.py index 0f8ddd0..b263f9a 100644 --- a/app_src/ui/screens/download_apk_screen.py +++ b/app_src/ui/screens/download_apk_screen.py @@ -376,7 +376,12 @@ def add_body_to_new_stuff_container(self, markup_text): def start_download(self,_=None): #p("Clicked start download...") - if not self.built_ui: + """ + Start downloading the update APK or switch to installation when a valid cached APK is available. + + The download runs in a background thread and updates the progress button as data arrives. + """ + if not self.built_ui: return import threading @@ -390,6 +395,9 @@ def progress(percent): self.clock_for_progress_update.cancel() self.clock_for_progress_update = Clock.schedule_once(lambda dt: self.update_button.update_progress(percent)) def worker(): + """ + Download the selected release APK and switch the download control to installation mode when successful. + """ filename = get_apk_filename(self.new_version) apk_path__ = download_apk( get_apk_download_url(self.new_version), @@ -526,7 +534,16 @@ def do_not_go_to_update_screen(msg): Clock.schedule_once(lambda dt, e=e: do_not_go_to_update_screen(f"Failed:{e}")) def get_release_note_txt(data,latest_version): - """Check GitHub latest release version""" + """ + Retrieve release notes for a specific version from the release assets. + + Parameters: + data (dict): GitHub release metadata containing an ``assets`` collection. + latest_version (str): Version used to identify the release-notes asset. + + Returns: + str: Downloaded release notes, or default release notes when the asset is unavailable or cannot be downloaded. + """ import time import traceback import requests @@ -557,13 +574,40 @@ def get_release_note_txt(data,latest_version): return release_notes or DEFAULT_RELEASE_NOTE def get_apk_filename(version): + """ + Build the filename for a versioned APK. + + Parameters: + version: The APK version identifier. + + Returns: + str: The versioned APK filename. + """ return f"waller-v{version}.apk" def get_apk_download_url(version): + """ + Build the GitHub release URL for a versioned APK. + + Parameters: + version: The APK release version. + + Returns: + str: The download URL for the versioned APK. + """ filename = get_apk_filename(version) return f"https://github.com/Fector101/wallpaper-carousel/releases/download/v{version}/{filename}" def get_apk_size(data): + """ + Finds the size of the first APK asset in release metadata. + + Parameters: + data (dict): Release metadata containing an `assets` collection. + + Returns: + int: The APK file size in bytes, or `0` if no APK asset is found. + """ for asset in data["assets"]: if asset["name"].endswith(".apk"): size = asset["size"]