Page MenuHomeSoftware Heritage

D7344.diff
No OneTemporary

D7344.diff

diff --git a/swh/web/api/views/add_forge_now.py b/swh/web/api/views/add_forge_now.py
--- a/swh/web/api/views/add_forge_now.py
+++ b/swh/web/api/views/add_forge_now.py
@@ -4,11 +4,12 @@
# See top-level LICENSE file for more information
import json
-from typing import Union
+from typing import Any, Dict, Union
from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import Paginator
from django.db import transaction
+from django.db.models import Q
from django.forms import CharField, ModelForm
from django.http import HttpResponseBadRequest
from django.http.request import HttpRequest
@@ -269,7 +270,45 @@
:statuscode 200: always
"""
- add_forge_requests = AddForgeRequest.objects.order_by("-id")
+ datatables = int(request.GET.get("draw", 0))
+
+ if datatables:
+ # datatables request handling
+ add_forge_requests = AddForgeRequest.objects.all()
+
+ table_data: Dict[str, Any] = {}
+ table_data["recordsTotal"] = add_forge_requests.count()
+ table_data["draw"] = int(request.GET["draw"])
+
+ search_value = request.GET.get("search[value]")
+
+ column_order = request.GET.get("order[0][column]")
+ field_order = request.GET.get(f"columns[{column_order}][name]")
+ order_dir = request.GET.get("order[0][dir]")
+
+ if field_order:
+ if order_dir == "desc":
+ field_order = "-" + field_order
+ add_forge_requests = add_forge_requests.order_by(field_order)
+ else:
+ add_forge_requests = add_forge_requests.order_by("-id")
+
+ per_page = int(request.GET["length"])
+ page_num = int(request.GET["start"]) // per_page + 1
+
+ if search_value:
+ add_forge_requests = add_forge_requests.filter(
+ Q(forge_type__icontains=search_value)
+ | Q(forge_url__icontains=search_value)
+ | Q(status__icontains=search_value)
+ )
+ else:
+ # standard Web API request handling
+ add_forge_requests = AddForgeRequest.objects.order_by("-id")
+
+ page_num = int(request.GET.get("page", 1))
+ per_page = int(request.GET.get("per_page", 10))
+ per_page = min(per_page, 1000)
if (
int(request.GET.get("user_requests_only", "0"))
@@ -279,35 +318,43 @@
submitter_name=request.user.username
)
- page_num = int(request.GET.get("page", 1))
- per_page = int(request.GET.get("per_page", 10))
- per_page = min(per_page, 1000)
-
paginator = Paginator(add_forge_requests, per_page)
page = paginator.page(page_num)
if request.user.has_perm(MODERATOR_ROLE):
- results = AddForgeNowRequestSerializer(page.object_list, many=True).data
+ requests = AddForgeNowRequestSerializer(page.object_list, many=True).data
else:
- results = AddForgeNowRequestPublicSerializer(page.object_list, many=True).data
+ requests = AddForgeNowRequestPublicSerializer(page.object_list, many=True).data
- response = {"results": results, "headers": {}}
+ results = [dict(request) for request in requests]
- if page.has_previous():
- response["headers"]["link-prev"] = reverse(
- "api-1-add-forge-request-list",
- query_params={"page": page.previous_page_number(), "per_page": per_page},
- request=request,
- )
+ if datatables:
+ # datatables response
+ table_data["recordsFiltered"] = add_forge_requests.count()
+ table_data["data"] = results
+ return table_data
+ else:
+ # standard Web API response
+ response: Dict[str, Any] = {"results": results, "headers": {}}
+
+ if page.has_previous():
+ response["headers"]["link-prev"] = reverse(
+ "api-1-add-forge-request-list",
+ query_params={
+ "page": page.previous_page_number(),
+ "per_page": per_page,
+ },
+ request=request,
+ )
- if page.has_next():
- response["headers"]["link-next"] = reverse(
- "api-1-add-forge-request-list",
- query_params={"page": page.next_page_number(), "per_page": per_page},
- request=request,
- )
+ if page.has_next():
+ response["headers"]["link-next"] = reverse(
+ "api-1-add-forge-request-list",
+ query_params={"page": page.next_page_number(), "per_page": per_page},
+ request=request,
+ )
- return response
+ return response
@api_route(
diff --git a/swh/web/tests/api/views/test_add_forge_now.py b/swh/web/tests/api/views/test_add_forge_now.py
--- a/swh/web/tests/api/views/test_add_forge_now.py
+++ b/swh/web/tests/api/views/test_add_forge_now.py
@@ -387,6 +387,150 @@
assert len(resp.data) == 1
+NB_FORGE_TYPE = 2
+NB_FORGES_PER_TYPE = 20
+
+
+def _create_add_forge_requests(api_client, regular_user, regular_user2):
+ requests = []
+ for i in range(NB_FORGES_PER_TYPE):
+ request = {
+ "forge_type": "gitlab",
+ "forge_url": f"https://gitlab.example{i:02d}.org",
+ "forge_contact_email": f"admin@gitlab.example{i:02d}.org",
+ "forge_contact_name": f"gitlab.example{i:02d}.org admin",
+ "forge_contact_comment": "user marked as owner in forge members",
+ }
+ _create_add_forge_request(
+ api_client, regular_user, data=request,
+ )
+ requests.append(request)
+
+ request = {
+ "forge_type": "gitea",
+ "forge_url": f"https://gitea.example{i:02d}.org",
+ "forge_contact_email": f"admin@gitea.example{i:02d}.org",
+ "forge_contact_name": f"gitea.example{i:02d}.org admin",
+ "forge_contact_comment": "user marked as owner in forge members",
+ }
+ _create_add_forge_request(
+ api_client, regular_user2, data=request,
+ )
+ requests.append(request)
+ return requests
+
+
+@pytest.mark.django_db(transaction=True, reset_sequences=True)
+def test_add_forge_request_list_datatables(
+ api_client, regular_user, regular_user2, moderator_user
+):
+ _create_add_forge_requests(api_client, regular_user, regular_user2)
+
+ length = 10
+
+ url = reverse(
+ "api-1-add-forge-request-list",
+ query_params={"draw": 1, "length": length, "start": 0},
+ )
+
+ api_client.force_login(regular_user)
+ resp = check_api_get_responses(api_client, url, status_code=200)
+
+ assert resp.data["draw"] == 1
+ assert resp.data["recordsFiltered"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert resp.data["recordsTotal"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert len(resp.data["data"]) == length
+ # default ordering is by descending id
+ assert resp.data["data"][0]["id"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert (
+ resp.data["data"][-1]["id"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE - length + 1
+ )
+ assert "submitter_name" not in resp.data["data"][0]
+
+ api_client.force_login(moderator_user)
+ resp = check_api_get_responses(api_client, url, status_code=200)
+
+ assert resp.data["draw"] == 1
+ assert resp.data["recordsFiltered"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert resp.data["recordsTotal"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert len(resp.data["data"]) == length
+ # default ordering is by descending id
+ assert resp.data["data"][0]["id"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert (
+ resp.data["data"][-1]["id"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE - length + 1
+ )
+ assert "submitter_name" in resp.data["data"][0]
+
+
+@pytest.mark.django_db(transaction=True, reset_sequences=True)
+def test_add_forge_request_list_datatables_ordering(
+ api_client, regular_user, regular_user2, moderator_user
+):
+ requests = _create_add_forge_requests(api_client, regular_user, regular_user2)
+ requests_sorted = list(sorted(requests, key=lambda d: d["forge_url"]))
+ forge_urls_asc = [request["forge_url"] for request in requests_sorted]
+ forge_urls_desc = list(reversed(forge_urls_asc))
+
+ length = 10
+
+ for direction in ("asc", "desc"):
+ for i in range(4):
+ url = reverse(
+ "api-1-add-forge-request-list",
+ query_params={
+ "draw": 1,
+ "length": length,
+ "start": i * length,
+ "order[0][column]": 2,
+ "order[0][dir]": direction,
+ "columns[2][name]": "forge_url",
+ },
+ )
+
+ api_client.force_login(regular_user)
+ resp = check_api_get_responses(api_client, url, status_code=200)
+
+ assert resp.data["draw"] == 1
+ assert resp.data["recordsFiltered"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert resp.data["recordsTotal"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert len(resp.data["data"]) == length
+
+ page_forge_urls = [request["forge_url"] for request in resp.data["data"]]
+ if direction == "asc":
+ expected_forge_urls = forge_urls_asc[i * length : (i + 1) * length]
+ else:
+ expected_forge_urls = forge_urls_desc[i * length : (i + 1) * length]
+ assert page_forge_urls == expected_forge_urls
+
+
+@pytest.mark.django_db(transaction=True, reset_sequences=True)
+def test_add_forge_request_list_datatables_search(
+ api_client, regular_user, regular_user2, moderator_user
+):
+ _create_add_forge_requests(api_client, regular_user, regular_user2)
+
+ url = reverse(
+ "api-1-add-forge-request-list",
+ query_params={
+ "draw": 1,
+ "length": NB_FORGES_PER_TYPE,
+ "start": 0,
+ "search[value]": "gitlab",
+ },
+ )
+
+ api_client.force_login(regular_user)
+ resp = check_api_get_responses(api_client, url, status_code=200)
+
+ assert resp.data["draw"] == 1
+ assert resp.data["recordsFiltered"] == NB_FORGES_PER_TYPE
+ assert resp.data["recordsTotal"] == NB_FORGE_TYPE * NB_FORGES_PER_TYPE
+ assert len(resp.data["data"]) == NB_FORGES_PER_TYPE
+
+ page_forge_type = [request["forge_type"] for request in resp.data["data"]]
+ assert page_forge_type == ["gitlab"] * NB_FORGES_PER_TYPE
+
+
@pytest.mark.django_db(transaction=True, reset_sequences=True)
def test_add_forge_request_get(api_client, regular_user, moderator_user):
resp = _create_add_forge_request(api_client, regular_user)

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 18, 12:58 AM (3 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3218339

Event Timeline