-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2346 from uktrade/LTD-5887-view-f680-caseworker
[LTD-5887] Add stub F680 case detail page
- Loading branch information
Showing
14 changed files
with
385 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{% extends 'layouts/case.html' %} | ||
{% block details %} | ||
<section class="govuk-!-margin-top-8"> | ||
<h1 class="govuk-visually-hidden">Case Summary</h1> | ||
{% include "f680/case/summary.html" %} | ||
</section> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{% extends "case/base-case-summary.html" %} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import pytest | ||
from datetime import timedelta | ||
from requests.exceptions import HTTPError | ||
|
||
from bs4 import BeautifulSoup | ||
from django.urls import reverse | ||
from django.utils import timezone | ||
|
||
from core import client | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def setup( | ||
mock_queue, | ||
mock_case, | ||
mock_approval_reason, | ||
mock_denial_reasons, | ||
mock_proviso, | ||
mock_footnote_details, | ||
): | ||
return | ||
|
||
|
||
@pytest.fixture | ||
def missing_case_id(): | ||
return "5eb8f65f-9ce0-4dd6-abde-5c3fc00b802c" | ||
|
||
|
||
@pytest.fixture | ||
def mock_missing_case(missing_case_id, requests_mock): | ||
url = client._build_absolute_uri(f"/cases/{missing_case_id}/") | ||
return requests_mock.get(url=url, status_code=404) | ||
|
||
|
||
@pytest.fixture | ||
def f680_case_id(): | ||
return "67271217-7e55-4345-9db4-31de1bfe4067" | ||
|
||
|
||
@pytest.fixture | ||
def f680_reference_code(): | ||
return "F680/2025/0000016" | ||
|
||
|
||
@pytest.fixture | ||
def data_f680_case(f680_case_id, f680_reference_code): | ||
submitted_at = timezone.now() - timedelta(days=7) | ||
return { | ||
"case": { | ||
"advice": [], | ||
"all_flags": [], | ||
"amendment_of": None, | ||
"assigned_users": {}, | ||
"case_officer": None, | ||
"case_type": { | ||
"id": "00000000-0000-0000-0000-000000000007", | ||
"reference": {"key": "f680", "value": "MOD F680 Clearance"}, | ||
"sub_type": {"key": "f680_clearance", "value": "MOD F680 Clearance"}, | ||
"type": {"key": "application", "value": "Application"}, | ||
}, | ||
"copy_of": None, | ||
"countersign_advice": [], | ||
"data": { | ||
"application": {"some": "json"}, | ||
"id": f680_case_id, | ||
"organisation": { | ||
"id": "1363b104-9669-4c53-8602-8fc3717b07cd", # /PS-IGNORE | ||
"name": "Parrish, Crosby and Friedman", | ||
"status": "active", | ||
"type": "commercial", | ||
}, | ||
"reference_code": f680_reference_code, | ||
"status": {"id": "00000000-0000-0000-0000-000000000001", "key": "submitted", "value": "Submitted"}, | ||
"submitted_at": submitted_at.isoformat(), | ||
"submitted_by": None, | ||
}, | ||
"flags": [], | ||
"has_advice": {"final": False, "my_team": False, "my_user": False, "team": False, "user": False}, | ||
"id": f680_case_id, | ||
"latest_activity": None, | ||
"licences": [], | ||
"queue_details": [], | ||
"queue_names": [], | ||
"queues": [], | ||
"reference_code": "F680/2025/0000016", | ||
"sla_days": 0, | ||
"sla_remaining_days": None, | ||
"submitted_at": submitted_at.isoformat(), | ||
"superseded_by": None, | ||
} | ||
} | ||
|
||
|
||
@pytest.fixture | ||
def mock_f680_case(f680_case_id, requests_mock, data_f680_case): | ||
url = client._build_absolute_uri(f"/cases/{f680_case_id}/") | ||
return requests_mock.get(url=url, json=data_f680_case) | ||
|
||
|
||
class TestCaseDetailView: | ||
|
||
def test_GET_success( | ||
self, authorized_client, data_queue, mock_f680_case, f680_case_id, f680_reference_code, data_f680_case | ||
): | ||
url = reverse("cases:f680:details", kwargs={"queue_pk": data_queue["id"], "pk": f680_case_id}) | ||
response = authorized_client.get(url) | ||
assert response.status_code == 200 | ||
assert dict(response.context["case"]) == data_f680_case["case"] | ||
soup = BeautifulSoup(response.content, "html.parser") | ||
assert f680_reference_code in soup.find("h1").text | ||
|
||
def test_GET_not_logged_in( | ||
self, client, data_queue, mock_f680_case, f680_case_id, f680_reference_code, data_f680_case | ||
): | ||
url = reverse("cases:f680:details", kwargs={"queue_pk": data_queue["id"], "pk": f680_case_id}) | ||
expected_redirect_location = reverse("auth:login") | ||
response = client.get(url) | ||
assert response.status_code == 302 | ||
assert response.url.startswith(expected_redirect_location) | ||
|
||
def test_GET_no_case_404(self, authorized_client, data_queue, missing_case_id, mock_missing_case): | ||
url = reverse("cases:f680:details", kwargs={"queue_pk": data_queue["id"], "pk": missing_case_id}) | ||
with pytest.raises(HTTPError, match="404"): | ||
authorized_client.get(url) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from django.urls import path | ||
|
||
from caseworker.f680 import views | ||
|
||
|
||
app_name = "f680" | ||
|
||
urlpatterns = [ | ||
path( | ||
"", | ||
views.CaseDetailView.as_view(), | ||
name="details", | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from django.views.generic import TemplateView | ||
|
||
from core.auth.views import LoginRequiredMixin | ||
|
||
from caseworker.cases.services import get_case | ||
from caseworker.cases.helpers.case import CaseworkerMixin | ||
from caseworker.queues.services import get_queue | ||
|
||
|
||
class CaseDetailView(LoginRequiredMixin, CaseworkerMixin, TemplateView): | ||
template_name = "f680/case/detail.html" | ||
|
||
def setup(self, request, *args, **kwargs): | ||
super().setup(request, *args, **kwargs) | ||
|
||
self.case_id = str(kwargs["pk"]) | ||
self.case = get_case(request, self.case_id) | ||
self.queue_id = kwargs["queue_pk"] | ||
self.queue = get_queue(request, self.queue_id) | ||
|
||
def get_context_data(self, **kwargs): | ||
context_data = super().get_context_data(**kwargs) | ||
context_data["case"] = self.case | ||
return context_data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
{% load rules %} | ||
|
||
{% test_rule 'can_user_change_case' request case as can_user_change_case %} | ||
|
||
<dl class="app-case__summary-list"> | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.EXPORTER_REFERENCE' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{{ case.data.name }} | ||
</dd> | ||
</div> | ||
{% if case.copy_of %} | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.COPY_OF' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
<a class="govuk-link govuk-link--no-visited-state" id="link-case-copy-of" href="{% url 'cases:case' queue.id case.copy_of.id %}">{{ case.copy_of.reference_code }}</a> | ||
</dd> | ||
</div> | ||
{% endif %} | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.SUBMITTED_AT' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{{ case.data.submitted_at|str_date }} | ||
</dd> | ||
</div> | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.SUBMITTED_BY' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{{ case.data.submitted_by }} | ||
</dd> | ||
</div> | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.STATUS' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{{ case.data.status.value }} | ||
</dd> | ||
<dd class="app-case__summary-list__actions"> | ||
{% if permissible_statuses %} | ||
{% if not is_terminal or 'REOPEN_CLOSED_CASES' in permissions %} | ||
{% if can_user_change_case %} | ||
<a id="link-change-status" class="govuk-link govuk-link--no-visited-state" href="{% url 'cases:change_status' queue.id case.id %}"> | ||
{% lcs 'generic.CHANGE' %} | ||
</a> | ||
{% endif %} | ||
{% endif %} | ||
{% endif %} | ||
</dd> | ||
</div> | ||
<div class="app-case__summary-list__row" id="case-sub-status"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.SUB_STATUS' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{% if case.data.sub_status %} | ||
{{ case.data.sub_status.name }} | ||
{% else %} | ||
<span class="govuk-hint govuk-!-margin-0">No sub-status set</span> | ||
{% endif %} | ||
</dd> | ||
{% test_rule 'can_user_change_sub_status' request case as can_user_change_sub_status %} | ||
{% if can_user_change_sub_status %} | ||
<dd class="app-case__summary-list__actions"> | ||
<a id="link-case-sub-status-change" class="govuk-link govuk-link--no-visited-state" href="{% url 'cases:change_sub_status' queue.id case.id %}">Change</a> | ||
</dd> | ||
{% endif %} | ||
</div> | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.ASSIGNED_QUEUES' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{% if case.queue_names %} | ||
<ol id="assigned-queues" class="govuk-list govuk-!-margin-0"> | ||
{% for queue_name in case.queue_names %} | ||
<li>{{ queue_name }}</li> | ||
{% endfor %} | ||
</ol> | ||
{% else %} | ||
<span class="govuk-hint govuk-!-margin-0"> | ||
{% lcs 'cases.CasePage.DetailsTab.NO_QUEUES_ASSIGNED' %} | ||
</span> | ||
{% endif %} | ||
</dd> | ||
<dd class="app-case__summary-list__actions"> | ||
{% if can_user_change_case %} | ||
<a id="link-change-queues" class="govuk-link govuk-link--no-visited-state" href="{% url 'cases:move' queue.id case.id %}"> | ||
{% lcs 'generic.CHANGE' %} | ||
</a> | ||
{% endif %} | ||
</dd> | ||
</div> | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.TYPE' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{{ case.case_type.reference.value }} | ||
</dd> | ||
</div> | ||
{% if case.data.updated_at %} | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.LAST_UPDATED' %} | ||
</dt> | ||
<dd class="app-case__summary-list__value"> | ||
{{ case.data.updated_at|str_date }} | ||
</dd> | ||
</div> | ||
{% endif %} | ||
<div class="app-case__summary-list__row"> | ||
<dt class="app-case__summary-list__key"> | ||
{% lcs 'cases.CasePage.DetailsTab.ASSIGNED_USERS' %} | ||
</dt> | ||
<dd id="assigned-users" class="app-case__summary-list__value"> | ||
{% for queue_name, users in case.assigned_users.items %} | ||
<span class="govuk-label">{{ queue_name }}</span> | ||
<ol class="govuk-list govuk-!-margin-0"> | ||
{% for user in users %} | ||
<li> | ||
<div class="app-case__summary-list__value__fullwidth"> | ||
<a href="{% url 'users:user' user.id %}?return_to={{ CURRENT_PATH|urlencode }}&return_to_text={{ case.reference_code }}" class="govuk-link govuk-link--no-visited-state">{{ user|username }}</a> | ||
<a href="{% url 'cases:remove-case-assignment' queue.id case.id %}?assignment_id={{user.assignment_id}}" class="govuk-link govuk-link--no-visited-state app-case__summary-list__value__item-action">Remove</a> | ||
</div> | ||
</li> | ||
{% endfor %} | ||
</ol> | ||
{% empty %} | ||
<span class="govuk-hint govuk-!-margin-0"> | ||
{% lcs 'cases.CasePage.DetailsTab.NO_USERS_ASSIGNED' %} | ||
</span> | ||
{% endfor %} | ||
{% test_rule 'can_user_allocate_case' request case as can_user_allocate_case %} | ||
{% if can_user_allocate_case %} | ||
<div class="app-case__summary-list__value__actions"> | ||
<a id="link-change-assigned-users" class="govuk-link govuk-link--no-visited-state" href="{% url 'queues:case_assignments_assign_user' queue.id %}?cases={{case.id}}&return_to={{CURRENT_PATH|urlencode}}"> | ||
{% lcs 'cases.CasePage.DetailsTab.ADD_ASSIGNED_USER' %} | ||
</a> | ||
</div> | ||
{% endif %} | ||
</dd> | ||
</div> | ||
{% block additional_summary %} | ||
{% endblock %} | ||
</dl> |
Oops, something went wrong.