diff --git a/schemes/views/schemes/milestones.py b/schemes/views/schemes/milestones.py index 76699037..537771f6 100644 --- a/schemes/views/schemes/milestones.py +++ b/schemes/views/schemes/milestones.py @@ -146,10 +146,6 @@ class ChangeMilestoneDatesForm(FlaskForm): # type: ignore required_message="Enter a construction completed planned date", invalid_message="Construction completed planned date must be a real date", ) - construction_completed_actual = MilestoneDateField( - required_message="Enter a construction completed actual date", - invalid_message="Construction completed actual date must be a real date", - ) @classmethod def from_domain(cls, milestones: SchemeMilestones) -> ChangeMilestoneDatesForm: @@ -181,9 +177,6 @@ def from_domain(cls, milestones: SchemeMilestones) -> ChangeMilestoneDatesForm: construction_completed_planned=milestones.get_current_status_date( Milestone.CONSTRUCTION_COMPLETED, ObservationType.PLANNED ), - construction_completed_actual=milestones.get_current_status_date( - Milestone.CONSTRUCTION_COMPLETED, ObservationType.ACTUAL - ), ) def update_domain(self, milestones: SchemeMilestones, now: datetime) -> None: @@ -213,11 +206,7 @@ def update_milestone(planned: date | None, actual: date | None, milestone: Miles self.construction_started_actual.data, Milestone.CONSTRUCTION_STARTED, ) - update_milestone( - self.construction_completed_planned.data, - self.construction_completed_actual.data, - Milestone.CONSTRUCTION_COMPLETED, - ) + update_milestone(self.construction_completed_planned.data, None, Milestone.CONSTRUCTION_COMPLETED) @dataclass(frozen=True) diff --git a/schemes/views/templates/scheme/milestones.html b/schemes/views/templates/scheme/milestones.html index df0591f6..57a6b29a 100644 --- a/schemes/views/templates/scheme/milestones.html +++ b/schemes/views/templates/scheme/milestones.html @@ -44,7 +44,7 @@

Change milestone dates

