diff --git a/app/models/validation_request.rb b/app/models/validation_request.rb
index 3473df784b..eab383e7f0 100644
--- a/app/models/validation_request.rb
+++ b/app/models/validation_request.rb
@@ -16,6 +16,8 @@ class ValidationRequest < ApplicationRecord
TimeExtensionValidationRequest
].freeze
+ REQUEST_TYPE_MAP = REQUEST_TYPES.index_by { |type| type[0..-18].underscore }.freeze
+
with_options to: :planning_application do
delegate :audits
delegate :validated?, prefix: :planning_application
@@ -122,8 +124,12 @@ def grouped_by_type
end
end
+ def type_param
+ type[0..-18].underscore
+ end
+
def type_symbol
- type.underscore.gsub(/_validation_request\z/, "").to_sym
+ type_param.to_sym
end
def response_due
diff --git a/bin/brakeman b/bin/brakeman
new file mode 100755
index 0000000000..a2eeb02f0c
--- /dev/null
+++ b/bin/brakeman
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'brakeman' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("brakeman", "brakeman")
diff --git a/config/brakeman.ignore b/config/brakeman.ignore
index 8e69c40a3e..dbdd167ff7 100644
--- a/config/brakeman.ignore
+++ b/config/brakeman.ignore
@@ -7,7 +7,7 @@
"check_name": "VerbConfusion",
"message": "Potential HTTP verb confusion. `HEAD` is routed like `GET` but `request.get?` will return `false`",
"file": "engines/bops_core/app/controllers/concerns/bops_core/application_controller.rb",
- "line": 98,
+ "line": 128,
"link": "https://brakemanscanner.org/docs/warning_types/http_verb_confusion/",
"code": "session[:back_path] = request.referer if request.get?",
"render_path": null,
@@ -57,6 +57,40 @@
],
"note": ""
},
+ {
+ "warning_type": "Dynamic Render Path",
+ "warning_code": 15,
+ "fingerprint": "5240d450204c9e3b74401ae28b8c08ad7dc4788ca35f31cfe0a56b8fa6005635",
+ "check_name": "Render",
+ "message": "Render path contains parameter value",
+ "file": "engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new.html.erb",
+ "line": 2,
+ "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+ "code": "render(action => \"#{controller_path}/new/#{PlanningApplicationPresenter.new(view_context, current_local_authority.planning_applications.find_by!(:reference => params[:reference])).validation_requests.find(params[:validation_request_id]).type_param}\", {})",
+ "render_path": [
+ {
+ "type": "controller",
+ "class": "BopsPreapps::ValidationRequests::CancellationsController",
+ "method": "create",
+ "line": 36,
+ "file": "engines/bops_preapps/app/controllers/bops_preapps/validation_requests/cancellations_controller.rb",
+ "rendered": {
+ "name": "bops_preapps/validation_requests/cancellations/new",
+ "file": "engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new.html.erb"
+ }
+ }
+ ],
+ "location": {
+ "type": "template",
+ "template": "bops_preapps/validation_requests/cancellations/new"
+ },
+ "user_input": "params[:validation_request_id]",
+ "confidence": "Weak",
+ "cwe_id": [
+ 22
+ ],
+ "note": ""
+ },
{
"warning_type": "Denial of Service",
"warning_code": 76,
@@ -64,7 +98,7 @@
"check_name": "RegexDoS",
"message": "Parameter value used in regular expression",
"file": "app/controllers/application_controller.rb",
- "line": 48,
+ "line": 55,
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
"code": "/\\/#{get_planning_application(params[planning_application_param]).id}/",
"render_path": null,
@@ -82,46 +116,36 @@
"note": ""
},
{
- "warning_type": "Cross-Site Scripting",
- "warning_code": 2,
- "fingerprint": "98a2eb7517c9b0fbbbb711af14b9eb2241ece8b3b375dc85bc30d394a659a0f5",
- "check_name": "CrossSiteScripting",
- "message": "Unescaped parameter value",
- "file": "app/views/planning_applications/site_notices/_status.html.erb",
- "line": 23,
- "link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
- "code": "PlanningApplicationPresenter.new(view_context, get_planning_application(params[planning_application_param])).last_site_notice.preview_content",
+ "warning_type": "Dynamic Render Path",
+ "warning_code": 15,
+ "fingerprint": "afeab00e1d4d52748bb9e6533d9761489e90595357a5f6ad2166530f1817d400",
+ "check_name": "Render",
+ "message": "Render path contains parameter value",
+ "file": "engines/bops_preapps/app/views/bops_preapps/validation_requests/edit.html.erb",
+ "line": 2,
+ "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+ "code": "render(action => \"#{controller_path}/edit/#{PlanningApplicationPresenter.new(view_context, current_local_authority.planning_applications.find_by!(:reference => params[:reference])).validation_requests.find(params[:id]).type_param}\", {})",
"render_path": [
{
"type": "controller",
- "class": "PlanningApplications::SiteNoticesController",
- "method": "create",
+ "class": "BopsPreapps::ValidationRequestsController",
+ "method": "update",
"line": 54,
- "file": "app/controllers/planning_applications/site_notices_controller.rb",
+ "file": "engines/bops_preapps/app/controllers/bops_preapps/validation_requests_controller.rb",
"rendered": {
- "name": "planning_applications/site_notices/new",
- "file": "app/views/planning_applications/site_notices/new.html.erb"
- }
- },
- {
- "type": "template",
- "name": "planning_applications/site_notices/new",
- "line": 22,
- "file": "app/views/planning_applications/site_notices/new.html.erb",
- "rendered": {
- "name": "planning_applications/site_notices/_status",
- "file": "app/views/planning_applications/site_notices/_status.html.erb"
+ "name": "bops_preapps/validation_requests/edit",
+ "file": "engines/bops_preapps/app/views/bops_preapps/validation_requests/edit.html.erb"
}
}
],
"location": {
"type": "template",
- "template": "planning_applications/site_notices/_status"
+ "template": "bops_preapps/validation_requests/edit"
},
- "user_input": "params[planning_application_param]",
+ "user_input": "params[:id]",
"confidence": "Weak",
"cwe_id": [
- 79
+ 22
],
"note": ""
},
@@ -158,6 +182,40 @@
22
],
"note": ""
+ },
+ {
+ "warning_type": "Dynamic Render Path",
+ "warning_code": 15,
+ "fingerprint": "df3f134a8f88aadd7d08404d76efb177eef78b6f38546392f66e0dba8b39a71d",
+ "check_name": "Render",
+ "message": "Render path contains parameter value",
+ "file": "engines/bops_preapps/app/views/bops_preapps/validation_requests/new.html.erb",
+ "line": 2,
+ "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+ "code": "render(action => \"#{controller_path}/new/#{PlanningApplicationPresenter.new(view_context, current_local_authority.planning_applications.find_by!(:reference => params[:reference])).validation_requests.new(:type => request_type).type_param}\", {})",
+ "render_path": [
+ {
+ "type": "controller",
+ "class": "BopsPreapps::ValidationRequestsController",
+ "method": "create",
+ "line": 30,
+ "file": "engines/bops_preapps/app/controllers/bops_preapps/validation_requests_controller.rb",
+ "rendered": {
+ "name": "bops_preapps/validation_requests/new",
+ "file": "engines/bops_preapps/app/views/bops_preapps/validation_requests/new.html.erb"
+ }
+ }
+ ],
+ "location": {
+ "type": "template",
+ "template": "bops_preapps/validation_requests/new"
+ },
+ "user_input": "params[:reference]",
+ "confidence": "Weak",
+ "cwe_id": [
+ 22
+ ],
+ "note": ""
}
],
"brakeman_version": "7.0.0"
diff --git a/engines/bops_preapps/app/controllers/bops_preapps/validation_requests/cancellations_controller.rb b/engines/bops_preapps/app/controllers/bops_preapps/validation_requests/cancellations_controller.rb
new file mode 100644
index 0000000000..f39f5bad26
--- /dev/null
+++ b/engines/bops_preapps/app/controllers/bops_preapps/validation_requests/cancellations_controller.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+module BopsPreapps
+ module ValidationRequests
+ class CancellationsController < AuthenticationController
+ before_action :set_layout
+ before_action :set_planning_application
+ before_action :set_case_record
+ before_action :set_validation_request
+
+ before_action :ensure_request_is_cancelable
+
+ helper_method :task_redirect_path
+
+ def new
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def create
+ @validation_request.assign_attributes(validation_request_params)
+ @validation_request.cancel_request!
+
+ if @planning_application.validation_complete?
+ @validation_request.send_cancelled_validation_request_mail
+ end
+
+ respond_to do |format|
+ format.html do
+ redirect_to task_redirect_path, notice: t(".#{@validation_request.type_param}")
+ end
+ end
+ rescue ValidationRequest::RecordCancelError
+ respond_to do |format|
+ format.html { render :new }
+ end
+ end
+
+ private
+
+ def set_layout
+ @show_header_bar = true
+ @show_sidebar = true
+ end
+
+ def set_planning_application
+ scope = current_local_authority.planning_applications
+ planning_application = scope.find_by!(reference: params[:reference])
+
+ @planning_application = PlanningApplicationPresenter.new(view_context, planning_application)
+ end
+
+ def set_case_record
+ @case_record = @planning_application.case_record
+ end
+
+ def set_validation_request
+ @validation_request = @planning_application.validation_requests.find(params[:validation_request_id])
+ end
+
+ def validation_request_params
+ params.require(:validation_request).permit(:cancel_reason)
+ end
+
+ def task_redirect_lookup(scope)
+ scope = "bops_preapps.validation_requests.#{scope}"
+ t(@validation_request.type_symbol, scope: scope.to_sym)
+ end
+
+ def task_redirect_slug
+ task_redirect_lookup("redirect_slugs")
+ end
+
+ def task_redirect_path
+ task_path(@planning_application, task_redirect_slug)
+ end
+
+ def ensure_request_is_cancelable
+ unless @validation_request.open_or_pending? && @planning_application.validation_complete?
+ redirect_to task_redirect_path, alert: t(".validation_request_not_cancelable")
+ end
+ end
+ end
+ end
+end
diff --git a/engines/bops_preapps/app/controllers/bops_preapps/validation_requests_controller.rb b/engines/bops_preapps/app/controllers/bops_preapps/validation_requests_controller.rb
new file mode 100644
index 0000000000..c3339707f9
--- /dev/null
+++ b/engines/bops_preapps/app/controllers/bops_preapps/validation_requests_controller.rb
@@ -0,0 +1,157 @@
+# frozen_string_literal: true
+
+module BopsPreapps
+ class ValidationRequestsController < AuthenticationController
+ before_action :set_layout
+ before_action :set_planning_application
+ before_action :set_case_record
+ before_action :set_validation_request, except: %i[new create]
+ before_action :build_validation_request, only: %i[new create]
+
+ before_action :ensure_request_is_createable, only: %i[new create]
+ before_action :ensure_request_is_editable, only: %i[edit update]
+ before_action :ensure_request_is_destroyable, only: %i[destroy]
+
+ helper_method :task_redirect_path
+
+ def new
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def create
+ respond_to do |format|
+ if @validation_request.save
+ format.html do
+ redirect_to task_redirect_path, notice: task_redirect_notice
+ end
+ else
+ format.html { render :new }
+ end
+ end
+ end
+
+ def show
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def edit
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def update
+ respond_to do |format|
+ if @validation_request.update(validation_request_params)
+ format.html do
+ redirect_to task_redirect_path, notice: task_redirect_notice
+ end
+ else
+ format.html { render :edit }
+ end
+ end
+ end
+
+ def destroy
+ respond_to do |format|
+ if @validation_request.destroy
+ format.html do
+ redirect_to task_redirect_path, notice: task_redirect_notice
+ end
+ else
+ format.html do
+ redirect_to task_redirect_path, alert: task_redirect_alert
+ end
+ end
+ end
+ end
+
+ private
+
+ def set_layout
+ @show_header_bar = true
+ @show_sidebar = true
+ end
+
+ def set_planning_application
+ scope = current_local_authority.planning_applications
+ planning_application = scope.find_by!(reference: params[:reference])
+
+ @planning_application = PlanningApplicationPresenter.new(view_context, planning_application)
+ end
+
+ def set_case_record
+ @case_record = @planning_application.case_record
+ end
+
+ def set_validation_request
+ @validation_request = @planning_application.validation_requests.find(params[:id])
+ end
+
+ def request_type
+ ValidationRequest::REQUEST_TYPE_MAP.fetch(params.fetch(:type))
+ rescue KeyError
+ raise BopsCore::Errors::BadRequestError, "Invalid validation request type"
+ end
+
+ def build_validation_request
+ @validation_request = @planning_application.validation_requests.new(type: request_type)
+
+ if action_name == "create"
+ @validation_request.assign_attributes(validation_request_params)
+ end
+ end
+
+ def validation_request_attributes
+ scope = "bops_preapps.validation_requests.attributes"
+ t(@validation_request.type_symbol, scope: scope.to_sym)
+ end
+
+ def validation_request_params
+ params.require(:validation_request).permit(*validation_request_attributes).merge(user: current_user)
+ end
+
+ def task_redirect_lookup(scope)
+ scope = "bops_preapps.validation_requests.#{scope}"
+ t(@validation_request.type_symbol, scope: scope.to_sym)
+ end
+
+ def task_redirect_notice
+ task_redirect_lookup("redirect_notices.#{action_name}")
+ end
+
+ def task_redirect_alert
+ task_redirect_lookup("redirect_alerts.#{action_name}")
+ end
+
+ def task_redirect_slug
+ task_redirect_lookup("redirect_slugs")
+ end
+
+ def task_redirect_path
+ task_path(@planning_application, task_redirect_slug)
+ end
+
+ def ensure_request_is_createable
+ if @planning_application.validated?
+ redirect_to task_redirect_path, alert: t(".validation_request_not_createable")
+ end
+ end
+
+ def ensure_request_is_editable
+ unless @planning_application.not_started?
+ redirect_to task_redirect_path, alert: t(".validation_request_not_editable")
+ end
+ end
+
+ def ensure_request_is_destroyable
+ unless @planning_application.not_started?
+ redirect_to task_redirect_path, alert: t(".validation_request_not_destroyable")
+ end
+ end
+ end
+end
diff --git a/engines/bops_preapps/app/forms/bops_preapps/tasks/other_validation_requests_form.rb b/engines/bops_preapps/app/forms/bops_preapps/tasks/other_validation_requests_form.rb
index f0a372ddd6..79dd332395 100644
--- a/engines/bops_preapps/app/forms/bops_preapps/tasks/other_validation_requests_form.rb
+++ b/engines/bops_preapps/app/forms/bops_preapps/tasks/other_validation_requests_form.rb
@@ -10,12 +10,27 @@ def created_by
def status
case state
+ when "pending"
+ "Not sent yet"
+ when "open"
+ overdue? ? "Overdue" : "Sent"
when "closed"
- :updated
+ "Responded"
when "cancelled"
- :cancelled
- else
- :invalid
+ "Cancelled"
+ end
+ end
+
+ def status_colour
+ case state
+ when "pending"
+ "yellow"
+ when "open"
+ overdue? ? "red" : "green"
+ when "closed"
+ nil
+ when "cancelled"
+ "red"
end
end
end
diff --git a/engines/bops_preapps/app/views/bops_preapps/tasks/check-and-validate/other-validation-issues/other-validation-requests/show.html.erb b/engines/bops_preapps/app/views/bops_preapps/tasks/check-and-validate/other-validation-issues/other-validation-requests/show.html.erb
index b384279088..8b86aa87a8 100644
--- a/engines/bops_preapps/app/views/bops_preapps/tasks/check-and-validate/other-validation-issues/other-validation-requests/show.html.erb
+++ b/engines/bops_preapps/app/views/bops_preapps/tasks/check-and-validate/other-validation-issues/other-validation-requests/show.html.erb
@@ -17,14 +17,14 @@
<% @form.each_validation_request do |validation_request| %>
|
- <%= govuk_link_to(main_app.planning_application_validation_validation_request_path(@planning_application, validation_request)) do %>
+ <%= govuk_link_to(validation_request_path(@planning_application, validation_request)) do %>
<%= truncate(validation_request.reason, length: 50) %>
<% end %>
|
<%= truncate(validation_request.suggestion, length: 50) %> |
<%= validation_request.created_by %> |
- <%= render(StatusTags::BaseComponent.new(status: validation_request.status)) %>
+ <%= govuk_tag(text: validation_request.status, colour: validation_request.status_colour) %>
|
<% end %>
@@ -38,9 +38,9 @@
<% end %>
- <% unless @planning_application.determined? %>
+ <% unless @planning_application.validated? %>
- <%= govuk_link_to "Add other validation request", main_app.new_planning_application_validation_validation_request_path(@planning_application, type: "other_change") %>
+ <%= govuk_link_to "Add other validation request", new_validation_request_path(@planning_application, type: "other_change") %>
<% end %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/_breadcrumbs.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/_breadcrumbs.html.erb
new file mode 100644
index 0000000000..d4255232de
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/_breadcrumbs.html.erb
@@ -0,0 +1,3 @@
+<% add_parent_breadcrumb_link "Home", preapp_home_path %>
+<% add_parent_breadcrumb_link "Application", main_app.planning_application_path(@planning_application) %>
+<% add_parent_breadcrumb_link "Validation", main_app.planning_application_validation_tasks_path(@planning_application) %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new.html.erb
new file mode 100644
index 0000000000..86fb2b42aa
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new.html.erb
@@ -0,0 +1,2 @@
+<%= render "bops_preapps/validation_requests/breadcrumbs" %>
+<%= render "#{controller_path}/new/#{@validation_request.type_param}" %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new/_other_change.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new/_other_change.html.erb
new file mode 100644
index 0000000000..66f92e7ec4
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/cancellations/new/_other_change.html.erb
@@ -0,0 +1,37 @@
+<% content_for :page_title do %>
+ Cancel other validation request — <%= t("page_title") %>
+<% end %>
+
+<%= form_with model: @validation_request, scope: :validation_request, method: :post, url: validation_request_cancellation_path(@planning_application) do |form| %>
+ <%= form.govuk_error_summary %>
+
+ Cancel validation request
+ <%= render "shared/proposal_header" %>
+
+
+
+
+ Other request to be cancelled
+
+
+
+
Reason it is invalid:
+ <%= render(FormattedContentComponent.new(text: @validation_request.reason)) %>
+
+
How it can be made valid:
+ <%= render(FormattedContentComponent.new(text: @validation_request.suggestion)) %>
+
+
+ <%= @validation_request.created_at.to_fs %>
+
+
+
+ <%= form.govuk_text_area(:cancel_reason, rows: 5,
+ label: {size: "m", text: "Explain to the applicant why this request is being cancelled"}) %>
+
+ <%= form.govuk_submit "Confirm cancellation" do %>
+ <%= govuk_button_link_to "Back", task_redirect_path, secondary: true %>
+ <% end %>
+
+
+<% end %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/edit.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/edit.html.erb
new file mode 100644
index 0000000000..bfa38ca755
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/edit.html.erb
@@ -0,0 +1,2 @@
+<%= render "breadcrumbs" %>
+<%= render "#{controller_path}/edit/#{@validation_request.type_param}" %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/edit/_other_change.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/edit/_other_change.html.erb
new file mode 100644
index 0000000000..dc3b22ebfe
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/edit/_other_change.html.erb
@@ -0,0 +1,27 @@
+<% content_for :page_title do %>
+ Update other validation request — <%= t("page_title") %>
+<% end %>
+
+<%= form_with model: @validation_request, scope: :validation_request, url: validation_request_path(@planning_application) do |form| %>
+ <%= form.govuk_error_summary %>
+
+ Request other validation change
+ <%= render "shared/proposal_header" %>
+
+
+
+ <%= hidden_field_tag :type, "other_change" %>
+
+ <%= form.govuk_text_area(:reason, rows: 5,
+ label: {size: "m", text: "Tell the applicant another reason why the application is invalid"}) %>
+
+ <%= form.govuk_text_area(:suggestion, rows: 5,
+ hint: {text: "Add all information that they will need to complete this action"},
+ label: {size: "m", text: "Explain to the applicant how the application can be made valid"}) %>
+
+ <%= form.govuk_submit "Update request" do %>
+ <%= govuk_button_link_to "Back", task_redirect_path, secondary: true %>
+ <% end %>
+
+
+<% end %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/new.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/new.html.erb
new file mode 100644
index 0000000000..b9112753da
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/new.html.erb
@@ -0,0 +1,2 @@
+<%= render "breadcrumbs" %>
+<%= render "#{controller_path}/new/#{@validation_request.type_param}" %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/new/_other_change.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/new/_other_change.html.erb
new file mode 100644
index 0000000000..5a74774c96
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/new/_other_change.html.erb
@@ -0,0 +1,33 @@
+<% content_for :page_title do %>
+ Other validation request — <%= t("page_title") %>
+<% end %>
+
+<%= form_with model: @validation_request, scope: :validation_request, url: validation_requests_path(@planning_application) do |form| %>
+ <%= form.govuk_error_summary %>
+
+ Request other validation change
+ <%= render "shared/proposal_header" %>
+
+
+
+ <%= hidden_field_tag :type, "other_change" %>
+
+ <%= form.govuk_text_area(:reason, rows: 5,
+ label: {size: "m", text: "Tell the applicant another reason why the application is invalid"}) %>
+
+ <%= form.govuk_text_area(:suggestion, rows: 5,
+ hint: {text: "Add all information that they will need to complete this action"},
+ label: {size: "m", text: "Explain to the applicant how the application can be made valid"}) %>
+
+ <% if @planning_application.not_started? %>
+ <%= form.govuk_submit "Save request" do %>
+ <%= govuk_button_link_to "Back", task_redirect_path, secondary: true %>
+ <% end %>
+ <% else %>
+ <%= form.govuk_submit "Send request" do %>
+ <%= govuk_button_link_to "Back", task_redirect_path, secondary: true %>
+ <% end %>
+ <% end %>
+
+
+<% end %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/show.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/show.html.erb
new file mode 100644
index 0000000000..d46e37dcf4
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/show.html.erb
@@ -0,0 +1,2 @@
+<%= render "breadcrumbs" %>
+<%= render "#{controller_path}/show/#{@validation_request.type_param}" %>
diff --git a/engines/bops_preapps/app/views/bops_preapps/validation_requests/show/_other_change.html.erb b/engines/bops_preapps/app/views/bops_preapps/validation_requests/show/_other_change.html.erb
new file mode 100644
index 0000000000..08d8456bc1
--- /dev/null
+++ b/engines/bops_preapps/app/views/bops_preapps/validation_requests/show/_other_change.html.erb
@@ -0,0 +1,64 @@
+<% content_for :page_title do %>
+ Other validation request — <%= t("page_title") %>
+<% end %>
+
+
+ <% if @validation_request.closed? %>
+ Check the response to other request
+ <% else %>
+ View other request
+ <% end %>
+
+<%= render "shared/proposal_header" %>
+
+
+
+
Officer request
+
+
+
Reason it is invalid:
+ <%= render(FormattedContentComponent.new(text: @validation_request.reason)) %>
+
+
How it can be made valid:
+ <%= render(FormattedContentComponent.new(text: @validation_request.suggestion)) %>
+
+
+ <%= @validation_request.created_at.to_fs %>
+
+
+
+
Applicant response
+
+
+ <% if @validation_request.closed? %>
+ <%= render(FormattedContentComponent.new(text: @validation_request.response)) %>
+
+
+ <%= @validation_request.updated_at.to_fs %>
+
+ <% else %>
+
Applicant has not responded yet
+ <% end %>
+
+
+ <% if @validation_request.open_or_pending? %>
+ <% if @planning_application.not_started? %>
+
+ <%= govuk_button_to "Delete request", validation_request_path(@planning_application, @validation_request), secondary: true, method: :delete, data: {confirm: "Are you sure?"} %>
+
+ <% elsif @planning_application.validation_complete? %>
+
+ <%= govuk_button_link_to "Cancel request", new_validation_request_cancellation_path(@planning_application, @validation_request), secondary: true %>
+
+ <% end %>
+ <% end %>
+
+
+ <%= govuk_button_link_to "Back", task_redirect_path, secondary: true %>
+
+ <% if @planning_application.not_started? %>
+ <%= govuk_link_to "Edit request", edit_validation_request_path(@planning_application, @validation_request) %>
+ <% end %>
+
+
+
diff --git a/engines/bops_preapps/config/locales/en.yml b/engines/bops_preapps/config/locales/en.yml
index 60e4c3ad6f..e0a6e9a37a 100644
--- a/engines/bops_preapps/config/locales/en.yml
+++ b/engines/bops_preapps/config/locales/en.yml
@@ -133,6 +133,39 @@ en:
summary-of-advice:
failure: Failed to save summary of advice
success: Summary of advice successfully updated
+ validation_requests:
+ attributes:
+ other_change:
+ - :reason
+ - :suggestion
+ cancellations:
+ create:
+ other_change: Change request successfully cancelled.
+ validation_request_not_cancelable: Validation request can't be cancelled.
+ new:
+ validation_request_not_cancelable: Validation request can't be cancelled.
+ create:
+ validation_request_not_createable: Validation requests can't be added.
+ destroy:
+ validation_request_not_destroyable: The validation request can't be deleted.
+ edit:
+ validation_request_not_editable: The validation request can't be edited.
+ new:
+ validation_request_not_createable: Validation requests can't be added.
+ redirect_alerts:
+ destroy:
+ other_change: Couldn't delete validation request — please contact support.
+ redirect_notices:
+ create:
+ other_change: Change request successfully created.
+ destroy:
+ other_change: Change request successfully deleted.
+ update:
+ other_change: Change request successfully updated.
+ redirect_slugs:
+ other_change: check-and-validate/other-validation-issues/other-validation-requests
+ update:
+ validation_request_not_editable: The validation request can't be edited.
shared:
task_submit_buttons:
save_draft: Save changes
diff --git a/engines/bops_preapps/config/routes.rb b/engines/bops_preapps/config/routes.rb
index 4c31d01be6..d3f468709e 100644
--- a/engines/bops_preapps/config/routes.rb
+++ b/engines/bops_preapps/config/routes.rb
@@ -9,6 +9,10 @@
scope "/:reference" do
get "/", to: redirect("/planning_applications/%{reference}")
+ resources :validation_requests, path: "/validation/requests", except: %i[index] do
+ resource :cancellation, only: %i[new create], module: "validation_requests"
+ end
+
get "/cancel", to: "cancel_requests#show", as: :cancel_request
patch "/cancel", to: "cancel_requests#update"
get "/*slug/edit", to: "tasks#edit", as: :edit_task
diff --git a/engines/bops_preapps/spec/system/tasks/other_validation_requests_spec.rb b/engines/bops_preapps/spec/system/tasks/other_validation_requests_spec.rb
new file mode 100644
index 0000000000..3b7b99d910
--- /dev/null
+++ b/engines/bops_preapps/spec/system/tasks/other_validation_requests_spec.rb
@@ -0,0 +1,729 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+RSpec.describe "Other validation requests", type: :system do
+ let(:local_authority) { create(:local_authority, :default) }
+ let(:reference) { planning_application.reference }
+ let(:case_record) { planning_application.case_record }
+ let(:slug) { "check-and-validate/other-validation-issues/other-validation-requests" }
+ let(:task) { case_record.find_task_by_slug_path!(slug) }
+
+ let(:user) { create(:user, local_authority:, name: "Vlad Idator") }
+
+ before do
+ sign_in(user)
+ visit "/planning_applications/#{planning_application.reference}/validation/tasks"
+ end
+
+ context "when the application has not started" do
+ let(:planning_application) { create(:planning_application, :not_started, :pre_application, local_authority:) }
+
+ it "a validation request can be added" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+ expect(page).to have_selector("h1", text: "Other validation requests")
+ expect(page).to have_content("No other validation requests have been added")
+
+ click_link "Add other validation request"
+ expect(page).to have_selector("h1", text: "Request other validation change")
+
+ fill_in "Tell the applicant another reason why the application is invalid", with: "Reason for invalidation"
+ fill_in "Explain to the applicant how the application can be made valid", with: "Suggestion on fixing"
+
+ click_button "Save request"
+ expect(page).to have_content("Change request successfully created")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Not sent yet")
+ end
+ end
+ end
+ end
+
+ context "and a request has been created" do
+ before do
+ create(:other_change_validation_request, :pending, planning_application:, user:, reason: "Reason for invalidation", suggestion: "Suggestion on fixing")
+ end
+
+ it "then the request can be edited" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Not sent yet")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+
+ click_link "Edit request"
+ expect(page).to have_selector("h1", text: "Request other validation change")
+
+ fill_in "Tell the applicant another reason why the application is invalid", with: "Other reason for invalidation"
+ fill_in "Explain to the applicant how the application can be made valid", with: "Other suggestion on fixing"
+
+ click_button "Update request"
+ expect(page).to have_selector("h1", text: "Other validation requests")
+ expect(page).to have_content("Change request successfully updated")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Other reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Other suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Not sent yet")
+ end
+ end
+ end
+ end
+
+ it "then the request can be deleted" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Not sent yet")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+
+ click_button "Delete request"
+ expect(page).to have_selector("h1", text: "Other validation requests")
+ expect(page).to have_content("Change request successfully deleted.")
+ expect(page).to have_content("No other validation requests have been added")
+ end
+ end
+ end
+
+ context "when the application has been invalidated" do
+ let(:planning_application) { create(:planning_application, :invalidated, :pre_application, local_authority:) }
+
+ it "a validation request can be sent" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+ expect(page).to have_content("No other validation requests have been added")
+
+ click_link "Add other validation request"
+ expect(page).to have_selector("h1", text: "Request other validation change")
+
+ fill_in "Tell the applicant another reason why the application is invalid", with: "Reason for invalidation"
+ fill_in "Explain to the applicant how the application can be made valid", with: "Suggestion on fixing"
+
+ click_button "Send request"
+ expect(page).to have_content("Change request successfully created")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+ end
+
+ context "and a request has been created" do
+ context "and it has not been responded to" do
+ before do
+ create(:other_change_validation_request, :open, planning_application:, user:, reason: "Reason for invalidation", suggestion: "Suggestion on fixing")
+ end
+
+ it "then the request can't be edited" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+ expect(page).not_to have_link("Edit request")
+ end
+
+ it "then the request can't be deleted" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+ expect(page).not_to have_button("Delete request")
+ end
+
+ it "then the request can be cancelled" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+
+ click_link "Cancel request"
+ expect(page).to have_selector("h1", text: "Cancel validation request")
+
+ click_button "Confirm cancellation"
+ expect(page).to have_content("Cancel reason can't be blank")
+
+ fill_in "Explain to the applicant why this request is being cancelled", with: "Cancellation reasons"
+
+ click_button "Confirm cancellation"
+ expect(page).to have_content("Change request successfully cancelled.")
+ expect(page).to have_selector("h1", text: "Other validation requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Cancelled")
+ end
+ end
+ end
+ end
+ end
+
+ context "and it has been responded to" do
+ before do
+ create(:other_change_validation_request, :closed, planning_application:, user:, reason: "Reason for invalidation", suggestion: "Suggestion on fixing")
+ end
+
+ it "then the request can't be edited" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Responded")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "Check the response to other request")
+ expect(page).to have_content("Some response")
+ expect(page).not_to have_link("Edit request")
+ end
+
+ it "then the request can't be deleted" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Responded")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "Check the response to other request")
+ expect(page).to have_content("Some response")
+ expect(page).not_to have_button("Delete request")
+ end
+
+ it "then the request can't be canceled" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Responded")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "Check the response to other request")
+ expect(page).to have_content("Some response")
+ expect(page).not_to have_link("Cancel request")
+ end
+ end
+ end
+ end
+
+ context "when the application has been validated" do
+ let(:planning_application) { create(:planning_application, :not_started, :pre_application, local_authority:) }
+
+ context "and there are no requests" do
+ before do
+ planning_application.update!(validated_at: planning_application.valid_from_date)
+ planning_application.start!
+ end
+
+ it "a validation request can't be sent" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+ expect(page).to have_content("No other validation requests have been added")
+ expect(page).not_to have_link("Add other validation request")
+ end
+ end
+
+ context "and a request has been created" do
+ context "and it has not been responded to" do
+ before do
+ create(:other_change_validation_request, :open, planning_application:, user:, reason: "Reason for invalidation", suggestion: "Suggestion on fixing")
+
+ planning_application.update!(validated_at: planning_application.valid_from_date)
+ planning_application.start!
+ end
+
+ it "then the request can't be edited" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+ expect(page).not_to have_link("Edit request")
+ end
+
+ it "then the request can't be deleted" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+ expect(page).not_to have_button("Delete request")
+ end
+
+ it "then the request can be cancelled" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Sent")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "View other request")
+ expect(page).to have_content("Reason it is invalid: Reason for invalidation")
+ expect(page).to have_content("How it can be made valid: Suggestion on fixing")
+
+ click_link "Cancel request"
+ expect(page).to have_selector("h1", text: "Cancel validation request")
+
+ click_button "Confirm cancellation"
+ expect(page).to have_content("Cancel reason can't be blank")
+
+ fill_in "Explain to the applicant why this request is being cancelled", with: "Cancellation reasons"
+
+ click_button "Confirm cancellation"
+ expect(page).to have_content("Change request successfully cancelled.")
+ expect(page).to have_selector("h1", text: "Other validation requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Cancelled")
+ end
+ end
+ end
+ end
+ end
+
+ context "and it has been responded to" do
+ before do
+ create(:other_change_validation_request, :closed, planning_application:, user:, reason: "Reason for invalidation", suggestion: "Suggestion on fixing")
+
+ planning_application.update!(validated_at: planning_application.valid_from_date)
+ planning_application.start!
+ end
+
+ it "then the request can't be edited" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Responded")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "Check the response to other request")
+ expect(page).to have_content("Some response")
+ expect(page).not_to have_link("Edit request")
+ end
+
+ it "then the request can't be deleted" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Responded")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "Check the response to other request")
+ expect(page).to have_content("Some response")
+ expect(page).not_to have_button("Delete request")
+ end
+
+ it "then the request can't be canceled" do
+ within ".bops-sidebar" do
+ click_link "Other validation requests"
+ end
+
+ expect(page).to have_current_path("/preapps/#{reference}/check-and-validate/other-validation-issues/other-validation-requests")
+
+ within "#other-validation-requests" do
+ within "tbody tr:nth-child(1)" do
+ within "td:nth-child(1)" do
+ expect(page).to have_content("Reason for invalidation")
+ end
+
+ within "td:nth-child(2)" do
+ expect(page).to have_content("Suggestion on fixing")
+ end
+
+ within "td:nth-child(3)" do
+ expect(page).to have_content("Vlad Idator")
+ end
+
+ within "td:nth-child(4)" do
+ expect(page).to have_content("Responded")
+ end
+ end
+ end
+
+ click_link "Reason for invalidation"
+ expect(page).to have_selector("h1", text: "Check the response to other request")
+ expect(page).to have_content("Some response")
+ expect(page).not_to have_link("Cancel request")
+ end
+ end
+ end
+ end
+end