Verified Commit 210d92e3 authored by Kevin Morris's avatar Kevin Morris
Browse files

Merge branch 'pu_packages_action_post' into pu

parents 36c1ee35 c588a4e8
Pipeline #12290 passed with stage
in 7 minutes and 53 seconds
...@@ -23,7 +23,8 @@ from aurweb.templates import make_context, render_raw_template, render_template ...@@ -23,7 +23,8 @@ from aurweb.templates import make_context, render_raw_template, render_template
router = APIRouter() router = APIRouter()
async def packages_get(request: Request, context: Dict[str, Any]): async def packages_get(request: Request, context: Dict[str, Any],
status_code: HTTPStatus = HTTPStatus.OK):
# Query parameters used in this request. # Query parameters used in this request.
context["q"] = dict(request.query_params) context["q"] = dict(request.query_params)
...@@ -94,7 +95,8 @@ async def packages_get(request: Request, context: Dict[str, Any]): ...@@ -94,7 +95,8 @@ async def packages_get(request: Request, context: Dict[str, Any]):
context.get("packages"), request.user) context.get("packages"), request.user)
context["packages_count"] = search.total_count context["packages_count"] = search.total_count
return render_template(request, "packages.html", context) return render_template(request, "packages.html", context,
status_code=status_code)
@router.get("/packages") @router.get("/packages")
...@@ -1024,3 +1026,42 @@ async def pkgbase_delete_post(request: Request, name: str, ...@@ -1024,3 +1026,42 @@ async def pkgbase_delete_post(request: Request, name: str,
delete_package(request.user, package) delete_package(request.user, package)
return RedirectResponse("/packages", status_code=HTTPStatus.SEE_OTHER) return RedirectResponse("/packages", status_code=HTTPStatus.SEE_OTHER)
# A mapping of action string -> callback functions used within the
# `packages_post` route below. We expect any action callback to
# return a tuple in the format: (succeeded: bool, message: List[str]).
PACKAGE_ACTIONS = {}
@router.post("/packages")
@auth_required(redirect="/packages")
async def packages_post(request: Request,
IDs: List[int] = Form(default=[]),
action: str = Form(default=str()),
merge_into: str = Form(default=str()),
confirm: bool = Form(default=False)):
# If an invalid action is specified, just render GET /packages
# with an BAD_REQUEST status_code.
if action not in PACKAGE_ACTIONS:
context = make_context(request, "Packages")
return await packages_get(request, context, HTTPStatus.BAD_REQUEST)
context = make_context(request, "Packages")
# We deal with `IDs`, `merge_into` and `confirm` arguments
# within action callbacks.
callback = PACKAGE_ACTIONS.get(action)
retval = await callback(request, package_ids=IDs, merge_into=merge_into,
confirm=confirm)
if retval: # If *anything* was returned:
success, messages = retval
if not success:
# If the first element was False:
context["errors"] = messages
return await packages_get(request, context, HTTPStatus.BAD_REQUEST)
else:
# Otherwise:
context["success"] = messages
return await packages_get(request, context)
...@@ -55,11 +55,10 @@ ...@@ -55,11 +55,10 @@
{% include "partials/widgets/pager.html" %} {% include "partials/widgets/pager.html" %}
{% endwith %} {% endwith %}
{# Package action form #} {# Package action form: persists query parameters. #}
<form id="pkglist-results-form" <form id="pkglist-results-form"
action="/packages/?{{ q | urlencode }}" action="/packages?{{ q | urlencode }}" method="post"
method="post"> >
{# Search results #} {# Search results #}
{% with voted = packages_voted, notified = packages_notified %} {% with voted = packages_voted, notified = packages_notified %}
{% include "partials/packages/search_results.html" %} {% include "partials/packages/search_results.html" %}
......
...@@ -3,6 +3,7 @@ import re ...@@ -3,6 +3,7 @@ import re
from datetime import datetime from datetime import datetime
from http import HTTPStatus from http import HTTPStatus
from typing import List from typing import List
from unittest import mock
import pytest import pytest
...@@ -26,7 +27,7 @@ from aurweb.models.relation_type import PROVIDES_ID, RelationType ...@@ -26,7 +27,7 @@ from aurweb.models.relation_type import PROVIDES_ID, RelationType
from aurweb.models.request_type import DELETION_ID, RequestType from aurweb.models.request_type import DELETION_ID, RequestType
from aurweb.models.user import User from aurweb.models.user import User
from aurweb.testing import setup_test_db from aurweb.testing import setup_test_db
from aurweb.testing.html import parse_root from aurweb.testing.html import get_errors, get_successes, parse_root
from aurweb.testing.requests import Request from aurweb.testing.requests import Request
...@@ -1987,3 +1988,49 @@ def test_pkgbase_delete(client: TestClient, tu_user: User, package: Package): ...@@ -1987,3 +1988,49 @@ def test_pkgbase_delete(client: TestClient, tu_user: User, package: Package):
PackageBase.Name == pkgbase.Name PackageBase.Name == pkgbase.Name
).first() ).first()
assert record is None assert record is None
def test_packages_post_unknown_action(client: TestClient, user: User,
package: Package):
cookies = {"AURSID": user.login(Request(), "testPassword")}
with client as request:
resp = request.post("/packages", data={"action": "unknown"},
cookies=cookies, allow_redirects=False)
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
def test_packages_post_error(client: TestClient, user: User, package: Package):
async def stub_action(request: Request, **kwargs):
return (False, ["Some error."])
actions = {"stub": stub_action}
with mock.patch.dict("aurweb.routers.packages.PACKAGE_ACTIONS", actions):
cookies = {"AURSID": user.login(Request(), "testPassword")}
with client as request:
resp = request.post("/packages", data={"action": "stub"},
cookies=cookies, allow_redirects=False)
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
errors = get_errors(resp.text)
expected = "Some error."
assert errors[0].text.strip() == expected
def test_packages_post(client: TestClient, user: User, package: Package):
async def stub_action(request: Request, **kwargs):
return (True, ["Some success."])
actions = {"stub": stub_action}
with mock.patch.dict("aurweb.routers.packages.PACKAGE_ACTIONS", actions):
cookies = {"AURSID": user.login(Request(), "testPassword")}
with client as request:
resp = request.post("/packages", data={"action": "stub"},
cookies=cookies, allow_redirects=False)
assert resp.status_code == int(HTTPStatus.OK)
errors = get_successes(resp.text)
expected = "Some success."
assert errors[0].text.strip() == expected
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment