Skip to content

Commit

Permalink
add application history
Browse files Browse the repository at this point in the history
  • Loading branch information
depsiatwal committed Jan 29, 2025
1 parent 8cf72a3 commit 6253ff6
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 24 deletions.
6 changes: 6 additions & 0 deletions exporter/applications/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,3 +587,9 @@ def get_survey(request, survey_id):
def update_survey_feedback(request, survey_id, json):
data = client.put(request, f"/survey/{survey_id}/", json)
return data.json(), data.status_code


def get_application_history(request, application_id):
response = client.get(request, f"/exporter/applications/{application_id}/history")
response.raise_for_status()
return response.json()
3 changes: 3 additions & 0 deletions exporter/applications/views/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
)
from exporter.applications.services import (
get_activity,
get_application_history,
get_applications,
get_case_notes,
get_case_generated_documents,
Expand Down Expand Up @@ -295,6 +296,7 @@ def dispatch(self, request, *args, **kwargs):

def get(self, request, **kwargs):
status_props, _ = get_status_properties(request, self.application["status"]["key"])

context = {
"case_id": self.application_id,
"application": self.application,
Expand All @@ -304,6 +306,7 @@ def get(self, request, **kwargs):
"errors": kwargs.get("errors"),
"text": kwargs.get("text", ""),
"activity": get_activity(request, self.application_id) or {},
"application_history": get_application_history(self.request, self.application_id),
}

if self.application.sub_type != HMRC:
Expand Down
21 changes: 3 additions & 18 deletions exporter/templates/applications/application.html
Original file line number Diff line number Diff line change
Expand Up @@ -177,27 +177,12 @@ <h1 class="govuk-heading-l">
</dd>
</div>
{% endif %}
{% if not summary_page %}
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key">
{% lcs 'applications.ApplicationSummaryPage.STATUS' %}
</dt>
<dd id="label-application-status" class="govuk-summary-list__value">
{{ application.status.value }}
</dd>
</div>
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key">
{% lcs 'applications.ApplicationSummaryPage.SUBMITTED_AT' %}
</dt>
<dd class="govuk-summary-list__value">
{{ application.submitted_at|str_date }}
</dd>
</div>
{% endif %}
</dl>
</div>
{% if not summary_page %}
<div id="application-history">
{% include "applications/history.html" %}
</div>
<div class="lite-tabs__container">
<div class="lite-tabs">
<a href="{% url 'applications:application' application.id %}" class="lite-tabs__tab {% if not type %}lite-tabs__tab--selected{% endif %}" id="link-details">
Expand Down
31 changes: 31 additions & 0 deletions exporter/templates/applications/history.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<h2 class="govuk-heading-m">Application History</h2>
<table class="govuk-table" id="table-application-history">
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th scope="col" class="govuk-table__header">ECJU Reference</th>
<th scope="col" class="govuk-table__header">Submitted</th>
<th scope="col" class="govuk-table__header">Status</th>
<th scope="col" class="govuk-table__header">Queries</th>
</tr>
</thead>
<tbody class="govuk-table__body">
{% for prev_application in application_history.amendment_history %}
<tr class="govuk-table__row">
<td class="govuk-table__cell">
{% if prev_application.id == application.id %}
{{ prev_application.reference_code }}
{% else %}
<a href="{% url 'applications:application' prev_application.id %}">{{ prev_application.reference_code }}</a>
{% endif %}
</td>
<td class="govuk-table__cell">{{ prev_application.submitted_at|str_date }}</td>
<td class="govuk-table__cell"> <div class="govuk-tag govuk-tag--grey govuk-!-margin-0">{{ prev_application.status.status_display }}</div></td>
<td class="govuk-table__cell">
{% if prev_application.ecju_query_count > 0 %}
<a href="{% url 'applications:application' prev_application.id 'ecju-queries' %}">{{ prev_application.ecju_query_count }}</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
2 changes: 1 addition & 1 deletion exporter/templates/applications/summary.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h2 class="govuk-heading-m">{{ key }}</h2>
{% endfor %}
</dl>
{% elif value|classname == 'list' %}
<table class="govuk-table">
<table class="govuk-table" id="table-application-products">
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th scope="col" class="govuk-table__header">#</th>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ def mock_application_get(requests_mock, data_standard_case):
return requests_mock.get(url=url, json=application)


@pytest.fixture
def mock_application_history_get(requests_mock, data_standard_case):
application = data_standard_case["case"]["data"]
url = client._build_absolute_uri(f'/exporter/applications/{application["id"]}/history')
return requests_mock.get(url=url, json={})


def test_convert_goods_on_application_no_answers(application, data_good_on_application):
# given the canonical good does not have is_good_controlled set
data_good_on_application["is_good_controlled"] = None
Expand Down Expand Up @@ -239,12 +246,14 @@ def test_convert_standard_application_has_security_approvals(application, settin
assert "Do you have a security approval?" in actual.keys()


def test_application_detail_shows_correct_cles(authorized_client, mock_application_get, application):
def test_application_detail_shows_correct_cles(
authorized_client, mock_application_get, mock_application_history_get, application
):
url = reverse("applications:application", kwargs={"pk": application["id"]})
response = authorized_client.get(url)
soup = BeautifulSoup(response.content, "html.parser")

products_table = soup.find_all("table", attrs={"class": "govuk-table"})[0]
products_table = soup.find("table", attrs={"id": "table-application-products"})
products_cles = []
body = products_table.find("tbody")
rows = body.find_all("tr")
Expand Down
30 changes: 30 additions & 0 deletions unit_tests/exporter/applications/views/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,36 @@ def mock_application_get(requests_mock, data_standard_case):
return requests_mock.get(url=url, json=application)


@pytest.fixture
def application_history(data_standard_case):
return {
"id": data_standard_case["case"]["data"]["id"],
"reference_code": data_standard_case["case"]["data"]["reference_code"],
"amendment_history": [
{
"status": {"status": "submitted", "status_display": "Submitted"},
"ecju_query_count": 0,
"reference_code": data_standard_case["case"]["data"]["reference_code"],
"submitted_at": data_standard_case["case"]["data"]["submitted_at"],
"id": data_standard_case["case"]["data"]["id"], # /PS-IGNORE
},
{
"status": {"status": "superseded_by_exporter_edit", "status_display": "Superseded by exporter edit"},
"ecju_query_count": 3,
"reference_code": "GBSIEL/2025/0000333/T",
"submitted_at": "2025-01-27T16:36:27.185326Z",
"id": "caba228c-b4c8-41ea-804a-c1bc6ba816c7", # /PS-IGNORE
},
],
}


@pytest.fixture
def mock_application_history_get(requests_mock, application_history):
url = client._build_absolute_uri(f'/exporter/applications/{application_history["id"]}/history')
return requests_mock.get(url=url, json=application_history)


@pytest.fixture
def mock_refused_application_get(requests_mock, data_standard_case):
application = data_standard_case["case"]["data"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ def application_url(requests_mock, data_standard_case):


@pytest.fixture()
def rendered_ecju_closed_queries(authorized_client, url):
def rendered_ecju_closed_queries(authorized_client, url, mock_application_history_get):
response = authorized_client.get(url)
return BeautifulSoup(response.content, "html.parser").find_all(id="closed-ecju-query")


@pytest.fixture()
def rendered_ecju_queries(authorized_client, url):
def rendered_ecju_queries(authorized_client, url, mock_application_history_get):
response = authorized_client.get(url)
return BeautifulSoup(response.content, "html.parser").find_all(id="open-ecju-query")

Expand Down
1 change: 1 addition & 0 deletions unit_tests/exporter/applications/views/test_amendments.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def test_edit_button_points_to_amend_by_copy(
application_detail_url,
application_major_edit_confirm_url,
mock_status_properties,
mock_application_history_get,
):
mock_status_properties["can_invoke_major_editable"] = True

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ def test_edit_button(
authorized_client,
data_standard_case,
mock_application_get,
mock_application_history_get,
mock_status_properties,
can_invoke_major_editable,
):

pk = data_standard_case["case"]["id"]
mock_status_properties["can_invoke_major_editable"] = can_invoke_major_editable

Expand All @@ -27,7 +29,11 @@ def test_edit_button(


def test_appeal_refusal_decision_button(
authorized_client, data_standard_case, mock_refused_application_get, mock_status_properties
authorized_client,
data_standard_case,
mock_refused_application_get,
mock_application_history_get,
mock_status_properties,
):
pk = data_standard_case["case"]["id"]

Expand All @@ -41,6 +47,7 @@ def test_appeal_button_not_shown_for_successful_application(
authorized_client,
data_standard_case,
mock_application_get,
mock_application_history_get,
):
pk = data_standard_case["case"]["id"]

Expand All @@ -62,6 +69,7 @@ def test_appeal_deadline_date_format(
authorized_client,
data_standard_case,
mock_application_get,
mock_application_history_get,
date_string,
):
data_standard_case["case"]["data"]["status"] = {
Expand All @@ -82,10 +90,44 @@ def test_user_id_hidden_field(
authorized_client,
data_standard_case,
mock_application_get,
mock_application_history_get,
mock_exporter_user,
):
pk = data_standard_case["case"]["id"]
application_url = reverse("applications:application", kwargs={"pk": pk})
response = authorized_client.get(application_url)
soup = BeautifulSoup(response.content, "html.parser")
assert soup.find(id="user_id")["value"] == mock_exporter_user["user"]["lite_api_user_id"]


def test_application_history_details(
authorized_client,
data_standard_case,
mock_application_get,
mock_application_history_get,
mock_exporter_user,
beautiful_soup,
):
pk = data_standard_case["case"]["id"]
application_url = reverse("applications:application", kwargs={"pk": pk})
response = authorized_client.get(application_url)
soup = beautiful_soup(response.content)

application_history_table = soup.find("table", attrs={"id": "table-application-history"})
body = application_history_table.find("tbody")

hist_application_1 = body.find_all("tr")[0].find_all("td")
hist_application_2 = body.find_all("tr")[1].find_all("td")

assert hist_application_1[0].text.strip() == "GBSIEL/2020/0002687/T"
assert hist_application_1[1].text.strip() == "4:57pm 01 October 2020"
assert hist_application_1[2].text.strip() == "Submitted"
assert hist_application_1[3].text.strip() == ""

assert hist_application_2[0].a["href"] == "/applications/caba228c-b4c8-41ea-804a-c1bc6ba816c7/"
assert hist_application_2[0].a.text.strip() == "GBSIEL/2025/0000333/T"

assert hist_application_2[1].text.strip() == "4:36pm 27 January 2025"
assert hist_application_2[2].text.strip() == "Superseded by exporter edit"
assert hist_application_2[3].a["href"] == "/applications/caba228c-b4c8-41ea-804a-c1bc6ba816c7/ecju-queries/"
assert hist_application_2[3].a.text.strip() == "3"
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def test_application_summary_view(
response = authorized_client.get(summary_url)

assert response.status_code == 200

soup = BeautifulSoup(response.content, "html.parser")
headings_govuk_heading_m = soup.find_all("h2", class_="govuk-heading-m")
headings_govuk_heading_m_text = [heading.text for heading in headings_govuk_heading_m]
Expand Down

0 comments on commit 6253ff6

Please sign in to comment.