Use Android build tools for APK validation
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""Unit tests for sideload module — no network, ADB, or apkanalyzer required."""
|
||||
"""Unit tests for sideload module — no network, ADB, or Android SDK required."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -243,14 +243,14 @@ class TestFdroidSource:
|
||||
"org.example.test": {
|
||||
"12345": {
|
||||
"file": {
|
||||
"name": "/repo/org.example.test_12345.apk",
|
||||
"name": "/org.example.test_12345.apk",
|
||||
"sha256": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
|
||||
"size": 1234567,
|
||||
}
|
||||
},
|
||||
"12344": {
|
||||
"file": {
|
||||
"name": "/repo/org.example.test_12344.apk",
|
||||
"name": "/org.example.test_12344.apk",
|
||||
"sha256": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
}
|
||||
},
|
||||
@@ -310,6 +310,29 @@ class TestFdroidSource:
|
||||
assert release.version == "12345"
|
||||
assert release.download_url.endswith("/repo/org.example.test_12345.apk")
|
||||
|
||||
def test_get_latest_release_uses_manifest_version_code(self, app_entry: sideload.AppEntry):
|
||||
index = {
|
||||
"packages": {
|
||||
"org.example.test": {
|
||||
"versions": {
|
||||
"sha256-of-version": {
|
||||
"file": {"name": "/org.example.test_36.apk", "sha256": "a" * 64},
|
||||
"manifest": {"versionCode": 36, "versionName": "5.1.1"},
|
||||
},
|
||||
"older-version": {
|
||||
"file": {"name": "/org.example.test_34.apk", "sha256": "b" * 64},
|
||||
"manifest": {"versionCode": 34, "versionName": "5.0.0"},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
source = sideload.FdroidSource(app_entry)
|
||||
with mock.patch("sideload._http_get", return_value=json.dumps(index).encode()):
|
||||
release = source.get_latest_release()
|
||||
assert release.version == "5.1.1"
|
||||
assert release.download_url.endswith("/org.example.test_36.apk")
|
||||
|
||||
def test_missing_repo_url_raises(self):
|
||||
entry = sideload.AppEntry(name="X", source="fdroid", app_id="x", config={})
|
||||
with pytest.raises(ValueError, match="repo_url is required"):
|
||||
@@ -471,7 +494,7 @@ class TestGitLabSource:
|
||||
|
||||
class TestApkValidator:
|
||||
def test_validate_success(self, apk_file: Path):
|
||||
validator = sideload.ApkValidator(apkanalyzer_bin="fake-apkanalyzer")
|
||||
validator = sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt")
|
||||
with mock.patch(
|
||||
"sideload._run",
|
||||
return_value=subprocess.CompletedProcess(
|
||||
@@ -482,7 +505,7 @@ class TestApkValidator:
|
||||
assert err is None
|
||||
|
||||
def test_validate_mismatch(self, apk_file: Path):
|
||||
validator = sideload.ApkValidator(apkanalyzer_bin="fake-apkanalyzer")
|
||||
validator = sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt")
|
||||
with mock.patch(
|
||||
"sideload._run",
|
||||
return_value=subprocess.CompletedProcess(
|
||||
@@ -493,12 +516,12 @@ class TestApkValidator:
|
||||
assert err is not None
|
||||
assert "mismatch" in err
|
||||
|
||||
def test_validate_apkanalyzer_fails(self, apk_file: Path):
|
||||
validator = sideload.ApkValidator(apkanalyzer_bin="fake-apkanalyzer")
|
||||
def test_validate_aapt_fails(self, apk_file: Path):
|
||||
validator = sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt")
|
||||
with mock.patch(
|
||||
"sideload._run",
|
||||
return_value=subprocess.CompletedProcess(
|
||||
args=[], returncode=1, stdout="", stderr="command not found"
|
||||
args=[], returncode=1, stdout="", stderr="invalid APK"
|
||||
),
|
||||
):
|
||||
err = validator.validate(apk_file, "org.example.test")
|
||||
@@ -662,7 +685,7 @@ class TestSideload:
|
||||
with mock.patch("sideload._run", side_effect=mock_run):
|
||||
result = sideload.sideload(
|
||||
app_entry, config, dry_run=True,
|
||||
validator=sideload.ApkValidator(apkanalyzer_bin="fake"),
|
||||
validator=sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt"),
|
||||
)
|
||||
assert result == 0
|
||||
|
||||
@@ -700,7 +723,7 @@ class TestSideload:
|
||||
with mock.patch("sideload._run", side_effect=mock_run):
|
||||
result = sideload.sideload(
|
||||
app_entry, config, dry_run=True,
|
||||
validator=sideload.ApkValidator(apkanalyzer_bin="fake"),
|
||||
validator=sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt"),
|
||||
)
|
||||
assert result == 1
|
||||
|
||||
@@ -744,7 +767,7 @@ class TestSideload:
|
||||
with mock.patch("sideload._run", side_effect=mock_run):
|
||||
result = sideload.sideload(
|
||||
app_entry, config,
|
||||
validator=sideload.ApkValidator(apkanalyzer_bin="fake"),
|
||||
validator=sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt"),
|
||||
adb_manager=sideload.AdbManager(binary="fake-adb"),
|
||||
)
|
||||
assert result == 1
|
||||
@@ -790,7 +813,7 @@ class TestSideload:
|
||||
result = sideload.sideload(
|
||||
app_entry, config,
|
||||
device_serial="NONEXISTENT",
|
||||
validator=sideload.ApkValidator(apkanalyzer_bin="fake"),
|
||||
validator=sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt"),
|
||||
adb_manager=sideload.AdbManager(binary="fake-adb"),
|
||||
)
|
||||
assert result == 1
|
||||
@@ -843,7 +866,7 @@ class TestSideload:
|
||||
result = sideload.sideload(
|
||||
app_entry, config,
|
||||
device_serial="ABCD1234",
|
||||
validator=sideload.ApkValidator(apkanalyzer_bin="fake"),
|
||||
validator=sideload.ApkValidator(aapt2_bin="fake-aapt2", aapt_bin="fake-aapt"),
|
||||
adb_manager=sideload.AdbManager(binary="fake-adb"),
|
||||
)
|
||||
assert result == 0
|
||||
|
||||
Reference in New Issue
Block a user