Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike supporting documents f680 #2372

Draft
wants to merge 14 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions caseworker/f680/templates/f680/case/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,13 @@
<h1 class="govuk-visually-hidden">Case Summary</h1>
{% include "f680/case/summary.html" %}
</section>

{% for section_key, section in case.data.application.sections.items %}
{% if section.type == "single" %}
{% include "f680/includes/application_section_single.html" with section=section section_key=section_key %}
{% else %}
{% include "f680/includes/application_section_multiple.html" with section=section section_key=section_key %}
{% endif %}
{% endfor %}

{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h2 class="govuk-heading-m">{{section.label}}</h2>

{% include "f680/includes/application_section_fields.html" with item=section section_key=section_key %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<table class="govuk-table application-section-{{section_key}}">
<tbody class="govuk-table__body">
{% for field in item.fields %}
<tr class="govuk-table__row">
<th scope="row" class="govuk-table__header">{{field.question}}</th>
<td class="govuk-table__cell">{{field.answer}}</td>
</tr>
{% endfor %}
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h2 class="govuk-heading-m">{{section.label}}</h2>

{% for item in section.items %}
{% include "f680/includes/application_section_fields.html" with item=item section_key=section_key %}
{% endfor %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h2 class="govuk-heading-m">{{section.label}}</h2>

{% include "f680/includes/application_section_fields.html" with item=section section_key=section_key %}
53 changes: 52 additions & 1 deletion caseworker/f680/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,30 @@ def data_f680_case(f680_case_id, f680_reference_code):
"copy_of": None,
"countersign_advice": [],
"data": {
"application": {"some": "json"},
"application": {
"sections": {
"general_application_details": {
"label": "General application details",
"type": "single",
"fields": [
{
"key": "name",
"answer": "some name",
"datatype": "string",
"question": "Name the application",
"raw_answer": "casdc",
},
{
"key": "is_exceptional_circumstances",
"answer": "No",
"datatype": "boolean",
"question": "Do you have exceptional circumstances that mean you need F680 approval in less than 30 days?",
"raw_answer": False,
},
],
},
}
},
"id": f680_case_id,
"organisation": {
"id": "1363b104-9669-4c53-8602-8fc3717b07cd", # /PS-IGNORE
Expand Down Expand Up @@ -97,6 +120,13 @@ def mock_f680_case(f680_case_id, requests_mock, data_f680_case):
return requests_mock.get(url=url, json=data_f680_case)


@pytest.fixture
def mock_f680_case_with_submitted_by(f680_case_id, requests_mock, data_f680_case):
data_f680_case["case"]["data"]["submitted_by"] = {"first_name": "foo", "last_name": "bar"}
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(
Expand All @@ -108,6 +138,27 @@ def test_GET_success(
assert dict(response.context["case"]) == data_f680_case["case"]
soup = BeautifulSoup(response.content, "html.parser")
assert f680_reference_code in soup.find("h1").text
assert "General application details" in soup.find("h2").text
table_elems = soup.find_all("table", {"class": "application-section-general_application_details"})
assert len(table_elems) == 1
table_text = table_elems[0].text
assert (
"Do you have exceptional circumstances that mean you need F680 approval in less than 30 days?" in table_text
)
assert "some name" in table_text

def test_GET_success_transformed_submitted_by(
self,
authorized_client,
data_queue,
mock_f680_case_with_submitted_by,
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

def test_GET_not_logged_in(
self, client, data_queue, mock_f680_case, f680_case_id, f680_reference_code, data_f680_case
Expand Down
3 changes: 3 additions & 0 deletions caseworker/f680/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ def setup(self, request, *args, **kwargs):

def get_context_data(self, **kwargs):
context_data = super().get_context_data(**kwargs)
submitted_by = self.case["data"]["submitted_by"]
if submitted_by and "first_name" in submitted_by:
self.case["data"]["submitted_by"] = " ".join([submitted_by["first_name"], submitted_by["last_name"]])
context_data["case"] = self.case
return context_data
2 changes: 1 addition & 1 deletion conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,4 @@ def show_toolbar(request):
GTM_ID = env.str("GTM_ID", default="")

GIT_COMMIT = env.str("GIT_COMMIT", default="")
FEATURE_FLAG_ALLOW_F680 = env.bool("FEATURE_FLAG_ALLOW_F680", default=False)
FEATURE_FLAG_ALLOW_F680 = env.bool("FEATURE_FLAG_ALLOW_F680", default=True)
2 changes: 1 addition & 1 deletion exporter/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def has_organisation_firearm_act_document(application, document_type):


def get_organisation_firearm_act_document(application, document_type):
documents = get_organisation_documents(application)
documents = 33(application)
return documents[document_type]


Expand Down
208 changes: 208 additions & 0 deletions exporter/f680/application_sections/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,211 @@ def mock_patch_f680_application(requests_mock, data_f680_case):
application_id = data_f680_case["id"]
url = client._build_absolute_uri(f"/exporter/f680/application/{application_id}/")
return requests_mock.patch(url=url, json=data_f680_case)


@pytest.fixture
def data_f680_case(data_organisation):
return {
"id": "6cf7b401-62dc-4577-ad1d-4282f2aabc96",
"application": {"name": "F680 Test 1"},
"reference_code": None,
"organisation": {
"id": "3913ff20-5a2b-468a-bf5d-427228459b06",
"name": "Archway Communications",
"type": "commercial",
"status": "active",
},
"submitted_at": None,
"submitted_by": None,
}


@pytest.fixture
def mock_f680_application_get_existing_data(requests_mock, data_f680_case):
data_f680_case["application"] = {
"sections": {
"approval_type": {
"type": "single",
"label": "Approval type",
"fields": [
{
"key": "approval_choices",
"answer": [
"Initial discussions or promoting products",
"Demonstration in the United Kingdom to overseas customers",
"Demonstration overseas",
"Training",
"Through life support",
"Supply",
],
"datatype": "list",
"question": "Select the types of approvals you need",
"raw_answer": [
"initial_discussion_or_promoting",
"demonstration_in_uk",
"demonstration_overseas",
"training",
"through_life_support",
"supply",
],
},
{
"key": "demonstration_in_uk",
"answer": "some UK demonstration reason",
"datatype": "string",
"question": "Explain what you are demonstrating and why",
"raw_answer": "some UK demonstration reason",
},
{
"key": "demonstration_overseas",
"answer": "some overseas demonstration reason",
"datatype": "string",
"question": "Explain what you are demonstrating and why",
"raw_answer": "some overseas demonstration reason",
},
{
"key": "approval_details_text",
"answer": "some details",
"datatype": "string",
"question": "Provide details about what you're seeking approval to do",
"raw_answer": "some details",
},
],
},
"product_information": {
"label": "Product information",
"fields": [
{
"key": "product_name",
"answer": "Test Info",
"raw_answer": "Test Info",
"question": "Give the item a descriptive name",
"datatype": "string",
},
{
"key": "product_description",
"answer": "It does things",
"raw_answer": "It does things",
"question": "Describe the item",
"datatype": "string",
},
{
"key": "is_foreign_tech_or_information_shared",
"answer": "Yes",
"raw_answer": True,
"question": "Will any foreign technology or information be shared with the item?",
"datatype": "boolean",
},
{
"key": "is_controlled_under_itar",
"answer": "Yes, it's controlled under ITAR",
"raw_answer": True,
"question": "Is the technology or information controlled under the US International Traffic in Arms Regulations (ITAR)?",
"datatype": "boolean",
},
{
"key": "controlled_info",
"answer": "It just is",
"raw_answer": "It just is",
"question": "Explain how the technology or information is controlled.Include countries classification levels and reference numbers. You can upload supporting documents later in your application",
"datatype": "string",
},
{
"key": "controlled_information",
"answer": "Some info",
"raw_answer": "Some info",
"question": "What is the ITAR controlled technology or information?",
"datatype": "string",
},
{
"key": "itar_reference_number",
"answer": "123456",
"raw_answer": "123456",
"question": "ITAR reference number",
"datatype": "string",
},
{
"key": "usml_categories",
"answer": "cat 1",
"raw_answer": "cat 1",
"question": "What are the United States Munitions List (USML) categories listed on your ITAR approval?",
"datatype": "string",
},
{
"key": "itar_approval_scope",
"answer": "no scope",
"raw_answer": "no scope",
"question": "Describe the scope of your ITAR approval",
"datatype": "string",
},
{
"key": "expected_time_in_possession",
"answer": "10 years",
"raw_answer": "10 years",
"question": "How long do you expect the technology or information that is controlled under the US ITAR to be in your possession?",
"datatype": "string",
},
{
"key": "is_including_cryptography_or_security_features",
"answer": "Yes",
"raw_answer": True,
"question": "Does the item include cryptography or other information security features?",
"datatype": "boolean",
},
{
"key": "cryptography_or_security_feature_info",
"answer": "some",
"raw_answer": "some",
"question": "Provide full details",
"datatype": "string",
},
{
"key": "is_item_rated_under_mctr",
"answer": "Yes, the product is MTCR Category 1",
"raw_answer": "mtcr_1",
"question": "Do you believe the item is rated under the Missile Technology Control Regime (MTCR)",
"datatype": "string",
},
{
"key": "is_item_manpad",
"answer": "No, the product is not a MANPAD",
"raw_answer": "no",
"question": "Do you believe the item is a man-portable air defence system (MANPAD)?",
"datatype": "string",
},
{
"key": "is_mod_electronic_data_shared",
"answer": "No",
"raw_answer": "no",
"question": "Will any electronic warfare data owned by the Ministry of Defence (MOD) be shared with the item?",
"datatype": "string",
},
{
"key": "funding_source",
"answer": "MOD",
"raw_answer": "mod",
"question": "Who is funding the item?",
"datatype": "string",
},
{
"key": "is_used_by_uk_armed_forces",
"answer": "No",
"raw_answer": False,
"question": "Will the item be used by the UK Armed Forces?",
"datatype": "boolean",
},
{
"key": "used_by_uk_armed_forces_info",
"answer": "",
"raw_answer": "",
"question": "Explain how it will be used",
"datatype": "string",
},
],
"type": "single",
},
}
}
application_id = data_f680_case["id"]
url = client._build_absolute_uri(f"/exporter/f680/application/{application_id}/")
return requests_mock.get(url=url, json=data_f680_case)
Empty file.
34 changes: 34 additions & 0 deletions exporter/f680/application_sections/supporting_documents/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from core.common.forms import BaseForm
from django import forms

from core.file_handler import validate_mime_type
from exporter.core.constants import FileUploadFileTypes
from exporter.core.forms import PotentiallyUnsafeClearableFileInput


class F680AttachSupportingDocument(BaseForm):
class Layout:
TITLE = "Attach a supporting document"

file = forms.FileField(
label=FileUploadFileTypes.UPLOAD_GUIDANCE_TEXT,
error_messages={
"required": "supporting document required",
},
validators=[
validate_mime_type,
],
widget=PotentiallyUnsafeClearableFileInput,
)

description = forms.CharField(
widget=forms.Textarea(attrs={"rows": "5"}),
label="Description (optional)",
required=False,
)

def get_layout_fields(self):
return (
"file",
"description",
)
11 changes: 11 additions & 0 deletions exporter/f680/application_sections/supporting_documents/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.urls import path

from . import views


app_name = "supporting_documents"

urlpatterns = [
path("", views.SupportingDocumentsView.as_view(), name="add"),
path("attach-document/", views.SupportingDocumentsAddView.as_view(), name="attach"),
]
Loading