def test_mkpkglists_extended_empty(config_mock: None): from aurweb.scripts import mkpkglists mkpkglists.main() PACKAGES = config.get("mkpkglists", "packagesfile") META = config.get("mkpkglists", "packagesmetafile") META_EXT = config.get("mkpkglists", "packagesmetaextfile") PKGBASE = config.get("mkpkglists", "pkgbasefile") USERS = config.get("mkpkglists", "userfile") expectations = [ (PACKAGES, ""), (PKGBASE, ""), (USERS, ""), (META, "[\n]"), (META_EXT, "[\n]"), ] for (file, expected_content) in expectations: with gzip.open(file, "r") as f: file_content = f.read().decode() assert file_content == expected_content, f"{file=} contents malformed" for file in (PACKAGES, PKGBASE, USERS, META, META_EXT): with open(f"{file}.sha256") as f: file_sig_content = f.read() expected_prefix = f"SHA256 ({os.path.basename(file)}) = " assert file_sig_content.startswith(expected_prefix) assert len(file_sig_content) == len(expected_prefix) + 64
def test_mkpkglists_extended(config_mock: None, user: User, packages: List[Package]): from aurweb.scripts import mkpkglists mkpkglists.main() PACKAGES = config.get("mkpkglists", "packagesfile") META = config.get("mkpkglists", "packagesmetafile") META_EXT = config.get("mkpkglists", "packagesmetaextfile") PKGBASE = config.get("mkpkglists", "pkgbasefile") USERS = config.get("mkpkglists", "userfile") expectations = [ ( PACKAGES, "pkg_0\npkg_1\npkg_2\npkg_3\npkg_4\n", ), ( PKGBASE, "pkgbase_0\npkgbase_1\npkgbase_2\npkgbase_3\npkgbase_4\n", ), (USERS, "test\n"), ] for (file, expected_content) in expectations: with gzip.open(file, "r") as f: file_content = f.read().decode() assert file_content == expected_content with gzip.open(META) as f: metadata = json.load(f) assert len(metadata) == len(packages) for pkg in metadata: for key in META_KEYS: assert key in pkg, f"{pkg=} record does not have {key=}" with gzip.open(META_EXT) as f: extended_metadata = json.load(f) assert len(extended_metadata) == len(packages) for pkg in extended_metadata: for key in META_KEYS: assert key in pkg, f"{pkg=} record does not have {key=}" assert isinstance(pkg["Depends"], list) assert isinstance(pkg["License"], list) for file in (PACKAGES, PKGBASE, USERS, META, META_EXT): with open(f"{file}.sha256") as f: file_sig_content = f.read() expected_prefix = f"SHA256 ({os.path.basename(file)}) = " assert file_sig_content.startswith(expected_prefix) assert len(file_sig_content) == len(expected_prefix) + 64
def _get_json_data(self, package: models.Package) -> Dict[str, Any]: """ Produce dictionary data of one Package that can be JSON-serialized. :param package: Package instance :returns: JSON-serializable dictionary """ # Produce RPC API compatible Popularity: If zero, it's an integer # 0, otherwise, it's formatted to the 6th decimal place. pop = package.Popularity pop = 0 if not pop else float(number_format(pop, 6)) snapshot_uri = config.get("options", "snapshot_uri") return { "ID": package.ID, "Name": package.Name, "PackageBaseID": package.PackageBaseID, "PackageBase": package.PackageBaseName, # Maintainer should be set following this update if one exists. "Maintainer": package.Maintainer, "Version": package.Version, "Description": package.Description, "URL": package.URL, "URLPath": snapshot_uri % package.Name, "NumVotes": package.NumVotes, "Popularity": pop, "OutOfDate": package.OutOfDateTS, "FirstSubmitted": package.SubmittedTS, "LastModified": package.ModifiedTS }
def sendmail(from_: str, to_: str, content: str) -> Email: binary = config.get("notifications", "sendmail") proc = Popen(binary, stdin=PIPE, stdout=PIPE, stderr=PIPE) content = f"From: {from_}\nTo: {to_}\n\n{content}" proc.communicate(content.encode()) proc.wait() assert proc.returncode == 0
def test_tu_index_guest(client): headers = {"referer": config.get("options", "aur_location") + "/tu"} with client as request: response = request.get("/tu", allow_redirects=False, headers=headers) assert response.status_code == int(HTTPStatus.SEE_OTHER) params = filters.urlencode({"next": "/tu"}) assert response.headers.get("location") == f"/login?{params}"
def documentation(): aurwebdir = config.get("options", "aurwebdir") rpc_doc = os.path.join(aurwebdir, "doc", "rpc.html") if not os.path.exists(rpc_doc): raise OSError("doc/rpc.html could not be read") with open(rpc_doc) as f: data = f.read() return HTMLResponse(data)
def test_source_uri_file(package: Package): FILE = "test_file" with db.begin(): pkgsrc = db.create(PackageSource, Source=FILE, Package=package, SourceArch="x86_64") source_file_uri = config.get("options", "source_file_uri") file, uri = util.source_uri(pkgsrc) expected = source_file_uri % (pkgsrc.Source, package.PackageBase.Name) assert (file, uri) == (FILE, expected)
def make_context(request: Request, pkgbase: PackageBase, context: Dict[str, Any] = None) -> Dict[str, Any]: """ Make a basic context for package or pkgbase. :param request: FastAPI request :param pkgbase: PackageBase instance :return: A pkgbase context without specific differences """ if not context: context = _make_context(request, pkgbase.Name) context["git_clone_uri_anon"] = config.get("options", "git_clone_uri_anon") context["git_clone_uri_priv"] = config.get("options", "git_clone_uri_priv") context["pkgbase"] = pkgbase context["comaintainers"] = [ c.User for c in pkgbase.comaintainers.order_by( PackageComaintainer.Priority.asc()).all() ] context["packages_count"] = pkgbase.packages.count() context["keywords"] = pkgbase.keywords context["comments"] = pkgbase.comments.order_by( PackageComment.CommentTS.desc()) context["pinned_comments"] = pkgbase.comments.filter( PackageComment.PinnedTS != 0).order_by(PackageComment.CommentTS.desc()) context["is_maintainer"] = bool(request.user == pkgbase.Maintainer) context["notified"] = request.user.notified(pkgbase) context["out_of_date"] = bool(pkgbase.OutOfDateTS) context["voted"] = request.user.package_votes.filter( PackageVote.PackageBaseID == pkgbase.ID).scalar() context["requests"] = pkgbase.requests.filter( and_(PackageRequest.Status == PENDING_ID, PackageRequest.ClosedTS.is_(None))).count() return context
def config_mock(tmpdir: py.path.local) -> None: config_get = config.get archivedir = config.get("mkpkglists", "archivedir") def mock_config(section: str, key: str) -> str: if section == "mkpkglists": if key == "archivedir": return str(tmpdir) return config_get(section, key).replace(archivedir, str(tmpdir)) return config_get(section, key) with mock.patch("aurweb.config.get", side_effect=mock_config): config.rehash() yield config.rehash()
def test_commit_hash(): # Hashes we'll use for this test. long_commit_hash should be # shortened to commit_hash for rendering. commit_hash = "abcdefg" long_commit_hash = commit_hash + "1234567" def config_get_with_fallback(section: str, option: str, fallback: str = None) -> str: if section == "devel" and option == "commit_hash": return long_commit_hash return config.original_get_with_fallback(section, option, fallback) # Fake config.get_with_fallback. config.original_get_with_fallback = config.get_with_fallback config.get_with_fallback = config_get_with_fallback request = Request() context = templates.make_context(request, "Test Context") render = templates.render_raw_template(request, "index.html", context) # We've faked config.get_with_fallback to return a "valid" commit_hash # when queried. Test that the expected render occurs. commit_url = config.get("devel", "commit_url") expected = commit_url % commit_hash assert expected in render assert f"HEAD@{commit_hash}" in render assert long_commit_hash not in render # Restore config.get_with_fallback. config.get_with_fallback = config.original_get_with_fallback config.original_get_with_fallback = None # Now, we no longer fake the commit_hash option: no commit # is displayed in the footer. Assert this expectation. context = templates.make_context(request, "Test Context") render = templates.render_raw_template(request, "index.html", context) assert commit_hash not in render
def source_uri(pkgsrc: models.PackageSource) -> Tuple[str, str]: """ Produce a (text, uri) tuple out of `pkgsrc`. In this filter, we cover various cases: 1. If "::" is anywhere in the Source column, split the string, which should produce a (text, uri), where text is before "::" and uri is after "::". 2. Otherwise, if "://" is anywhere in the Source column, it's just some sort of URI, which we'll return varbatim as both text and uri. 3. Otherwise, we'll return a path to the source file in a uri produced out of options.source_file_uri formatted with the source file and the package base name. :param pkgsrc: PackageSource instance :return (text, uri) tuple """ if "::" in pkgsrc.Source: return pkgsrc.Source.split("::", 1) elif "://" in pkgsrc.Source: return (pkgsrc.Source, pkgsrc.Source) path = config.get("options", "source_file_uri") pkgbasename = pkgsrc.Package.PackageBase.Name return (pkgsrc.Source, path % (pkgsrc.Source, pkgbasename))
from typing import Tuple import pytest from aurweb import config, db, time from aurweb.models import TUVote, TUVoteInfo, User from aurweb.models.account_type import TRUSTED_USER_ID from aurweb.scripts import tuvotereminder as reminder from aurweb.testing.email import Email aur_location = config.get("options", "aur_location") def create_vote(user: User, voteinfo: TUVoteInfo) -> TUVote: with db.begin(): vote = db.create(TUVote, User=user, VoteID=voteinfo.ID) return vote def create_user(username: str, type_id: int): with db.begin(): user = db.create(User, AccountTypeID=type_id, Username=username, Email=f"{username}@example.org", Passwd=str()) return user def email_pieces(voteinfo: TUVoteInfo) -> Tuple[str, str]: """
def test_get(): assert config.get("options", "disable_http_login") == "0"
from logging import ERROR from typing import List from unittest import mock import pytest from aurweb import config, db, models, time from aurweb.models import Package, PackageBase, PackageRequest, User from aurweb.models.account_type import TRUSTED_USER_ID, USER_ID from aurweb.models.request_type import ORPHAN_ID from aurweb.scripts import notify, rendercomment from aurweb.testing.email import Email from aurweb.testing.smtp import FakeSMTP, FakeSMTP_SSL aur_location = config.get("options", "aur_location") aur_request_ml = config.get("options", "aur_request_ml") @pytest.fixture(autouse=True) def setup(db_test): return @pytest.fixture def user() -> User: with db.begin(): user = db.create(User, Username="******", Email="*****@*****.**", Passwd=str(), AccountTypeID=USER_ID)