Add Codeberg releases source
This commit is contained in:
@@ -120,6 +120,19 @@ def gitlab_entry() -> sideload.AppEntry:
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def codeberg_entry() -> sideload.AppEntry:
|
||||
return sideload.AppEntry(
|
||||
name="CoMaps",
|
||||
source="codeberg",
|
||||
app_id="app.comaps",
|
||||
config={
|
||||
"url": "https://codeberg.org/comaps/comaps",
|
||||
"asset_pattern": r"^CoMaps-.*-main-release\.apk$",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config(tmp_config: Path) -> sideload.Config:
|
||||
return sideload.Config.from_file(tmp_config)
|
||||
@@ -428,6 +441,91 @@ class TestGitHubSource:
|
||||
assert result.read_bytes() == apk_data
|
||||
|
||||
|
||||
# ── CodebergSource tests ──────────────────────────────────────────────────────
|
||||
|
||||
|
||||
class TestCodebergSource:
|
||||
CODEBERG_RELEASE = {
|
||||
"tag_name": "v2026.08.0",
|
||||
"assets": [
|
||||
{
|
||||
"name": "CoMaps-2026.08.0-main-release.apk",
|
||||
"browser_download_url": "https://codeberg.org/comaps/comaps/releases/download/v2026.08.0/CoMaps-2026.08.0-main-release.apk",
|
||||
"size": 12345678,
|
||||
},
|
||||
{
|
||||
"name": "CoMaps-2026.08.0-debug.apk",
|
||||
"browser_download_url": "https://codeberg.org/comaps/comaps/releases/download/v2026.08.0/CoMaps-2026.08.0-debug.apk",
|
||||
},
|
||||
{
|
||||
"name": "CoMaps-2026.08.0-test.apk",
|
||||
"browser_download_url": "https://codeberg.org/comaps/comaps/releases/download/v2026.08.0/CoMaps-2026.08.0-test.apk",
|
||||
},
|
||||
{
|
||||
"name": "CoMaps-2026.08.0-unsigned.apk",
|
||||
"browser_download_url": "https://codeberg.org/comaps/comaps/releases/download/v2026.08.0/CoMaps-2026.08.0-unsigned.apk",
|
||||
},
|
||||
{
|
||||
"name": "Source code (zip)",
|
||||
"browser_download_url": "https://codeberg.org/comaps/comaps/archive/v2026.08.0.zip",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
def test_get_latest_release(self, codeberg_entry: sideload.AppEntry):
|
||||
source = sideload.CodebergSource(codeberg_entry)
|
||||
with mock.patch("sideload._http_get", return_value=json.dumps(self.CODEBERG_RELEASE).encode()) as http_get:
|
||||
release = source.get_latest_release()
|
||||
http_get.assert_called_once_with(
|
||||
"https://codeberg.org/api/v1/repos/comaps/comaps/releases/latest"
|
||||
)
|
||||
assert release.version == "2026.08.0"
|
||||
assert release.download_url.endswith("CoMaps-2026.08.0-main-release.apk")
|
||||
assert release.file_size == 12345678
|
||||
|
||||
def test_get_latest_release_ambiguous_assets(self, codeberg_entry: sideload.AppEntry):
|
||||
source = sideload.CodebergSource(codeberg_entry)
|
||||
release = {
|
||||
"tag_name": "v1.0",
|
||||
"assets": [
|
||||
{"name": "CoMaps-one-main-release.apk", "browser_download_url": "https://example.com/one.apk"},
|
||||
{"name": "CoMaps-two-main-release.apk", "browser_download_url": "https://example.com/two.apk"},
|
||||
],
|
||||
}
|
||||
with mock.patch("sideload._http_get", return_value=json.dumps(release).encode()):
|
||||
with pytest.raises(ValueError, match="multiple APK assets match"):
|
||||
source.get_latest_release()
|
||||
|
||||
def test_get_latest_release_no_apk(self, codeberg_entry: sideload.AppEntry):
|
||||
source = sideload.CodebergSource(codeberg_entry)
|
||||
release = {"tag_name": "v1.0", "assets": [{"name": "Source code (tar.gz)"}]}
|
||||
with mock.patch("sideload._http_get", return_value=json.dumps(release).encode()):
|
||||
with pytest.raises(ValueError, match="no APK asset"):
|
||||
source.get_latest_release()
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"url",
|
||||
[
|
||||
"http://codeberg.org/comaps/comaps",
|
||||
"https://example.com/comaps/comaps",
|
||||
"https://codeberg.org/comaps",
|
||||
"https://codeberg.org/comaps/comaps/releases",
|
||||
],
|
||||
)
|
||||
def test_invalid_url_raises(self, url: str):
|
||||
entry = sideload.AppEntry(
|
||||
name="CoMaps", source="codeberg", app_id="app.comaps", config={"url": url}
|
||||
)
|
||||
with pytest.raises(ValueError, match="HTTPS Codeberg repository URL"):
|
||||
sideload.CodebergSource(entry)
|
||||
|
||||
def test_get_latest_release_network_error(self, codeberg_entry: sideload.AppEntry):
|
||||
source = sideload.CodebergSource(codeberg_entry)
|
||||
with mock.patch("sideload._http_get", side_effect=RuntimeError("network down")):
|
||||
with pytest.raises(RuntimeError, match="network down"):
|
||||
source.get_latest_release()
|
||||
|
||||
|
||||
# ── GitLabSource tests ────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -645,6 +743,10 @@ class TestMakeSource:
|
||||
s = sideload._make_source(gitlab_entry)
|
||||
assert isinstance(s, sideload.GitLabSource)
|
||||
|
||||
def test_codeberg(self, codeberg_entry: sideload.AppEntry):
|
||||
s = sideload._make_source(codeberg_entry)
|
||||
assert isinstance(s, sideload.CodebergSource)
|
||||
|
||||
def test_unknown_source_raises(self):
|
||||
entry = sideload.AppEntry(name="X", source="unknown", app_id="x", config={})
|
||||
with pytest.raises(ValueError, match="unknown source type"):
|
||||
|
||||
Reference in New Issue
Block a user