View recommendation
{% if my_advice %}
- {% test_rule 'can_user_make_desnz_edit' request case as can_user_make_desnz_edit %}
+ {% test_rule 'can_user_make_edit' request case as can_user_make_edit %}
{% if buttons.edit_recommendation %}
- {% if can_user_make_desnz_edit %}
+ {% if can_user_make_edit %}
Edit recommendation
{% else %}
Edit recommendation
diff --git a/caseworker/advice/urls.py b/caseworker/advice/urls.py
index b104d7a086..08ebf0becd 100644
--- a/caseworker/advice/urls.py
+++ b/caseworker/advice/urls.py
@@ -1,13 +1,13 @@
from django.urls import path
from caseworker.advice.views import consolidate, views
-from caseworker.advice.views.approval import GiveApprovalAdviceView
+from caseworker.advice.views.approval import GiveApprovalAdviceView, SelectAdviceView
from caseworker.advice.views.edit import EditAdviceView
urlpatterns = [
path("", views.AdviceView.as_view(), name="advice_view"),
path("case-details/", views.CaseDetailView.as_view(), name="case_details"),
- path("select-advice/", views.SelectAdviceView.as_view(), name="select_advice"),
+ path("select-advice/", SelectAdviceView.as_view(), name="select_advice"),
path("approve-all-legacy/", views.GiveApprovalAdviceViewLegacy.as_view(), name="approve_all_legacy"),
path("approve-all/", GiveApprovalAdviceView.as_view(), name="approve_all"),
path("refuse-all/", views.RefusalAdviceView.as_view(), name="refuse_all"),
diff --git a/caseworker/advice/views/approval.py b/caseworker/advice/views/approval.py
index 4565fb8cce..7c10c60934 100644
--- a/caseworker/advice/views/approval.py
+++ b/caseworker/advice/views/approval.py
@@ -1,10 +1,11 @@
from http import HTTPStatus
-from caseworker.advice.conditionals import form_add_licence_conditions, is_desnz_team
+from caseworker.advice.conditionals import form_add_licence_conditions, is_fcdo_team
from caseworker.advice.forms.approval import (
FootnotesApprovalAdviceForm,
PicklistLicenceConditionsForm,
SimpleLicenceConditionsForm,
RecommendAnApprovalForm,
+ SelectAdviceForm,
)
from caseworker.advice.payloads import GiveApprovalAdvicePayloadBuilder
from caseworker.advice.picklist_helpers import approval_picklist, footnote_picklist, proviso_picklist
@@ -14,16 +15,37 @@
from django.urls import reverse
from caseworker.advice.views.mixins import CaseContextMixin
from caseworker.advice import services
-
from caseworker.advice.constants import AdviceSteps
from core.auth.views import LoginRequiredMixin
from core.decorators import expect_status
+from django.views.generic import FormView
+
+
+class SelectAdviceView(LoginRequiredMixin, CaseContextMixin, FormView):
+ template_name = "advice/select_advice.html"
+ form_class = SelectAdviceForm
+
+ def get_success_url(self):
+ if self.recommendation == "approve_all":
+ if self.caseworker["team"]["alias"] == services.FCDO_TEAM:
+ return reverse("cases:approve_all_legacy", kwargs=self.kwargs)
+ return reverse("cases:approve_all", kwargs=self.kwargs)
+ else:
+ return reverse("cases:refuse_all", kwargs=self.kwargs)
+
+ def form_valid(self, form):
+ self.recommendation = form.cleaned_data["recommendation"]
+ return super().form_valid(form)
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ return {**context, "security_approvals_classified_display": self.security_approvals_classified_display}
class BaseApprovalAdviceView(LoginRequiredMixin, CaseContextMixin, BaseSessionWizardView):
condition_dict = {
- AdviceSteps.RECOMMEND_APPROVAL: C(is_desnz_team),
+ AdviceSteps.RECOMMEND_APPROVAL: ~C(is_fcdo_team),
AdviceSteps.LICENCE_CONDITIONS: C(form_add_licence_conditions(AdviceSteps.RECOMMEND_APPROVAL)),
AdviceSteps.LICENCE_FOOTNOTES: C(form_add_licence_conditions(AdviceSteps.RECOMMEND_APPROVAL)),
}
diff --git a/caseworker/advice/views/views.py b/caseworker/advice/views/views.py
index 67a258e737..9fd9e8bd71 100644
--- a/caseworker/advice/views/views.py
+++ b/caseworker/advice/views/views.py
@@ -1,5 +1,5 @@
from http import HTTPStatus
-from caseworker.advice.forms.approval import MoveCaseForwardForm, SelectAdviceForm
+from caseworker.advice.forms.approval import MoveCaseForwardForm
from caseworker.advice.forms.consolidate import (
ConsolidateApprovalForm,
LUConsolidateRefusalForm,
@@ -50,24 +50,6 @@ class CaseDetailView(LoginRequiredMixin, CaseContextMixin, TemplateView):
template_name = "advice/case_detail_example.html"
-class SelectAdviceView(LoginRequiredMixin, CaseContextMixin, FormView):
- template_name = "advice/select_advice.html"
- form_class = SelectAdviceForm
-
- def get_success_url(self):
- recommendation = self.request.POST.get("recommendation")
- if recommendation == "approve_all":
- if self.caseworker["team"]["alias"] in services.DESNZ_TEAMS:
- return reverse("cases:approve_all", kwargs=self.kwargs)
- return reverse("cases:approve_all_legacy", kwargs=self.kwargs)
- else:
- return reverse("cases:refuse_all", kwargs=self.kwargs)
-
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- return {**context, "security_approvals_classified_display": self.security_approvals_classified_display}
-
-
class GiveApprovalAdviceViewLegacy(LoginRequiredMixin, CaseContextMixin, FormView):
"""
Form to recommend approval advice for all products on the application
@@ -76,13 +58,10 @@ class GiveApprovalAdviceViewLegacy(LoginRequiredMixin, CaseContextMixin, FormVie
template_name = "advice/give-approval-advice.html"
def get_form(self):
- if self.caseworker["team"]["alias"] == services.FCDO_TEAM:
- return FCDOApprovalAdviceForm(
- services.unadvised_countries(self.caseworker, self.case),
- **self.get_form_kwargs(),
- )
- else:
- return GiveApprovalAdviceForm(**self.get_form_kwargs())
+ return FCDOApprovalAdviceForm(
+ services.unadvised_countries(self.caseworker, self.case),
+ **self.get_form_kwargs(),
+ )
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
diff --git a/conf/caseworker.py b/conf/caseworker.py
index 70820fdbd3..5816548d62 100644
--- a/conf/caseworker.py
+++ b/conf/caseworker.py
@@ -134,3 +134,4 @@
# using it here as some browsers still don't support CSP_REPORT_TO which replaces it
CSP_REPORT_URI = env.tuple("CASEWORKER_CSP_REPORT_URI", default=("",))
+E2E_WAIT_MULTIPLIER = env.int("E2E_WAIT_MULTIPLIER", default=1)
diff --git a/conf/exporter.py b/conf/exporter.py
index 2879f0d034..c2baebadfe 100644
--- a/conf/exporter.py
+++ b/conf/exporter.py
@@ -129,3 +129,4 @@
# using it here as some browsers still don't support CSP_REPORT_TO which replaces it
CSP_REPORT_URI = env.tuple("EXPORTER_CSP_REPORT_URI", default=("",))
+E2E_WAIT_MULTIPLIER = env.int("E2E_WAIT_MULTIPLIER", default=1)
diff --git a/tests_common/functions.py b/tests_common/functions.py
index 484e8ae233..c4ed6b12c4 100644
--- a/tests_common/functions.py
+++ b/tests_common/functions.py
@@ -7,6 +7,7 @@
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
+from django.conf import settings
def click_submit(driver: WebDriver):
@@ -70,7 +71,7 @@ def select_multi_select_options(driver: WebDriver, element_selector: str, option
element = driver.find_element(by=By.CSS_SELECTOR, value=element_selector)
element.send_keys(option)
element.send_keys(Keys.ENTER)
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located(
(By.XPATH, f"//span[@class='selected-options__option-text' and contains(text(), '{option}')]")
),
@@ -83,17 +84,17 @@ def click_apply_filters(driver: WebDriver):
def open_case_filters(driver: WebDriver):
if not driver.find_element(by=By.CLASS_NAME, value="case-filters").is_displayed():
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, "show-filters-link"))
).click()
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.element_to_be_clickable((By.ID, "accordion-case-filters"))
).click()
def try_open_filters(driver: WebDriver):
if not driver.find_element(by=By.CLASS_NAME, value="lite-filter-bar").is_displayed():
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, "show-filters-link"))
).click()
@@ -115,7 +116,7 @@ def click_next_page(driver: WebDriver):
def select_report_summary_subject_and_fill(driver, subject):
suggestion_input_autocomplete = driver.find_element(by=By.ID, value="_report_summary_subject")
suggestion_input_autocomplete.send_keys(subject)
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.text_to_be_present_in_element(
(By.CSS_SELECTOR, ".lite-autocomplete__menu--visible #_report_summary_subject__option--0"),
subject,
@@ -128,7 +129,7 @@ def select_report_summary_subject_and_fill(driver, subject):
def select_report_summary_prefix_and_fill(driver, prefix):
suggestion_input_autocomplete = driver.find_element(by=By.ID, value="_report_summary_prefix")
suggestion_input_autocomplete.send_keys(prefix)
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.text_to_be_present_in_element(
(By.CSS_SELECTOR, ".lite-autocomplete__menu--visible #_report_summary_prefix__option--0"),
prefix,
diff --git a/ui_tests/caseworker/conftest.py b/ui_tests/caseworker/conftest.py
index d42c1d3cc4..20dcdd35a4 100644
--- a/ui_tests/caseworker/conftest.py
+++ b/ui_tests/caseworker/conftest.py
@@ -284,7 +284,7 @@ def prepare_case(api_test_client, nlr): # noqa
def submit_form(driver): # noqa
old_page = driver.find_element(by=By.TAG_NAME, value="html")
Shared(driver).click_submit()
- WebDriverWait(driver, 45).until(expected_conditions.staleness_of(old_page))
+ WebDriverWait(driver, 45 * settings.E2E_WAIT_MULTIPLIER).until(expected_conditions.staleness_of(old_page))
@when(parsers.parse('I click the text "{text}"'))
@@ -295,7 +295,7 @@ def click_text(driver, text): # noqa
@when(parsers.parse('I click "{button_text}"'))
def click_button_with_text(driver, button_text): # noqa
- WebDriverWait(driver, 20).until(
+ WebDriverWait(driver, 20 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located(
(
By.XPATH,
@@ -396,21 +396,28 @@ def case_list_page(driver, internal_url): # noqa
@when("I go to my profile page") # noqa
def get_profile_page(driver): # noqa
- WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.ID, "link-profile"))).click()
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
+ expected_conditions.presence_of_element_located((By.ID, "link-profile"))
+ ).click()
@when(parsers.parse('I change my team to "{team}" and default queue to "{queue}"')) # noqa
def go_to_team_edit_page(driver, team, queue): # noqa
# we should already be on the profile page
- WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.ID, "link-edit-team"))).click()
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
+ expected_conditions.presence_of_element_located((By.ID, "link-edit-team"))
+ ).click()
teams_page = TeamsPages(driver)
teams_page.select_team_from_dropdown(team)
teams_page.select_default_queue_from_dropdown(queue)
functions.click_submit(driver)
# Ensure we return to the profile page
- WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.ID, "link-edit-team")))
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
+ expected_conditions.presence_of_element_located((By.ID, "link-edit-team"))
+ )
# Check that the team/queue change was applied successfully
assert driver.find_element(by=By.ID, value="user-team-name").text == team
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER)
assert driver.find_element(by=By.ID, value="user-default-queue").text == queue
@@ -432,7 +439,9 @@ def system_queue_shown_in_dropdown(driver, queue_name): # noqa
@when(parsers.parse('I switch to "{queue_name}" queue')) # noqa
def switch_to_queue(driver, queue_name): # noqa
driver.find_element(by=By.ID, value="link-queue").click()
- WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.ID, "filter-queues")))
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
+ expected_conditions.presence_of_element_located((By.ID, "filter-queues"))
+ )
driver.find_element(by=By.ID, value="filter-queues").send_keys(queue_name)
elements = [
item
@@ -678,7 +687,7 @@ def click_edit_case_flags_link(driver, flag_name):
old_page = driver.find_element(by=By.TAG_NAME, value="html")
functions.click_submit(driver)
- WebDriverWait(driver, 45).until(expected_conditions.staleness_of(old_page))
+ WebDriverWait(driver, 45 * settings.E2E_WAIT_MULTIPLIER).until(expected_conditions.staleness_of(old_page))
@given(parsers.parse('the status is set to "{status}"')) # noqa
@@ -1005,7 +1014,7 @@ def approve_case_as_team(driver, team, queue, context, internal_url, internal_in
recommendation_and_decisions_page.click_make_recommendation()
recommendation_and_decisions_page.click_approve_all()
Shared(driver).click_submit()
- recommendation_and_decisions_page.enter_reasons_for_approving("approving")
+ recommendation_and_decisions_page.enter_approval_reasons("approving")
functions.click_submit(driver) # Submit recommmendation
functions.click_submit(driver) # Move case forward
click_on_created_application(driver, context, internal_url)
diff --git a/ui_tests/caseworker/features/give_advice/lu_consolidate_advice.feature b/ui_tests/caseworker/features/give_advice/lu_consolidate_advice.feature
index 25b69321fc..72755b3432 100644
--- a/ui_tests/caseworker/features/give_advice/lu_consolidate_advice.feature
+++ b/ui_tests/caseworker/features/give_advice/lu_consolidate_advice.feature
@@ -99,17 +99,20 @@ Feature: I want to record my user advice and any comments and conditions relatin
And I click make recommendation
And I click approve all
And I click continue
- And I enter "reason for approving" as the reasons for approving
- And I click the text "Add a licence condition, instruction to exporter or footnote"
- And I enter "MOD licence condition" as the licence condition
- And I enter "instruction for exporter" as the instructions for the exporter
- And I enter "reporting footnote" as the reporting footnote
+ And I enter "reason for approving" as the approval reasons
+ And I click add licence condition
+ And I click continue
+ And I enter "MOD licence condition" into the licence condition
+ And I click continue
+ And I enter "instruction for exporter" as the instructions for the exporter on the instructions step
+ And I enter "reporting footnote" as the reporting footnote on the instructions step
And I click submit recommendation
Then I see "reason for approving" as the reasons for approving
And I see "MOD licence condition" as the licence condition
And I see "instruction for exporter" as the instructions for the exporter
And I see "reporting footnote" as the reporting footnote
+
##### FCDO Sub-advisor to give advice #####
When I go to my profile page
And I change my team to "FCDO" and default queue to "FCDO Cases to Review"
diff --git a/ui_tests/caseworker/features/give_advice/mod_approve_advice.feature b/ui_tests/caseworker/features/give_advice/mod_approve_advice.feature
index 949cd0e657..6cc0695655 100644
--- a/ui_tests/caseworker/features/give_advice/mod_approve_advice.feature
+++ b/ui_tests/caseworker/features/give_advice/mod_approve_advice.feature
@@ -51,16 +51,19 @@ Feature: I want to record my user advice and any comments and conditions relatin
And I click make recommendation
And I click approve all
And I click continue
- And I enter "reason for approving" as the reasons for approving
- And I click the text "Add a licence condition, instruction to exporter or footnote"
- And I enter "licence condition" as the licence condition
- And I enter "instruction for exporter" as the instructions for the exporter
- And I enter "reporting footnote" as the reporting footnote
- And I click submit recommendation
+ And I enter "reason for approving" as the approval reasons
+ And I click add licence condition
+ And I click continue
+ And I enter "licence condition" into the licence condition
+ And I click continue
+ And I enter "instruction for exporter" as the instructions for the exporter on the instructions step
+ And I enter "reporting footnote" as the reporting footnote on the instructions step
+ And I click continue
Then I see "reason for approving" as the reasons for approving
And I see "licence condition" as the licence condition
And I see "instruction for exporter" as the instructions for the exporter
And I see "reporting footnote" as the reporting footnote
+
When I click move case forward
Then I don't see previously created application
diff --git a/ui_tests/caseworker/features/give_advice/mod_clear_advice.feature b/ui_tests/caseworker/features/give_advice/mod_clear_advice.feature
index 2adb9f834f..39e813b961 100644
--- a/ui_tests/caseworker/features/give_advice/mod_clear_advice.feature
+++ b/ui_tests/caseworker/features/give_advice/mod_clear_advice.feature
@@ -19,13 +19,15 @@ Feature: I want to record my user advice and any comments and conditions relatin
And I click make recommendation
And I click approve all
And I click continue
- And I enter "reason for approving" as the reasons for approving
- And I click the text "Add a licence condition, instruction to exporter or footnote"
- And I enter "licence condition" as the licence condition
- And I enter "instruction for exporter" as the instructions for the exporter
- And I enter "reporting footnote" as the reporting footnote
- And I click submit recommendation
- Then I see "reason for approving" as the reasons for approving
+ And I enter "approval reason" as the approval reasons
+ And I click add licence condition
+ And I click continue
+ And I enter "licence condition" into the licence condition
+ And I click continue
+ And I enter "instruction for exporter" as the instructions for the exporter on the instructions step
+ And I enter "reporting footnote" as the reporting footnote on the instructions step
+ And I click continue
+ Then I see "approval reason" as the reasons for approving
And I see "licence condition" as the licence condition
And I see "instruction for exporter" as the instructions for the exporter
And I see "reporting footnote" as the reporting footnote
diff --git a/ui_tests/caseworker/features/give_advice/mod_edit_advice.feature b/ui_tests/caseworker/features/give_advice/mod_edit_advice.feature
index a3fe28166a..9de6d73403 100644
--- a/ui_tests/caseworker/features/give_advice/mod_edit_advice.feature
+++ b/ui_tests/caseworker/features/give_advice/mod_edit_advice.feature
@@ -19,23 +19,26 @@ Feature: I want to record my user advice and any comments and conditions relatin
And I click make recommendation
And I click approve all
And I click continue
- And I enter "reason for approving" as the reasons for approving
- And I click the text "Add a licence condition, instruction to exporter or footnote"
- And I enter "licence condition" as the licence condition
- And I enter "instruction for exporter" as the instructions for the exporter
- And I enter "reporting footnote" as the reporting footnote
- And I click submit recommendation
- Then I see "reason for approving" as the reasons for approving
+ And I enter "approval reason" as the approval reasons
+ And I click add licence condition
+ And I click continue
+ And I enter "licence condition" into the licence condition
+ And I click continue
+ And I enter "instruction for exporter" as the instructions for the exporter on the instructions step
+ And I enter "reporting footnote" as the reporting footnote on the instructions step
+ And I click continue
+ Then I see "approval reason" as the reasons for approving
And I see "licence condition" as the licence condition
And I see "instruction for exporter" as the instructions for the exporter
And I see "reporting footnote" as the reporting footnote
When I click "Edit recommendation"
- And I enter "reason for approving1" as the reasons for approving
- And I click the text "Add a licence condition, instruction to exporter or footnote"
- And I enter "licence condition1" as the licence condition
- And I enter "instruction for exporter1" as the instructions for the exporter
- And I enter "reporting footnote1" as the reporting footnote
- And I click submit recommendation
+ And I enter "reason for approving1" as the approval reasons
+ And I click continue
+ And I enter "licence condition1" into the licence condition
+ And I click continue
+ And I enter "instruction for exporter1" as the instructions for the exporter on the instructions step
+ And I enter "reporting footnote1" as the reporting footnote on the instructions step
+ And I click continue
Then I see "reason for approving1" as the reasons for approving
And I see "licence condition1" as the licence condition
And I see "instruction for exporter1" as the instructions for the exporter
diff --git a/ui_tests/caseworker/features/give_advice/ogd_approve_advice.feature b/ui_tests/caseworker/features/give_advice/ogd_approve_advice.feature
new file mode 100644
index 0000000000..f7a13d9605
--- /dev/null
+++ b/ui_tests/caseworker/features/give_advice/ogd_approve_advice.feature
@@ -0,0 +1,35 @@
+@all @internal @give_advice
+Feature: I want to record my user advice and any comments and conditions relating to my recommendation
+ As a logged in government user working on a specific case that is assigned to me
+ I want to record my user advice and any comments and conditions relating to my recommendation
+ So that other users can see my decision and know that I have finished assessing this case
+
+ @ogd_approve_advice
+ Scenario: DESNZ to approve advice journey
+ Given I sign in as Test UAT user
+ And I create standard application or standard application has been previously created
+ When I go to application previously created
+ And I assign myself to the case
+ And I assign the case to "DESNZ Chemical cases to review" queue
+ And I go to my profile page
+ And I change my team to "DESNZ Chemical" and default queue to "DESNZ Chemical cases to review"
+ And I go to my case list
+ And I click the application previously created
+ And I click the recommendations and decision tab
+ And I click make recommendation
+ And I click approve all
+ And I click continue
+ And I enter "Hello World" as the approval reasons
+ And I click add licence condition
+ And I click continue
+ And I enter "licence condition" into the licence condition
+ And I click continue
+ And I enter "instruction for exporter" as the instructions for the exporter on the instructions step
+ And I enter "reporting footnote" as the reporting footnote on the instructions step
+ And I click continue
+ Then I see "Hello World" as the reasons for approving
+ And I see "licence condition" as the licence condition
+ And I see "instruction for exporter" as the instructions for the exporter
+ And I see "reporting footnote" as the reporting footnote
+ When I click move case forward
+ Then I don't see previously created application
diff --git a/ui_tests/caseworker/pages/BasePage.py b/ui_tests/caseworker/pages/BasePage.py
index 4f12d577dc..c35cb44741 100644
--- a/ui_tests/caseworker/pages/BasePage.py
+++ b/ui_tests/caseworker/pages/BasePage.py
@@ -4,6 +4,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from tests_common import functions
+from django.conf import settings
class BasePage:
@@ -12,7 +13,9 @@ def __init__(self, driver: WebDriver):
# Wait for the cases list to load before interacting with the page
if functions.element_with_id_exists(self.driver, "link-queue"):
- WebDriverWait(driver, 60).until(expected_conditions.visibility_of_element_located((By.ID, "all-cases-tab")))
+ WebDriverWait(driver, 60 * settings.E2E_WAIT_MULTIPLIER).until(
+ expected_conditions.visibility_of_element_located((By.ID, "all-cases-tab"))
+ )
# The case header is sticky and can often overlay elements preventing clicks,
# therefore disable the stickyness of the header when running tests
diff --git a/ui_tests/caseworker/pages/add_denial_records_page.py b/ui_tests/caseworker/pages/add_denial_records_page.py
index c456219a13..6153a2573d 100644
--- a/ui_tests/caseworker/pages/add_denial_records_page.py
+++ b/ui_tests/caseworker/pages/add_denial_records_page.py
@@ -7,6 +7,7 @@
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
+from django.conf import settings
from ui_tests.caseworker.pages.BasePage import BasePage
@@ -14,7 +15,7 @@ class AddDenialRecordsPage(BasePage):
CSV_FILE_LOCATION = "/tmp/downloads/example-denials.csv"
def download_example_csv_file(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.LINK_TEXT, "Download an example .csv file"))
).click()
diff --git a/ui_tests/caseworker/pages/advice.py b/ui_tests/caseworker/pages/advice.py
index 47d685c6d6..b019a469af 100644
--- a/ui_tests/caseworker/pages/advice.py
+++ b/ui_tests/caseworker/pages/advice.py
@@ -104,6 +104,11 @@ def click_approve_all(self):
def click_refuse_all(self):
self.driver.find_element(by=By.XPATH, value="//input[@type='radio' and @value='refuse_all']").click()
+ def click_add_licence_condition(self):
+ self.driver.find_element(
+ by=By.XPATH, value="//input[@id='id_recommend_approval-add_licence_conditions']"
+ ).click()
+
def select_country(self, country):
self.driver.find_element(by=By.XPATH, value=f"//input[@type='checkbox' and @value='{country}']").click()
@@ -115,6 +120,11 @@ def enter_reasons_for_approving(self, reasons):
el.clear()
el.send_keys(reasons)
+ def enter_approval_reasons(self, reasons):
+ el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='recommend_approval-approval_reasons']")
+ el.clear()
+ el.send_keys(reasons)
+
def enter_reasons_for_refusal(self, reasons):
el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='refusal_reasons']")
el.clear()
@@ -125,17 +135,42 @@ def enter_refusal_note(self, note):
el.clear()
el.send_keys(note)
- def enter_licence_condition(self, licence_condition):
- el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='proviso']")
+ def enter_licence_condition(self, licence_condition, condition_selected):
+ self.driver.find_element(
+ by=By.XPATH, value=f"//input[@type='checkbox' and @value='{condition_selected}']"
+ ).click()
+ el = self.driver.find_element(by=By.XPATH, value=f"//textarea[@name='licence_conditions-{condition_selected}']")
+ el.clear()
+ el.send_keys(licence_condition)
+
+ def enter_licence_condition_edit(self, licence_condition):
+ el = self.driver.find_element(by=By.XPATH, value=f"//textarea[@name='licence_conditions-proviso']")
el.clear()
el.send_keys(licence_condition)
def enter_instructions_for_exporter(self, instructions):
- el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='instructions_to_exporter']")
+ el = self.driver.find_element(
+ by=By.XPATH, value="//textarea[@name='licence_footnotes-instructions_to_exporter']"
+ )
el.clear()
el.send_keys(instructions)
def enter_reporting_footnote(self, footnote):
+ el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='licence_footnotes-footnote_details']")
+ el.clear()
+ el.send_keys(footnote)
+
+ def enter_licence_condition_legacy(self, licence_condition):
+ el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='proviso']")
+ el.clear()
+ el.send_keys(licence_condition)
+
+ def enter_instructions_for_exporter_legacy(self, instructions):
+ el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='instructions_to_exporter']")
+ el.clear()
+ el.send_keys(instructions)
+
+ def enter_reporting_footnote_legacy(self, footnote):
el = self.driver.find_element(by=By.XPATH, value="//textarea[@name='footnote_details']")
el.clear()
el.send_keys(footnote)
diff --git a/ui_tests/caseworker/pages/application_page.py b/ui_tests/caseworker/pages/application_page.py
index efd6716fb2..c3764fbe5d 100644
--- a/ui_tests/caseworker/pages/application_page.py
+++ b/ui_tests/caseworker/pages/application_page.py
@@ -4,6 +4,7 @@
from selenium.webdriver.support.ui import Select
from tests_common import functions
+from django.conf import settings
from ui_tests.caseworker.pages.BasePage import BasePage
from tests_common.tools.helpers import scroll_to_element_by_id
from tests_common.tools.helpers import scroll_to_element_below_header_by_id
@@ -67,7 +68,7 @@ def get_case_copy_of_field_href(self):
return self.driver.find_element(by=By.ID, value=self.CASE_COPY_OF_ID).get_attribute("href")
def click_visible_to_exporter_checkbox(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.IS_VISIBLE_TO_EXPORTER_CHECKBOX_ID))
).click()
@@ -82,7 +83,7 @@ def get_text_of_case_note_field(self):
return self.driver.find_element(by=By.ID, value=self.INPUT_CASE_NOTE_ID).text
def click_post_note_btn(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located(
(By.CSS_SELECTOR, f"#{self.BUTTON_POST_NOTE_ID}:not([disabled])")
)
@@ -90,7 +91,7 @@ def click_post_note_btn(self):
functions.click_submit(self.driver)
def click_cancel_btn(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.LINK_CANCEL_NOTE_ID))
).click()
@@ -150,7 +151,7 @@ def select_a_good(self):
self.driver.execute_script("arguments[0].click();", element)
def click_move_case_button(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.MOVE_CASE_BUTTON))
).click()
@@ -241,7 +242,7 @@ def click_assign_user_button(self):
self.driver.find_element(by=By.ID, value=self.ASSIGN_USER_ID).click()
def click_im_done_button(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.BUTTON_IM_DONE_ID))
).click()
@@ -305,7 +306,7 @@ def get_matches(self, match_type):
"""Return a list of names that have denial matches based on
the supplied match_type - one of "PARTIAL MATCH" or "EXACT MATCH".
"""
- table = WebDriverWait(self.driver, 30).until(
+ table = WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.XPATH, "//table[@id='table-denial-matches']"))
)
diff --git a/ui_tests/caseworker/pages/case_list_page.py b/ui_tests/caseworker/pages/case_list_page.py
index cda3687c13..5d4d9ae747 100644
--- a/ui_tests/caseworker/pages/case_list_page.py
+++ b/ui_tests/caseworker/pages/case_list_page.py
@@ -4,6 +4,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.select import Select
+from django.conf import settings
from ui_tests.caseworker.pages.BasePage import BasePage
from ui_tests.caseworker.pages.shared import Shared
from tests_common import functions
@@ -154,7 +155,7 @@ def click_on_queue_title(self):
self.driver.find_element(by=By.ID, value=self.LINK_CHANGE_QUEUE_ID).click()
def search_for_queue(self, queue_name):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.QUEUE_SEARCH_BOX))
)
self.driver.find_element(by=By.ID, value=self.QUEUE_SEARCH_BOX).send_keys(queue_name)
@@ -216,6 +217,6 @@ def click_checkbox_to_show_team_ecju_query_and_hidden_cases(self):
return self.driver.find_element(by=By.ID, value=self.SHOW_TEAM_ECJU_AND_HIDDEN_CASES).click()
def click_export_enforcement_xml(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.EXPORT_ENFORCEMENT_XML_BUTTON_ID))
).click()
diff --git a/ui_tests/caseworker/pages/case_page.py b/ui_tests/caseworker/pages/case_page.py
index 9323081a8c..d3b205eaa8 100644
--- a/ui_tests/caseworker/pages/case_page.py
+++ b/ui_tests/caseworker/pages/case_page.py
@@ -1,6 +1,7 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
+from django.conf import settings
from ui_tests.caseworker.pages.shared import Shared
from ui_tests.caseworker.pages.BasePage import BasePage
from tests_common import selectors
@@ -128,7 +129,9 @@ def is_flag_applied(self, flag_name):
self.driver.find_element(by=By.ID, value="candy-flags").click()
- WebDriverWait(self.driver, 30).until(expected_conditions.presence_of_element_located((By.ID, POPUP_FLAGS_ID)))
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
+ expected_conditions.presence_of_element_located((By.ID, POPUP_FLAGS_ID))
+ )
return flag_name in self.driver.find_element(by=By.ID, value=POPUP_FLAGS_ID).text
diff --git a/ui_tests/caseworker/pages/header_page.py b/ui_tests/caseworker/pages/header_page.py
index a91646d333..65330c08a0 100644
--- a/ui_tests/caseworker/pages/header_page.py
+++ b/ui_tests/caseworker/pages/header_page.py
@@ -1,3 +1,4 @@
+from django.conf import settings
from ui_tests.caseworker.pages.BasePage import BasePage
from tests_common.tools.wait import wait_until_page_is_loaded
@@ -21,7 +22,7 @@ def click_lite_menu(self):
self.driver.find_element(by=By.ID, value=self.MENU_BUTTON).click()
def click_organisations(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.CSS_SELECTOR, self.ORGANISATIONS_LINK))
).click()
diff --git a/ui_tests/caseworker/pages/product_assessment.py b/ui_tests/caseworker/pages/product_assessment.py
index ed3212dae6..afdc9e0522 100644
--- a/ui_tests/caseworker/pages/product_assessment.py
+++ b/ui_tests/caseworker/pages/product_assessment.py
@@ -4,6 +4,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from tests_common import functions
+from django.conf import settings
from ui_tests.caseworker.pages.BasePage import BasePage
@@ -23,7 +24,7 @@ def assess_report_summary_prefix(self, ars_prefix):
ars_prefix_element = self.driver.find_element(by=By.ID, value="report_summary_prefix_container")
ars_prefix_input = ars_prefix_element.find_element(by=By.ID, value="_report_summary_prefix")
ars_prefix_input.send_keys(ars_prefix)
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, "_report_summary_prefix__listbox"))
)
@@ -39,7 +40,7 @@ def assess_report_summary_subject(self, ars_subject):
ars_subject_element = self.driver.find_element(by=By.ID, value="report_summary_subject_container")
ars_subject_input = ars_subject_element.find_element(by=By.ID, value="_report_summary_subject")
ars_subject_input.send_keys(ars_subject)
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, "_report_summary_subject__listbox"))
)
diff --git a/ui_tests/caseworker/pages/shared.py b/ui_tests/caseworker/pages/shared.py
index ebde39faca..d651f66678 100644
--- a/ui_tests/caseworker/pages/shared.py
+++ b/ui_tests/caseworker/pages/shared.py
@@ -3,6 +3,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from tests_common import functions
+from django.conf import settings
from ui_tests.caseworker.pages.BasePage import BasePage
from tests_common.tools.helpers import scroll_to_element_by_id
@@ -122,14 +123,14 @@ def click_first_link_in_row(self):
def expand_govuk_details(self):
self.driver.find_element(by=By.CLASS_NAME, value=self.GOVUK_DETAILS).click()
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located(
(By.XPATH, f"//*[contains(@class, '{self.GOVUK_DETAILS}') and ancestor::details/@open]")
)
)
def try_open_filters(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.CLASS_NAME, "lite-filter-bar"))
)
diff --git a/ui_tests/caseworker/step_defs/test_documents.py b/ui_tests/caseworker/step_defs/test_documents.py
index 747efc190b..9581301763 100644
--- a/ui_tests/caseworker/step_defs/test_documents.py
+++ b/ui_tests/caseworker/step_defs/test_documents.py
@@ -3,6 +3,7 @@
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
+from django.conf import settings
from ui_tests.caseworker.pages.application_page import ApplicationPage
from ui_tests.caseworker.pages.attach_document_page import AttachDocumentPage
from ui_tests.caseworker.pages.documents_page import DocumentsPage
@@ -28,7 +29,7 @@ def upload_a_file(driver, filename, description, tmp_path):
old_page = driver.find_element(by=By.TAG_NAME, value="html")
attach_document_page.click_submit_btn()
- WebDriverWait(driver, 45).until(expected_conditions.staleness_of(old_page))
+ WebDriverWait(driver, 45 * settings.E2E_WAIT_MULTIPLIER).until(expected_conditions.staleness_of(old_page))
@then(parsers.parse('I see a file with filename "{filename}" is uploaded'))
diff --git a/ui_tests/caseworker/step_defs/test_enforcement.py b/ui_tests/caseworker/step_defs/test_enforcement.py
index 82180a921f..823f54f8e1 100644
--- a/ui_tests/caseworker/step_defs/test_enforcement.py
+++ b/ui_tests/caseworker/step_defs/test_enforcement.py
@@ -8,6 +8,7 @@
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
+from django.conf import settings
from ui_tests.caseworker.pages.application_page import ApplicationPage
from ui_tests.caseworker.pages.case_list_page import CaseListPage
from ui_tests.caseworker.pages.shared import Shared
@@ -146,9 +147,9 @@ def i_attach_updated_file(driver, enforcement_check_import_xml_file_path): # no
upload_btn = driver.find_element(by=By.XPATH, value="//button[@type='submit']")
upload_btn.click()
- WebDriverWait(driver, 45).until(expected_conditions.staleness_of(old_page))
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(expected_conditions.staleness_of(old_page))
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.text_to_be_present_in_element(
(By.CSS_SELECTOR, ".app-snackbar__content"),
"Enforcement XML imported successfully",
@@ -161,7 +162,7 @@ def i_attach_updated_file(driver, enforcement_check_import_xml_file_path): # no
@then(parsers.parse('the application is removed from "{queue}" queue'))
def application_removed_from_queue(driver, queue):
ASSIGNED_QUEUES_ID = "assigned-queues"
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, ASSIGNED_QUEUES_ID))
).is_enabled()
queue_list = driver.find_element(by=By.ID, value=ASSIGNED_QUEUES_ID).text.split("\n")
diff --git a/ui_tests/caseworker/step_defs/test_give_advice/conftest.py b/ui_tests/caseworker/step_defs/test_give_advice/conftest.py
index d22b7034ea..4b97614e6a 100644
--- a/ui_tests/caseworker/step_defs/test_give_advice/conftest.py
+++ b/ui_tests/caseworker/step_defs/test_give_advice/conftest.py
@@ -39,6 +39,11 @@ def click_refuse_all(driver): # noqa
RecommendationsAndDecisionPage(driver).click_refuse_all()
+@when("I click add licence condition")
+def click_add_licence_condition(driver): # noqa
+ RecommendationsAndDecisionPage(driver).click_add_licence_condition()
+
+
@when(parsers.parse('I select refusal criteria "{criteria}"'))
def select_refusal_criteria(driver, criteria): # noqa
functions.select_multi_select_options(
@@ -62,6 +67,11 @@ def enter_reasons_for_approving(driver, reasons, context): # noqa
RecommendationsAndDecisionPage(driver).enter_reasons_for_approving(reasons)
+@when(parsers.parse('I enter "{reasons}" as the approval reasons'))
+def enter_approval_reasons(driver, reasons, context): # noqa
+ RecommendationsAndDecisionPage(driver).enter_approval_reasons(reasons)
+
+
@when(parsers.parse('I enter "{reasons}" as the reasons for refusal'))
def enter_reasons_for_refusal(driver, reasons, context): # noqa
RecommendationsAndDecisionPage(driver).enter_reasons_for_refusal(reasons)
@@ -72,21 +82,41 @@ def enter_refusal_note(driver, note, context): # noqa
RecommendationsAndDecisionPage(driver).enter_refusal_note(note)
-@when(parsers.parse('I enter "{licence_condition}" as the licence condition'))
-def enter_licence_condition(driver, licence_condition, context): # noqa
- RecommendationsAndDecisionPage(driver).enter_licence_condition(licence_condition)
+@when(parsers.parse('I enter "{licence_condition}" as the licence condition into the "{condition_selected}" checkbox'))
+def enter_licence_condition(driver, licence_condition, condition_selected, context): # noqa
+ RecommendationsAndDecisionPage(driver).enter_licence_condition(licence_condition, condition_selected)
-@when(parsers.parse('I enter "{instructions}" as the instructions for the exporter'))
+@when(parsers.parse('I enter "{licence_condition}" into the licence condition'))
+def enter_licence_condition_edit(driver, licence_condition, context): # noqa
+ RecommendationsAndDecisionPage(driver).enter_licence_condition_edit(licence_condition)
+
+
+@when(parsers.parse('I enter "{instructions}" as the instructions for the exporter on the instructions step'))
def enter_instructions_for_exporter(driver, instructions, context): # noqa
RecommendationsAndDecisionPage(driver).enter_instructions_for_exporter(instructions)
-@when(parsers.parse('I enter "{footnote}" as the reporting footnote'))
+@when(parsers.parse('I enter "{footnote}" as the reporting footnote on the instructions step'))
def enter_reporting_footnote(driver, footnote, context): # noqa
RecommendationsAndDecisionPage(driver).enter_reporting_footnote(footnote)
+@when(parsers.parse('I enter "{licence_condition}" as the licence condition'))
+def enter_licence_condition_legacy(driver, licence_condition, context): # noqa
+ RecommendationsAndDecisionPage(driver).enter_licence_condition_legacy(licence_condition)
+
+
+@when(parsers.parse('I enter "{instructions}" as the instructions for the exporter'))
+def enter_instructions_for_exporter_legacy(driver, instructions, context): # noqa
+ RecommendationsAndDecisionPage(driver).enter_instructions_for_exporter_legacy(instructions)
+
+
+@when(parsers.parse('I enter "{footnote}" as the reporting footnote'))
+def enter_reporting_footnote_legacy(driver, footnote, context): # noqa
+ RecommendationsAndDecisionPage(driver).enter_reporting_footnote_legacy(footnote)
+
+
@then(parsers.parse('I should see my recommendation for "{countries}" with "{reasons}"'))
def should_see_recommendation(driver, countries, reasons): # noqa
text = driver.find_element(by=By.XPATH, value="//main[@class='govuk-main-wrapper']//*").text
diff --git a/ui_tests/caseworker/step_defs/test_give_advice/test_ogd_approve_advice.py b/ui_tests/caseworker/step_defs/test_give_advice/test_ogd_approve_advice.py
new file mode 100644
index 0000000000..7d20f0486c
--- /dev/null
+++ b/ui_tests/caseworker/step_defs/test_give_advice/test_ogd_approve_advice.py
@@ -0,0 +1,3 @@
+from pytest_bdd import scenarios
+
+scenarios("../../features/give_advice/ogd_approve_advice.feature", strict_gherkin=False)
diff --git a/ui_tests/caseworker/step_defs/test_product_search.py b/ui_tests/caseworker/step_defs/test_product_search.py
index 0559e53b97..9f505a6dd2 100644
--- a/ui_tests/caseworker/step_defs/test_product_search.py
+++ b/ui_tests/caseworker/step_defs/test_product_search.py
@@ -8,6 +8,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from tests_common import functions
+from django.conf import settings
from ui_tests.caseworker.pages.product_search import ProductSearchPage
@@ -16,7 +17,7 @@
@when("I go to product search page")
def go_to_product_search_page(driver):
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, "link-product-search"))
).click()
diff --git a/ui_tests/exporter/conftest.py b/ui_tests/exporter/conftest.py
index ad435c4cc6..d0b454e28f 100644
--- a/ui_tests/exporter/conftest.py
+++ b/ui_tests/exporter/conftest.py
@@ -1242,7 +1242,7 @@ def edit_good_details_in_application(driver, field_name, updated_value): # noqa
@when(parsers.parse('I click on "{link_text}"')) # noqa
def click_link_with_text(driver, link_text): # noqa
- WebDriverWait(driver, 30).until(
+ WebDriverWait(driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located(
(
By.LINK_TEXT,
diff --git a/ui_tests/exporter/pages/shared.py b/ui_tests/exporter/pages/shared.py
index 24a9b074f5..ba9a9646a1 100644
--- a/ui_tests/exporter/pages/shared.py
+++ b/ui_tests/exporter/pages/shared.py
@@ -1,3 +1,4 @@
+from django.conf import settings
from ui_tests.exporter.pages.BasePage import BasePage
from selenium.webdriver.common.by import By
@@ -33,7 +34,7 @@ def get_table_rows(self):
return self.driver.find_elements_by_css_selector(self.GOV_TABLE_ROW)
def get_text_of_organisation_heading(self):
- WebDriverWait(self.driver, 30).until(
+ WebDriverWait(self.driver, 30 * settings.E2E_WAIT_MULTIPLIER).until(
expected_conditions.presence_of_element_located((By.ID, self.ORG_NAME_HEADING_ID))
)
diff --git a/unit_tests/caseworker/advice/test_rules.py b/unit_tests/caseworker/advice/test_rules.py
index 87922f445d..417489d76d 100644
--- a/unit_tests/caseworker/advice/test_rules.py
+++ b/unit_tests/caseworker/advice/test_rules.py
@@ -189,7 +189,7 @@ def test_can_user_allocate_and_approve(mock_gov_user, data_fake_queue, data_stan
assert rules.test_rule("can_user_allocate_and_approve", request, case)
-def test_can_user_make_desnz_edit_valid(
+def test_can_user_make_edit_valid(
mock_gov_user, data_fake_queue, data_assigned_case, standard_case_with_advice, mocker
):
mock_gov_user["user"]["team"]["alias"] = services.DESNZ_TEAMS[0]
@@ -198,44 +198,44 @@ def test_can_user_make_desnz_edit_valid(
mocker.patch(
"caseworker.advice.rules.services.filter_current_user_advice", return_value=standard_case_with_advice["advice"]
)
- assert rules.test_rule("can_user_make_desnz_edit", request, data_assigned_case)
+ assert rules.test_rule("can_user_make_edit", request, data_assigned_case)
-def test_can_user_make_desnz_edit_invalid_advice(mock_gov_user, data_fake_queue, data_assigned_case):
+def test_can_user_make_edit_invalid_advice(mock_gov_user, data_fake_queue, data_assigned_case):
mock_gov_user["user"]["team"]["alias"] = services.DESNZ_TEAMS[0]
data_fake_queue["alias"] = services.DESNZ_CHEMICAL_CASES_TO_REVIEW
- data_assigned_case
request = get_mock_request(mock_gov_user["user"], data_fake_queue)
- assert not rules.test_rule("can_user_make_desnz_edit", request, data_assigned_case)
+ assert not rules.test_rule("can_user_make_edit", request, data_assigned_case)
-def test_can_user_make_desnz_edit_invalid_user(
+def test_can_user_make_edit_invalid_user(
mock_gov_user, data_fake_queue, data_assigned_case, standard_case_with_advice, mocker
):
- data_fake_queue["alias"] = services.DESNZ_CHEMICAL_CASES_TO_REVIEW
+ mock_gov_user["user"]["team"]["alias"] = services.FCDO_TEAM
+ data_fake_queue["alias"] = services.FCDO_CASES_TO_REVIEW_QUEUE
request = get_mock_request(mock_gov_user["user"], data_fake_queue)
mocker.patch(
"caseworker.advice.rules.services.filter_current_user_advice", return_value=standard_case_with_advice["advice"]
)
- assert not rules.test_rule("can_user_make_desnz_edit", request, data_assigned_case)
+ assert not rules.test_rule("can_user_make_edit", request, data_assigned_case)
-def test_can_user_make_desnz_edit_invalid_advice_and_user(mock_gov_user, data_fake_queue, data_assigned_case):
- data_fake_queue["alias"] = services.DESNZ_CHEMICAL_CASES_TO_REVIEW
- data_assigned_case
+def test_can_user_make_edit_invalid_advice_and_user(mock_gov_user, data_fake_queue, data_assigned_case):
+ mock_gov_user["user"]["team"]["alias"] = services.FCDO_TEAM
+ data_fake_queue["alias"] = services.FCDO_CASES_TO_REVIEW_QUEUE
request = get_mock_request(mock_gov_user["user"], data_fake_queue)
- assert not rules.test_rule("can_user_make_desnz_edit", request, data_assigned_case)
+ assert not rules.test_rule("can_user_make_edit", request, data_assigned_case)
-def test_can_user_make_desnz_edit_request_missing_attributes(mock_gov_user, data_fake_queue, data_standard_case):
+def test_can_user_make_edit_request_missing_attributes(mock_gov_user, data_fake_queue, data_standard_case):
case = Case(data_standard_case["case"])
request = None
- assert not advice_rules.can_user_make_desnz_edit(request, case)
+ assert not advice_rules.can_user_make_edit(request, case)
-def test_can_user_make_desnz_edit_user_not_allocated(mock_gov_user, data_fake_queue, data_standard_case):
+def test_can_user_make_edit_user_not_allocated(mock_gov_user, data_fake_queue, data_standard_case):
case = Case(data_standard_case["case"])
request = get_mock_request(mock_gov_user["user"], data_fake_queue)
- assert not rules.test_rule("can_user_make_desnz_edit", request, case)
+ assert not rules.test_rule("can_user_make_edit", request, case)
diff --git a/unit_tests/caseworker/advice/views/test_edit_advice.py b/unit_tests/caseworker/advice/views/test_edit_advice.py
index 7dc8fc90c0..437b66cb7e 100644
--- a/unit_tests/caseworker/advice/views/test_edit_advice.py
+++ b/unit_tests/caseworker/advice/views/test_edit_advice.py
@@ -20,7 +20,19 @@ def url(data_queue, data_standard_case):
)
-def test_edit_approve_advice_post(authorized_client, requests_mock, data_standard_case, standard_case_with_advice, url):
+@pytest.fixture
+def url_approve(data_queue, data_standard_case):
+ return reverse(f"cases:edit_advice", kwargs={"queue_pk": data_queue["id"], "pk": data_standard_case["case"]["id"]})
+
+
+@pytest.fixture
+def post_to_step(post_to_step_factory, url_approve):
+ return post_to_step_factory(url_approve)
+
+
+def test_edit_approve_advice_post_legacy(
+ authorized_client, requests_mock, data_standard_case, standard_case_with_advice, url
+):
user_advice_create_url = f"/cases/{data_standard_case['case']['id']}/user-advice/"
requests_mock.post(user_advice_create_url, json={})
case_data = deepcopy(data_standard_case)
@@ -107,6 +119,210 @@ def test_edit_approve_advice_post(authorized_client, requests_mock, data_standar
]
+def test_edit_approve_advice_post(
+ authorized_client, requests_mock, mock_post_advice, data_standard_case, standard_case_with_advice, post_to_step
+):
+ user_advice_create_url = f"/cases/{data_standard_case['case']['id']}/user-advice/"
+ case_data = deepcopy(data_standard_case)
+ case_data["case"]["data"]["goods"] = standard_case_with_advice["data"]["goods"]
+ case_data["case"]["advice"] = standard_case_with_advice["advice"]
+
+ requests_mock.get(client._build_absolute_uri(f"/cases/{data_standard_case['case']['id']}"), json=case_data)
+ requests_mock.get(
+ client._build_absolute_uri(f"/gov_users/{data_standard_case['case']['id']}"),
+ json={"user": {"id": "58e62718-e889-4a01-b603-e676b794b394"}},
+ )
+
+ data = {"approval_reasons": "meets the requirements updated", "add_licence_conditions": False}
+ response = post_to_step(
+ AdviceSteps.RECOMMEND_APPROVAL,
+ data,
+ )
+ assert response.status_code == 302
+ history = [item for item in requests_mock.request_history if user_advice_create_url in item.url]
+ assert len(history) == 1
+ history = history[0]
+ assert history.method == "POST"
+ assert history.json() == [
+ {
+ "denial_reasons": [],
+ "end_user": "95d3ea36-6ab9-41ea-a744-7284d17b9cc5",
+ "footnote": "",
+ "footnote_required": False,
+ "note": "",
+ "proviso": "",
+ "text": "meets the requirements updated",
+ "type": "approve",
+ },
+ {
+ "consignee": "cd2263b4-a427-4f14-8552-505e1d192bb8",
+ "denial_reasons": [],
+ "footnote": "",
+ "footnote_required": False,
+ "note": "",
+ "proviso": "",
+ "text": "meets the requirements updated",
+ "type": "approve",
+ },
+ {
+ "ultimate_end_user": "9f077b3c-6116-4111-b9a0-b2491198aa72",
+ "denial_reasons": [],
+ "footnote": "",
+ "footnote_required": False,
+ "note": "",
+ "proviso": "",
+ "text": "meets the requirements updated",
+ "type": "approve",
+ },
+ {
+ "denial_reasons": [],
+ "footnote": "",
+ "footnote_required": False,
+ "note": "",
+ "proviso": "",
+ "text": "meets the requirements updated",
+ "third_party": "95c2d6b7-5cfd-47e8-b3c8-dc76e1ac9747",
+ "type": "approve",
+ },
+ {
+ "denial_reasons": [],
+ "footnote": "",
+ "footnote_required": False,
+ "good": "9fbffa7f-ef50-402e-93ac-2f3f37d09030",
+ "note": "",
+ "proviso": "",
+ "text": "meets the requirements updated",
+ "type": "approve",
+ },
+ {
+ "denial_reasons": [],
+ "footnote": "",
+ "footnote_required": False,
+ "good": "d4feac1e-851d-41a5-b833-eb28addb8547",
+ "note": "",
+ "proviso": "",
+ "text": "",
+ "type": "no_licence_required",
+ },
+ ]
+
+
+def test_give_approval_advice_post_valid_add_conditional(
+ authorized_client,
+ requests_mock,
+ data_standard_case,
+ mock_approval_reason,
+ mock_proviso,
+ mock_footnote_details,
+ mock_post_advice,
+ standard_case_with_advice,
+ post_to_step,
+ beautiful_soup,
+ mocker,
+):
+ case_data = deepcopy(data_standard_case)
+ case_data["case"]["data"]["goods"] = standard_case_with_advice["data"]["goods"]
+ case_data["case"]["advice"] = standard_case_with_advice["advice"]
+
+ requests_mock.get(client._build_absolute_uri(f"/cases/{data_standard_case['case']['id']}"), json=case_data)
+ requests_mock.get(
+ client._build_absolute_uri(f"/gov_users/{data_standard_case['case']['id']}"),
+ json={"user": {"id": "58e62718-e889-4a01-b603-e676b794b394"}},
+ )
+
+ response = post_to_step(
+ AdviceSteps.RECOMMEND_APPROVAL,
+ {"approval_reasons": "reason updated", "add_licence_conditions": True},
+ )
+ assert response.status_code == 200
+ soup = beautiful_soup(response.content)
+ # redirected to next form
+ header = soup.find("h1")
+ assert header.text == "Add licence conditions (optional)"
+
+ add_licence_condition_response = post_to_step(
+ AdviceSteps.LICENCE_CONDITIONS,
+ {"proviso": "proviso updated"},
+ )
+ assert add_licence_condition_response.status_code == 200
+ soup = beautiful_soup(add_licence_condition_response.content)
+ # redirected to next form
+ header = soup.find("h1")
+ assert header.text == "Add instructions to the exporter, or a reporting footnote (optional)"
+
+ add_instructions_response = post_to_step(
+ AdviceSteps.LICENCE_FOOTNOTES,
+ {"instructions_to_exporter": "instructions updated", "footnote_details": "footnotes updated"},
+ )
+ assert add_instructions_response.status_code == 302
+ history = mock_post_advice.request_history
+ assert len(history) == 1
+ history = history[0]
+ assert history.method == "POST"
+ assert history.json() == [
+ {
+ "type": "proviso",
+ "text": "reason updated",
+ "proviso": "proviso updated",
+ "note": "instructions updated",
+ "footnote_required": True,
+ "footnote": "footnotes updated",
+ "end_user": "95d3ea36-6ab9-41ea-a744-7284d17b9cc5",
+ "denial_reasons": [],
+ },
+ {
+ "type": "proviso",
+ "text": "reason updated",
+ "proviso": "proviso updated",
+ "note": "instructions updated",
+ "footnote_required": True,
+ "footnote": "footnotes updated",
+ "consignee": "cd2263b4-a427-4f14-8552-505e1d192bb8",
+ "denial_reasons": [],
+ },
+ {
+ "type": "proviso",
+ "text": "reason updated",
+ "proviso": "proviso updated",
+ "note": "instructions updated",
+ "footnote_required": True,
+ "footnote": "footnotes updated",
+ "ultimate_end_user": "9f077b3c-6116-4111-b9a0-b2491198aa72",
+ "denial_reasons": [],
+ },
+ {
+ "type": "proviso",
+ "text": "reason updated",
+ "proviso": "proviso updated",
+ "note": "instructions updated",
+ "footnote_required": True,
+ "footnote": "footnotes updated",
+ "third_party": "95c2d6b7-5cfd-47e8-b3c8-dc76e1ac9747",
+ "denial_reasons": [],
+ },
+ {
+ "type": "proviso",
+ "text": "reason updated",
+ "proviso": "proviso updated",
+ "note": "instructions updated",
+ "footnote_required": True,
+ "footnote": "footnotes updated",
+ "good": "9fbffa7f-ef50-402e-93ac-2f3f37d09030",
+ "denial_reasons": [],
+ },
+ {
+ "type": "no_licence_required",
+ "text": "",
+ "proviso": "",
+ "note": "",
+ "footnote_required": False,
+ "footnote": "",
+ "good": "d4feac1e-851d-41a5-b833-eb28addb8547",
+ "denial_reasons": [],
+ },
+ ]
+
+
def test_edit_refuse_advice_post(
authorized_client,
requests_mock,
@@ -139,19 +355,19 @@ def test_edit_refuse_advice_post(
assert history.method == "POST"
assert history.json() == [
{
- "denial_reasons": ["3", "4", "5", "5a", "5b"],
- "end_user": "95d3ea36-6ab9-41ea-a744-7284d17b9cc5",
- "footnote_required": False,
- "text": "doesn't meet the requirement",
"type": "refuse",
+ "text": "doesn't meet the requirement",
+ "footnote_required": False,
+ "end_user": "95d3ea36-6ab9-41ea-a744-7284d17b9cc5",
+ "denial_reasons": ["3", "4", "5", "5a", "5b"],
"is_refusal_note": False,
},
{
+ "type": "refuse",
+ "text": "doesn't meet the requirement",
+ "footnote_required": False,
"consignee": "cd2263b4-a427-4f14-8552-505e1d192bb8",
"denial_reasons": ["3", "4", "5", "5a", "5b"],
- "footnote_required": False,
- "text": "doesn't meet the requirement",
- "type": "refuse",
"is_refusal_note": False,
},
{
@@ -163,30 +379,30 @@ def test_edit_refuse_advice_post(
"is_refusal_note": False,
},
{
- "denial_reasons": ["3", "4", "5", "5a", "5b"],
- "footnote_required": False,
+ "type": "refuse",
"text": "doesn't meet the requirement",
+ "footnote_required": False,
"third_party": "95c2d6b7-5cfd-47e8-b3c8-dc76e1ac9747",
- "type": "refuse",
+ "denial_reasons": ["3", "4", "5", "5a", "5b"],
"is_refusal_note": False,
},
{
- "denial_reasons": ["3", "4", "5", "5a", "5b"],
+ "type": "refuse",
+ "text": "doesn't meet the requirement",
"footnote_required": False,
"good": "9fbffa7f-ef50-402e-93ac-2f3f37d09030",
- "text": "doesn't meet the requirement",
- "type": "refuse",
+ "denial_reasons": ["3", "4", "5", "5a", "5b"],
"is_refusal_note": False,
},
{
- "denial_reasons": [],
- "footnote": "",
+ "type": "no_licence_required",
+ "text": "",
+ "proviso": "",
+ "note": "",
"footnote_required": False,
+ "footnote": "",
"good": "d4feac1e-851d-41a5-b833-eb28addb8547",
- "note": "",
- "proviso": "",
- "text": "",
- "type": "no_licence_required",
+ "denial_reasons": [],
},
]
@@ -209,16 +425,6 @@ def test_edit_refuse_advice_get(
assert response.context["current_user"] == mock_gov_user["user"]
-@pytest.fixture
-def url_desnz(data_queue, data_standard_case):
- return reverse(f"cases:edit_advice", kwargs={"queue_pk": data_queue["id"], "pk": data_standard_case["case"]["id"]})
-
-
-@pytest.fixture
-def post_to_step(post_to_step_factory, url_desnz):
- return post_to_step_factory(url_desnz)
-
-
def test_DESNZ_give_approval_advice_post_valid(
authorized_client,
requests_mock,
@@ -230,7 +436,6 @@ def test_DESNZ_give_approval_advice_post_valid(
mock_post_advice,
standard_case_with_advice,
post_to_step,
- beautiful_soup,
mocker,
):
get_gov_user_value = (
diff --git a/unit_tests/caseworker/advice/views/test_give_approval_advice_view.py b/unit_tests/caseworker/advice/views/test_give_approval_advice_view.py
index 5a2a4504bd..adc8fcb87b 100644
--- a/unit_tests/caseworker/advice/views/test_give_approval_advice_view.py
+++ b/unit_tests/caseworker/advice/views/test_give_approval_advice_view.py
@@ -21,19 +21,115 @@ def url(data_queue, data_standard_case):
)
+@pytest.fixture
+def url_approve(data_queue, data_standard_case):
+ return reverse("cases:approve_all", kwargs={"queue_pk": data_queue["id"], "pk": data_standard_case["case"]["id"]})
+
+
+@pytest.fixture
+def post_to_step(post_to_step_factory, url_approve):
+ return post_to_step_factory(url_approve)
+
+
def test_give_approval_advice_get(authorized_client, url):
response = authorized_client.get(url)
assert response.status_code == 200
-def test_select_advice_post(authorized_client, requests_mock, data_standard_case, url):
- requests_mock.post(f"/cases/{data_standard_case['case']['id']}/user-advice/", json={})
-
- data = {"approval_reasons": "meets the requirements", "instructions_to_exporter": "no specific instructions"}
- response = authorized_client.post(url, data=data)
+def test_approval_advice_post_valid(
+ authorized_client,
+ data_standard_case,
+ url,
+ mock_approval_reason,
+ mock_proviso,
+ mock_footnote_details,
+ mock_post_advice,
+ post_to_step,
+ beautiful_soup,
+):
+ response = post_to_step(
+ AdviceSteps.RECOMMEND_APPROVAL,
+ {"approval_reasons": "Data"},
+ )
assert response.status_code == 302
+def test_approval_advice_post_valid_add_conditional(
+ authorized_client,
+ data_standard_case,
+ url,
+ mock_approval_reason,
+ mock_proviso,
+ mock_footnote_details,
+ mock_post_advice,
+ post_to_step,
+ beautiful_soup,
+):
+ response = post_to_step(
+ AdviceSteps.RECOMMEND_APPROVAL,
+ {"approval_reasons": "reason", "add_licence_conditions": True},
+ )
+ assert response.status_code == 200
+ soup = beautiful_soup(response.content)
+ # redirected to next form
+ header = soup.find("h1")
+ assert header.text == "Add licence conditions (optional)"
+
+ add_LC_response = post_to_step(
+ AdviceSteps.LICENCE_CONDITIONS,
+ {"proviso": "proviso"},
+ )
+ assert add_LC_response.status_code == 200
+ soup = beautiful_soup(add_LC_response.content)
+ # redirected to next form
+ header = soup.find("h1")
+ assert header.text == "Add instructions to the exporter, or a reporting footnote (optional)"
+
+ add_instructions_response = post_to_step(
+ AdviceSteps.LICENCE_FOOTNOTES,
+ {"instructions_to_exporter": "instructions", "footnote_details": "footnotes"},
+ )
+ assert add_instructions_response.status_code == 302
+
+
+def test_approval_advice_post_valid_add_conditional_optional(
+ authorized_client,
+ data_standard_case,
+ url,
+ mock_approval_reason,
+ mock_proviso,
+ mock_footnote_details,
+ mock_post_advice,
+ post_to_step,
+ beautiful_soup,
+):
+ response = post_to_step(
+ AdviceSteps.RECOMMEND_APPROVAL,
+ {"approval_reasons": "reason", "add_licence_conditions": True},
+ )
+ assert response.status_code == 200
+ soup = beautiful_soup(response.content)
+ # redirected to next form
+ header = soup.find("h1")
+ assert header.text == "Add licence conditions (optional)"
+
+ add_LC_response = post_to_step(
+ AdviceSteps.LICENCE_CONDITIONS,
+ {},
+ )
+ assert add_LC_response.status_code == 200
+ soup = beautiful_soup(add_LC_response.content)
+ # redirected to next form
+ header = soup.find("h1")
+ assert header.text == "Add instructions to the exporter, or a reporting footnote (optional)"
+
+ add_instructions_response = post_to_step(
+ AdviceSteps.LICENCE_FOOTNOTES,
+ {},
+ )
+ assert add_instructions_response.status_code == 302
+
+
@mock.patch("caseworker.advice.views.mixins.get_gov_user")
def test_fco_give_approval_advice_get(mock_get_gov_user, authorized_client, url):
mock_get_gov_user.return_value = (
@@ -118,16 +214,6 @@ def test_fcdo_give_approval_advice_post(
assert response.status_code == expected_status_code
-@pytest.fixture
-def url_desnz(data_queue, data_standard_case):
- return reverse("cases:approve_all", kwargs={"queue_pk": data_queue["id"], "pk": data_standard_case["case"]["id"]})
-
-
-@pytest.fixture
-def post_to_step(post_to_step_factory, url_desnz):
- return post_to_step_factory(url_desnz)
-
-
@mock.patch("caseworker.advice.views.mixins.get_gov_user")
def test_DESNZ_give_approval_advice_post_valid(
mock_get_gov_user,
diff --git a/unit_tests/caseworker/advice/views/test_select_advice_view.py b/unit_tests/caseworker/advice/views/test_select_advice_view.py
index 58155c632a..23e73e5e6d 100644
--- a/unit_tests/caseworker/advice/views/test_select_advice_view.py
+++ b/unit_tests/caseworker/advice/views/test_select_advice_view.py
@@ -21,10 +21,33 @@ def test_select_advice_get(authorized_client, url):
assert response.status_code == 200
+@pytest.mark.parametrize("recommendation, redirect", [("approve_all", "approve-all"), ("refuse_all", "refuse-all")])
+def test_select_advice_post(authorized_client, url, recommendation, redirect, data_standard_case):
+ response = authorized_client.post(url, data={"recommendation": recommendation})
+ assert response.status_code == 302
+ assert (
+ response.url
+ == f'/queues/00000000-0000-0000-0000-000000000001/cases/{data_standard_case["case"]["id"]}/advice/{redirect}/'
+ )
+
+
@pytest.mark.parametrize(
"recommendation, redirect", [("approve_all", "approve-all-legacy"), ("refuse_all", "refuse-all")]
)
-def test_select_advice_post(authorized_client, url, recommendation, redirect, data_standard_case):
+def test_select_advice_post_fcdo(authorized_client, url, recommendation, redirect, data_standard_case, mocker):
+ get_gov_user_value = (
+ {
+ "user": {
+ "team": {
+ "id": "56273dd4-4634-4ad7-a782-e480f85a85a9",
+ "name": "FCDO",
+ "alias": services.FCDO_TEAM,
+ }
+ }
+ },
+ None,
+ )
+ mocker.patch("caseworker.advice.views.mixins.get_gov_user", return_value=get_gov_user_value)
response = authorized_client.post(url, data={"recommendation": recommendation})
assert response.status_code == 302
assert (