feat(fastapi): add /pkgbase/{name}/merge (get)

Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
Kevin Morris 2021-10-11 23:17:54 -07:00
parent 990f4d182b
commit 2b9840149e
No known key found for this signature in database
GPG key ID: F7E46DED420788F3
4 changed files with 120 additions and 0 deletions

View file

@ -1080,3 +1080,34 @@ async def packages_post(request: Request,
context["success"] = messages context["success"] = messages
return await packages_get(request, context) return await packages_get(request, context)
@router.get("/pkgbase/{name}/merge")
@auth_required(redirect="/pkgbase/{name}/merge")
async def pkgbase_merge_get(request: Request, name: str,
into: str = Query(default=str()),
next: str = Query(default=str())):
pkgbase = get_pkg_or_base(name, models.PackageBase)
if not next:
next = f"/pkgbase/{pkgbase.Name}"
context = make_context(request, "Package Merging")
context.update({
"pkgbase": pkgbase,
"into": into,
"next": next
})
status_code = HTTPStatus.OK
# TODO: Lookup errors from credential instead of hardcoding them.
# Idea: Something like credential_errors("CRED_PKGBASE_MERGE").
# Perhaps additionally: bad_credential_status_code("CRED_PKGBASE_MERGE").
# Don't take these examples verbatim. We should find good naming.
if not request.user.has_credential("CRED_PKGBASE_MERGE"):
context["errors"] = [
"Only Trusted Users and Developers can merge packages."]
status_code = HTTPStatus.UNAUTHORIZED
return render_template(request, "pkgbase/merge.html", context,
status_code=status_code)

View file

@ -0,0 +1,65 @@
{% extends "partials/layout.html" %}
{% block pageContent %}
<div class="box">
<h2>{{ "Merge Package" | tr }}: {{ pkgbase.Name }}</h2>
<p>
{{
"Use this form to merge the package base %s%s%s into "
"another package."
| tr | format("<strong>", pkgbase.Name, "</strong>") | safe
}}
{{ "The following packages will be deleted: " | tr }}
</p>
<ul>
{% for package in pkgbase.packages.all() %}
<li>{{ package.Name }}</li>
{% endfor %}
</ul>
<p>
{{ "Once the package has been merged it cannot be reversed. " | tr }}
{{ "Enter the package name you wish to merge the package into. " | tr }}
{{ "Select the checkbox to confirm action." | tr }}
</p>
<form id="merge-form" action="/pkgbase/{{ pkgbase.Name }}/merge" method="post">
<fieldset>
<input type="hidden" name="next" value="{{ next }}" />
<p>
<label id="merge-into" for="merge_into">
{{ "Merge into:" | tr }}
</label>
<input id="merge_into"
type="text"
name="into"
value="{{ into }}"
autocomplete="off"
/>
</p>
<p>
<label class="confirmation">
<input type="checkbox" name="confirm" />
{{ "Confirm package merge" | tr }}
</label>
</p>
<p>
<input class="button"
type="submit"
value="{{ 'Merge' | tr }}"
/>
</p>
</fieldset>
</form>
{# Bootstrap typeahead-pkgbase-merge.js #}
<script type="text/javascript"
src="/static/js/typeahead-pkgbase-merge.js"></script>
</div>
{% endblock %}

View file

@ -2049,3 +2049,21 @@ def test_packages_post(client: TestClient, user: User, package: Package):
errors = get_successes(resp.text) errors = get_successes(resp.text)
expected = "Some success." expected = "Some success."
assert errors[0].text.strip() == expected assert errors[0].text.strip() == expected
def test_pkgbase_merge_unauthorized(client: TestClient, user: User,
package: Package):
cookies = {"AURSID": user.login(Request(), "testPassword")}
endpoint = f"/pkgbase/{package.PackageBase.Name}/merge"
with client as request:
resp = request.get(endpoint, cookies=cookies)
assert resp.status_code == int(HTTPStatus.UNAUTHORIZED)
def test_pkgbase_merge(client: TestClient, tu_user: User, package: Package):
cookies = {"AURSID": tu_user.login(Request(), "testPassword")}
endpoint = f"/pkgbase/{package.PackageBase.Name}/merge"
with client as request:
resp = request.get(endpoint, cookies=cookies)
assert resp.status_code == int(HTTPStatus.OK)
assert not get_errors(resp.text)

View file

@ -0,0 +1,6 @@
document.addEventListener('DOMContentLoaded', function() {
const input = document.getElementById('merge_into');
const form = document.getElementById('merge-form');
const type = "suggest-pkgbase";
typeahead.init(type, input, form, false);
});