{{ milestone("Preliminary design completed", form.preliminary_design_completed_planned, form.preliminary_design_completed_actual) }} {{ milestone("Detailed design completed", form.detailed_design_completed_planned, form.detailed_design_completed_actual) }} {{ milestone("Construction started", form.construction_started_planned, form.construction_started_actual) }} - {{ milestone("Construction completed", form.construction_completed_planned, form.construction_completed_actual) }} + {{ milestone("Construction completed", form.construction_completed_planned, None) }}
{{ govukButton({ @@ -71,15 +71,17 @@

{{ name }}

} }) }}
-
- {{ actual_field(params={ - "fieldset": { - "describedBy": "date-hint", - "legend": { - "text": "Actual date" + {% if actual_field %} +
+ {{ actual_field(params={ + "fieldset": { + "describedBy": "date-hint", + "legend": { + "text": "Actual date" + } } - } - }) }} -
+ }) }} +
+ {% endif %} {%- endmacro %} diff --git a/tests/integration/pages.py b/tests/integration/pages.py index 178461bc..61c4ec66 100644 --- a/tests/integration/pages.py +++ b/tests/integration/pages.py @@ -399,7 +399,8 @@ def __init__(self, heading: Tag): grid_row = heading.find_next_sibling("div", class_="govuk-grid-row") assert isinstance(grid_row, Tag) self.planned = DateComponent(one(grid_row.select("fieldset:has(legend:-soup-contains('Planned date'))"))) - self.actual = DateComponent(one(grid_row.select("fieldset:has(legend:-soup-contains('Actual date'))"))) + actual_tag = grid_row.select_one("fieldset:has(legend:-soup-contains('Actual date'))") + self.actual = DateComponent(actual_tag) if actual_tag else None class DateComponent: diff --git a/tests/integration/test_scheme_milestones.py b/tests/integration/test_scheme_milestones.py index 40518270..4735bdea 100644 --- a/tests/integration/test_scheme_milestones.py +++ b/tests/integration/test_scheme_milestones.py @@ -151,20 +151,24 @@ def test_milestones_form_shows_fields(self, schemes: SchemeRepository, client: F assert ( change_milestone_dates_page.form.feasibility_design_completed.planned.name == "feasibility_design_completed_planned" + and change_milestone_dates_page.form.feasibility_design_completed.actual and change_milestone_dates_page.form.feasibility_design_completed.actual.name == "feasibility_design_completed_actual" and change_milestone_dates_page.form.preliminary_design_completed.planned.name == "preliminary_design_completed_planned" + and change_milestone_dates_page.form.preliminary_design_completed.actual and change_milestone_dates_page.form.preliminary_design_completed.actual.name == "preliminary_design_completed_actual" and change_milestone_dates_page.form.detailed_design_completed.planned.name == "detailed_design_completed_planned" + and change_milestone_dates_page.form.detailed_design_completed.actual and change_milestone_dates_page.form.detailed_design_completed.actual.name == "detailed_design_completed_actual" and change_milestone_dates_page.form.construction_started.planned.name == "construction_started_planned" + and change_milestone_dates_page.form.construction_started.actual and change_milestone_dates_page.form.construction_started.actual.name == "construction_started_actual" and change_milestone_dates_page.form.construction_completed.planned.name == "construction_completed_planned" - and change_milestone_dates_page.form.construction_completed.actual.name == "construction_completed_actual" + and change_milestone_dates_page.form.construction_completed.actual is None ) def test_milestones_form_shows_date(self, schemes: SchemeRepository, client: FlaskClient) -> None: @@ -174,7 +178,7 @@ def test_milestones_form_shows_date(self, schemes: SchemeRepository, client: Fla id_=1, effective=DateRange(datetime(2020, 1, 1, 12), None), milestone=Milestone.CONSTRUCTION_STARTED, - observation_type=ObservationType.ACTUAL, + observation_type=ObservationType.PLANNED, status_date=date(2020, 1, 2), source=DataSource.ATF4_BID, ) @@ -184,7 +188,7 @@ def test_milestones_form_shows_date(self, schemes: SchemeRepository, client: Fla change_milestone_dates_page = ChangeMilestoneDatesPage.open(client, id_=1) assert change_milestone_dates_page.title == "Update your capital schemes - Active Travel England - GOV.UK" - assert change_milestone_dates_page.form.construction_started.actual.value == "2 1 2020" + assert change_milestone_dates_page.form.construction_started.planned.value == "2 1 2020" def test_milestones_form_shows_confirm(self, schemes: SchemeRepository, client: FlaskClient) -> None: schemes.add(build_scheme(id_=1, name="Wirral Package", authority_id=1)) @@ -234,7 +238,7 @@ def test_milestones_updates_milestones( id_=1, effective=DateRange(datetime(2020, 1, 1, 12), None), milestone=Milestone.CONSTRUCTION_STARTED, - observation_type=ObservationType.ACTUAL, + observation_type=ObservationType.PLANNED, status_date=date(2020, 1, 2), source=DataSource.ATF4_BID, ) @@ -242,7 +246,7 @@ def test_milestones_updates_milestones( schemes.add(scheme) client.post( - "/schemes/1/milestones", data={"csrf_token": csrf_token, "construction_started_actual": ["3", "1", "2020"]} + "/schemes/1/milestones", data={"csrf_token": csrf_token, "construction_started_planned": ["3", "1", "2020"]} ) actual_scheme = schemes.get(1) @@ -254,7 +258,7 @@ def test_milestones_updates_milestones( assert ( milestone_revision2.effective == DateRange(datetime(2020, 2, 1, 13), None) and milestone_revision2.milestone == Milestone.CONSTRUCTION_STARTED - and milestone_revision2.observation_type == ObservationType.ACTUAL + and milestone_revision2.observation_type == ObservationType.PLANNED and milestone_revision2.status_date == date(2020, 1, 3) and milestone_revision2.source == DataSource.AUTHORITY_UPDATE ) @@ -275,7 +279,7 @@ def test_cannot_milestones_when_error( id_=1, effective=DateRange(datetime(2020, 1, 1, 12), None), milestone=Milestone.CONSTRUCTION_STARTED, - observation_type=ObservationType.ACTUAL, + observation_type=ObservationType.PLANNED, status_date=date(2020, 1, 2), source=DataSource.ATF4_BID, ) @@ -286,7 +290,7 @@ def test_cannot_milestones_when_error( client.post( "/schemes/1/milestones", data=self.empty_change_milestone_dates_form() - | {"csrf_token": csrf_token, "construction_started_actual": ["x", "x", "x"]}, + | {"csrf_token": csrf_token, "construction_started_planned": ["x", "x", "x"]}, ) ) @@ -294,13 +298,13 @@ def test_cannot_milestones_when_error( change_milestone_dates_page.title == "Error: Update your capital schemes - Active Travel England - GOV.UK" ) assert change_milestone_dates_page.errors and list(change_milestone_dates_page.errors) == [ - "Construction started actual date must be a real date" + "Construction started planned date must be a real date" ] assert ( - change_milestone_dates_page.form.construction_started.actual.is_errored - and change_milestone_dates_page.form.construction_started.actual.error - == "Error: Construction started actual date must be a real date" - and change_milestone_dates_page.form.construction_started.actual.value == "x x x" + change_milestone_dates_page.form.construction_started.planned.is_errored + and change_milestone_dates_page.form.construction_started.planned.error + == "Error: Construction started planned date must be a real date" + and change_milestone_dates_page.form.construction_started.planned.value == "x x x" ) actual_scheme = schemes.get(1) assert actual_scheme @@ -310,7 +314,7 @@ def test_cannot_milestones_when_error( milestone_revision1.id == 1 and milestone_revision1.effective == DateRange(datetime(2020, 1, 1, 12), None) and milestone_revision1.milestone == Milestone.CONSTRUCTION_STARTED - and milestone_revision1.observation_type == ObservationType.ACTUAL + and milestone_revision1.observation_type == ObservationType.PLANNED and milestone_revision1.status_date == date(2020, 1, 2) and milestone_revision1.source == DataSource.ATF4_BID ) @@ -381,5 +385,4 @@ def empty_change_milestone_dates_form(self) -> dict[str, list[str]]: "construction_started_planned": empty_date, "construction_started_actual": empty_date, "construction_completed_planned": empty_date, - "construction_completed_actual": empty_date, } diff --git a/tests/views/schemes/test_milestones.py b/tests/views/schemes/test_milestones.py index d963d198..f04ee78e 100644 --- a/tests/views/schemes/test_milestones.py +++ b/tests/views/schemes/test_milestones.py @@ -177,7 +177,6 @@ class TestChangeMilestoneDatesForm: "construction_started_planned", "construction_started_actual", "construction_completed_planned", - "construction_completed_actual", ] field_names_milestones_observation_types = [ ("feasibility_design_completed_planned", Milestone.FEASIBILITY_DESIGN_COMPLETED, ObservationType.PLANNED), @@ -189,7 +188,6 @@ class TestChangeMilestoneDatesForm: ("construction_started_planned", Milestone.CONSTRUCTION_STARTED, ObservationType.PLANNED), ("construction_started_actual", Milestone.CONSTRUCTION_STARTED, ObservationType.ACTUAL), ("construction_completed_planned", Milestone.CONSTRUCTION_COMPLETED, ObservationType.PLANNED), - ("construction_completed_actual", Milestone.CONSTRUCTION_COMPLETED, ObservationType.ACTUAL), ] @pytest.mark.parametrize("field_name, milestone, observation_type", field_names_milestones_observation_types) @@ -233,7 +231,6 @@ def test_from_domain_when_minimal(self) -> None: and form.construction_started_planned.data is None and form.construction_started_actual.data is None and form.construction_completed_planned.data is None - and form.construction_completed_actual.data is None ) @pytest.mark.parametrize("field_name, milestone, observation_type", field_names_milestones_observation_types) @@ -329,6 +326,22 @@ def test_update_domain_ignores_unchanged_dates( and milestone_revision1.source == DataSource.ATF4_BID ) + def test_update_domain_ignores_construction_completed_actual_date(self) -> None: + form = ChangeMilestoneDatesForm( + formdata=MultiDict( + [ + ("construction_completed_actual", "2"), + ("construction_completed_actual", "1"), + ("construction_completed_actual", "2020"), + ] + ) + ) + milestones = SchemeMilestones() + + form.update_domain(milestones, now=datetime(2020, 2, 1, 13)) + + assert not milestones.milestone_revisions + @pytest.mark.parametrize("field_name", field_names) def test_no_errors_when_valid(self, field_name: str) -> None: form = ChangeMilestoneDatesForm( @@ -361,7 +374,6 @@ def test_date_without_initial_value_is_optional(self, field_name: str) -> None: ("construction_started_planned", "Enter a construction started planned date"), ("construction_started_actual", "Enter a construction started actual date"), ("construction_completed_planned", "Enter a construction completed planned date"), - ("construction_completed_actual", "Enter a construction completed actual date"), ], ) @pytest.mark.parametrize( @@ -398,7 +410,6 @@ def test_date_with_initial_value_is_required( ("construction_started_planned", "Construction started planned date must be a real date"), ("construction_started_actual", "Construction started actual date must be a real date"), ("construction_completed_planned", "Construction completed planned date must be a real date"), - ("construction_completed_actual", "Construction completed actual date must be a real date"), ], ) @pytest.mark.parametrize(