-
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 #2367 from uktrade/dev
UAT Release
- Loading branch information
Showing
22 changed files
with
610 additions
and
15 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.
2 changes: 2 additions & 0 deletions
2
exporter/f680/application_sections/additional_information/constants.py
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,2 @@ | ||
class FormSteps: | ||
NOTES_FOR_CASEWORKER = "NOTES_FOR_CASEWORKER" |
17 changes: 17 additions & 0 deletions
17
exporter/f680/application_sections/additional_information/forms.py
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,17 @@ | ||
from django import forms | ||
|
||
from core.common.forms import BaseForm | ||
|
||
|
||
class NotesForCaseOfficerForm(BaseForm): | ||
class Layout: | ||
TITLE = "Notes" | ||
SUBMIT_BUTTON_TEXT = "Save and continue" | ||
|
||
note = forms.CharField( | ||
label="Add note", | ||
widget=forms.Textarea(attrs={"cols": "80"}), | ||
) | ||
|
||
def get_layout_fields(self): | ||
return ("note",) |
Empty file.
153 changes: 153 additions & 0 deletions
153
exporter/f680/application_sections/additional_information/tests/test_views.py
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,153 @@ | ||
import pytest | ||
|
||
from django.urls import reverse | ||
|
||
from core import client | ||
|
||
from ..forms import NotesForCaseOfficerForm | ||
from ..constants import FormSteps | ||
|
||
|
||
@pytest.fixture() | ||
def unset_f680_feature_flag(settings): | ||
settings.FEATURE_FLAG_ALLOW_F680 = False | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def setup(mock_exporter_user_me, settings): | ||
settings.FEATURE_FLAG_ALLOW_F680 = True | ||
|
||
|
||
@pytest.fixture | ||
def missing_application_id(): | ||
return "6bb0828c-1520-4624-b729-7f3e6e5b9f5d" | ||
|
||
|
||
@pytest.fixture | ||
def missing_f680_application_wizard_url(missing_application_id): | ||
return reverse( | ||
"f680:additional_information:notes_wizard", | ||
kwargs={"pk": missing_application_id}, | ||
) | ||
|
||
|
||
@pytest.fixture | ||
def f680_application_wizard_url(data_f680_case): | ||
return reverse( | ||
"f680:additional_information:notes_wizard", | ||
kwargs={"pk": data_f680_case["id"]}, | ||
) | ||
|
||
|
||
@pytest.fixture | ||
def mock_f680_application_get_404(requests_mock, missing_application_id): | ||
url = client._build_absolute_uri(f"/exporter/f680/application/{missing_application_id}/") | ||
return requests_mock.get(url=url, json={}, status_code=404) | ||
|
||
|
||
@pytest.fixture | ||
def mock_f680_application_get(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.get(url=url, json=data_f680_case) | ||
|
||
|
||
@pytest.fixture | ||
def mock_f680_application_get_existing_data(requests_mock, data_f680_case): | ||
data_f680_case["application"] = { | ||
"additional_information": {"answers": {"note": "Some note text"}, "questions": {"note": "Add note"}} | ||
} | ||
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) | ||
|
||
|
||
@pytest.fixture | ||
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 post_to_step(post_to_step_factory, f680_application_wizard_url): | ||
return post_to_step_factory(f680_application_wizard_url) | ||
|
||
|
||
@pytest.fixture | ||
def goto_step(goto_step_factory, f680_application_wizard_url): | ||
return goto_step_factory(f680_application_wizard_url) | ||
|
||
|
||
class TestAdditionalInformationView: | ||
|
||
def test_GET_no_application_404( | ||
self, | ||
authorized_client, | ||
missing_f680_application_wizard_url, | ||
mock_f680_application_get_404, | ||
): | ||
response = authorized_client.get(missing_f680_application_wizard_url) | ||
assert response.status_code == 404 | ||
|
||
def test_GET_success( | ||
self, | ||
authorized_client, | ||
mock_f680_application_get, | ||
f680_application_wizard_url, | ||
): | ||
response = authorized_client.get(f680_application_wizard_url) | ||
assert response.status_code == 200 | ||
assert isinstance(response.context["form"], NotesForCaseOfficerForm) | ||
|
||
def test_GET_no_feature_flag_forbidden( | ||
self, | ||
authorized_client, | ||
mock_f680_application_get, | ||
f680_application_wizard_url, | ||
unset_f680_feature_flag, | ||
): | ||
response = authorized_client.get(f680_application_wizard_url) | ||
assert response.status_code == 200 | ||
assert response.context["title"] == "Forbidden" | ||
|
||
def test_POST_approval_type_and_submit_wizard_success( | ||
self, post_to_step, goto_step, mock_f680_application_get, mock_patch_f680_application | ||
): | ||
response = post_to_step( | ||
FormSteps.NOTES_FOR_CASEWORKER, | ||
{"note": "Some information"}, | ||
) | ||
assert response.status_code == 302 | ||
assert mock_patch_f680_application.called_once | ||
assert mock_patch_f680_application.last_request.json() == { | ||
"application": { | ||
"name": "F680 Test 1", | ||
"additional_information": {"answers": {"note": "Some information"}, "questions": {"note": "Add note"}}, | ||
} | ||
} | ||
|
||
def test_POST_to_step_validation_error( | ||
self, | ||
post_to_step, | ||
goto_step, | ||
mock_f680_application_get, | ||
): | ||
goto_step(FormSteps.NOTES_FOR_CASEWORKER) | ||
response = post_to_step( | ||
FormSteps.NOTES_FOR_CASEWORKER, | ||
{}, | ||
) | ||
assert response.status_code == 200 | ||
assert response.context["form"]["note"].errors == ["This field is required."] | ||
|
||
def test_GET_with_existing_data_success( | ||
self, | ||
authorized_client, | ||
mock_f680_application_get_existing_data, | ||
f680_application_wizard_url, | ||
): | ||
response = authorized_client.get(f680_application_wizard_url) | ||
assert response.status_code == 200 | ||
assert isinstance(response.context["form"], NotesForCaseOfficerForm) | ||
assert response.context["form"]["note"].initial == "Some note text" |
10 changes: 10 additions & 0 deletions
10
exporter/f680/application_sections/additional_information/urls.py
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,10 @@ | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
|
||
app_name = "additional_information" | ||
|
||
urlpatterns = [ | ||
path("notes/", views.NotesForCaseOfficersView.as_view(), name="notes_wizard"), | ||
] |
11 changes: 11 additions & 0 deletions
11
exporter/f680/application_sections/additional_information/views.py
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,11 @@ | ||
from exporter.f680.application_sections.views import F680ApplicationSectionWizard | ||
|
||
from .constants import FormSteps | ||
from .forms import NotesForCaseOfficerForm | ||
|
||
|
||
class NotesForCaseOfficersView(F680ApplicationSectionWizard): | ||
form_list = [ | ||
(FormSteps.NOTES_FOR_CASEWORKER, NotesForCaseOfficerForm), | ||
] | ||
section = "additional_information" |
Empty file.
2 changes: 2 additions & 0 deletions
2
exporter/f680/application_sections/approval_details/constants.py
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,2 @@ | ||
class FormSteps: | ||
APPROVAL_TYPE = "APPROVAL_TYPE" |
84 changes: 84 additions & 0 deletions
84
exporter/f680/application_sections/approval_details/forms.py
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,84 @@ | ||
from django import forms | ||
from django.db.models import TextChoices | ||
from django.template.loader import render_to_string | ||
|
||
from crispy_forms_gds.layout.content import HTML | ||
|
||
from core.common.forms import BaseForm, TextChoice | ||
from core.forms.layouts import F680ConditionalCheckboxes, F680ConditionalCheckboxesQuestion | ||
|
||
|
||
class ApprovalTypeForm(BaseForm): | ||
class Layout: | ||
TITLE = "Select the types of approvals you need" | ||
TITLE_AS_LABEL_FOR = "approval_choices" | ||
SUBMIT_BUTTON_TEXT = "Save and continue" | ||
|
||
class ApprovalTypeChoices(TextChoices): | ||
INITIAL_DISCUSSIONS_OR_PROMOTING = ( | ||
"initial_discussion_or_promoting", | ||
"Initial discussions or promoting products", | ||
) | ||
DEMONSTRATION_IN_THE_UK = ( | ||
"demonstration_in_uk", | ||
"Demonstration in the United Kingdom to overseas customers", | ||
) | ||
DEMONSTRATION_OVERSEAS = "demonstration_overseas", "Demonstration overseas" | ||
TRAINING = "training", "Training" | ||
THROUGH_LIFE_SUPPORT = "through_life_support", "Through life support" | ||
SUPPLY = "supply", "Supply" | ||
|
||
ApprovalTypeChoices = ( | ||
TextChoice(ApprovalTypeChoices.INITIAL_DISCUSSIONS_OR_PROMOTING), | ||
TextChoice(ApprovalTypeChoices.DEMONSTRATION_IN_THE_UK), | ||
TextChoice(ApprovalTypeChoices.DEMONSTRATION_OVERSEAS), | ||
TextChoice(ApprovalTypeChoices.TRAINING), | ||
TextChoice(ApprovalTypeChoices.THROUGH_LIFE_SUPPORT), | ||
TextChoice(ApprovalTypeChoices.SUPPLY), | ||
) | ||
|
||
approval_choices = forms.MultipleChoiceField( | ||
label=Layout.TITLE, | ||
choices=(), | ||
error_messages={ | ||
"required": "Select an approval choice", | ||
}, | ||
widget=forms.CheckboxSelectMultiple(), | ||
) | ||
|
||
demonstration_in_uk = forms.CharField( | ||
label="Explain what you are demonstrating and why", | ||
help_text="Explain what materials will be involved and if you'll use a substitute product", | ||
widget=forms.Textarea(attrs={"rows": 5}), | ||
required=False, | ||
) | ||
|
||
demonstration_overseas = forms.CharField( | ||
label="Explain what you are demonstrating and why", | ||
help_text="Explain what materials will be involved and if you'll use a substitute product", | ||
widget=forms.Textarea(attrs={"rows": 5}), | ||
required=False, | ||
) | ||
|
||
approval_details_text = forms.CharField( | ||
label="Provide details about what you're seeking approval to do", | ||
widget=forms.Textarea(attrs={"rows": 5}), | ||
required=False, | ||
) | ||
|
||
def __init__(self, *args, **kwargs): | ||
self.conditional_checkbox_choices = ( | ||
F680ConditionalCheckboxesQuestion(choices.label, choices.value) for choices in self.ApprovalTypeChoices | ||
) | ||
super().__init__(*args, **kwargs) | ||
self.fields["approval_choices"].choices = self.ApprovalTypeChoices | ||
|
||
def get_layout_fields(self): | ||
return ( | ||
F680ConditionalCheckboxes("approval_choices", *self.conditional_checkbox_choices), | ||
"approval_details_text", | ||
HTML.details( | ||
"Help with exceptional circumstances", | ||
render_to_string("f680/forms/help_with_approval_type.html"), | ||
), | ||
) |
Empty file.
Oops, something went wrong.