diff --git a/app/helpers/question_attribute_helper.rb b/app/helpers/question_attribute_helper.rb index 020ea1909..601368c22 100644 --- a/app/helpers/question_attribute_helper.rb +++ b/app/helpers/question_attribute_helper.rb @@ -11,7 +11,7 @@ module QuestionAttributeHelper { "data-controller": "conditional-question", "data-action": "click->conditional-question#displayConditional", - "data-info": { conditional_questions: conditional_for, type: type }.to_json, + "data-info": { conditional_questions: conditional_for, type: }.to_json, } end diff --git a/app/models/form/common/questions/created_by_id.rb b/app/models/form/common/questions/created_by_id.rb index b0558e5e2..b8409d99c 100644 --- a/app/models/form/common/questions/created_by_id.rb +++ b/app/models/form/common/questions/created_by_id.rb @@ -19,7 +19,7 @@ class Form::Common::Questions::CreatedById < ::Form::Question end end - def displayed_answer_options(log) + def displayed_answer_options(log, _user = nil) return answer_options unless log.owning_organisation user_ids = log.owning_organisation.users.pluck(:id) + [""] diff --git a/app/models/form/common/questions/owning_organisation_id.rb b/app/models/form/common/questions/owning_organisation_id.rb index 84eefbf21..9adb0bf64 100644 --- a/app/models/form/common/questions/owning_organisation_id.rb +++ b/app/models/form/common/questions/owning_organisation_id.rb @@ -19,7 +19,7 @@ class Form::Common::Questions::OwningOrganisationId < ::Form::Question end end - def displayed_answer_options(_log) + def displayed_answer_options(_log, _user = nil) answer_options end diff --git a/app/models/form/lettings/pages/created_by.rb b/app/models/form/lettings/pages/created_by.rb new file mode 100644 index 000000000..42289befa --- /dev/null +++ b/app/models/form/lettings/pages/created_by.rb @@ -0,0 +1,19 @@ +class Form::Lettings::Pages::CreatedBy < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "created_by" + @header = "" + @description = "" + @subsection = subsection + end + + def questions + @questions ||= [ + Form::Lettings::Questions::CreatedById.new(nil, nil, self), + ] + end + + def routed_to?(_log, current_user) + !!current_user&.support? + end +end diff --git a/app/models/form/lettings/pages/housing_provider.rb b/app/models/form/lettings/pages/housing_provider.rb new file mode 100644 index 000000000..a1c3a6687 --- /dev/null +++ b/app/models/form/lettings/pages/housing_provider.rb @@ -0,0 +1,30 @@ +class Form::Lettings::Pages::HousingProvider < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "housing_provider" + @header = "" + @description = "" + @subsection = subsection + end + + def questions + @questions ||= [ + Form::Lettings::Questions::HousingProvider.new(nil, nil, self), + ] + end + + def routed_to?(log, current_user) + return false unless current_user + return true if current_user.support? + return true unless current_user.organisation.holds_own_stock? + + housing_providers = current_user.organisation.housing_providers + + return false if housing_providers.count.zero? + return true if housing_providers.count > 1 + + log.update!(owning_organisation: housing_providers.first) + + false + end +end diff --git a/app/models/form/lettings/pages/managing_organisation.rb b/app/models/form/lettings/pages/managing_organisation.rb new file mode 100644 index 000000000..67e8ae586 --- /dev/null +++ b/app/models/form/lettings/pages/managing_organisation.rb @@ -0,0 +1,30 @@ +class Form::Lettings::Pages::ManagingOrganisation < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "managing_organisation" + @header = "" + @description = "" + @subsection = subsection + end + + def questions + @questions ||= [ + Form::Lettings::Questions::ManagingOrganisation.new(nil, nil, self), + ] + end + + def routed_to?(log, current_user) + return false unless current_user + return true if current_user.support? + return true unless current_user.organisation.holds_own_stock? + + managing_agents = current_user.organisation.managing_agents + + return false if managing_agents.count.zero? + return true if managing_agents.count > 1 + + log.update!(managing_organisation: managing_agents.first) + + false + end +end diff --git a/app/models/form/lettings/questions/created_by_id.rb b/app/models/form/lettings/questions/created_by_id.rb new file mode 100644 index 000000000..cf7323940 --- /dev/null +++ b/app/models/form/lettings/questions/created_by_id.rb @@ -0,0 +1,48 @@ +class Form::Lettings::Questions::CreatedById < ::Form::Question + def initialize(id, hsh, page) + super + @id = "created_by_id" + @check_answer_label = "Log owner" + @header = "Which user are you creating this log for?" + @hint_text = "" + @type = "select" + @page = page + end + + def answer_options + answer_opts = { "" => "Select an option" } + return answer_opts unless ActiveRecord::Base.connected? + + User.select(:id, :name, :email).each_with_object(answer_opts) do |user, hsh| + hsh[user.id] = "#{user.name} (#{user.email})" + hsh + end + end + + def displayed_answer_options(log, _user = nil) + return answer_options unless log.owning_organisation + + user_ids = log.owning_organisation.users.pluck(:id) + [""] + answer_options.select { |k, _v| user_ids.include?(k) } + end + + def label_from_value(value) + return unless value + + answer_options[value] + end + + def hidden_in_check_answers?(_log, current_user) + !current_user.support? + end + + def derived? + true + end + +private + + def selected_answer_option_is_derived?(_log) + true + end +end diff --git a/app/models/form/lettings/questions/housing_provider.rb b/app/models/form/lettings/questions/housing_provider.rb new file mode 100644 index 000000000..f0b69f9f7 --- /dev/null +++ b/app/models/form/lettings/questions/housing_provider.rb @@ -0,0 +1,68 @@ +class Form::Lettings::Questions::HousingProvider < ::Form::Question + attr_accessor :current_user, :log + + def initialize(id, hsh, page) + super + @id = "owning_organisation_id" + @check_answer_label = "Housing provider" + @header = "Which organisation owns this property?" + @type = "select" + @page = page + end + + def answer_options + answer_opts = { "" => "Select an option" } + return answer_opts unless ActiveRecord::Base.connected? + return answer_opts unless current_user + + if !current_user.support? && current_user.organisation.holds_own_stock? + answer_opts[current_user.organisation.id] = "#{current_user.organisation.name} (Your organisation)" + end + + answer_opts.merge(housing_providers_answer_options) + end + + def displayed_answer_options(log, user = nil) + @current_user = user + @log = log + + answer_options + end + + def label_from_value(value) + return unless value + + answer_options[value] + end + + def derived? + true + end + + def hidden_in_check_answers?(_log, user = nil) + @current_user = user + + return false unless @current_user + return false if @current_user.support? + + housing_providers_answer_options.count < 2 + end + + def enabled + true + end + +private + + def selected_answer_option_is_derived?(_log) + true + end + + def housing_providers_answer_options + @housing_providers_answer_options ||= if current_user.support? + Organisation + else + current_user.organisation.housing_providers + end.pluck(:id, :name).to_h + end +end diff --git a/app/models/form/lettings/questions/managing_organisation.rb b/app/models/form/lettings/questions/managing_organisation.rb new file mode 100644 index 000000000..ff6da010a --- /dev/null +++ b/app/models/form/lettings/questions/managing_organisation.rb @@ -0,0 +1,74 @@ +class Form::Lettings::Questions::ManagingOrganisation < ::Form::Question + attr_accessor :current_user, :log + + def initialize(id, hsh, page) + super + @id = "managing_organisation_id" + @check_answer_label = "Managing agent" + @header = "Which organisation manages this letting?" + @type = "select" + @answer_options = answer_options + @page = page + end + + def answer_options + opts = { "" => "Select an option" } + return opts unless ActiveRecord::Base.connected? + return opts unless current_user + return opts unless log + + if current_user.support? + if log.owning_organisation.holds_own_stock? + opts[log.owning_organisation.id] = "#{log.owning_organisation.name} (Owning organisation)" + end + elsif current_user.organisation.holds_own_stock? + opts[current_user.organisation.id] = "#{current_user.organisation.name} (Your organisation)" + end + + opts.merge(managing_organisations_answer_options) + end + + def displayed_answer_options(log, user) + @current_user = user + @log = log + + answer_options + end + + def label_from_value(value) + return unless value + + answer_options[value] + end + + def derived? + true + end + + def hidden_in_check_answers?(_log, user = nil) + @current_user = user + + return false unless @current_user + return false if @current_user.support? + + managing_organisations_answer_options.count < 2 + end + + def enabled + true + end + +private + + def selected_answer_option_is_derived?(_log) + true + end + + def managing_organisations_answer_options + @managing_organisations_answer_options ||= if current_user.support? + log.owning_organisation + else + current_user.organisation + end.managing_agents.pluck(:id, :name).to_h + end +end diff --git a/app/models/form/lettings/questions/scheme_id.rb b/app/models/form/lettings/questions/scheme_id.rb index 7d7966c00..d576a3f72 100644 --- a/app/models/form/lettings/questions/scheme_id.rb +++ b/app/models/form/lettings/questions/scheme_id.rb @@ -20,7 +20,7 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question end end - def displayed_answer_options(lettings_log) + def displayed_answer_options(lettings_log, _user = nil) organisation = lettings_log.owning_organisation || lettings_log.created_by&.organisation schemes = organisation ? Scheme.select(:id).where(owning_organisation_id: organisation.id, confirmed: true) : Scheme.select(:id).where(confirmed: true) filtered_scheme_ids = schemes.joins(:locations).merge(Location.where("startdate <= ? or startdate IS NULL", Time.zone.today)).map(&:id) diff --git a/app/models/form/lettings/subsections/setup.rb b/app/models/form/lettings/subsections/setup.rb index 79d346599..e871406be 100644 --- a/app/models/form/lettings/subsections/setup.rb +++ b/app/models/form/lettings/subsections/setup.rb @@ -8,8 +8,10 @@ class Form::Lettings::Subsections::Setup < ::Form::Subsection def pages @pages ||= [ - Form::Common::Pages::Organisation.new(nil, nil, self), - Form::Common::Pages::CreatedBy.new(nil, nil, self), + organisation_page, + housing_provider_page, + managing_organisation_page, + created_by_page, Form::Lettings::Pages::NeedsType.new(nil, nil, self), Form::Lettings::Pages::Scheme.new(nil, nil, self), Form::Lettings::Pages::Location.new(nil, nil, self), @@ -18,11 +20,7 @@ class Form::Lettings::Subsections::Setup < ::Form::Subsection Form::Lettings::Pages::RentType.new(nil, nil, self), Form::Lettings::Pages::TenantCode.new(nil, nil, self), Form::Lettings::Pages::PropertyReference.new(nil, nil, self), - ] - end - - def applicable_questions(lettings_log) - questions.select { |q| support_only_questions.include?(q.id) } + super + ].compact end def enabled?(_lettings_log) @@ -31,7 +29,29 @@ class Form::Lettings::Subsections::Setup < ::Form::Subsection private - def support_only_questions - %w[owning_organisation_id created_by_id].freeze + def organisation_page + return if FeatureToggle.managing_for_other_user_enabled? + + Form::Common::Pages::Organisation.new(nil, nil, self) + end + + def housing_provider_page + return unless FeatureToggle.managing_for_other_user_enabled? + + Form::Lettings::Pages::HousingProvider.new(nil, nil, self) + end + + def managing_organisation_page + return unless FeatureToggle.managing_for_other_user_enabled? + + Form::Lettings::Pages::ManagingOrganisation.new(nil, nil, self) + end + + def created_by_page + if FeatureToggle.managing_for_other_user_enabled? + Form::Lettings::Pages::CreatedBy.new(nil, nil, self) + else + Form::Common::Pages::CreatedBy.new(nil, nil, self) + end end end diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 7f3717d4a..13b1c62c9 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -107,7 +107,7 @@ class Form::Question false end - def displayed_answer_options(log) + def displayed_answer_options(log, _current_user = nil) answer_options.select do |_key, val| !val.is_a?(Hash) || !val["depends_on"] || form.depends_on_met(val["depends_on"], log) end diff --git a/app/models/organisation_relationship.rb b/app/models/organisation_relationship.rb index acda8d2c4..d1f073737 100644 --- a/app/models/organisation_relationship.rb +++ b/app/models/organisation_relationship.rb @@ -2,6 +2,9 @@ class OrganisationRelationship < ApplicationRecord belongs_to :child_organisation, class_name: "Organisation" belongs_to :parent_organisation, class_name: "Organisation" + scope :owning, -> { where(relationship_type: OWNING) } + scope :managing, -> { where(relationship_type: MANAGING) } + OWNING = "owning".freeze MANAGING = "managing".freeze RELATIONSHIP_TYPE = { diff --git a/app/views/form/_radio_question.html.erb b/app/views/form/_radio_question.html.erb index ed5e71a0b..bac6fec8f 100644 --- a/app/views/form/_radio_question.html.erb +++ b/app/views/form/_radio_question.html.erb @@ -5,7 +5,7 @@ legend: legend(question, page_header, conditional), hint: { text: question.hint_text&.html_safe } do %> - <% question.displayed_answer_options(@log).map do |key, options| %> + <% question.displayed_answer_options(@log, current_user).map do |key, options| %> <% if key.starts_with?("divider") %> <%= f.govuk_radio_divider %> <% else %> diff --git a/app/views/form/_select_question.html.erb b/app/views/form/_select_question.html.erb index 63f50fb94..c1ee8c3e0 100644 --- a/app/views/form/_select_question.html.erb +++ b/app/views/form/_select_question.html.erb @@ -1,7 +1,7 @@ <%= render partial: "form/guidance/#{question.guidance_partial}" if question.top_guidance? %> <% selected = @log.public_send(question.id) || "" %> -<% answers = question.displayed_answer_options(@log).map { |key, value| OpenStruct.new(id: key, name: value.respond_to?(:service_name) ? value.service_name : nil, resource: value) } %> +<% answers = question.displayed_answer_options(@log, current_user).map { |key, value| OpenStruct.new(id: key, name: value.respond_to?(:service_name) ? value.service_name : nil, resource: value) } %> <%= f.govuk_select(question.id.to_sym, label: legend(question, page_header, conditional), "data-controller": "accessible-autocomplete", diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb index d3ab1db57..1a4b8a862 100644 --- a/config/initializers/feature_toggle.rb +++ b/config/initializers/feature_toggle.rb @@ -20,4 +20,8 @@ class FeatureToggle false end + + def self.managing_for_other_user_enabled? + !Rails.env.production? + end end diff --git a/db/schema.rb b/db/schema.rb index 5faff28ba..0f2ad0025 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -360,16 +360,16 @@ ActiveRecord::Schema[7.0].define(version: 2022_11_11_102656) do t.integer "hholdcount" t.integer "age3" t.integer "age3_known" + t.string "la" + t.integer "la_known" + t.integer "income1" + t.integer "income1nk" t.integer "age4" t.integer "age4_known" t.integer "age5" t.integer "age5_known" t.integer "age6" t.integer "age6_known" - t.string "la" - t.integer "la_known" - t.integer "income1" - t.integer "income1nk" t.integer "details_known_2" t.integer "details_known_3" t.integer "details_known_4" diff --git a/db/seeds.rb b/db/seeds.rb index e357e6efe..9d78fd8cb 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -8,8 +8,8 @@ # rubocop:disable Rails/Output unless Rails.env.test? - housing_provider = Organisation.find_or_create_by!( - name: "Housing Provider", + housing_provider1 = Organisation.find_or_create_by!( + name: "Housing Provider 1", address_line1: "2 Marsham Street", address_line2: "London", postcode: "SW1P 4DF", @@ -18,8 +18,28 @@ unless Rails.env.test? managing_agents_label: "None", provider_type: "LA", ) - managing_agent = Organisation.find_or_create_by!( - name: "Managing Agent", + housing_provider2 = Organisation.find_or_create_by!( + name: "Housing Provider 2", + address_line1: "2 Marsham Street", + address_line2: "London", + postcode: "SW1P 4DF", + holds_own_stock: true, + other_stock_owners: "None", + managing_agents_label: "None", + provider_type: "LA", + ) + managing_agent1 = Organisation.find_or_create_by!( + name: "Managing Agent 1", + address_line1: "2 Marsham Street", + address_line2: "London", + postcode: "SW1P 4DF", + holds_own_stock: true, + other_stock_owners: "None", + managing_agents_label: "None", + provider_type: "LA", + ) + managing_agent2 = Organisation.find_or_create_by!( + name: "Managing Agent 2", address_line1: "2 Marsham Street", address_line2: "London", postcode: "SW1P 4DF", @@ -49,11 +69,21 @@ unless Rails.env.test? OrganisationRelationship.create!( child_organisation: org, - parent_organisation: housing_provider, + parent_organisation: housing_provider1, + relationship_type: OrganisationRelationship::OWNING, + ) + OrganisationRelationship.create!( + child_organisation: org, + parent_organisation: housing_provider2, relationship_type: OrganisationRelationship::OWNING, ) OrganisationRelationship.create!( - child_organisation: managing_agent, + child_organisation: managing_agent1, + parent_organisation: org, + relationship_type: OrganisationRelationship::MANAGING, + ) + OrganisationRelationship.create!( + child_organisation: managing_agent2, parent_organisation: org, relationship_type: OrganisationRelationship::MANAGING, ) diff --git a/spec/features/lettings_log_spec.rb b/spec/features/lettings_log_spec.rb index 1bd72b5cf..294ef51cd 100644 --- a/spec/features/lettings_log_spec.rb +++ b/spec/features/lettings_log_spec.rb @@ -3,10 +3,10 @@ require "rails_helper" RSpec.describe "Lettings Log Features" do context "when searching for specific logs" do context "when I am signed in and there are logs in the database" do - let(:user) { FactoryBot.create(:user, last_sign_in_at: Time.zone.now) } - let!(:log_to_search) { FactoryBot.create(:lettings_log, owning_organisation: user.organisation) } - let!(:same_organisation_log) { FactoryBot.create(:lettings_log, owning_organisation: user.organisation) } - let!(:another_organisation_log) { FactoryBot.create(:lettings_log) } + let(:user) { create(:user, last_sign_in_at: Time.zone.now) } + let!(:log_to_search) { create(:lettings_log, owning_organisation: user.organisation) } + let!(:same_organisation_log) { create(:lettings_log, owning_organisation: user.organisation) } + let!(:another_organisation_log) { create(:lettings_log) } before do visit("/lettings-logs") @@ -58,7 +58,7 @@ RSpec.describe "Lettings Log Features" do end context "when the signed is user is a Support user" do - let(:support_user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) } + let(:support_user) { create(:user, :support, last_sign_in_at: Time.zone.now) } let(:devise_notify_mailer) { DeviseNotifyMailer.new } let(:notify_client) { instance_double(Notifications::Client) } let(:mfa_template_id) { User::MFA_TEMPLATE_ID } @@ -77,26 +77,29 @@ RSpec.describe "Lettings Log Features" do click_button("Submit") end - context "when completing the setup lettings log section" do + context "when completing the setup lettings log section", :aggregate_failure do it "includes the organisation and created by questions" do visit("/lettings-logs") click_button("Create a new lettings log") click_link("Set up this lettings log") select(support_user.organisation.name, from: "lettings-log-owning-organisation-id-field") click_button("Save and continue") + select("#{support_user.organisation.name} (Owning organisation)", from: "lettings-log-managing-organisation-id-field") + click_button("Save and continue") select(support_user.name, from: "lettings-log-created-by-id-field") click_button("Save and continue") log_id = page.current_path.scan(/\d/).join visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Owning organisation #{support_user.organisation.name}") - expect(page).to have_content("User #{support_user.name}") - expect(page).to have_content("You have answered 2 of 8 questions") + expect(page).to have_content("Housing provider #{support_user.organisation.name}") + expect(page).to have_content("Managing agent #{support_user.organisation.name}") + expect(page).to have_content("Log owner #{support_user.name}") + expect(page).to have_content("You have answered 3 of 9 questions") end end end context "when the signed is user is not a Support user" do - let(:support_user) { FactoryBot.create(:user) } + let(:support_user) { create(:user) } let(:devise_notify_mailer) { DeviseNotifyMailer.new } let(:notify_client) { instance_double(Notifications::Client) } diff --git a/spec/models/form/lettings/pages/created_by_spec.rb b/spec/models/form/lettings/pages/created_by_spec.rb new file mode 100644 index 000000000..c4fd460cb --- /dev/null +++ b/spec/models/form/lettings/pages/created_by_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::CreatedBy, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form) } + let(:lettings_log) { instance_double(LettingsLog) } + + describe "#routed_to?" do + context "when nil" do + it "is not shown" do + expect(page.routed_to?(nil, nil)).to eq(false) + end + end + + context "when support" do + it "is shown" do + expect(page.routed_to?(nil, create(:user, :support))).to eq(true) + end + end + + context "when not support" do + it "is not shown" do + expect(page.routed_to?(nil, create(:user, :data_coordinator))).to eq(false) + end + end + end + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[created_by_id]) + end + + it "has the correct id" do + expect(page.id).to eq("created_by") + end + + it "has the correct header" do + expect(page.header).to eq("") + end + + it "has the correct description" do + expect(page.description).to eq("") + end + + it "has the correct depends_on" do + expect(page.depends_on).to be nil + end +end diff --git a/spec/models/form/lettings/pages/housing_provider_spec.rb b/spec/models/form/lettings/pages/housing_provider_spec.rb new file mode 100644 index 000000000..97420506e --- /dev/null +++ b/spec/models/form/lettings/pages/housing_provider_spec.rb @@ -0,0 +1,128 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::HousingProvider, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[owning_organisation_id]) + end + + it "has the correct id" do + expect(page.id).to eq("housing_provider") + end + + it "has the correct header" do + expect(page.header).to eq("") + end + + it "has the correct description" do + expect(page.description).to eq("") + end + + it "has the correct depends_on" do + expect(page.depends_on).to be nil + end + + describe "#routed_to?" do + let(:log) { create(:lettings_log, owning_organisation_id: nil) } + + context "when user nil" do + it "is not shown" do + expect(page.routed_to?(log, nil)).to eq(false) + end + + it "does not update owning_organisation_id" do + expect { page.routed_to?(log, nil) }.not_to change(log.reload, :owning_organisation).from(nil) + end + end + + context "when support" do + let(:user) { create(:user, :support) } + + it "is shown" do + expect(page.routed_to?(log, user)).to eq(true) + end + + it "does not update owning_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :owning_organisation).from(nil) + end + end + + context "when not support" do + context "when does not hold own stock" do + let(:user) do + create(:user, :data_coordinator, organisation: create(:organisation, holds_own_stock: false)) + end + + it "is shown" do + expect(page.routed_to?(log, user)).to eq(true) + end + + it "does not update owning_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :owning_organisation).from(nil) + end + end + + context "when holds own stock" do + let(:user) do + create(:user, :data_coordinator, organisation: create(:organisation, holds_own_stock: true)) + end + + context "with 0 housing_providers" do + it "is not shown" do + expect(page.routed_to?(log, user)).to eq(false) + end + + it "does not update owning_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :owning_organisation).from(nil) + end + end + + context "with >1 housing_providers" do + before do + create(:organisation_relationship, :owning, child_organisation: user.organisation) + create(:organisation_relationship, :owning, child_organisation: user.organisation) + end + + it "is shown" do + expect(page.routed_to?(log, user)).to eq(true) + end + + it "does not update owning_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :owning_organisation).from(nil) + end + end + + context "with 1 housing_providers" do + let(:housing_provider) { create(:organisation) } + + before do + create( + :organisation_relationship, + :owning, + child_organisation: user.organisation, + parent_organisation: housing_provider, + ) + end + + it "is not shown" do + expect(page.routed_to?(log, user)).to eq(false) + end + + it "updates owning_organisation_id" do + expect { page.routed_to?(log, user) }.to change(log.reload, :owning_organisation).from(nil).to(housing_provider) + end + end + end + end + end +end diff --git a/spec/models/form/lettings/pages/managing_organisation_spec.rb b/spec/models/form/lettings/pages/managing_organisation_spec.rb new file mode 100644 index 000000000..fcb93d565 --- /dev/null +++ b/spec/models/form/lettings/pages/managing_organisation_spec.rb @@ -0,0 +1,130 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::ManagingOrganisation, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[managing_organisation_id]) + end + + it "has the correct id" do + expect(page.id).to eq("managing_organisation") + end + + it "has the correct header" do + expect(page.header).to eq("") + end + + it "has the correct description" do + expect(page.description).to eq("") + end + + it "has the correct depends_on" do + expect(page.depends_on).to be nil + end + + describe "#routed_to?" do + let(:log) { create(:lettings_log) } + let(:organisation) { create(:organisation) } + + context "when user nil" do + it "is not shown" do + expect(page.routed_to?(log, nil)).to eq(false) + end + + it "does not update managing_organisation_id" do + expect { page.routed_to?(log, nil) }.not_to change(log.reload, :managing_organisation) + end + end + + context "when support" do + let(:organisation) { create(:organisation) } + let(:user) { create(:user, :support, organisation:) } + + it "is shown" do + expect(page.routed_to?(log, user)).to eq(true) + end + + it "does not update managing_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :managing_organisation) + end + end + + context "when not support" do + context "when does not hold own stock" do + let(:user) do + create(:user, :data_coordinator, organisation: create(:organisation, holds_own_stock: false)) + end + + it "is shown" do + expect(page.routed_to?(log, user)).to eq(true) + end + + it "does not update managing_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :managing_organisation) + end + end + + context "when holds own stock" do + let(:user) do + create(:user, :data_coordinator, organisation: create(:organisation, holds_own_stock: true)) + end + + context "with 0 managing_agents" do + it "is not shown" do + expect(page.routed_to?(log, user)).to eq(false) + end + + it "does not update managing_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :managing_organisation) + end + end + + context "with >1 managing_agents" do + before do + create(:organisation_relationship, :managing, parent_organisation: user.organisation) + create(:organisation_relationship, :managing, parent_organisation: user.organisation) + end + + it "is shown" do + expect(page.routed_to?(log, user)).to eq(true) + end + + it "does not update managing_organisation_id" do + expect { page.routed_to?(log, user) }.not_to change(log.reload, :managing_organisation) + end + end + + context "with 1 managing_agents" do + let(:managing_agent) { create(:organisation) } + + before do + create( + :organisation_relationship, + :managing, + child_organisation: managing_agent, + parent_organisation: user.organisation, + ) + end + + it "is not shown" do + expect(page.routed_to?(log, user)).to eq(false) + end + + it "updates managing_organisation_id" do + expect { page.routed_to?(log, user) }.to change(log.reload, :managing_organisation).to(managing_agent) + end + end + end + end + end +end diff --git a/spec/models/form/lettings/questions/created_by_id_spec.rb b/spec/models/form/lettings/questions/created_by_id_spec.rb new file mode 100644 index 000000000..152a24265 --- /dev/null +++ b/spec/models/form/lettings/questions/created_by_id_spec.rb @@ -0,0 +1,82 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::CreatedById, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form) } + let(:user_1) { FactoryBot.create(:user, name: "first user") } + let(:user_2) { FactoryBot.create(:user, name: "second user") } + let!(:expected_answer_options) do + { + "" => "Select an option", + user_1.id => "#{user_1.name} (#{user_1.email})", + user_2.id => "#{user_2.name} (#{user_2.email})", + } + end + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("created_by_id") + end + + it "has the correct header" do + expect(question.header).to eq("Which user are you creating this log for?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Log owner") + end + + it "has the correct type" do + expect(question.type).to eq("select") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "has the correct answer options" do + expect(question.answer_options).to eq(expected_answer_options) + end + + it "is marked as derived" do + expect(question.derived?).to be true + end + + context "when the current user is support" do + let(:support_user) { FactoryBot.build(:user, :support) } + + it "is shown in check answers" do + expect(question.hidden_in_check_answers?(nil, support_user)).to be false + end + end + + context "when the current user is not support" do + let(:user) { FactoryBot.build(:user) } + + it "is not shown in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be true + end + end + + context "when the owning organisation is already set" do + let(:lettings_log) { FactoryBot.create(:lettings_log, owning_organisation: user_2.organisation) } + let(:expected_answer_options) do + { + "" => "Select an option", + user_2.id => "#{user_2.name} (#{user_2.email})", + } + end + + it "only displays users that belong to that organisation" do + expect(question.displayed_answer_options(lettings_log)).to eq(expected_answer_options) + end + end +end diff --git a/spec/models/form/lettings/questions/housing_provider_spec.rb b/spec/models/form/lettings/questions/housing_provider_spec.rb new file mode 100644 index 000000000..073c59e37 --- /dev/null +++ b/spec/models/form/lettings/questions/housing_provider_spec.rb @@ -0,0 +1,117 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::HousingProvider, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("owning_organisation_id") + end + + it "has the correct header" do + expect(question.header).to eq("Which organisation owns this property?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Housing provider") + end + + it "has the correct type" do + expect(question.type).to eq("select") + end + + it "has the correct hint_text" do + expect(question.hint_text).to be_nil + end + + describe "answer options" do + let(:options) { { "" => "Select an option" } } + + context "when current_user nil" do + it "shows default options" do + expect(question.answer_options).to eq(options) + end + end + + context "when user not support and owns own stock" do + let(:user) { create(:user, :data_coordinator, organisation: create(:organisation, holds_own_stock: true)) } + let(:options) do + { + "" => "Select an option", + user.organisation.id => "#{user.organisation.name} (Your organisation)", + } + end + + before do + question.current_user = user + end + + it "shows housing providers with own org at the top" do + expect(question.answer_options).to eq(options) + end + end + + context "when user support" do + before do + question.current_user = create(:user, :support) + end + + let(:expected_opts) do + Organisation.all.each_with_object(options) do |organisation, hsh| + hsh[organisation.id] = organisation.name + hsh + end + end + + it "shows all orgs" do + expect(question.answer_options).to eq(expected_opts) + end + end + end + + it "is marked as derived" do + expect(question.derived?).to be true + end + + describe "#hidden_in_check_answers?" do + context "when housing providers < 2" do + context "when not support user" do + let(:user) { create(:user) } + + it "is hidden in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be true + end + end + + context "when support" do + let(:user) { create(:user, :support) } + + it "is not hiddes in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be false + end + end + end + + context "when housing providers >= 2" do + let(:user) { create(:user) } + + before do + create(:organisation_relationship, :owning, child_organisation: user.organisation) + create(:organisation_relationship, :owning, child_organisation: user.organisation) + end + + it "is not hidden in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be false + end + end + end +end diff --git a/spec/models/form/lettings/questions/managing_organisation_spec.rb b/spec/models/form/lettings/questions/managing_organisation_spec.rb new file mode 100644 index 000000000..f80099d67 --- /dev/null +++ b/spec/models/form/lettings/questions/managing_organisation_spec.rb @@ -0,0 +1,155 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::ManagingOrganisation, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection) } + let(:form) { instance_double(Form) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("managing_organisation_id") + end + + it "has the correct header" do + expect(question.header).to eq("Which organisation manages this letting?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Managing agent") + end + + it "has the correct type" do + expect(question.type).to eq("select") + end + + it "has the correct hint_text" do + expect(question.hint_text).to be_nil + end + + describe "#displayed_answer_options" do + let(:options) { { "" => "Select an option" } } + + context "when current_user nil" do + let(:log) { create(:lettings_log) } + + it "shows default options" do + expect(question.displayed_answer_options(log, nil)).to eq(options) + end + end + + context "when log nil" do + let(:user) { create(:user) } + + it "shows default options" do + expect(question.displayed_answer_options(nil, user)).to eq(options) + end + end + + context "when user not support and owns own stock" do + let(:user) { create(:user, :data_coordinator, organisation: create(:organisation, holds_own_stock: true)) } + + let(:log) { create(:lettings_log) } + let!(:org_rel1) { create(:organisation_relationship, :managing, parent_organisation: user.organisation) } + let!(:org_rel2) { create(:organisation_relationship, :managing, parent_organisation: user.organisation) } + + let(:options) do + { + "" => "Select an option", + user.organisation.id => "#{user.organisation.name} (Your organisation)", + org_rel1.child_organisation.id => org_rel1.child_organisation.name, + org_rel2.child_organisation.id => org_rel2.child_organisation.name, + } + end + + it "shows managing agents with own org at the top" do + expect(question.displayed_answer_options(log, user)).to eq(options) + end + end + + context "when support user and org does not own own stock" do + let(:user) { create(:user, :support) } + let(:log_owning_org) { create(:organisation, holds_own_stock: false) } + let(:log) { create(:lettings_log, owning_organisation: log_owning_org) } + let!(:org_rel1) { create(:organisation_relationship, :managing, parent_organisation: log_owning_org) } + let!(:org_rel2) { create(:organisation_relationship, :managing, parent_organisation: log_owning_org) } + + let(:options) do + { + "" => "Select an option", + org_rel1.child_organisation.id => org_rel1.child_organisation.name, + org_rel2.child_organisation.id => org_rel2.child_organisation.name, + } + end + + it "shows owning org managing agents with hint" do + expect(question.displayed_answer_options(log, user)).to eq(options) + end + end + + context "when support user and org does own stock" do + let(:user) { create(:user, :support) } + let(:log_owning_org) { create(:organisation, holds_own_stock: true) } + let(:log) { create(:lettings_log, owning_organisation: log_owning_org) } + let!(:org_rel1) { create(:organisation_relationship, :managing, parent_organisation: log_owning_org) } + let!(:org_rel2) { create(:organisation_relationship, :managing, parent_organisation: log_owning_org) } + + let(:options) do + { + "" => "Select an option", + log_owning_org.id => "#{log_owning_org.name} (Owning organisation)", + org_rel1.child_organisation.id => org_rel1.child_organisation.name, + org_rel2.child_organisation.id => org_rel2.child_organisation.name, + } + end + + it "shows owning org managing agents + " do + expect(question.displayed_answer_options(log, user)).to eq(options) + end + end + end + + it "is marked as derived" do + expect(question.derived?).to be true + end + + describe "#hidden_in_check_answers?" do + context "when housing providers < 2" do + context "when not support user" do + let(:user) { create(:user) } + + it "is hidden in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be true + end + end + + context "when support" do + let(:user) { create(:user, :support) } + + it "is not hiddes in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be false + end + end + end + + context "when managing agents >= 2" do + let(:user) { create(:user) } + + before do + create(:organisation_relationship, :managing, parent_organisation: user.organisation) + create(:organisation_relationship, :managing, parent_organisation: user.organisation) + end + + it "is not hidden in check answers" do + expect(question.hidden_in_check_answers?(nil, user)).to be false + end + end + end +end diff --git a/spec/models/form/lettings/subsections/setup_spec.rb b/spec/models/form/lettings/subsections/setup_spec.rb index 3e2fba32f..6188cc1e0 100644 --- a/spec/models/form/lettings/subsections/setup_spec.rb +++ b/spec/models/form/lettings/subsections/setup_spec.rb @@ -13,16 +13,19 @@ RSpec.describe Form::Lettings::Subsections::Setup, type: :model do it "has correct pages" do expect(setup.pages.map(&:id)).to eq( - %w[organisation - created_by - needs_type - scheme - location - renewal - tenancy_start_date - rent_type - tenant_code - property_reference], + %w[ + housing_provider + managing_organisation + created_by + needs_type + scheme + location + renewal + tenancy_start_date + rent_type + tenant_code + property_reference + ], ) end @@ -33,4 +36,47 @@ RSpec.describe Form::Lettings::Subsections::Setup, type: :model do it "has the correct label" do expect(setup.label).to eq("Set up this lettings log") end + + context "when not production" do + it "has correct pages" do + expect(setup.pages.map(&:id)).to eq( + %w[ + housing_provider + managing_organisation + created_by + needs_type + scheme + location + renewal + tenancy_start_date + rent_type + tenant_code + property_reference + ], + ) + end + end + + context "when production" do + before do + allow(Rails.env).to receive(:production?).and_return(true) + end + + it "has the correct pages" do + expect(setup.pages.map(&:id)).to eq( + %w[ + organisation + created_by + needs_type + scheme + location + renewal + tenancy_start_date + rent_type + tenant_code + property_reference + ], + ) + end + end end diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index c6a47c107..e4056c6c1 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -27,13 +27,13 @@ RSpec.describe FormHandler do it "is able to load a current lettings form" do form = form_handler.get_form("current_lettings") expect(form).to be_a(Form) - expect(form.pages.count).to eq(45) + expect(form.pages.count).to eq(46) end it "is able to load a next lettings form" do form = form_handler.get_form("next_lettings") expect(form).to be_a(Form) - expect(form.pages.count).to eq(12) + expect(form.pages.count).to eq(13) end end @@ -49,13 +49,13 @@ RSpec.describe FormHandler do it "is able to load a current lettings form" do form = form_handler.get_form("current_lettings") expect(form).to be_a(Form) - expect(form.pages.count).to eq(12) + expect(form.pages.count).to eq(13) end it "is able to load a previous lettings form" do form = form_handler.get_form("previous_lettings") expect(form).to be_a(Form) - expect(form.pages.count).to eq(45) + expect(form.pages.count).to eq(46) end it "is able to load a current sales form" do diff --git a/spec/requests/form_controller_spec.rb b/spec/requests/form_controller_spec.rb index ade87cfde..1bb73f399 100644 --- a/spec/requests/form_controller_spec.rb +++ b/spec/requests/form_controller_spec.rb @@ -2,18 +2,18 @@ require "rails_helper" RSpec.describe FormController, type: :request do let(:page) { Capybara::Node::Simple.new(response.body) } - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } let(:organisation) { user.organisation } - let(:other_organisation) { FactoryBot.create(:organisation) } + let(:other_organisation) { create(:organisation) } let!(:unauthorized_lettings_log) do - FactoryBot.create( + create( :lettings_log, owning_organisation: other_organisation, managing_organisation: other_organisation, ) end let(:setup_complete_lettings_log) do - FactoryBot.create( + create( :lettings_log, :about_completed, status: 1, @@ -23,7 +23,7 @@ RSpec.describe FormController, type: :request do ) end let(:completed_lettings_log) do - FactoryBot.create( + create( :lettings_log, :completed, owning_organisation: organisation, @@ -39,7 +39,7 @@ RSpec.describe FormController, type: :request do context "when a user is not signed in" do let!(:lettings_log) do - FactoryBot.create( + create( :lettings_log, owning_organisation: organisation, managing_organisation: organisation, @@ -68,7 +68,7 @@ RSpec.describe FormController, type: :request do context "when a user is signed in" do let!(:lettings_log) do - FactoryBot.create( + create( :lettings_log, owning_organisation: organisation, managing_organisation: organisation, @@ -83,8 +83,8 @@ RSpec.describe FormController, type: :request do describe "GET" do context "with form pages" do context "when forms exist for multiple years" do - let(:lettings_log_year_1) { FactoryBot.create(:lettings_log, startdate: Time.zone.local(2021, 5, 1), owning_organisation: organisation, created_by: user) } - let(:lettings_log_year_2) { FactoryBot.create(:lettings_log, :about_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } + let(:lettings_log_year_1) { create(:lettings_log, startdate: Time.zone.local(2021, 5, 1), owning_organisation: organisation, created_by: user) } + let(:lettings_log_year_2) { create(:lettings_log, :about_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } it "displays the correct question details for each lettings log based on form year" do get "/lettings-logs/#{lettings_log_year_1.id}/tenant-code-test", headers: headers, params: {} @@ -110,11 +110,11 @@ RSpec.describe FormController, type: :request do context "when viewing the setup section schemes page" do context "when the user is support" do - let(:user) { FactoryBot.create(:user, :support) } + let(:user) { create(:user, :support) } context "when organisation and user have not been selected yet" do let(:lettings_log) do - FactoryBot.create( + create( :lettings_log, owning_organisation: nil, managing_organisation: nil, @@ -124,7 +124,7 @@ RSpec.describe FormController, type: :request do end before do - locations = FactoryBot.create_list(:location, 5) + locations = create_list(:location, 5) locations.each { |location| location.scheme.update!(arrangement_type: "The same organisation that owns the housing stock", managing_organisation_id: location.scheme.owning_organisation_id) } end @@ -147,7 +147,7 @@ RSpec.describe FormController, type: :request do context "when no other sections are enabled" do let(:lettings_log_2022) do - FactoryBot.create( + create( :lettings_log, startdate: Time.zone.local(2022, 12, 1), owning_organisation: organisation, @@ -194,17 +194,17 @@ RSpec.describe FormController, type: :request do context "when viewing a user dependent page" do context "when the dependency is met" do - let(:user) { FactoryBot.create(:user, :support) } + let(:user) { create(:user, :support) } it "routes to the page" do - get "/lettings-logs/#{lettings_log.id}/organisation" + get "/lettings-logs/#{lettings_log.id}/created-by" expect(response).to have_http_status(:ok) end end context "when the dependency is not met" do it "redirects to the tasklist page" do - get "/lettings-logs/#{lettings_log.id}/organisation" + get "/lettings-logs/#{lettings_log.id}/created-by" expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}") end end @@ -213,10 +213,10 @@ RSpec.describe FormController, type: :request do describe "Submit Form" do context "with a form page" do - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } let(:organisation) { user.organisation } let(:lettings_log) do - FactoryBot.create( + create( :lettings_log, owning_organisation: organisation, managing_organisation: organisation, @@ -527,9 +527,9 @@ RSpec.describe FormController, type: :request do context "with lettings logs that are not owned or managed by your organisation" do let(:answer) { 25 } - let(:other_organisation) { FactoryBot.create(:organisation) } + let(:other_organisation) { create(:organisation) } let(:unauthorized_lettings_log) do - FactoryBot.create( + create( :lettings_log, owning_organisation: other_organisation, managing_organisation: other_organisation,