diff --git a/aurweb/config.py b/aurweb/config.py
index 9ab9ae45..c26698c2 100644
--- a/aurweb/config.py
+++ b/aurweb/config.py
@@ -6,7 +6,7 @@ from typing import Any
# Publicly visible version of aurweb. This is used to display
# aurweb versioning in the footer and must be maintained.
# Todo: Make this dynamic/automated.
-AURWEB_VERSION = "v6.0.1"
+AURWEB_VERSION = "v6.0.2"
_parser = None
diff --git a/aurweb/pkgbase/util.py b/aurweb/pkgbase/util.py
index 76b8a8c9..fbfcd869 100644
--- a/aurweb/pkgbase/util.py
+++ b/aurweb/pkgbase/util.py
@@ -25,6 +25,9 @@ def make_context(request: Request, pkgbase: PackageBase) -> Dict[str, Any]:
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"] = pkgbase.comaintainers.order_by(
+ PackageComaintainer.Priority.asc()
+ ).all()
context["packages_count"] = pkgbase.packages.count()
context["keywords"] = pkgbase.keywords
context["comments"] = pkgbase.comments.order_by(
diff --git a/aurweb/routers/html.py b/aurweb/routers/html.py
index 74901762..74df62f7 100644
--- a/aurweb/routers/html.py
+++ b/aurweb/routers/html.py
@@ -138,9 +138,15 @@ async def index(request: Request):
packages = db.query(models.Package).join(models.PackageBase)
maintained = packages.join(
- models.User, models.PackageBase.MaintainerUID == models.User.ID
+ models.PackageComaintainer,
+ models.PackageComaintainer.PackageBaseID == models.PackageBase.ID,
+ isouter=True
+ ).join(
+ models.User,
+ or_(models.PackageBase.MaintainerUID == models.User.ID,
+ models.PackageComaintainer.UsersID == models.User.ID)
).filter(
- models.PackageBase.MaintainerUID == request.user.ID
+ models.User.ID == request.user.ID
)
# Packages maintained by the user that have been flagged.
diff --git a/templates/partials/packages/details.html b/templates/partials/packages/details.html
index 6dc8ae77..1c4d01d6 100644
--- a/templates/partials/packages/details.html
+++ b/templates/partials/packages/details.html
@@ -105,13 +105,16 @@
{% endif %}
-
{{ "Maintainer" | tr }}: |
- {% if request.user.is_authenticated() and pkgbase.Maintainer %}
+ {% if pkgbase.Maintainer %}
{{ pkgbase.Maintainer.Username }}
+ {% if comaintainers %}
+ ({% for co in comaintainers %}{{ co.User }}{% endfor %})
+ {% endif %}
{% else %}
{{ pkgbase.Maintainer.Username | default("None" | tr) }}
{% endif %}
diff --git a/test/test_homepage.py b/test/test_homepage.py
index 5d3bc711..63b832e3 100644
--- a/test/test_homepage.py
+++ b/test/test_homepage.py
@@ -36,6 +36,14 @@ def user():
yield user
+@pytest.fixture
+def user2():
+ with db.begin():
+ user = db.create(User, Username="test2", Email="test2@example.org",
+ Passwd="testPassword", AccountTypeID=USER_ID)
+ yield user
+
+
@pytest.fixture
def redis():
redis = redis_connection()
@@ -54,6 +62,17 @@ def redis():
delete_keys()
+@pytest.fixture
+def package(user: User) -> Package:
+ now = time.utcnow()
+ with db.begin():
+ pkgbase = db.create(PackageBase, Name="test-pkg",
+ Maintainer=user, Packager=user,
+ SubmittedTS=now, ModifiedTS=now)
+ pkg = db.create(Package, PackageBase=pkgbase, Name=pkgbase.Name)
+ yield pkg
+
+
@pytest.fixture
def packages(user):
""" Yield a list of num_packages Package objects maintained by user. """
@@ -221,3 +240,36 @@ def test_homepage_dashboard_flagged_packages(redis, packages, user):
flagged_pkg = root.xpath('//table[@id="flagged-packages"]/tbody/tr').pop(0)
flagged_name = flagged_pkg.xpath('./td/a').pop(0)
assert flagged_name.text.strip() == pkg.Name
+
+
+def test_homepage_dashboard_flagged(user: User, user2: User, package: Package):
+ pkgbase = package.PackageBase
+
+ now = time.utcnow()
+ with db.begin():
+ db.create(PackageComaintainer, User=user2,
+ PackageBase=pkgbase, Priority=1)
+ pkgbase.OutOfDateTS = now - 5
+ pkgbase.Flagger = user
+
+ # Test that a comaintainer viewing the dashboard shows them their
+ # flagged co-maintained packages.
+ comaint_cookies = {"AURSID": user2.login(Request(), "testPassword")}
+ with client as request:
+ resp = request.get("/", cookies=comaint_cookies)
+ assert resp.status_code == int(HTTPStatus.OK)
+
+ root = parse_root(resp.text)
+ flagged = root.xpath('//table[@id="flagged-packages"]//tr/td/a')[0]
+ assert flagged.text.strip() == package.Name
+
+ # Test that a maintainer viewing the dashboard shows them their
+ # flagged maintained packages.
+ cookies = {"AURSID": user.login(Request(), "testPassword")}
+ with client as request:
+ resp = request.get("/", cookies=cookies)
+ assert resp.status_code == int(HTTPStatus.OK)
+
+ root = parse_root(resp.text)
+ flagged = root.xpath('//table[@id="flagged-packages"]//tr/td/a')[0]
+ assert flagged.text.strip() == package.Name
diff --git a/test/test_pkgbase_routes.py b/test/test_pkgbase_routes.py
index 17f69811..3f5a791a 100644
--- a/test/test_pkgbase_routes.py
+++ b/test/test_pkgbase_routes.py
@@ -253,6 +253,31 @@ def test_pkgbase(client: TestClient, package: Package):
assert pkgs[i].text.strip() == name
+def test_pkgbase_maintainer(client: TestClient, user: User, maintainer: User,
+ package: Package):
+ """
+ Test that the Maintainer field is beind displayed correctly.
+
+ Co-maintainers are displayed, if they exist, within a parens after
+ the maintainer.
+ """
+ with db.begin():
+ db.create(PackageComaintainer, User=user,
+ PackageBase=package.PackageBase,
+ Priority=1)
+
+ with client as request:
+ resp = request.get(f"/pkgbase/{package.Name}")
+ assert resp.status_code == int(HTTPStatus.OK)
+
+ root = parse_root(resp.text)
+
+ maint = root.xpath('//table[@id="pkginfo"]/tr[@class="pkgmaint"]/td')[0]
+ maint, comaint = maint.xpath('./a')
+ assert maint.text.strip() == maintainer.Username
+ assert comaint.text.strip() == user.Username
+
+
def test_pkgbase_voters(client: TestClient, tu_user: User, package: Package):
pkgbase = package.PackageBase
endpoint = f"/pkgbase/{pkgbase.Name}/voters"
|