Files
tinyproject-monorepo/prg/sjaur/tests/test_metadata.py
T
2026-10-02 15:29:35 +02:00

114 lines
3.4 KiB
Python

"""Tests for metadata parsing (tolerant of real-world dump quirks)."""
from __future__ import annotations
import pytest
from sjaur.errors import CacheCorruptError
from sjaur.metadata import format_timestamp, parse_packages
def test_parse_minimal_entry():
packages, skipped = parse_packages([{"Name": "firefox"}])
assert skipped == 0
(package,) = packages
assert package.name == "firefox"
assert package.version == ""
assert package.description == ""
assert package.maintainer == ""
assert package.votes == 0
assert package.popularity == 0.0
assert package.out_of_date is None
assert package.is_orphan
assert package.aur_url == "https://aur.archlinux.org/packages/firefox"
def test_parse_full_entry():
entry = {
"Name": "cower",
"PackageBase": "cower",
"Version": "14-2",
"Description": "A simple AUR agent",
"URL": "http://example.com",
"NumVotes": 590,
"Popularity": 24.59,
"OutOfDate": None,
"Maintainer": "falconindy",
"FirstSubmitted": 1293676237,
"LastModified": 1441804093,
"Depends": ["curl", "openssl"],
"MakeDepends": ["perl"],
"Keywords": ["aur"],
"License": ["MIT"],
}
packages, skipped = parse_packages([entry])
assert skipped == 0
(package,) = packages
assert package.name == "cower"
assert package.version == "14-2"
assert package.votes == 590
assert package.popularity == 24.59
assert package.out_of_date is None
assert package.maintainer == "falconindy"
assert package.depends == ("curl", "openssl")
assert package.make_depends == ("perl",)
assert package.keywords == ("aur",)
assert package.licenses == ("MIT",)
assert not package.is_orphan
def test_out_of_date_timestamp_is_kept():
packages, _ = parse_packages([{"Name": "x", "OutOfDate": 1720000000}])
assert packages[0].out_of_date == 1720000000
def test_missing_fields_are_omitted_by_server():
# The dump omits fields a package does not have; lists must be empty, not None.
packages, _ = parse_packages([{"Name": "x", "Depends": None, "Keywords": []}])
assert packages[0].depends == ()
assert packages[0].keywords == ()
def test_malformed_entries_are_skipped_and_counted():
packages, skipped = parse_packages(
[
{"Name": "ok"},
"not a dict",
42,
{"Version": "1.0"}, # no Name
{"Name": " "}, # blank Name
None,
]
)
assert [p.name for p in packages] == ["ok"]
assert skipped == 5
def test_non_list_payload_is_rejected():
with pytest.raises(CacheCorruptError):
parse_packages({"Name": "firefox"})
def test_type_mismatches_do_not_crash():
entry = {
"Name": "weird",
"Version": 123,
"NumVotes": "many",
"Popularity": None,
"Depends": "python", # wrong container type
"Keywords": [1, None, "ok"],
}
packages, _ = parse_packages([entry])
package = packages[0]
assert package.version == ""
assert package.votes == 0
assert package.popularity == 0.0
assert package.depends == ()
assert package.keywords == ("ok",)
def test_format_timestamp():
assert format_timestamp(None) == "unknown"
assert format_timestamp(0) == "unknown"
assert format_timestamp(1441804093) == "2015-09-09 13:08 UTC"