From 7815965af141420ff5720d3457101218102dda8a Mon Sep 17 00:00:00 2001 From: J G <7750475+moarpheus@users.noreply.github.com> Date: Thu, 30 Jun 2022 07:29:09 +0100 Subject: [PATCH] CLDC-1290 Permitted user can create a new scheme (#671) * added test to find link to create a new scheme * added button to create a new scheme * testing arriving to the new scheme form * non exsiting link to controller new action * SPIKEEEE * first page complete * posting to create * refactored scheme to enums * refactored new scheme page to use enums as well * views * SPIKE WIP * SPIKE WIP * SPIKE WIP * drawing list of scheme details * expanded on feature seeing more fields to fill in * expanded on feature seeing more fields to fill in 2nd page * refactored * working back buttons * working flash * more change in wip * default value for org * working spike * some spacing * filling answers * spike finished * correct name for details * testing fill in details * removed gem and further tests * Add has other client group field to schemes. Display it in the check answers. Fix tests and routing * remove details view and path Co-authored-by: baarkerlounger * WIP change update paths * Implement changing answers (except the details one) * Add details page back for editing scheme details * added missing test for support questions and nested check answers under correct context * checking the back functionality * rubo and lint * checking the back functionality for primary gourp * checking the back functionality for confirm secondary * checking the back functionality for secondary group * checking the back functionality for support answers * checking the back functionality for returning to check answers from details page * checking the back functionality for returning to check answers from primary group page * checking the back functionality for secondary group confirm yes * checking the back functionality for secondary group confirm yes - fixed * checking the back functionality for secondary group * checking the back functionality for secondary group -fixed * checking the back functionality for returning from support page * Do not display secondary client group if the scheme doesn't have one * Add details path to schemes controller update method * Add more tests for back button * Add tests for new controller method * Add tests for creating schemes as data coordinator * fixed schema * added test for missing params when creating scheme * create for support user with or withotu required param * code to get controller render errors when required param is missing * code to implement correct validation * code to implement correct validation - part 2 * highlight missing field * doing silly dance to get correct field highlighted on the error * testing patch for schemes * testing patch for schemes - correct path * small refactoring * testing primary client group update via regular path * testing primary client group update via check answers page * testing confirm secondary group update with YES NO and returning from check answers page * testing updating secondary client group update and returning from check answers page * testing support answers and returning from check answers page * testing details and returning from check answers page * weird path when no names supplied * rubocop * lost in rebasing * started id to code refactoring * model specs remastered * fixed scheme controller specs * further refactorings * fixing feature schemes * final touches * removed code from db * remaining code purged * rubocop * included check for owning org field * checking for stock owning org selection * added stock owning org * added stock owning org on new page * added stock owning org to details * removed total units * managing related schems properly via Org * managing related schems properly via Org - rubocop * small refactoring * small refactoring - 2 * small refactoring - 3 * tests for owned_schemes and managed_schemes * rubocop * added tests for support user creating scheme * rubocop -a * tests for a primary-client-group * tests for a secondary-client-group * tests for a confirm-secondary-client-group * tests for a check-answers * tests for a details * rubocop * redundant action in controller * Trigger WF * switched to int for confirm * flashing test * flashing test for support user * flashing test rubocop Co-authored-by: Kat Co-authored-by: baarkerlounger --- app/controllers/schemes_controller.rb | 105 +- app/helpers/details_table_helper.rb | 2 +- app/helpers/tab_nav_helper.rb | 4 +- app/models/organisation.rb | 3 +- app/models/scheme.rb | 181 +-- app/views/organisations/schemes.html.erb | 2 + app/views/schemes/_scheme_list.html.erb | 2 +- app/views/schemes/check_answers.html.erb | 65 ++ app/views/schemes/confirm_secondary.html.erb | 32 + app/views/schemes/details.html.erb | 76 ++ app/views/schemes/index.html.erb | 2 + app/views/schemes/new.html.erb | 72 ++ .../schemes/primary_client_group.html.erb | 35 + .../schemes/secondary_client_group.html.erb | 35 + app/views/schemes/support.html.erb | 39 + config/locales/en.yml | 8 + config/routes.rb | 9 +- ...0220616130451_add_reference_to_case_log.rb | 2 +- ...132228_add_has_other_client_group_field.rb | 7 + ...20220629100324_remove_code_from_schemes.rb | 5 + ...dd_stock_owning_organisation_to_schemes.rb | 5 + db/schema.rb | 7 +- db/seeds.rb | 3 - spec/factories/scheme.rb | 1 - spec/features/schemes_spec.rb | 450 ++++++-- spec/helpers/tab_nav_helper_spec.rb | 4 +- spec/models/organisation_spec.rb | 10 +- spec/models/scheme_spec.rb | 26 +- .../requests/organisations_controller_spec.rb | 24 +- spec/requests/schemes_controller_spec.rb | 1020 ++++++++++++++++- 30 files changed, 2023 insertions(+), 213 deletions(-) create mode 100644 app/views/schemes/check_answers.html.erb create mode 100644 app/views/schemes/confirm_secondary.html.erb create mode 100644 app/views/schemes/details.html.erb create mode 100644 app/views/schemes/new.html.erb create mode 100644 app/views/schemes/primary_client_group.html.erb create mode 100644 app/views/schemes/secondary_client_group.html.erb create mode 100644 app/views/schemes/support.html.erb create mode 100644 db/migrate/20220623132228_add_has_other_client_group_field.rb create mode 100644 db/migrate/20220629100324_remove_code_from_schemes.rb create mode 100644 db/migrate/20220629105452_add_stock_owning_organisation_to_schemes.rb diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index e97a08e4b..4dd657534 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -7,6 +7,7 @@ class SchemesController < ApplicationController before_action :authenticate_scope! def index + flash[:notice] = "#{Scheme.find(params[:scheme_id].to_i).service_name} has been created." if params[:scheme_id] redirect_to schemes_organisation_path(current_user.organisation) unless current_user.support? all_schemes = Scheme.all @@ -25,20 +26,120 @@ class SchemesController < ApplicationController @total_count = @scheme.locations.size end + def new + @scheme = Scheme.new + end + + def create + @scheme = Scheme.new(scheme_params) + if @scheme.save + render "schemes/primary_client_group" + else + @scheme.errors.add(:organisation_id, message: @scheme.errors[:organisation]) + @scheme.errors.delete(:organisation) + render :new, status: :unprocessable_entity + end + end + + def update + check_answers = params[:scheme][:check_answers] + page = params[:scheme][:page] + + if @scheme.update(scheme_params) + if check_answers + if confirm_secondary_page? page + redirect_to scheme_secondary_client_group_path(@scheme, check_answers: "true") + else + @scheme.update!(secondary_client_group: nil) if @scheme.has_other_client_group == "No" + redirect_to scheme_check_answers_path(@scheme) + end + else + redirect_to next_page_path params[:scheme][:page] + end + else + render request.current_url, status: :unprocessable_entity + end + end + + def primary_client_group + render "schemes/primary_client_group" + end + + def confirm_secondary_client_group + render "schemes/confirm_secondary" + end + + def secondary_client_group + render "schemes/secondary_client_group" + end + + def support + render "schemes/support" + end + + def details + render "schemes/details" + end + + def check_answers + render "schemes/check_answers" + end + private + def confirm_secondary_page?(page) + page == "confirm-secondary" && @scheme.has_other_client_group == "Yes" + end + + def next_page_path(page) + case page + when "primary-client-group" + scheme_confirm_secondary_client_group_path(@scheme) + when "confirm-secondary" + @scheme.has_other_client_group == "Yes" ? scheme_secondary_client_group_path(@scheme) : scheme_support_path(@scheme) + when "secondary-client-group" + scheme_support_path(@scheme) + when "support" + scheme_check_answers_path(@scheme) + when "details" + scheme_primary_client_group_path(@scheme) + end + end + + def scheme_params + required_params = params.require(:scheme).permit(:service_name, + :sensitive, + :organisation_id, + :stock_owning_organisation_id, + :scheme_type, + :registered_under_care_act, + :total_units, + :id, + :has_other_client_group, + :primary_client_group, + :secondary_client_group, + :support_type, + :intended_stay) + + required_params[:sensitive] = required_params[:sensitive].to_i if required_params[:sensitive] + if current_user.data_coordinator? + required_params[:organisation_id] = current_user.organisation_id + end + required_params + end + def search_term params["search"] end def find_resource - @scheme = Scheme.find_by(id: params[:id]) + @scheme = Scheme.find_by(id: params[:id]) || Scheme.find_by(id: params[:scheme_id]) end def authenticate_scope! head :unauthorized and return unless current_user.data_coordinator? || current_user.support? - if %w[show locations].include?(action_name) && !((current_user.organisation == @scheme.organisation) || current_user.support?) + if %w[show locations primary_client_group confirm_secondary_client_group secondary_client_group support details check_answers].include?(action_name) && !((current_user.organisation == @scheme.organisation) || current_user.support?) render_not_found and return end end diff --git a/app/helpers/details_table_helper.rb b/app/helpers/details_table_helper.rb index b436cab38..c39bf75d7 100644 --- a/app/helpers/details_table_helper.rb +++ b/app/helpers/details_table_helper.rb @@ -4,7 +4,7 @@ module DetailsTableHelper list = attribute[:value].map { |value| "
  • #{value}
  • " }.join simple_format(list, { class: "govuk-list govuk-list--bullet" }, wrapper_tag: "ul") else - value = attribute[:value].is_a?(Array) ? attribute[:value].first : attribute[:value] + value = attribute[:value].is_a?(Array) ? attribute[:value].first : attribute[:value] || "None" simple_format(value.to_s, { class: "govuk-body" }, wrapper_tag: "p") end diff --git a/app/helpers/tab_nav_helper.rb b/app/helpers/tab_nav_helper.rb index bb163ddd8..f316d5ab2 100644 --- a/app/helpers/tab_nav_helper.rb +++ b/app/helpers/tab_nav_helper.rb @@ -7,8 +7,8 @@ module TabNavHelper end def scheme_cell(scheme) - link_text = scheme.service_name.presence - [govuk_link_to(link_text, scheme), "Scheme #{scheme.primary_client_group_display}"].join("\n") + link_text = scheme.service_name + [govuk_link_to(link_text, scheme), "Scheme #{scheme.primary_client_group}"].join("\n") end def org_cell(user) diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 92102aee9..65fce7e51 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -4,7 +4,8 @@ class Organisation < ApplicationRecord has_many :managed_case_logs, class_name: "CaseLog", foreign_key: "managing_organisation_id" has_many :data_protection_confirmations has_many :organisation_rent_periods - has_many :schemes + has_many :owned_schemes, class_name: "Scheme", foreign_key: "stock_owning_organisation_id" + has_many :managed_schemes, class_name: "Scheme" scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") } scope :search_by, ->(param) { search_by_name(param) } diff --git a/app/models/scheme.rb b/app/models/scheme.rb index 90f027f2f..f93c08778 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -1,110 +1,145 @@ class Scheme < ApplicationRecord belongs_to :organisation + belongs_to :stock_owning_organisation, optional: true, class_name: "Organisation" has_many :locations has_many :case_logs - scope :search_by_code, ->(code) { where("code ILIKE ?", "%#{code}%") } + scope :filter_by_id, ->(id) { where(id: (id.start_with?("S") ? id[1..] : id)) } scope :search_by_service_name, ->(name) { where("service_name ILIKE ?", "%#{name}%") } scope :search_by_postcode, ->(postcode) { joins(:locations).where("locations.postcode ILIKE ?", "%#{postcode.delete(' ')}%") } - scope :search_by, ->(param) { search_by_postcode(param).or(search_by_service_name(param)).or(search_by_code(param)).distinct } + scope :search_by, ->(param) { search_by_postcode(param).or(search_by_service_name(param)).or(filter_by_id(param)).distinct } - SCHEME_TYPE = { - 0 => "Missings", - 4 => "Foyer", - 5 => "Direct Access Hostel", - 6 => "Other Supported Housing", - 7 => "Housing for older people", + SENSITIVE = { + No: 0, + Yes: 1, }.freeze - PRIMARY_CLIENT_GROUP = { - "O" => "Homeless families with support needs", - "H" => "Offenders & people at risk of offending", - "M" => "Older people with support needs", - "L" => "People at risk of domestic violence", - "A" => "People with a physical or sensory disability", - "G" => "People with alcohol problems", - "F" => "People with drug problems", - "B" => "People with HIV or AIDS", - "D" => "People with learning disabilities", - "E" => "People with mental health problems", - "I" => "Refugees (permanent)", - "S" => "Rough sleepers", - "N" => "Single homeless people with support needs", - "R" => "Teenage parents", - "Q" => "Young people at risk", - "P" => "Young people leaving care", - "X" => "Missing", + enum sensitive: SENSITIVE, _suffix: true + + REGISTERED_UNDER_CARE_ACT = { + "No": 0, + "Yes – registered care home providing nursing care": 1, + "Yes – registered care home providing personal care": 2, + "Yes – part registered as a care home": 3, }.freeze + enum registered_under_care_act: REGISTERED_UNDER_CARE_ACT + + SCHEME_TYPE = { + "Missing": 0, + "Foyer": 4, + "Direct Access Hostel": 5, + "Other Supported Housing": 6, + "Housing for older people": 7, + }.freeze + + enum scheme_type: SCHEME_TYPE, _suffix: true + SUPPORT_TYPE = { - 0 => "Missing", - 1 => "Resettlement Support", - 2 => "Low levels of support", - 3 => "Medium levels of support", - 4 => "High levels of care and support", - 5 => "Nursing care services to a care home", - 6 => "Floating Support", + "Missing": 0, + "Resettlement support": 1, + "Low levels of support": 2, + "Medium levels of support": 3, + "High levels of care and support": 4, + "Nursing care services to a care home": 5, + "Floating Support": 6, }.freeze - INTENDED_STAY = { - "M" => "Medium stay", - "P" => "Permanent", - "S" => "Short Stay", - "V" => "Very short stay", - "X" => "Missing", + enum support_type: SUPPORT_TYPE, _suffix: true + + PRIMARY_CLIENT_GROUP = { + "Homeless families with support needs": "O", + "Offenders & people at risk of offending": "H", + "Older people with support needs": "M", + "People at risk of domestic violence": "L", + "People with a physical or sensory disability": "A", + "People with alcohol problems": "G", + "People with drug problems": "F", + "People with HIV or AIDS": "B", + "People with learning disabilities": "D", + "People with mental health problems": "E", + "Refugees (permanent)": "I", + "Rough sleepers": "S", + "Single homeless people with support needs": "N", + "Teenage parents": "R", + "Young people at risk": "Q", + "Young people leaving care": "P", + "Missing": "X", }.freeze - REGISTERED_UNDER_CARE_ACT = { - 0 => "No", - 1 => "Yes – part registered as a care home", + enum primary_client_group: PRIMARY_CLIENT_GROUP, _suffix: true + enum secondary_client_group: PRIMARY_CLIENT_GROUP, _suffix: true + + INTENDED_STAY = { + "Medium stay": "M", + "Permanent": "P", + "Short stay": "S", + "Very short stay": "V", + "Missing": "X", }.freeze - SENSITIVE = { - 0 => "No", - 1 => "Yes", + HAS_OTHER_CLIENT_GROUP = { + No: 0, + Yes: 1, }.freeze - def display_attributes + enum intended_stay: INTENDED_STAY, _suffix: true + enum has_other_client_group: HAS_OTHER_CLIENT_GROUP, _suffix: true + + def id_to_display + "S#{id}" + end + + def check_details_attributes [ - { name: "Service code", value: code }, + { name: "Service code", value: id_to_display }, { name: "Name", value: service_name }, - { name: "Confidential information", value: sensitive_display }, + { name: "Confidential information", value: sensitive }, + { name: "Housing stock owned by", value: stock_owning_organisation&.name }, { name: "Managed by", value: organisation.name }, - { name: "Type of scheme", value: scheme_type_display }, - { name: "Registered under Care Standards Act 2000", value: registered_under_care_act_display }, - { name: "Total number of units", value: total_units }, - { name: "Primary client group", value: primary_client_group_display }, - { name: "Secondary client group", value: secondary_client_group_display }, - { name: "Level of support given", value: support_type_display }, - { name: "Intended length of stay", value: intended_stay_display }, + { name: "Type of scheme", value: scheme_type }, + { name: "Registered under Care Standards Act 2000", value: registered_under_care_act }, ] end - def scheme_type_display - SCHEME_TYPE[scheme_type] - end - - def sensitive_display - SENSITIVE[sensitive] - end - - def registered_under_care_act_display - REGISTERED_UNDER_CARE_ACT[registered_under_care_act] + def check_primary_client_attributes + [ + { name: "Primary client group", value: primary_client_group }, + ] end - def primary_client_group_display - PRIMARY_CLIENT_GROUP[primary_client_group] + def check_secondary_client_confirmation_attributes + [ + { name: "Has another client group", value: has_other_client_group }, + ] end - def secondary_client_group_display - PRIMARY_CLIENT_GROUP[secondary_client_group] + def check_secondary_client_attributes + [ + { name: "Secondary client group", value: secondary_client_group }, + ] end - def support_type_display - SUPPORT_TYPE[support_type] + def check_support_attributes + [ + { name: "Level of support given", value: support_type }, + { name: "Intended length of stay", value: intended_stay }, + ] end - def intended_stay_display - INTENDED_STAY[intended_stay] + def display_attributes + [ + { name: "Service code", value: id_to_display }, + { name: "Name", value: service_name }, + { name: "Confidential information", value: sensitive }, + { name: "Housing stock owned by", value: stock_owning_organisation&.name }, + { name: "Managed by", value: organisation.name }, + { name: "Type of scheme", value: scheme_type }, + { name: "Registered under Care Standards Act 2000", value: registered_under_care_act }, + { name: "Primary client group", value: primary_client_group }, + { name: "Secondary client group", value: secondary_client_group }, + { name: "Level of support given", value: support_type }, + { name: "Intended length of stay", value: intended_stay }, + ] end end diff --git a/app/views/organisations/schemes.html.erb b/app/views/organisations/schemes.html.erb index 65f7e7f23..4c59601e6 100644 --- a/app/views/organisations/schemes.html.erb +++ b/app/views/organisations/schemes.html.erb @@ -11,6 +11,8 @@ ) %> <% end %> +<%= govuk_button_link_to "Create a new supported housing scheme", new_scheme_path, html: { method: :post } %> +

    Supported housing schemes

    <%= render SearchComponent.new(current_user:, search_label: "Search by scheme name, code or postcode", value: @searched) %> diff --git a/app/views/schemes/_scheme_list.html.erb b/app/views/schemes/_scheme_list.html.erb index a5b2ab06b..8b5c6c85c 100644 --- a/app/views/schemes/_scheme_list.html.erb +++ b/app/views/schemes/_scheme_list.html.erb @@ -22,7 +22,7 @@ <% @schemes.each do |scheme| %> <%= table.body do |body| %> <%= body.row do |row| %> - <% row.cell(text: scheme.code) %> + <% row.cell(text: scheme.id_to_display) %> <% row.cell(text: simple_format(scheme_cell(scheme), { class: "govuk-!-font-weight-bold" }, wrapper_tag: "div")) %> <% row.cell(text: scheme.organisation.name) %> <% row.cell(text: scheme.created_at.to_formatted_s(:govuk_date)) %> diff --git a/app/views/schemes/check_answers.html.erb b/app/views/schemes/check_answers.html.erb new file mode 100644 index 000000000..78fff8674 --- /dev/null +++ b/app/views/schemes/check_answers.html.erb @@ -0,0 +1,65 @@ +<% content_for :title, "Check your answers before creating this scheme" %> + +<%= render partial: "organisations/headings", locals: { main: "Check your changes before updating this scheme", sub: @scheme.service_name } %> + +<%= govuk_tabs(title: "Check your answers before creating this scheme") do |component| %> + <% component.tab(label: "Scheme") do %> + <%= govuk_summary_list do |summary_list| %> + <% @scheme.check_details_attributes.each do |attr| %> + <% next if current_user.data_coordinator? && attr[:name] == ("Managed by") %> + <%= summary_list.row do |row| %> + <% row.key { attr[:name].to_s } %> + <% row.value { details_html(attr) } %> + <% row.action( + text: "Change", + href: scheme_details_path(scheme_id: @scheme.id, check_answers: true), + ) %> + <% end %> + <% end %> + <% @scheme.check_primary_client_attributes.each do |attr| %> + <%= summary_list.row do |row| %> + <% row.key { attr[:name].to_s } %> + <% row.value { details_html(attr) } %> + <% row.action( + text: "Change", + href: scheme_primary_client_group_path(scheme_id: @scheme.id, check_answers: true), + ) %> + <% end %> + <% end %> + <% @scheme.check_secondary_client_confirmation_attributes.each do |attr| %> + <%= summary_list.row do |row| %> + <% row.key { attr[:name].to_s } %> + <% row.value { details_html(attr) } %> + <% row.action( + text: "Change", + href: scheme_confirm_secondary_client_group_path(scheme_id: @scheme.id, check_answers: true), + ) %> + <% end %> + <% end %> + <% if @scheme.has_other_client_group == "Yes" %> + <% @scheme.check_secondary_client_attributes.each do |attr| %> + <%= summary_list.row do |row| %> + <% row.key { attr[:name].to_s } %> + <% row.value { details_html(attr) } %> + <% row.action( + text: "Change", + href: scheme_secondary_client_group_path(scheme_id: @scheme.id, check_answers: true), + ) %> + <% end %> + <% end %> + <% end %> + <% @scheme.check_support_attributes.each do |attr| %> + <%= summary_list.row do |row| %> + <% row.key { attr[:name].to_s } %> + <% row.value { details_html(attr) } %> + <% row.action( + text: "Change", + href: scheme_support_path(scheme_id: @scheme.id, check_answers: true), + ) %> + <% end %> + <% end %> + <% end %> + <% end %> +<% end %> + +<%= govuk_button_link_to "Create scheme", schemes_path(scheme_id: @scheme.id), html: { method: :get } %> diff --git a/app/views/schemes/confirm_secondary.html.erb b/app/views/schemes/confirm_secondary.html.erb new file mode 100644 index 000000000..b511c5a01 --- /dev/null +++ b/app/views/schemes/confirm_secondary.html.erb @@ -0,0 +1,32 @@ +<% content_for :title, "Does this scheme provide for another client group?" %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/primary-client-group", + ) %> +<% end %> + +<%= render partial: "organisations/headings", locals: { main: "Does this scheme provide for another client group?", sub: @scheme.service_name } %> + +<%= form_for(@scheme, method: :patch) do |f| %> +
    +
    + + <% selection = [OpenStruct.new(id: "Yes", name: "Yes"), OpenStruct.new(id: "No", name: "No")] %> + + <%= f.govuk_collection_radio_buttons :has_other_client_group, + selection, + :id, + :name, + legend: nil %> + + <%= f.hidden_field :page, value: "confirm-secondary" %> + <% if request.query_parameters["check_answers"] == "true" %> + <%= f.hidden_field :check_answers, value: "true" %> + <% end %> + + <%= f.govuk_submit "Save and continue" %> +
    +
    +<% end %> diff --git a/app/views/schemes/details.html.erb b/app/views/schemes/details.html.erb new file mode 100644 index 000000000..73ef511aa --- /dev/null +++ b/app/views/schemes/details.html.erb @@ -0,0 +1,76 @@ +<% content_for :title, "Create a new supported housing scheme" %> + + <% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: :back, + ) %> + <% end %> + + <%= render partial: "organisations/headings", locals: { main: "Create a new supported housing scheme", sub: nil } %> + + <%= form_for(@scheme, method: :patch) do |f| %> +
    +
    + <%= f.govuk_error_summary %> + + <%= f.govuk_text_field :service_name, + label: { text: "Scheme name", size: "m" }, + hint: { text: "This is how you’ll refer to this supported housing scheme within your organisation. For example, the name could relate to the address or location. You’ll be able to see the client group when selecting it." } %> + + <%= f.govuk_check_box :sensitive, + 1, + 0, + checked: @scheme.sensitive?, + multiple: false, + label: { text: "This scheme contains confidential information" } %> + + <% null_option = [OpenStruct.new(id: "", name: "Select an option")] %> + <% organisations = Organisation.all.map { |org| OpenStruct.new(id: org.id, name: org.name) } %> + <% stock_org_answer_options = null_option + organisations %> + + <%= f.govuk_collection_select :stock_owning_organisation_id, + stock_org_answer_options, + :id, + :name, + label: { text: "Which organisation owns the housing stock for this scheme?", size: "m" }, + "data-controller": %w[accessible-autocomplete conditional-filter] %> + + <% if current_user.support? %> + <%= f.govuk_collection_select :organisation_id, + organisations, + :id, + :name, + label: { text: "Which organisation manages this scheme?", size: "m" }, + options: { required: true }, + "data-controller": %w[accessible-autocomplete conditional-filter] %> + <% end %> + + <% if current_user.data_coordinator? %> + <%= f.hidden_field :organisation_id, value: current_user.organisation.id %> + <% end %> + + <% scheme_types_selection = Scheme.scheme_types.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + + <%= f.govuk_collection_radio_buttons :scheme_type, + scheme_types_selection, + :id, + :name, + legend: { text: "What is this type of scheme?", size: "m" } %> + + <% care_acts_selection = Scheme.registered_under_care_acts.keys.reverse.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + + <%= f.govuk_collection_radio_buttons :registered_under_care_act, + care_acts_selection, + :id, + :name, + legend: { text: "Is this scheme registered under the Care Standards Act 2000?", size: "m" } %> + + <%= f.hidden_field :page, value: "details" %> + <% if request.query_parameters["check_answers"] %> + <%= f.hidden_field :check_answers, value: "true" %> + <% end %> + <%= f.govuk_submit "Save and continue" %> +
    +
    + <% end %> diff --git a/app/views/schemes/index.html.erb b/app/views/schemes/index.html.erb index ae8f344e7..190d29d3d 100644 --- a/app/views/schemes/index.html.erb +++ b/app/views/schemes/index.html.erb @@ -7,6 +7,8 @@

    Supported housing schemes

    +<%= govuk_button_link_to "Create a new supported housing scheme", new_scheme_path, html: { method: :post } %> + <%= render SearchComponent.new(current_user:, search_label: "Search by scheme name, code or postcode", value: @searched) %>
    diff --git a/app/views/schemes/new.html.erb b/app/views/schemes/new.html.erb new file mode 100644 index 000000000..194f61c3e --- /dev/null +++ b/app/views/schemes/new.html.erb @@ -0,0 +1,72 @@ +<% content_for :title, "Create a new supported housing scheme" %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: "javascript:history.go(-1);", + ) %> +<% end %> + +<%= form_for(@scheme, as: :scheme, method: :post) do |f| %> +
    +
    + <%= f.govuk_error_summary %> + +

    + <%= content_for(:title) %> +

    + + <%= f.govuk_text_field :service_name, + label: { text: "Scheme name", size: "m" }, + hint: { text: "This is how you refer to this supported housing scheme within your organisation. For example, the name could relate to the address or location. You’ll be able to see the client group when selecting it." } %> + + <%= f.govuk_check_box :sensitive, + "Yes", + checked: @scheme.sensitive?, + multiple: false, + label: { text: "This scheme contains confidential information" } %> + + <% null_option = [OpenStruct.new(id: "", name: "Select an option")] %> + <% organisations = Organisation.all.map { |org| OpenStruct.new(id: org.id, name: org.name) } %> + <% answer_options = null_option + organisations %> + + <%= f.govuk_collection_select :stock_owning_organisation_id, + answer_options, + :id, + :name, + label: { text: "Which organisation owns the housing stock for this scheme?", size: "m" }, + "data-controller": %w[accessible-autocomplete conditional-filter] %> + + <% if current_user.support? %> + <%= f.govuk_collection_select :organisation_id, + answer_options, + :id, + :name, + label: { text: "Which organisation manages this scheme?", size: "m" }, + "data-controller": %w[accessible-autocomplete conditional-filter] %> + <% end %> + + <% if current_user.data_coordinator? %> + <%= f.hidden_field :organisation_id, value: current_user.organisation.id %> + <% end %> + + <% scheme_types_selection = Scheme.scheme_types.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + + <%= f.govuk_collection_radio_buttons :scheme_type, + scheme_types_selection, + :id, + :name, + legend: { text: "What is this type of scheme?", size: "m" } %> + + <% care_acts_selection = Scheme.registered_under_care_acts.keys.reverse.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + + <%= f.govuk_collection_radio_buttons :registered_under_care_act, + care_acts_selection, + :id, + :name, + legend: { text: "Is this scheme registered under the Care Standards Act 2000?", size: "m" } %> + + <%= f.govuk_submit "Save and continue" %> +
    +
    +<% end %> diff --git a/app/views/schemes/primary_client_group.html.erb b/app/views/schemes/primary_client_group.html.erb new file mode 100644 index 000000000..af3ea80e5 --- /dev/null +++ b/app/views/schemes/primary_client_group.html.erb @@ -0,0 +1,35 @@ +<% content_for :title, "What client group is this scheme intended for?" %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/details", + ) %> +<% end %> + +<%= render partial: "organisations/headings", locals: { main: "What client group is this scheme intended for?", sub: @scheme.service_name } %> + +<%= form_for(@scheme, method: :patch) do |f| %> +
    +
    + <%= f.govuk_error_summary %> + + + + + <% primary_client_group_selection = Scheme.primary_client_groups.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + <%= f.govuk_collection_radio_buttons :primary_client_group, + primary_client_group_selection, + :id, + :name, + legend: nil %> + + <%= f.hidden_field :page, value: "primary-client-group" %> + <% if request.query_parameters["check_answers"] == "true" %> + <%= f.hidden_field :check_answers, value: "true" %> + <% end %> + + <%= f.govuk_submit "Save and continue" %> +
    +
    +<% end %> diff --git a/app/views/schemes/secondary_client_group.html.erb b/app/views/schemes/secondary_client_group.html.erb new file mode 100644 index 000000000..f785fb887 --- /dev/null +++ b/app/views/schemes/secondary_client_group.html.erb @@ -0,0 +1,35 @@ +<% content_for :title, "What is the other client group?" %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/confirm-secondary-client-group", + ) %> +<% end %> + +<%= render partial: "organisations/headings", locals: { main: "What is the other client group?", sub: @scheme.service_name } %> + +<%= form_for(@scheme, method: :patch) do |f| %> +
    +
    + <%= f.govuk_error_summary %> + + + + + <% secondary_client_group_selection = Scheme.secondary_client_groups.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + <%= f.govuk_collection_radio_buttons :secondary_client_group, + secondary_client_group_selection, + :id, + :name, + legend: nil %> + + <%= f.hidden_field :page, value: "secondary-client-group" %> + <% if request.query_parameters["check_answers"] == "true" %> + <%= f.hidden_field :check_answers, value: "true" %> + <% end %> + + <%= f.govuk_submit "Save and continue" %> +
    +
    +<% end %> diff --git a/app/views/schemes/support.html.erb b/app/views/schemes/support.html.erb new file mode 100644 index 000000000..317b1d4f1 --- /dev/null +++ b/app/views/schemes/support.html.erb @@ -0,0 +1,39 @@ +<% content_for :title, "What support does this scheme provide?" %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/secondary-client-group", + ) %> +<% end %> + +<%= render partial: "organisations/headings", locals: { main: "What support does this scheme provide?", sub: @scheme.service_name } %> + +<%= form_for(@scheme, method: :patch) do |f| %> +
    +
    + <%= f.govuk_error_summary %> + + + + + <% support_type_selection = Scheme.support_types.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + <%= f.govuk_collection_radio_buttons :support_type, + support_type_selection, + :id, + :name, + legend: { text: "Level of support given", size: "m" } %> + + <% intended_stay_selection = Scheme.intended_stays.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> + <%= f.govuk_collection_radio_buttons :intended_stay, + intended_stay_selection, + :id, + :name, + legend: { text: "Intended length of stay", size: "m" } %> + + <%= f.hidden_field :page, value: "support" %> + + <%= f.govuk_submit "Save and continue" %> +
    +
    +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index f073b658a..deec6bc74 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -38,6 +38,14 @@ en: create_password: "Create a password to finish setting up your account" reset_password: "Reset your password" + activerecord: + errors: + models: + scheme: + attributes: + organisation: + required: "Enter the existing organisation’s name" + validations: organisation: name_missing: "Enter the organisation’s name" diff --git a/config/routes.rb b/config/routes.rb index 01efc2623..0cbaa82c2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -35,7 +35,14 @@ Rails.application.routes.draw do get "edit/password", to: "users#edit_password" end - resources :schemes, only: %i[index show] do + resources :schemes do + get "primary-client-group", to: "schemes#primary_client_group" + get "confirm-secondary-client-group", to: "schemes#confirm_secondary_client_group" + get "secondary-client-group", to: "schemes#secondary_client_group" + get "support", to: "schemes#support" + get "details", to: "schemes#details" + get "check-answers", to: "schemes#check_answers" + member do get "locations", to: "schemes#locations" end diff --git a/db/migrate/20220616130451_add_reference_to_case_log.rb b/db/migrate/20220616130451_add_reference_to_case_log.rb index 52f7bfecb..6fca582a9 100644 --- a/db/migrate/20220616130451_add_reference_to_case_log.rb +++ b/db/migrate/20220616130451_add_reference_to_case_log.rb @@ -1,5 +1,5 @@ class AddReferenceToCaseLog < ActiveRecord::Migration[7.0] def change - add_reference :case_logs, :scheme, foreign_key: true + add_reference :case_logs, :scheme, foreign_key: true, null: true end end diff --git a/db/migrate/20220623132228_add_has_other_client_group_field.rb b/db/migrate/20220623132228_add_has_other_client_group_field.rb new file mode 100644 index 000000000..af04a6af8 --- /dev/null +++ b/db/migrate/20220623132228_add_has_other_client_group_field.rb @@ -0,0 +1,7 @@ +class AddHasOtherClientGroupField < ActiveRecord::Migration[7.0] + def change + change_table :schemes, bulk: true do |t| + t.column :has_other_client_group, :integer + end + end +end diff --git a/db/migrate/20220629100324_remove_code_from_schemes.rb b/db/migrate/20220629100324_remove_code_from_schemes.rb new file mode 100644 index 000000000..be918f62f --- /dev/null +++ b/db/migrate/20220629100324_remove_code_from_schemes.rb @@ -0,0 +1,5 @@ +class RemoveCodeFromSchemes < ActiveRecord::Migration[7.0] + def change + remove_column :schemes, :code, :string + end +end diff --git a/db/migrate/20220629105452_add_stock_owning_organisation_to_schemes.rb b/db/migrate/20220629105452_add_stock_owning_organisation_to_schemes.rb new file mode 100644 index 000000000..1623eb654 --- /dev/null +++ b/db/migrate/20220629105452_add_stock_owning_organisation_to_schemes.rb @@ -0,0 +1,5 @@ +class AddStockOwningOrganisationToSchemes < ActiveRecord::Migration[7.0] + def change + add_reference :schemes, :stock_owning_organisation, foreign_key: { to_table: :organisations } + end +end diff --git a/db/schema.rb b/db/schema.rb index 56f4c9b08..280bd3b59 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2022_06_17_102313) do +ActiveRecord::Schema[7.0].define(version: 2022_06_29_105452) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -297,7 +297,6 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_17_102313) do end create_table "schemes", force: :cascade do |t| - t.string "code" t.string "service_name" t.bigint "organisation_id", null: false t.datetime "created_at", null: false @@ -311,7 +310,10 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_17_102313) do t.integer "support_type" t.string "intended_stay" t.datetime "end_date" + t.integer "has_other_client_group" + t.bigint "stock_owning_organisation_id" t.index ["organisation_id"], name: "index_schemes_on_organisation_id" + t.index ["stock_owning_organisation_id"], name: "index_schemes_on_stock_owning_organisation_id" end create_table "users", force: :cascade do |t| @@ -370,4 +372,5 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_17_102313) do add_foreign_key "case_logs", "schemes" add_foreign_key "locations", "schemes" add_foreign_key "schemes", "organisations" + add_foreign_key "schemes", "organisations", column: "stock_owning_organisation_id" end diff --git a/db/seeds.rb b/db/seeds.rb index fdf9d6172..654f1c777 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -71,7 +71,6 @@ unless Rails.env.test? if Rails.env.development? && Scheme.count.zero? scheme1 = Scheme.create!( - code: "S878", service_name: "Beulahside Care", sensitive: 0, registered_under_care_act: 0, @@ -86,7 +85,6 @@ unless Rails.env.test? ) scheme2 = Scheme.create!( - code: "S312", service_name: "Abdullahview Point", sensitive: 0, registered_under_care_act: 1, @@ -101,7 +99,6 @@ unless Rails.env.test? ) Scheme.create!( - code: "7XYZ", service_name: "Caspermouth Center", sensitive: 1, registered_under_care_act: 1, diff --git a/spec/factories/scheme.rb b/spec/factories/scheme.rb index d4f2c1cfb..b16cc75cf 100644 --- a/spec/factories/scheme.rb +++ b/spec/factories/scheme.rb @@ -1,6 +1,5 @@ FactoryBot.define do factory :scheme do - code { Faker::Name.initials(number: 4) } service_name { Faker::Name.name } sensitive { Faker::Number.within(range: 0..1) } registered_under_care_act { Faker::Number.within(range: 0..1) } diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb index 44cc276f8..62107aaac 100644 --- a/spec/features/schemes_spec.rb +++ b/spec/features/schemes_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe "Schemes scheme Features" do context "when viewing list of schemes" do context "when I am signed as a coordinator user and there are schemes in the database" do - let(:user) { FactoryBot.create(:user, :data_coordinator, last_sign_in_at: Time.zone.now) } + let!(:user) { FactoryBot.create(:user, :data_coordinator, last_sign_in_at: Time.zone.now) } let!(:schemes) { FactoryBot.create_list(:scheme, 5, organisation: user.organisation) } let!(:scheme_to_search) { FactoryBot.create(:scheme, organisation: user.organisation) } @@ -25,7 +25,7 @@ RSpec.describe "Schemes scheme Features" do it "shows list of schemes" do schemes.each do |scheme| - expect(page).to have_content(scheme.code) + expect(page).to have_content(scheme.id) end end @@ -38,12 +38,12 @@ RSpec.describe "Schemes scheme Features" do context "when I fill in search information and press the search button" do before do - fill_in("search", with: scheme_to_search.code) + fill_in("search", with: scheme_to_search.id_to_display) click_button("Search") end it "displays scheme matching the scheme code" do - expect(page).to have_content(scheme_to_search.code) + expect(page).to have_content(scheme_to_search.id_to_display) end context "when I want to clear results" do @@ -53,9 +53,9 @@ RSpec.describe "Schemes scheme Features" do it "displays all schemes after I clear the search results" do click_link("Clear search") - expect(page).to have_content(scheme_to_search.code) + expect(page).to have_content(scheme_to_search.id) schemes.each do |scheme| - expect(page).to have_content(scheme.code) + expect(page).to have_content(scheme.id) end end end @@ -63,30 +63,32 @@ RSpec.describe "Schemes scheme Features" do end end end + end - context "when I am signed as a support user and there are schemes in the database" do - let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) } - let!(:schemes) { FactoryBot.create_list(:scheme, 5) } - let!(:scheme_to_search) { FactoryBot.create(:scheme) } - let(:notify_client) { instance_double(Notifications::Client) } - let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" } - let(:devise_notify_mailer) { DeviseNotifyMailer.new } - let(:otp) { "999111" } - - before do - allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) - allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) - allow(Devise).to receive(:friendly_token).and_return(confirmation_token) - allow(notify_client).to receive(:send_email).and_return(true) - allow(SecureRandom).to receive(:random_number).and_return(otp) - visit("/logs") - fill_in("user[email]", with: user.email) - fill_in("user[password]", with: user.password) - click_button("Sign in") - fill_in("code", with: otp) - click_button("Submit") - end + context "when I am signed as a support user and there are schemes in the database" do + let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) } + let!(:schemes) { FactoryBot.create_list(:scheme, 5) } + let!(:scheme_to_search) { FactoryBot.create(:scheme) } + let(:notify_client) { instance_double(Notifications::Client) } + let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" } + let(:devise_notify_mailer) { DeviseNotifyMailer.new } + let(:otp) { "999111" } + + before do + allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) + allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) + allow(Devise).to receive(:friendly_token).and_return(confirmation_token) + allow(notify_client).to receive(:send_email).and_return(true) + allow(SecureRandom).to receive(:random_number).and_return(otp) + visit("/logs") + fill_in("user[email]", with: user.email) + fill_in("user[password]", with: user.password) + click_button("Sign in") + fill_in("code", with: otp) + click_button("Submit") + end + context "when viewing list of schemes" do it "displays the link to the schemes" do expect(page).to have_link("Schemes", href: "/schemes") end @@ -98,7 +100,7 @@ RSpec.describe "Schemes scheme Features" do it "shows list of schemes" do schemes.each do |scheme| - expect(page).to have_content(scheme.code) + expect(page).to have_content(scheme.id) end end @@ -111,12 +113,12 @@ RSpec.describe "Schemes scheme Features" do context "when I fill in search information and press the search button" do before do - fill_in("search", with: scheme_to_search.code) + fill_in("search", with: scheme_to_search.id_to_display) click_button("Search") end it "displays scheme matching the scheme code" do - expect(page).to have_content(scheme_to_search.code) + expect(page).to have_content(scheme_to_search.id_to_display) end context "when I want to clear results" do @@ -126,9 +128,9 @@ RSpec.describe "Schemes scheme Features" do it "displays all schemes after I clear the search results" do click_link("Clear search") - expect(page).to have_content(scheme_to_search.code) + expect(page).to have_content(scheme_to_search.id_to_display) schemes.each do |scheme| - expect(page).to have_content(scheme.code) + expect(page).to have_content(scheme.id_to_display) end end end @@ -136,31 +138,8 @@ RSpec.describe "Schemes scheme Features" do end end end - end - - context "when viewing individual scheme" do - context "when I am signed as a support user and there are schemes in the database" do - let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) } - let!(:schemes) { FactoryBot.create_list(:scheme, 5) } - let(:notify_client) { instance_double(Notifications::Client) } - let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" } - let(:devise_notify_mailer) { DeviseNotifyMailer.new } - let(:otp) { "999111" } - - before do - allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) - allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) - allow(Devise).to receive(:friendly_token).and_return(confirmation_token) - allow(notify_client).to receive(:send_email).and_return(true) - allow(SecureRandom).to receive(:random_number).and_return(otp) - visit("/logs") - fill_in("user[email]", with: user.email) - fill_in("user[password]", with: user.password) - click_button("Sign in") - fill_in("code", with: otp) - click_button("Submit") - end + context "when viewing individual scheme" do context "when I visit schemes page" do before do visit("schemes") @@ -169,7 +148,7 @@ RSpec.describe "Schemes scheme Features" do it "shows list of links to schemes" do schemes.each do |scheme| expect(page).to have_link(scheme.service_name) - expect(page).to have_content(scheme.primary_client_group_display) + expect(page).to have_content(scheme.primary_client_group) end end @@ -181,16 +160,15 @@ RSpec.describe "Schemes scheme Features" do end it "shows me details about the selected scheme" do - expect(page).to have_content(schemes.first.code) + expect(page).to have_content(schemes.first.id_to_display) expect(page).to have_content(schemes.first.service_name) - expect(page).to have_content(schemes.first.sensitive_display) - expect(page).to have_content(schemes.first.scheme_type_display) - expect(page).to have_content(schemes.first.registered_under_care_act_display) - expect(page).to have_content(schemes.first.total_units) - expect(page).to have_content(schemes.first.primary_client_group_display) - expect(page).to have_content(schemes.first.secondary_client_group_display) - expect(page).to have_content(schemes.first.support_type_display) - expect(page).to have_content(schemes.first.intended_stay_display) + expect(page).to have_content(schemes.first.sensitive) + expect(page).to have_content(schemes.first.scheme_type) + expect(page).to have_content(schemes.first.registered_under_care_act) + expect(page).to have_content(schemes.first.primary_client_group) + expect(page).to have_content(schemes.first.secondary_client_group) + expect(page).to have_content(schemes.first.support_type) + expect(page).to have_content(schemes.first.intended_stay) end context "when I click to go back" do @@ -203,7 +181,7 @@ RSpec.describe "Schemes scheme Features" do click_on("Back") schemes.each do |scheme| expect(page).to have_link(scheme.service_name) - expect(page).to have_content(scheme.primary_client_group_display) + expect(page).to have_content(scheme.primary_client_group) end end end @@ -238,5 +216,341 @@ RSpec.describe "Schemes scheme Features" do end end end + + context "when creating a new scheme" do + before do + Scheme.destroy_all + click_link "Schemes", href: "/schemes" + end + + it "displays the link to create a new scheme" do + expect(page).to have_current_path("/schemes") + expect(page).to have_link("Create a new supported housing scheme") + end + + context "when I press create a new scheme" do + let!(:organisation) { FactoryBot.create(:organisation, name: "FooBar") } + + before do + click_link "Create a new supported housing scheme" + end + + it "lets me fill in the scheme details" do + expect(page).to have_current_path("/schemes/new") + expect(page).to have_content "Scheme name" + expect(page).to have_content "This scheme contains confidential information" + expect(page).to have_content "Which organisation owns the housing stock for this scheme?" + expect(page).to have_content "Which organisation manages this scheme?" + expect(page).to have_content "What is this type of scheme?" + expect(page).to have_content "Is this scheme registered under the Care Standards Act 2000?" + end + + context "when I fill in scheme details and I press save I see primary client group section" do + let(:scheme) { Scheme.first } + + before do + fill_in "Scheme name", with: "FooBar" + check "This scheme contains confidential information" + choose "Direct access hostel" + choose "Yes – registered care home providing nursing care" + select organisation.name, from: "scheme-organisation-id-field" + select organisation.name, from: "scheme-stock-owning-organisation-id-field" + click_button "Save and continue" + end + + it "lets me fill in the scheme details" do + expect(page).to have_content "What client group is this scheme intended for?" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me fill in the scheme details" do + expect(page).to have_current_path("/schemes/#{scheme.id}/details") + expect(page).to have_content "Scheme name" + expect(page).to have_content "This scheme contains confidential information" + expect(page).to have_content "Which organisation manages this scheme" + expect(page).to have_content "What is this type of scheme?" + expect(page).to have_content "Is this scheme registered under the Care Standards Act 2000?" + end + + context "when we amend scheme details" do + it "returns to the primary client group question" do + click_button "Save and continue" + expect(page).to have_current_path("/schemes/#{scheme.id}/primary-client-group") + end + end + end + + context "when I select primary client group details" do + before do + choose "Homeless families with support needs" + click_button "Save and continue" + end + + it "lets me confirm if I want to select secondary group details" do + expect(page).to have_content "Does this scheme provide for another client group?" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the primary client group" do + expect(page).to have_current_path("/schemes/#{scheme.id}/primary-client-group") + expect(page).to have_content "What client group is this scheme intended for?" + end + + context "when we amend primary client group" do + it "returns to the confirm secondary client group question" do + click_button "Save and continue" + expect(page).to have_current_path("/schemes/#{scheme.id}/confirm-secondary-client-group") + end + end + end + + context "when I confirm the secondary group" do + before do + choose "Yes" + click_button "Save and continue" + end + + it "lets me select secondary client group" do + expect(page).to have_content "What is the other client group?" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me confirm the secondary group" do + expect(page).to have_current_path("/schemes/#{scheme.id}/confirm-secondary-client-group") + expect(page).to have_content "Does this scheme provide for another client group?" + end + + context "when we amend confirm secondary client" do + it "returns to the secondary client group question" do + click_button "Save and continue" + expect(page).to have_current_path("/schemes/#{scheme.id}/secondary-client-group") + end + end + end + + context "when I select the secondary group" do + before do + choose "Homeless families with support needs" + click_button "Save and continue" + end + + it "lets me select level of support" do + expect(page).to have_content "What support does this scheme provide?" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the secondary group" do + expect(page).to have_current_path("/schemes/#{scheme.id}/secondary-client-group") + expect(page).to have_content "What is the other client group?" + end + + context "when we amend secondary client" do + it "returns to the support question" do + click_button "Save and continue" + expect(page).to have_current_path("/schemes/#{scheme.id}/support") + end + end + end + + context "when I select the support answers" do + before do + choose "Floating support" + choose "Very short stay" + click_button "Save and continue" + end + + it "lets me check my answers" do + expect(page).to have_content "Check your changes before updating this scheme" + end + + context "when changing answers" do + it "displays change links" do + assert_selector "a", text: "Change", count: 12 + end + + context "when changing details" do + before do + click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first) + end + + it "allows changing details questions" do + expect(page).to have_current_path("/schemes/#{scheme.id}/details?check_answers=true") + + fill_in "Scheme name", with: "Example" + choose "Direct access hostel" + choose "Yes – registered care home providing nursing care" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Example" + expect(page).to have_content "Yes – registered care home providing nursing care" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the support answers" do + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Check your changes before updating this scheme" + end + end + end + + context "when changing primary client group" do + before do + click_link("Change", href: "/schemes/#{scheme.id}/primary-client-group?check_answers=true") + end + + it "allows changing primary-client-group question" do + expect(page).to have_current_path("/schemes/#{scheme.id}/primary-client-group?check_answers=true") + + choose "Older people with support needs" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Older people with support needs" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the support answers" do + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Check your changes before updating this scheme" + end + end + end + + context "when changing confirm secondary group answer" do + before do + click_link("Change", href: "/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true") + end + + it "allows changing confirm-secondary-client-group question to yes" do + expect(page).to have_current_path("/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true") + + choose "Yes" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/secondary-client-group?check_answers=true") + + choose "People at risk of domestic violence" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "People at risk of domestic violence" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the support answers" do + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Check your changes before updating this scheme" + end + end + end + + context "when allows changing confirm-secondary-client-group question to no" do + before do + click_link("Change", href: "/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true") + end + + it "allows changing confirm-secondary-client-group question to no" do + expect(page).to have_current_path("/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true") + + choose "No" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).not_to have_content "Secondary client group" + end + end + + context "when changing secondary-client-group question" do + before do + click_link("Change", href: "/schemes/#{scheme.id}/secondary-client-group?check_answers=true") + end + + it "allows changing secondary-client-group question" do + expect(page).to have_current_path("/schemes/#{scheme.id}/secondary-client-group?check_answers=true") + + choose "People at risk of domestic violence" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "People at risk of domestic violence" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the support answers" do + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Check your changes before updating this scheme" + end + end + end + + context "when changing support questions" do + before do + click_link("Change", href: "/schemes/#{scheme.id}/support?check_answers=true", match: :first) + end + + it "allows changing support questions" do + expect(page).to have_current_path("/schemes/#{scheme.id}/support?check_answers=true") + + choose "Resettlement support" + choose "Medium stay" + click_button "Save and continue" + + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Resettlement support" + expect(page).to have_content "Medium stay" + end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "lets me select the support answers" do + expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers") + expect(page).to have_content "Check your changes before updating this scheme" + end + end + end + end + end + end + end + end + end + end + end end end diff --git a/spec/helpers/tab_nav_helper_spec.rb b/spec/helpers/tab_nav_helper_spec.rb index bd57a1c5a..f1e483fd1 100644 --- a/spec/helpers/tab_nav_helper_spec.rb +++ b/spec/helpers/tab_nav_helper_spec.rb @@ -20,8 +20,8 @@ RSpec.describe TabNavHelper do end describe "#scheme_cell" do - it "returns the scheme link, name and primary user group separated by a newline character" do - expected_html = "#{scheme.service_name}\nScheme #{scheme.primary_client_group_display}" + it "returns the scheme link service name and primary user group separated by a newline character" do + expected_html = "#{scheme.service_name}\nScheme #{scheme.primary_client_group}" expect(scheme_cell(scheme)).to match(expected_html) end end diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb index 11b7954a0..3addfd76b 100644 --- a/spec/models/organisation_spec.rb +++ b/spec/models/organisation_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Organisation, type: :model do describe "#new" do let(:user) { FactoryBot.create(:user) } let!(:organisation) { user.organisation } - let!(:scheme) { FactoryBot.create(:scheme, organisation:) } + let!(:scheme) { FactoryBot.create(:scheme, organisation:, stock_owning_organisation: organisation) } it "has expected fields" do expect(organisation.attribute_names).to include("name", "phone", "provider_type") @@ -14,8 +14,12 @@ RSpec.describe Organisation, type: :model do expect(organisation.users.first).to eq(user) end - it "has schemes" do - expect(organisation.schemes.first).to eq(scheme) + it "has managed_schemes" do + expect(organisation.managed_schemes.first).to eq(scheme) + end + + it "has owned_schemes" do + expect(organisation.owned_schemes.first).to eq(scheme) end it "validates provider_type presence" do diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb index d6e39ae2e..1581bb1e0 100644 --- a/spec/models/scheme_spec.rb +++ b/spec/models/scheme_spec.rb @@ -14,14 +14,12 @@ RSpec.describe Scheme, type: :model do let!(:location) { FactoryBot.create(:location, scheme: scheme_1) } let!(:location_2) { FactoryBot.create(:location, scheme: scheme_2) } - context "when searching by code" do + context "when filtering by id" do it "returns case insensitive matching records" do - expect(described_class.search_by_code(scheme_1.code.upcase).count).to eq(1) - expect(described_class.search_by_code(scheme_1.code.downcase).count).to eq(1) - expect(described_class.search_by_code(scheme_1.code.downcase).first.code).to eq(scheme_1.code) - expect(described_class.search_by_code(scheme_2.code.upcase).count).to eq(1) - expect(described_class.search_by_code(scheme_2.code.downcase).count).to eq(1) - expect(described_class.search_by_code(scheme_2.code.downcase).first.code).to eq(scheme_2.code) + expect(described_class.filter_by_id(scheme_1.id.to_s).count).to eq(1) + expect(described_class.filter_by_id(scheme_1.id.to_s).first.id).to eq(scheme_1.id) + expect(described_class.filter_by_id(scheme_2.id.to_s).count).to eq(1) + expect(described_class.filter_by_id(scheme_2.id.to_s).first.id).to eq(scheme_2.id) end end @@ -49,12 +47,14 @@ RSpec.describe Scheme, type: :model do context "when searching by all searchable fields" do it "returns case insensitive matching records" do - expect(described_class.search_by(scheme_1.code.upcase).count).to eq(1) - expect(described_class.search_by(scheme_1.code.downcase).count).to eq(1) - expect(described_class.search_by(scheme_1.code.downcase).first.code).to eq(scheme_1.code) - expect(described_class.search_by_service_name(scheme_2.service_name.upcase).count).to eq(1) - expect(described_class.search_by_service_name(scheme_2.service_name.downcase).count).to eq(1) - expect(described_class.search_by_service_name(scheme_2.service_name.downcase).first.service_name).to eq(scheme_2.service_name) + expect(described_class.search_by(scheme_1.id.to_s).count).to eq(1) + expect(described_class.search_by(scheme_1.id.to_s).first.id).to eq(scheme_1.id) + expect(described_class.search_by(scheme_2.service_name.upcase).count).to eq(1) + expect(described_class.search_by(scheme_2.service_name.downcase).count).to eq(1) + expect(described_class.search_by(scheme_2.service_name.downcase).first.service_name).to eq(scheme_2.service_name) + expect(described_class.search_by(location.postcode.upcase).count).to eq(1) + expect(described_class.search_by(location.postcode.downcase).count).to eq(1) + expect(described_class.search_by(location.postcode.downcase).first.locations.first.postcode).to eq(location.postcode) end end end diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index a929f9304..e2237a673 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -65,15 +65,15 @@ RSpec.describe OrganisationsController, type: :request do end it "shows only schemes belonging to the same organisation" do - expect(page).to have_content(same_org_scheme.code) + expect(page).to have_content(same_org_scheme.id) schemes.each do |scheme| - expect(page).not_to have_content(scheme.code) + expect(page).not_to have_content(scheme.id) end end context "when searching" do - let!(:searched_scheme) { FactoryBot.create(:scheme, code: "CODE321", organisation: user.organisation) } - let(:search_param) { "CODE321" } + let!(:searched_scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let(:search_param) { searched_scheme.id } before do FactoryBot.create(:location, scheme: searched_scheme) @@ -82,9 +82,9 @@ RSpec.describe OrganisationsController, type: :request do end it "returns matching results" do - expect(page).to have_content(searched_scheme.code) + expect(page).to have_content(searched_scheme.id) schemes.each do |scheme| - expect(page).not_to have_content(scheme.code) + expect(page).not_to have_content(scheme.id) end end @@ -122,9 +122,9 @@ RSpec.describe OrganisationsController, type: :request do end it "shows only schemes belonging to the same organisation" do - expect(page).to have_content(same_org_scheme.code) + expect(page).to have_content(same_org_scheme.id) schemes.each do |scheme| - expect(page).not_to have_content(scheme.code) + expect(page).not_to have_content(scheme.id) end end @@ -141,8 +141,8 @@ RSpec.describe OrganisationsController, type: :request do end context "when searching" do - let!(:searched_scheme) { FactoryBot.create(:scheme, code: "CODE321", organisation: user.organisation) } - let(:search_param) { "CODE321" } + let!(:searched_scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let(:search_param) { searched_scheme.id } before do FactoryBot.create(:location, scheme: searched_scheme) @@ -150,9 +150,9 @@ RSpec.describe OrganisationsController, type: :request do end it "returns matching results" do - expect(page).to have_content(searched_scheme.code) + expect(page).to have_content(searched_scheme.id) schemes.each do |scheme| - expect(page).not_to have_content(scheme.code) + expect(page).not_to have_content(scheme.id) end end diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index be17ec13e..30cba5cf2 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -37,6 +37,14 @@ RSpec.describe SchemesController, type: :request do get "/schemes" end + context "when params scheme_id is present" do + it "shows a success banner" do + get "/schemes", params: { scheme_id: schemes.first.id } + follow_redirect! + expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") + end + end + it "redirects to the organisation schemes path" do follow_redirect! expect(path).to match("/organisations/#{user.organisation.id}/schemes") @@ -56,7 +64,7 @@ RSpec.describe SchemesController, type: :request do it "shows all schemes" do schemes.each do |scheme| - expect(page).to have_content(scheme.code) + expect(page).to have_content(scheme.id_to_display) end end @@ -77,6 +85,13 @@ RSpec.describe SchemesController, type: :request do expect(CGI.unescape_html(response.body)).to include(expected_field) end + context "when params scheme_id is present" do + it "shows a success banner" do + get "/schemes", params: { scheme_id: schemes.first.id } + expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") + end + end + context "when paginating over 20 results" do let(:total_schemes_count) { Scheme.count } @@ -136,8 +151,8 @@ RSpec.describe SchemesController, type: :request do end context "when searching" do - let!(:searched_scheme) { FactoryBot.create(:scheme, code: "CODE321") } - let(:search_param) { "CODE321" } + let!(:searched_scheme) { FactoryBot.create(:scheme) } + let(:search_param) { searched_scheme.id_to_display } before do FactoryBot.create(:location, scheme: searched_scheme) @@ -145,9 +160,9 @@ RSpec.describe SchemesController, type: :request do end it "returns matching results" do - expect(page).to have_content(searched_scheme.code) + expect(page).to have_content(searched_scheme.id_to_display) schemes.each do |scheme| - expect(page).not_to have_content(scheme.code) + expect(page).not_to have_content(scheme.id_to_display) end end @@ -196,20 +211,19 @@ RSpec.describe SchemesController, type: :request do it "has page heading" do get "/schemes/#{specific_scheme.id}" - expect(page).to have_content(specific_scheme.code) + expect(page).to have_content(specific_scheme.id_to_display) expect(page).to have_content(specific_scheme.service_name) expect(page).to have_content(specific_scheme.organisation.name) - expect(page).to have_content(specific_scheme.sensitive_display) - expect(page).to have_content(specific_scheme.code) + expect(page).to have_content(specific_scheme.sensitive) + expect(page).to have_content(specific_scheme.id_to_display) expect(page).to have_content(specific_scheme.service_name) - expect(page).to have_content(specific_scheme.sensitive_display) - expect(page).to have_content(specific_scheme.scheme_type_display) - expect(page).to have_content(specific_scheme.registered_under_care_act_display) - expect(page).to have_content(specific_scheme.total_units) - expect(page).to have_content(specific_scheme.primary_client_group_display) - expect(page).to have_content(specific_scheme.secondary_client_group_display) - expect(page).to have_content(specific_scheme.support_type_display) - expect(page).to have_content(specific_scheme.intended_stay_display) + expect(page).to have_content(specific_scheme.sensitive) + expect(page).to have_content(specific_scheme.scheme_type) + expect(page).to have_content(specific_scheme.registered_under_care_act) + expect(page).to have_content(specific_scheme.primary_client_group) + expect(page).to have_content(specific_scheme.secondary_client_group) + expect(page).to have_content(specific_scheme.support_type) + expect(page).to have_content(specific_scheme.intended_stay) end context "when coordinator attempts to see scheme belonging to a different organisation" do @@ -230,20 +244,19 @@ RSpec.describe SchemesController, type: :request do end it "has page heading" do - expect(page).to have_content(specific_scheme.code) + expect(page).to have_content(specific_scheme.id_to_display) expect(page).to have_content(specific_scheme.service_name) expect(page).to have_content(specific_scheme.organisation.name) - expect(page).to have_content(specific_scheme.sensitive_display) - expect(page).to have_content(specific_scheme.code) + expect(page).to have_content(specific_scheme.sensitive) + expect(page).to have_content(specific_scheme.id_to_display) expect(page).to have_content(specific_scheme.service_name) - expect(page).to have_content(specific_scheme.sensitive_display) - expect(page).to have_content(specific_scheme.scheme_type_display) - expect(page).to have_content(specific_scheme.registered_under_care_act_display) - expect(page).to have_content(specific_scheme.total_units) - expect(page).to have_content(specific_scheme.primary_client_group_display) - expect(page).to have_content(specific_scheme.secondary_client_group_display) - expect(page).to have_content(specific_scheme.support_type_display) - expect(page).to have_content(specific_scheme.intended_stay_display) + expect(page).to have_content(specific_scheme.sensitive) + expect(page).to have_content(specific_scheme.scheme_type) + expect(page).to have_content(specific_scheme.registered_under_care_act) + expect(page).to have_content(specific_scheme.primary_client_group) + expect(page).to have_content(specific_scheme.secondary_client_group) + expect(page).to have_content(specific_scheme.support_type) + expect(page).to have_content(specific_scheme.intended_stay) end end end @@ -448,4 +461,957 @@ RSpec.describe SchemesController, type: :request do end end end + + describe "#new" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/new" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/new" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + + before do + sign_in user + get "/schemes/new" + end + + it "returns a template for a new scheme" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Create a new supported housing scheme") + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/new" + end + + it "returns a template for a new scheme" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Create a new supported housing scheme") + end + end + end + + describe "#create" do + context "when not signed in" do + it "redirects to the sign in page" do + post "/schemes" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + post "/schemes" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let(:params) { { scheme: { service_name: "testy", sensitive: "1", scheme_type: "Foyer", registered_under_care_act: "No", total_units: "1" } } } + + before do + sign_in user + end + + it "creates a new scheme for user organisation with valid params and renders correct page" do + expect { post "/schemes", params: }.to change(Scheme, :count).by(1) + expect(response).to have_http_status(:ok) + expect(page).to have_content("What client group is this scheme intended for?") + end + + it "creates a new scheme for user organisation with valid params" do + post "/schemes", params: params + + expect(Scheme.last.organisation_id).to eq(user.organisation_id) + expect(Scheme.last.service_name).to eq("testy") + expect(Scheme.last.scheme_type).to eq("Foyer") + expect(Scheme.last.sensitive).to eq("Yes") + expect(Scheme.last.registered_under_care_act).to eq("No") + expect(Scheme.last.id).not_to eq(nil) + expect(Scheme.last.has_other_client_group).to eq(nil) + expect(Scheme.last.primary_client_group).to eq(nil) + expect(Scheme.last.secondary_client_group).to eq(nil) + expect(Scheme.last.support_type).to eq(nil) + expect(Scheme.last.intended_stay).to eq(nil) + expect(Scheme.last.id_to_display).to match(/S*/) + end + end + + context "when signed in as a support user" do + let(:organisation) { FactoryBot.create(:organisation) } + let(:user) { FactoryBot.create(:user, :support) } + let(:params) { { scheme: { service_name: "testy", sensitive: "1", scheme_type: "Foyer", registered_under_care_act: "No", total_units: "1", organisation_id: organisation.id } } } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + end + + it "creates a new scheme for user organisation with valid params and renders correct page" do + expect { post "/schemes", params: }.to change(Scheme, :count).by(1) + expect(response).to have_http_status(:ok) + expect(page).to have_content("What client group is this scheme intended for?") + end + + it "creates a new scheme for user organisation with valid params" do + post "/schemes", params: params + + expect(Scheme.last.organisation_id).to eq(organisation.id) + expect(Scheme.last.service_name).to eq("testy") + expect(Scheme.last.scheme_type).to eq("Foyer") + expect(Scheme.last.sensitive).to eq("Yes") + expect(Scheme.last.registered_under_care_act).to eq("No") + expect(Scheme.last.id).not_to eq(nil) + expect(Scheme.last.has_other_client_group).to eq(nil) + expect(Scheme.last.primary_client_group).to eq(nil) + expect(Scheme.last.secondary_client_group).to eq(nil) + expect(Scheme.last.support_type).to eq(nil) + expect(Scheme.last.intended_stay).to eq(nil) + expect(Scheme.last.id_to_display).to match(/S*/) + end + + context "when required organisation id param is missing" do + let(:params) { { "scheme" => { "service_name" => "qweqwer", "sensitive" => "Yes", "organisation_id" => "", "scheme_type" => "Foyer", "registered_under_care_act" => "Yes – part registered as a care home", "total_units" => "1" } } } + + it "displays the new page with an error message" do + post "/schemes", params: params + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.organisation.required")) + end + end + end + end + + describe "#update" do + context "when not signed in" do + it "redirects to the sign in page" do + patch "/schemes/#{schemes.first.id}" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + patch "/schemes/#{schemes.first.id}" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let(:scheme_to_update) { FactoryBot.create(:scheme, organisation: user.organisation) } + + before do + sign_in user + patch "/schemes/#{scheme_to_update.id}", params: + end + + context "when updating primary client group" do + let(:params) { { scheme: { primary_client_group: "Homeless families with support needs", page: "primary-client-group" } } } + + it "renders confirm secondary group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Does this scheme provide for another client group?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.primary_client_group).to eq("Homeless families with support needs") + end + + context "when updating from check answers page" do + let(:params) { { scheme: { primary_client_group: "Homeless families with support needs", page: "primary-client-group", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.primary_client_group).to eq("Homeless families with support needs") + end + end + end + + context "when updating confirm secondary client group" do + let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary" } } } + + it "renders secondary client group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What is the other client group?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.has_other_client_group).to eq("Yes") + end + + context "when updating from check answers page with the answer YES" do + let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What is the other client group?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.has_other_client_group).to eq("Yes") + end + end + + context "when updating from check answers page with the answer NO" do + let(:params) { { scheme: { has_other_client_group: "No", page: "confirm-secondary", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.has_other_client_group).to eq("No") + end + end + end + + context "when updating secondary client group" do + let(:params) { { scheme: { secondary_client_group: "Homeless families with support needs", page: "secondary-client-group" } } } + + it "renders confirm support page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What support does this scheme provide?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.secondary_client_group).to eq("Homeless families with support needs") + end + + context "when updating from check answers page" do + let(:params) { { scheme: { secondary_client_group: "Homeless families with support needs", page: "secondary-client-group", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.secondary_client_group).to eq("Homeless families with support needs") + end + end + end + + context "when updating support" do + let(:params) { { scheme: { intended_stay: "Medium stay", support_type: "Resettlement support", page: "support" } } } + + it "renders confirm secondary group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.intended_stay).to eq("Medium stay") + expect(scheme_to_update.reload.support_type).to eq("Resettlement support") + end + + context "when updating from check answers page" do + let(:params) { { scheme: { intended_stay: "Medium stay", support_type: "Resettlement support", page: "support", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.intended_stay).to eq("Medium stay") + expect(scheme_to_update.reload.support_type).to eq("Resettlement support") + end + end + end + + context "when updating details" do + let(:params) { { scheme: { service_name: "testy", sensitive: "1", scheme_type: "Foyer", registered_under_care_act: "No", total_units: "1", page: "details" } } } + + it "renders confirm secondary group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What client group is this scheme intended for?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.service_name).to eq("testy") + expect(scheme_to_update.reload.scheme_type).to eq("Foyer") + expect(scheme_to_update.reload.sensitive).to eq("Yes") + expect(scheme_to_update.reload.registered_under_care_act).to eq("No") + expect(scheme_to_update.reload.total_units).to eq(1) + end + + context "when updating from check answers page" do + let(:params) { { scheme: { service_name: "testy", sensitive: "1", scheme_type: "Foyer", registered_under_care_act: "No", total_units: "1", page: "details", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.service_name).to eq("testy") + expect(scheme_to_update.reload.scheme_type).to eq("Foyer") + expect(scheme_to_update.reload.sensitive).to eq("Yes") + expect(scheme_to_update.reload.registered_under_care_act).to eq("No") + expect(scheme_to_update.reload.total_units).to eq(1) + end + end + end + end + + context "when signed in as a support" do + let(:user) { FactoryBot.create(:user, :support) } + let(:scheme_to_update) { FactoryBot.create(:scheme, organisation: user.organisation) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + patch "/schemes/#{scheme_to_update.id}", params: + end + + context "when updating primary client group" do + let(:params) { { scheme: { primary_client_group: "Homeless families with support needs", page: "primary-client-group" } } } + + it "renders confirm secondary group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Does this scheme provide for another client group?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.primary_client_group).to eq("Homeless families with support needs") + end + + context "when updating from check answers page" do + let(:params) { { scheme: { primary_client_group: "Homeless families with support needs", page: "primary-client-group", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.primary_client_group).to eq("Homeless families with support needs") + end + end + end + + context "when updating confirm secondary client group" do + let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary" } } } + + it "renders secondary client group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What is the other client group?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.has_other_client_group).to eq("Yes") + end + + context "when updating from check answers page with the answer YES" do + let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What is the other client group?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.has_other_client_group).to eq("Yes") + end + end + + context "when updating from check answers page with the answer NO" do + let(:params) { { scheme: { has_other_client_group: "No", page: "confirm-secondary", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.has_other_client_group).to eq("No") + end + end + end + + context "when updating secondary client group" do + let(:params) { { scheme: { secondary_client_group: "Homeless families with support needs", page: "secondary-client-group" } } } + + it "renders confirm support page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What support does this scheme provide?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.secondary_client_group).to eq("Homeless families with support needs") + end + + context "when updating from check answers page" do + let(:params) { { scheme: { secondary_client_group: "Homeless families with support needs", page: "secondary-client-group", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.secondary_client_group).to eq("Homeless families with support needs") + end + end + end + + context "when updating support" do + let(:params) { { scheme: { intended_stay: "Medium stay", support_type: "Resettlement support", page: "support" } } } + + it "renders confirm secondary group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.intended_stay).to eq("Medium stay") + expect(scheme_to_update.reload.support_type).to eq("Resettlement support") + end + + context "when updating from check answers page" do + let(:params) { { scheme: { intended_stay: "Medium stay", support_type: "Resettlement support", page: "support", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.intended_stay).to eq("Medium stay") + expect(scheme_to_update.reload.support_type).to eq("Resettlement support") + end + end + end + + context "when updating details" do + let(:another_organisation) { FactoryBot.create(:organisation) } + let(:params) do + { scheme: { service_name: "testy", + sensitive: "1", + scheme_type: "Foyer", + registered_under_care_act: "No", + total_units: "1", + page: "details", + organisation_id: another_organisation.id, + stock_owning_organisation_id: another_organisation.id } } + end + + it "renders confirm secondary group after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("What client group is this scheme intended for?") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.service_name).to eq("testy") + expect(scheme_to_update.reload.scheme_type).to eq("Foyer") + expect(scheme_to_update.reload.sensitive).to eq("Yes") + expect(scheme_to_update.reload.registered_under_care_act).to eq("No") + expect(scheme_to_update.reload.total_units).to eq(1) + expect(scheme_to_update.reload.organisation_id).to eq(another_organisation.id) + expect(scheme_to_update.reload.stock_owning_organisation_id).to eq(another_organisation.id) + end + + context "when updating from check answers page" do + let(:params) { { scheme: { service_name: "testy", sensitive: "1", scheme_type: "Foyer", registered_under_care_act: "No", total_units: "1", page: "details", check_answers: "true" } } } + + it "renders check answers page after successful update" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + it "updates a scheme with valid params" do + follow_redirect! + expect(scheme_to_update.reload.service_name).to eq("testy") + expect(scheme_to_update.reload.scheme_type).to eq("Foyer") + expect(scheme_to_update.reload.sensitive).to eq("Yes") + expect(scheme_to_update.reload.registered_under_care_act).to eq("No") + expect(scheme_to_update.reload.total_units).to eq(1) + end + end + end + end + end + + describe "#primary_client_group" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/primary-client-group" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/primary-client-group" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let!(:another_scheme) { FactoryBot.create(:scheme) } + + before do + sign_in user + get "/schemes/#{scheme.id}/primary-client-group" + end + + it "returns a template for a primary-client-group" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("What client group is this scheme intended for?") + end + + context "when attempting to access primary-client-group scheme page for another organisation" do + before do + get "/schemes/#{another_scheme.id}/primary-client-group" + end + + it "returns 404 not_found" do + request + expect(response).to have_http_status(:not_found) + end + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + let!(:scheme) { FactoryBot.create(:scheme) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/#{scheme.id}/primary-client-group" + end + + it "returns a template for a primary-client-group" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("What client group is this scheme intended for?") + end + end + end + + describe "#confirm_secondary_client_group" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/confirm-secondary-client-group" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/confirm-secondary-client-group" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let!(:another_scheme) { FactoryBot.create(:scheme) } + + before do + sign_in user + get "/schemes/#{scheme.id}/confirm-secondary-client-group" + end + + it "returns a template for a confirm-secondary-client-group" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Does this scheme provide for another client group?") + end + + context "when attempting to access confirm-secondary-client-group scheme page for another organisation" do + before do + get "/schemes/#{another_scheme.id}/confirm-secondary-client-group" + end + + it "returns 404 not_found" do + request + expect(response).to have_http_status(:not_found) + end + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + let!(:scheme) { FactoryBot.create(:scheme) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/#{scheme.id}/confirm-secondary-client-group" + end + + it "returns a template for a confirm-secondary-client-group" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Does this scheme provide for another client group?") + end + end + end + + describe "#secondary_client_group" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/secondary-client-group" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/secondary-client-group" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let!(:another_scheme) { FactoryBot.create(:scheme) } + + before do + sign_in user + get "/schemes/#{scheme.id}/secondary-client-group" + end + + it "returns a template for a secondary-client-group" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("What is the other client group?") + end + + context "when attempting to access secondary-client-group scheme page for another organisation" do + before do + get "/schemes/#{another_scheme.id}/secondary-client-group" + end + + it "returns 404 not_found" do + request + expect(response).to have_http_status(:not_found) + end + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + let!(:scheme) { FactoryBot.create(:scheme) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/#{scheme.id}/secondary-client-group" + end + + it "returns a template for a secondary-client-group" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("What is the other client group?") + end + end + end + + describe "#support" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/support" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/support" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let!(:another_scheme) { FactoryBot.create(:scheme) } + + before do + sign_in user + get "/schemes/#{scheme.id}/support" + end + + it "returns a template for a support" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("What support does this scheme provide?") + end + + context "when attempting to access secondary-client-group scheme page for another organisation" do + before do + get "/schemes/#{another_scheme.id}/support" + end + + it "returns 404 not_found" do + request + expect(response).to have_http_status(:not_found) + end + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + let!(:scheme) { FactoryBot.create(:scheme) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/#{scheme.id}/support" + end + + it "returns a template for a support" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("What support does this scheme provide?") + end + end + end + + describe "#check-answers" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/check-answers" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/check-answers" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let!(:another_scheme) { FactoryBot.create(:scheme) } + + before do + sign_in user + get "/schemes/#{scheme.id}/check-answers" + end + + it "returns a template for a support" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + + context "when attempting to access check-answers scheme page for another organisation" do + before do + get "/schemes/#{another_scheme.id}/check-answers" + end + + it "returns 404 not_found" do + request + expect(response).to have_http_status(:not_found) + end + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + let!(:scheme) { FactoryBot.create(:scheme) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/#{scheme.id}/check-answers" + end + + it "returns a template for a support" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Check your changes before updating this scheme") + end + end + end + + describe "#details" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/details" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/details" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, organisation: user.organisation) } + let!(:another_scheme) { FactoryBot.create(:scheme) } + + before do + sign_in user + get "/schemes/#{scheme.id}/details" + end + + it "returns a template for a support" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Create a new supported housing scheme") + end + + context "when attempting to access check-answers scheme page for another organisation" do + before do + get "/schemes/#{another_scheme.id}/details" + end + + it "returns 404 not_found" do + request + expect(response).to have_http_status(:not_found) + end + end + end + + context "when signed in as a support user" do + let(:user) { FactoryBot.create(:user, :support) } + let!(:scheme) { FactoryBot.create(:scheme) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + get "/schemes/#{scheme.id}/details" + end + + it "returns a template for a support" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("Create a new supported housing scheme") + end + end + end end