diff --git a/aurweb/routers/packages.py b/aurweb/routers/packages.py index bcc0be56..e227fe23 100644 --- a/aurweb/routers/packages.py +++ b/aurweb/routers/packages.py @@ -816,6 +816,29 @@ async def requests_close_post(request: Request, id: int, return RedirectResponse("/requests", status_code=HTTPStatus.SEE_OTHER) +@router.post("/pkgbase/{name}/keywords") +async def pkgbase_keywords(request: Request, name: str, + keywords: str = Form(default=str())): + pkgbase = get_pkg_or_base(name, models.PackageBase) + keywords = set(keywords.split(" ")) + + # Delete all keywords which are not supplied by the user. + with db.begin(): + db.delete(models.PackageKeyword, + and_(models.PackageKeyword.PackageBaseID == pkgbase.ID, + ~models.PackageKeyword.Keyword.in_(keywords))) + + existing_keywords = set(kwd.Keyword for kwd in pkgbase.keywords.all()) + with db.begin(): + for keyword in keywords.difference(existing_keywords): + db.create(models.PackageKeyword, + PackageBase=pkgbase, + Keyword=keyword) + + return RedirectResponse(f"/pkgbase/{name}", + status_code=HTTPStatus.SEE_OTHER) + + @router.get("/pkgbase/{name}/flag") @auth_required(True, redirect="/pkgbase/{name}/flag") async def pkgbase_flag_get(request: Request, name: str): diff --git a/templates/partials/packages/details.html b/templates/partials/packages/details.html index 583149f8..d525f63b 100644 --- a/templates/partials/packages/details.html +++ b/templates/partials/packages/details.html @@ -37,7 +37,7 @@ {{ "Keywords" | tr }}: {% if request.user.has_credential("CRED_PKGBASE_SET_KEYWORDS", approved=[pkgbase.Maintainer]) %} -
@@ -51,7 +51,7 @@ {% else %} - {% for keyword in pkgbase.keywords %} + {% for keyword in pkgbase.keywords.all() %} diff --git a/test/test_packages_routes.py b/test/test_packages_routes.py index c4d9ab1c..887945d9 100644 --- a/test/test_packages_routes.py +++ b/test/test_packages_routes.py @@ -2604,3 +2604,33 @@ def test_account_comments(client: TestClient, user: User, package: Package): expected = rendered_comment.RenderedComment.replace( "

", "").replace("

", "") assert rendered[0].text.strip() == expected + + +def test_pkgbase_keywords(client: TestClient, user: User, package: Package): + endpoint = f"/pkgbase/{package.PackageBase.Name}" + with client as request: + resp = request.get(endpoint) + assert resp.status_code == int(HTTPStatus.OK) + + root = parse_root(resp.text) + keywords = root.xpath('//a[@class="keyword"]') + assert len(keywords) == 0 + + cookies = {"AURSID": user.login(Request(), "testPassword")} + post_endpoint = f"{endpoint}/keywords" + with client as request: + resp = request.post(post_endpoint, data={ + "keywords": "abc test" + }, cookies=cookies) + assert resp.status_code == int(HTTPStatus.SEE_OTHER) + + with client as request: + resp = request.get(resp.headers.get("location")) + assert resp.status_code == int(HTTPStatus.OK) + + root = parse_root(resp.text) + keywords = root.xpath('//a[@class="keyword"]') + assert len(keywords) == 2 + expected = ["abc", "test"] + for i, keyword in enumerate(keywords): + assert keyword.text.strip() == expected[i]