diff --git a/app/admin/admin_users.rb b/app/admin/admin_users.rb index fed0ec1a8..c09dc1804 100644 --- a/app/admin/admin_users.rb +++ b/app/admin/admin_users.rb @@ -1,6 +1,13 @@ ActiveAdmin.register AdminUser do permit_params :email, :password, :password_confirmation + controller do + def update_resource(object, attributes) + update_method = attributes.first[:password].present? ? :update_attributes : :update_without_password + object.send(update_method, *attributes) + end + end + index do selectable_column id_column diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index 43cea56b2..4efa249b3 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,122 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armedforces ecstat1 other_hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status + tenant_code + age1 + sex1 + tenant_ethnic_group + tenant_nationality + previous_housing_situation + armedforces + ecstat1 + other_hhmemb + relat2 + age2 + sex2 + ecstat2 + relat3 + age3 + sex3 + ecstat3 + relat4 + age4 + sex4 + ecstat4 + relat5 + age5 + sex5 + ecstat5 + relat6 + age6 + sex6 + ecstat6 + relat7 + age7 + person_7_gender + ecstat7 + relat8 + age8 + sex8 + ecstat8 + homelessness + reason + benefit_cap_spare_room_subsidy + armed_forces_active + armed_forces_injured + medical_conditions + pregnancy + accessibility_requirements + condition_effects + tenancy_code + tenancy_start_date + starter_tenancy + fixed_term_tenancy + tenancy_type + letting_type + letting_provider + la + previous_postcode + property_relet + property_vacancy_reason + property_reference + property_unit_type + property_building_type + property_number_of_bedrooms + property_void_date + majorrepairs + mrcdate + property_wheelchair_accessible + net_income + net_income_frequency + net_income_uc_proportion + hb + rent_frequency + basic_rent + service_charge + personal_service_charge + support_charge + total_charge + tshortfall + time_lived_in_la + time_on_la_waiting_list + prevloc + property_postcode + reasonable_preference + reasonable_preference_reason + cbl_letting + chr_letting + cap_letting + hbrentshortfall + other_reason + accessibility_requirements_fully_wheelchair_accessible_housing + accessibility_requirements_wheelchair_access_to_essential_rooms + accessibility_requirements_level_access_housing + accessibility_requirements_other_disability_requirements + accessibility_requirements_no_disability_requirements + accessibility_requirements_do_not_know + accessibility_requirements_prefer_not_to_say + condition_effects_vision + condition_effects_hearing + condition_effects_mobility + condition_effects_dexterity + condition_effects_stamina + condition_effects_learning + condition_effects_memory + condition_effects_mental_health + condition_effects_social_or_behavioral + condition_effects_other + condition_effects_prefer_not_to_say + reasonable_preference_reason_homeless + reasonable_preference_reason_unsatisfactory_housing + reasonable_preference_reason_medical_grounds + reasonable_preference_reason_avoid_hardship + reasonable_preference_reason_do_not_know + other_tenancy_type + override_net_income_validation + net_income_known + owning_organisation_id + managing_organisation_id] permitted end @@ -14,6 +129,8 @@ ActiveAdmin.register CaseLog do column :status column :tenant_code column :property_postcode + column :owning_organisation + column :managing_organisation actions end end diff --git a/app/admin/organisations.rb b/app/admin/organisations.rb new file mode 100644 index 000000000..bbf9efe90 --- /dev/null +++ b/app/admin/organisations.rb @@ -0,0 +1,31 @@ +ActiveAdmin.register Organisation do + permit_params do + permitted = %i[name + phone + org_type + address_line1 + address_line2 + postcode + local_authorities + holds_own_stock + other_stock_owners + managing_agents] + permitted + end + + index do + selectable_column + id_column + column :name + column :org_type + column "Address Line 1", :address_line1 + column "Address Line 2", :address_line2 + column :postcode + column "Phone Number", :phone + column :local_authorities + column :holds_own_stock + column :other_stock_owners + column :managing_agents + actions + end +end diff --git a/app/admin/users.rb b/app/admin/users.rb new file mode 100644 index 000000000..75575402d --- /dev/null +++ b/app/admin/users.rb @@ -0,0 +1,40 @@ +ActiveAdmin.register User do + permit_params :name, :email, :password, :password_confirmation, :organisation_id + + controller do + def update_resource(object, attributes) + update_method = attributes.first[:password].present? ? :update_attributes : :update_without_password + object.send(update_method, *attributes) + end + end + + index do + selectable_column + id_column + column :name + column :email + column :organisation + column :current_sign_in_at + column :sign_in_count + column :created_at + actions + end + + filter :email + filter :name + filter :organisation + filter :current_sign_in_at + filter :sign_in_count + filter :created_at + + form do |f| + f.inputs do + f.input :name + f.input :email + f.input :password + f.input :password_confirmation + f.input :organisation + end + f.actions + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d12a..bac7edc5a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,9 @@ class ApplicationController < ActionController::Base + def render_not_found_html + render file: Rails.root.join("public/404.html"), status: :not_found + end + + def render_not_found_json(class_name, id) + render json: { error: "#{class_name} #{id} not found" }, status: :not_found + end end diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb index f75d8c318..069100299 100644 --- a/app/controllers/case_logs_controller.rb +++ b/app/controllers/case_logs_controller.rb @@ -4,12 +4,12 @@ class CaseLogsController < ApplicationController before_action :authenticate_user!, unless: :json_api_request? def index - @completed_case_logs = CaseLog.completed - @in_progress_case_logs = CaseLog.not_completed + @completed_case_logs = current_user.completed_case_logs + @in_progress_case_logs = current_user.not_completed_case_logs end def create - case_log = CaseLog.create(api_case_log_params) + case_log = CaseLog.create(case_log_params) respond_to do |format| format.html { redirect_to case_log } format.json do @@ -30,7 +30,7 @@ class CaseLogsController < ApplicationController render json: { errors: case_log.errors.messages }, status: :unprocessable_entity end else - render json: { error: "Case Log #{params[:id]} not found" }, status: :not_found + render_not_found_json("Case log", params[:id]) end end @@ -42,7 +42,7 @@ class CaseLogsController < ApplicationController if (case_log = CaseLog.find_by(id: params[:id])) render json: case_log, status: :ok else - render json: { error: "Case Log #{params[:id]} not found" }, status: :not_found + render_not_found_json("Case log", params[:id]) end end end @@ -50,21 +50,29 @@ class CaseLogsController < ApplicationController def edit @form = FormHandler.instance.get_form("2021_2022") - @case_log = CaseLog.find(params[:id]) - render :edit + @case_log = current_user.case_logs.find_by(id: params[:id]) + if @case_log + render :edit + else + render_not_found_html + end end def submit_form form = FormHandler.instance.get_form("2021_2022") - @case_log = CaseLog.find(params[:id]) - page = form.get_page(params[:case_log][:page]) - responses_for_page = responses_for_page(page) - if @case_log.update(responses_for_page) && @case_log.has_no_unresolved_soft_errors? - redirect_path = form.next_page_redirect_path(page, @case_log) - redirect_to(send(redirect_path, @case_log)) + @case_log = current_user.case_logs.find_by(id: params[:id]) + if @case_log + page = form.get_page(params[:case_log][:page]) + responses_for_page = responses_for_page(page) + if @case_log.update(responses_for_page) && @case_log.has_no_unresolved_soft_errors? + redirect_path = form.next_page_redirect_path(page, @case_log) + redirect_to(send(redirect_path, @case_log)) + else + subsection = form.subsection_for_page(page) + render "form/page", locals: { form: form, page: page, subsection: subsection.label }, status: :unprocessable_entity + end else - subsection = form.subsection_for_page(page) - render "form/page", locals: { form: form, page: page, subsection: subsection.label }, status: :unprocessable_entity + render_not_found_html end end @@ -76,24 +84,32 @@ class CaseLogsController < ApplicationController render json: { errors: case_log.errors.messages }, status: :unprocessable_entity end else - render json: { error: "Case Log #{params[:id]} not found" }, status: :not_found + render_not_found_json("Case log", params[:id]) end end def check_answers form = FormHandler.instance.get_form("2021_2022") - @case_log = CaseLog.find(params[:case_log_id]) - current_url = request.env["PATH_INFO"] - subsection = form.get_subsection(current_url.split("/")[-2]) - render "form/check_answers", locals: { subsection: subsection, form: form } + @case_log = current_user.case_logs.find_by(id: params[:case_log_id]) + if @case_log + current_url = request.env["PATH_INFO"] + subsection = form.get_subsection(current_url.split("/")[-2]) + render "form/check_answers", locals: { subsection: subsection, form: form } + else + render_not_found_html + end end form = FormHandler.instance.get_form("2021_2022") form.pages.map do |page| define_method(page.id) do |_errors = {}| - @case_log = CaseLog.find(params[:case_log_id]) - subsection = form.subsection_for_page(page) - render "form/page", locals: { form: form, page: page, subsection: subsection.label } + @case_log = current_user.case_logs.find_by(id: params[:case_log_id]) + if @case_log + subsection = form.subsection_for_page(page) + render "form/page", locals: { form: form, page: page, subsection: subsection.label } + else + render_not_found_html + end end end @@ -137,6 +153,21 @@ private http_basic_authenticate_or_request_with name: ENV["API_USER"], password: ENV["API_KEY"] end + def case_log_params + if current_user + org_params.merge(api_case_log_params) + else + api_case_log_params + end + end + + def org_params + { + "owning_organisation_id" => current_user.organisation.id, + "managing_organisation_id" => current_user.organisation.id, + } + end + def api_case_log_params return {} unless params[:case_log] diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb index 082ac4709..4c57974ed 100644 --- a/app/helpers/check_answers_helper.rb +++ b/app/helpers/check_answers_helper.rb @@ -1,6 +1,6 @@ -include GovukLinkHelper - module CheckAnswersHelper + include GovukLinkHelper + def display_answered_questions_summary(subsection, case_log) total = subsection.applicable_questions_count(case_log) answered = subsection.answered_questions_count(case_log) diff --git a/app/helpers/tasklist_helper.rb b/app/helpers/tasklist_helper.rb index d3dbca0b5..83b8d02e1 100644 --- a/app/helpers/tasklist_helper.rb +++ b/app/helpers/tasklist_helper.rb @@ -1,6 +1,6 @@ -include GovukLinkHelper - module TasklistHelper + include GovukLinkHelper + STATUSES = { not_started: "Not started", cannot_start_yet: "Cannot start yet", diff --git a/app/models/bulk_upload.rb b/app/models/bulk_upload.rb index 6f6d1f066..8bf0e2131 100644 --- a/app/models/bulk_upload.rb +++ b/app/models/bulk_upload.rb @@ -26,8 +26,14 @@ class BulkUpload else data_range = FIRST_DATA_ROW..last_row data_range.map do |row_num| - case_log = CaseLog.create! - map_row(sheet.row(row_num)).each do |attr_key, attr_val| + row = sheet.row(row_num) + owning_organisation = Organisation.find(row[111]) + managing_organisation = Organisation.find(row[113]) + case_log = CaseLog.create!( + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + map_row(row).each do |attr_key, attr_val| update = case_log.update(attr_key => attr_val) unless update # TODO: determine what to do when a bulk upload contains field values that don't pass validations @@ -167,9 +173,9 @@ class BulkUpload # postcode: row[108], # postcod2: row[109], # row[110] removed - property_owner_organisation: row[111], + # row[111] is owning organisation used above # username: row[112], - property_manager_organisation: row[113], + # row[113] is managing organisation used above leftreg: row[114], # uprn: row[115], incfreq: row[116], diff --git a/app/models/case_log.rb b/app/models/case_log.rb index e9aab905d..acd65bb0c 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -36,6 +36,11 @@ class CaseLog < ApplicationRecord validates_with CaseLogValidator before_save :update_status! + belongs_to :owning_organisation, class_name: "Organisation" + belongs_to :managing_organisation, class_name: "Organisation" + + scope :for_organisation, ->(org) { where(owning_organisation: org).or(where(managing_organisation: org)) } + enum status: { "not_started" => 0, "in_progress" => 1, "completed" => 2 } enum ethnic: DbEnums.ethnic @@ -214,7 +219,9 @@ private end def all_fields_nil? - mandatory_fields.all? { |_key, val| val.nil? } + init_fields = %w[owning_organisation_id managing_organisation_id] + fields = mandatory_fields.except(*init_fields) + fields.all? { |_key, val| val.nil? } end def mandatory_fields diff --git a/app/models/organisation.rb b/app/models/organisation.rb new file mode 100644 index 000000000..fb6dab181 --- /dev/null +++ b/app/models/organisation.rb @@ -0,0 +1,17 @@ +class Organisation < ApplicationRecord + has_many :users + has_many :owned_case_logs, class_name: "CaseLog", foreign_key: "owning_organisation_id" + has_many :managed_case_logs, class_name: "CaseLog", foreign_key: "managing_organisation_id" + + def case_logs + CaseLog.for_organisation(self) + end + + def completed_case_logs + case_logs.completed + end + + def not_completed_case_logs + case_logs.not_completed + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 0ef982f25..3640e1829 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,4 +2,20 @@ class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :recoverable, :rememberable, :validatable + + belongs_to :organisation + has_many :owned_case_logs, through: :organisation + has_many :managed_case_logs, through: :organisation + + def case_logs + CaseLog.for_organisation(organisation) + end + + def completed_case_logs + case_logs.completed + end + + def not_completed_case_logs + case_logs.not_completed + end end diff --git a/db/migrate/20211126140433_create_organisations.rb b/db/migrate/20211126140433_create_organisations.rb new file mode 100644 index 000000000..515daa97d --- /dev/null +++ b/db/migrate/20211126140433_create_organisations.rb @@ -0,0 +1,18 @@ +class CreateOrganisations < ActiveRecord::Migration[6.1] + def change + create_table :organisations do |t| + t.string :name + t.integer :phone + t.integer :org_type + t.string :address_line1 + t.string :address_line2 + t.string :postcode + t.string :local_authorities + t.boolean :holds_own_stock + t.string :other_stock_owners + t.string :managing_agents + + t.timestamps + end + end +end diff --git a/db/migrate/20211126142105_user_case_logs_belong_to_organisation.rb b/db/migrate/20211126142105_user_case_logs_belong_to_organisation.rb new file mode 100644 index 000000000..d689910bf --- /dev/null +++ b/db/migrate/20211126142105_user_case_logs_belong_to_organisation.rb @@ -0,0 +1,23 @@ +class UserCaseLogsBelongToOrganisation < ActiveRecord::Migration[6.1] + def up + change_table :users, bulk: true do |t| + t.remove :organisation + t.belongs_to :organisation + end + change_table :case_logs, bulk: true do |t| + t.belongs_to :owning_organisation, class_name: "Organisation" + t.belongs_to :managing_organisation, class_name: "Organisation" + end + end + + def down + change_table :users, bulk: true do |t| + t.remove :organisation_id + t.column :organisation, :string + end + change_table :case_logs, bulk: true do |t| + t.remove :owning_organisation_id + t.remove :managing_organisation_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index b63e15a8f..e88f28f52 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.define(version: 2021_11_25_154916) do +ActiveRecord::Schema.define(version: 2021_11_26_142105) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -165,8 +165,27 @@ ActiveRecord::Schema.define(version: 2021_11_25_154916) do t.string "why_dont_you_know_la" t.integer "unitletas" t.integer "builtype" + t.bigint "owning_organisation_id" + t.bigint "managing_organisation_id" t.datetime "property_void_date" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" + t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id" + t.index ["owning_organisation_id"], name: "index_case_logs_on_owning_organisation_id" + end + + create_table "organisations", force: :cascade do |t| + t.string "name" + t.integer "phone" + t.integer "org_type" + t.string "address_line1" + t.string "address_line2" + t.string "postcode" + t.string "local_authorities" + t.boolean "holds_own_stock" + t.string "other_stock_owners" + t.string "managing_agents" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false end create_table "users", force: :cascade do |t| @@ -179,8 +198,9 @@ ActiveRecord::Schema.define(version: 2021_11_25_154916) do t.datetime "updated_at", precision: 6, null: false t.string "name" t.string "role" - t.string "organisation" + t.bigint "organisation_id" t.index ["email"], name: "index_users_on_email", unique: true + t.index ["organisation_id"], name: "index_users_on_organisation_id" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end diff --git a/db/seeds.rb b/db/seeds.rb index 6156dff01..99d537266 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -6,5 +6,6 @@ # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) -User.create!(email: "test@example.com", password: "password") +org = Organisation.create!(name: "DLUHC", address_line1: "2 Marsham Street", address_line2: "London", postcode: "SW1P 4DF") +User.create!(email: "test@example.com", password: "password", organisation: org) AdminUser.create!(email: "admin@example.com", password: "password") diff --git a/spec/controllers/admin/admin_users_controller_spec.rb b/spec/controllers/admin/admin_users_controller_spec.rb index 73f339ac4..6be860042 100644 --- a/spec/controllers/admin/admin_users_controller_spec.rb +++ b/spec/controllers/admin/admin_users_controller_spec.rb @@ -23,20 +23,37 @@ describe Admin::AdminUsersController, type: :controller do describe "Create admin users" do let(:params) { { admin_user: { email: "test2@example.com", password: "pAssword1" } } } - it "creates a new admin users" do + it "creates a new admin user" do expect { post :create, session: valid_session, params: params }.to change(AdminUser, :count).by(1) end end describe "Update admin users" do - before do - get :edit, session: valid_session, params: { id: AdminUser.first.id } + context "edit form" do + before do + get :edit, session: valid_session, params: { id: AdminUser.first.id } + end + + it "shows an edit form" do + expect(page).to have_field("admin_user_email") + expect(page).to have_field("admin_user_password") + expect(page).to have_field("admin_user_password_confirmation") + end end - it "creates a new admin users" do - expect(page).to have_field("admin_user_email") - expect(page).to have_field("admin_user_password") - expect(page).to have_field("admin_user_password_confirmation") + context "update" do + let(:admin_user) { FactoryBot.create(:admin_user) } + let(:email) { "new_email@example.com" } + let(:params) { { id: admin_user.id, admin_user: { email: email } } } + + before do + patch :update, session: valid_session, params: params + end + + it "updates the user without needing to input a password" do + admin_user.reload + expect(admin_user.email).to eq(email) + end end end end diff --git a/spec/controllers/admin/case_logs_controller_spec.rb b/spec/controllers/admin/case_logs_controller_spec.rb index 1ffec1073..fc26bdb42 100644 --- a/spec/controllers/admin/case_logs_controller_spec.rb +++ b/spec/controllers/admin/case_logs_controller_spec.rb @@ -18,12 +18,23 @@ describe Admin::CaseLogsController, type: :controller do expect(page).to have_content(resource_title) expect(page).to have_table("index_table_case_logs") expect(page).to have_link(case_log.id.to_s) + expect(page).to have_link(case_log.owning_organisation.name.to_s) end end describe "Create case logs" do + let(:owning_organisation) { FactoryBot.create(:organisation) } + let(:managing_organisation) { owning_organisation } + let(:params) do + { + "case_log": { + "owning_organisation_id": owning_organisation.id, + "managing_organisation_id": managing_organisation.id, + }, + } + end it "creates a new case log" do - expect { post :create, session: valid_session }.to change(CaseLog, :count).by(1) + expect { post :create, session: valid_session, params: params }.to change(CaseLog, :count).by(1) end end end diff --git a/spec/controllers/admin/organisations_controller_spec.rb b/spec/controllers/admin/organisations_controller_spec.rb new file mode 100644 index 000000000..276742898 --- /dev/null +++ b/spec/controllers/admin/organisations_controller_spec.rb @@ -0,0 +1,43 @@ +require "rails_helper" +require_relative "../../support/devise" + +describe Admin::OrganisationsController, type: :controller do + render_views + let(:page) { Capybara::Node::Simple.new(response.body) } + let(:resource_title) { "Organisations" } + let(:valid_session) { {} } + let!(:organisation) { FactoryBot.create(:organisation) } + login_admin_user + + describe "Organisations" do + before do + get :index, session: valid_session + end + + it "returns a table of admin users" do + expect(page).to have_content(resource_title) + expect(page).to have_table("index_table_organisations") + expect(page).to have_link(organisation.id.to_s) + end + end + + describe "Create admin users" do + let(:params) { { organisation: { name: "DLUHC" } } } + + it "creates a organisation" do + expect { post :create, session: valid_session, params: params }.to change(Organisation, :count).by(1) + end + end + + describe "Update organisation" do + before do + get :edit, session: valid_session, params: { id: organisation.id } + end + + it "creates a new admin users" do + expect(page).to have_field("organisation_name") + expect(page).to have_field("organisation_org_type") + expect(page).to have_field("organisation_phone") + end + end +end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb new file mode 100644 index 000000000..a7615adba --- /dev/null +++ b/spec/controllers/admin/users_controller_spec.rb @@ -0,0 +1,71 @@ +require "rails_helper" +require_relative "../../support/devise" + +describe Admin::UsersController, type: :controller do + render_views + let!(:user) { FactoryBot.create(:user) } + let(:organisation) { FactoryBot.create(:organisation) } + let(:page) { Capybara::Node::Simple.new(response.body) } + let(:resource_title) { "Users" } + let(:valid_session) { {} } + login_admin_user + + describe "Get users" do + before do + get :index, session: valid_session + end + + it "returns a table of users" do + expect(page).to have_content(resource_title) + expect(page).to have_table("index_table_users") + expect(page).to have_link(user.id.to_s) + end + end + + describe "Create users" do + let(:params) do + { + user: { + email: "somethin5@example.com", + name: "Jane", + password: "pAssword1", + organisation_id: organisation.id, + }, + } + end + + it "creates a new user" do + expect { post :create, session: valid_session, params: params }.to change(User, :count).by(1) + end + end + + describe "Update users" do + context "update form" do + before do + get :edit, session: valid_session, params: { id: user.id } + end + + it "shows an edit form" do + expect(page).to have_field("user_email") + expect(page).to have_field("user_name") + expect(page).to have_field("user_organisation_id") + expect(page).to have_field("user_password") + expect(page).to have_field("user_password_confirmation") + end + end + + context "update" do + let(:name) { "Pete" } + let(:params) { { id: user.id, user: { name: name } } } + + before do + patch :update, session: valid_session, params: params + end + + it "updates the user without needing to input a password" do + user.reload + expect(user.name).to eq(name) + end + end + end +end diff --git a/spec/controllers/case_logs_controller_spec.rb b/spec/controllers/case_logs_controller_spec.rb index 257981879..43458e1b8 100644 --- a/spec/controllers/case_logs_controller_spec.rb +++ b/spec/controllers/case_logs_controller_spec.rb @@ -1,9 +1,20 @@ require "rails_helper" -require_relative "../support/devise" RSpec.describe CaseLogsController, type: :controller do let(:valid_session) { {} } - login_user + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end + let(:id) { case_log.id } + + before do + sign_in user + end context "Collection routes" do describe "GET #index" do @@ -14,23 +25,29 @@ RSpec.describe CaseLogsController, type: :controller do end describe "Post #create" do + let(:owning_organisation) { FactoryBot.create(:organisation) } + let(:managing_organisation) { owning_organisation } + let(:params) do + { + "owning_organisation_id": owning_organisation.id, + "managing_organisation_id": managing_organisation.id, + } + end + it "creates a new case log record" do expect { - post :create, params: {}, session: valid_session + post :create, params: params, session: valid_session }.to change(CaseLog, :count).by(1) end it "redirects to that case log" do - post :create, params: {}, session: valid_session + post :create, params: params, session: valid_session expect(response.status).to eq(302) end end end context "Instance routes" do - let!(:case_log) { FactoryBot.create(:case_log) } - let(:id) { case_log.id } - describe "GET #show" do it "returns a success response" do get :show, params: { id: id } @@ -47,8 +64,6 @@ RSpec.describe CaseLogsController, type: :controller do end describe "submit_form" do - let!(:case_log) { FactoryBot.create(:case_log) } - let(:id) { case_log.id } let(:case_log_form_params) do { accessibility_requirements: %w[ housingneeds_a diff --git a/spec/factories/case_log.rb b/spec/factories/case_log.rb index 944be4237..dd636f9d9 100644 --- a/spec/factories/case_log.rb +++ b/spec/factories/case_log.rb @@ -1,5 +1,7 @@ FactoryBot.define do factory :case_log do + owning_organisation { FactoryBot.create(:organisation) } + managing_organisation { FactoryBot.create(:organisation) } trait :in_progress do status { 1 } tenant_code { "TH356" } diff --git a/spec/factories/organisation.rb b/spec/factories/organisation.rb new file mode 100644 index 000000000..91e4179e7 --- /dev/null +++ b/spec/factories/organisation.rb @@ -0,0 +1,11 @@ +FactoryBot.define do + factory :organisation do + name { "DLUHC" } + org_type { 1 } + address_line1 { "2 Marsham Street" } + address_line2 { "London" } + postcode { "SW1P 4DF" } + created_at { Time.zone.now } + updated_at { Time.zone.now } + end +end diff --git a/spec/factories/user.rb b/spec/factories/user.rb index c9f427a98..6509c2457 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :user do sequence(:email) { |i| "test#{i}@example.com" } password { "pAssword1" } + organisation created_at { Time.zone.now } updated_at { Time.zone.now } end diff --git a/spec/features/form/check_answers_page_spec.rb b/spec/features/form/check_answers_page_spec.rb index 2da1982a2..236eaca2f 100644 --- a/spec/features/form/check_answers_page_spec.rb +++ b/spec/features/form/check_answers_page_spec.rb @@ -3,12 +3,26 @@ require_relative "helpers" RSpec.describe "Form Check Answers Page" do include Helpers - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } - let(:empty_case_log) { FactoryBot.create(:case_log) } + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end + let(:empty_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) + sign_in user end let(:subsection) { "household_characteristics" } diff --git a/spec/features/form/conditional_questions_spec.rb b/spec/features/form/conditional_questions_spec.rb index dc6193fa2..3ab8b6f87 100644 --- a/spec/features/form/conditional_questions_spec.rb +++ b/spec/features/form/conditional_questions_spec.rb @@ -1,11 +1,21 @@ require "rails_helper" +require_relative "helpers" RSpec.describe "Form Conditional Questions" do - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } + include Helpers + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) + sign_in user end context "given a page where some questions are only conditionally shown, depending on how you answer the first question" do diff --git a/spec/features/form/form_navigation_spec.rb b/spec/features/form/form_navigation_spec.rb index 0c697ae3d..965b46955 100644 --- a/spec/features/form/form_navigation_spec.rb +++ b/spec/features/form/form_navigation_spec.rb @@ -1,7 +1,17 @@ require "rails_helper" +require_relative "helpers" RSpec.describe "Form Navigation" do - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } + include Helpers + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } let(:question_answers) do { @@ -13,7 +23,7 @@ RSpec.describe "Form Navigation" do end before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) + sign_in user end describe "Create new log" do diff --git a/spec/features/form/helpers.rb b/spec/features/form/helpers.rb index e5ea8e173..e0c1631b4 100644 --- a/spec/features/form/helpers.rb +++ b/spec/features/form/helpers.rb @@ -15,4 +15,11 @@ module Helpers choose("case-log-hb-prefer-not-to-say-field") click_button("Save and continue") end + + def sign_in(user) + visit("/case_logs") + fill_in("user_email", with: user.email) + fill_in("user_password", with: user.password) + click_button("Sign in") + end end diff --git a/spec/features/form/page_routing_spec.rb b/spec/features/form/page_routing_spec.rb index 0a9146c61..b508c860b 100644 --- a/spec/features/form/page_routing_spec.rb +++ b/spec/features/form/page_routing_spec.rb @@ -1,12 +1,22 @@ require "rails_helper" +require_relative "helpers" RSpec.describe "Form Page Routing" do - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } + include Helpers + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) allow_any_instance_of(CaseLogValidator).to receive(:validate_pregnancy).and_return(true) + sign_in user end it "can route the user to a different page based on their answer on the current page", js: true do diff --git a/spec/features/form/saving_data_spec.rb b/spec/features/form/saving_data_spec.rb index 9a3b0cd41..e066c73eb 100644 --- a/spec/features/form/saving_data_spec.rb +++ b/spec/features/form/saving_data_spec.rb @@ -1,13 +1,25 @@ require "rails_helper" +require_relative "helpers" RSpec.describe "Form Saving Data" do - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } + include Helpers + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } let(:case_log_with_checkbox_questions_answered) do FactoryBot.create( :case_log, :in_progress, housingneeds_a: "Yes", - housingneeds_c: "Yes" + housingneeds_c: "Yes", + owning_organisation: user.organisation, + managing_organisation: user.organisation ) end let(:question_answers) do @@ -20,7 +32,7 @@ RSpec.describe "Form Saving Data" do end before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) + sign_in user end it "updates model attributes correctly for each question" do diff --git a/spec/features/form/tasklist_page_spec.rb b/spec/features/form/tasklist_page_spec.rb index a2073f755..7ec4fce13 100644 --- a/spec/features/form/tasklist_page_spec.rb +++ b/spec/features/form/tasklist_page_spec.rb @@ -3,13 +3,27 @@ require_relative "helpers" RSpec.describe "Task List" do include Helpers - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } - let(:empty_case_log) { FactoryBot.create(:case_log) } + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end + let(:empty_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } let(:status) { case_log.status } before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) + sign_in user end it "displays a tasklist header" do diff --git a/spec/features/form/validations_spec.rb b/spec/features/form/validations_spec.rb index 43ebcf732..2721dcef9 100644 --- a/spec/features/form/validations_spec.rb +++ b/spec/features/form/validations_spec.rb @@ -3,12 +3,26 @@ require_relative "helpers" RSpec.describe "validations" do include Helpers - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } - let(:empty_case_log) { FactoryBot.create(:case_log) } + let(:user) { FactoryBot.create(:user) } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end + let(:empty_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:id) { case_log.id } before do - allow_any_instance_of(CaseLogsController).to receive(:authenticate_user!).and_return(true) + sign_in user end describe "Question validation" do @@ -86,7 +100,15 @@ RSpec.describe "validations" do describe "Soft Validation" do context "given a weekly net income that is above the expected amount for the given economic status but below the hard max" do - let(:case_log) { FactoryBot.create(:case_log, :in_progress, ecstat1: "Full-time - 30 hours or more") } + let(:case_log) do + FactoryBot.create( + :case_log, + :in_progress, + ecstat1: "Full-time - 30 hours or more", + owning_organisation: user.organisation, + managing_organisation: user.organisation, + ) + end let(:income_over_soft_limit) { 750 } let(:income_under_soft_limit) { 700 } diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index b52d04a63..84602d1dc 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -1,32 +1,89 @@ require "rails_helper" RSpec.describe Form, type: :model do + let(:owning_organisation) { FactoryBot.create(:organisation) } + let(:managing_organisation) { owning_organisation } + describe "#new" do it "validates age is a number" do - expect { CaseLog.create!(age1: "random") }.to raise_error(ActiveRecord::RecordInvalid) - expect { CaseLog.create!(age3: "random") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age1: "random", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age3: "random", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validates age is under 120" do - expect { CaseLog.create!(age1: 121) }.to raise_error(ActiveRecord::RecordInvalid) - expect { CaseLog.create!(age3: 121) }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age1: 121, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age3: 121, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validates age is over 0" do - expect { CaseLog.create!(age1: 0) }.to raise_error(ActiveRecord::RecordInvalid) - expect { CaseLog.create!(age3: 0) }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age1: 0, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age3: 0, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validates number of relets is a number" do - expect { CaseLog.create!(offered: "random") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + offered: "random", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validates number of relets is under 20" do - expect { CaseLog.create!(offered: 21) }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + offered: 21, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validates number of relets is over 0" do - expect { CaseLog.create!(offered: 0) }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + offered: 0, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end context "reasonable preference is yes" do @@ -37,7 +94,9 @@ RSpec.describe Form, type: :model do rp_insan_unsat: nil, rp_medwel: nil, rp_hardship: nil, - rp_dontknow: nil) + rp_dontknow: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -46,6 +105,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( homeless: "No", reasonpref: "Yes", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -54,7 +115,12 @@ RSpec.describe Form, type: :model do context "reasonable preference is no" do it "validates no reason is needed" do expect { - CaseLog.create!(reasonpref: "No", rp_homeless: "No") + CaseLog.create!( + reasonpref: "No", + rp_homeless: "No", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) }.not_to raise_error end @@ -63,6 +129,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( reasonpref: "No", rp_medwel: "Yes", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -72,7 +140,9 @@ RSpec.describe Form, type: :model do it "Reason for leaving must be don't know if reason for leaving settled home (Q9a) is don't know." do expect { CaseLog.create!(reason: "Do not know", - underoccupation_benefitcap: "Yes - benefit cap") + underoccupation_benefitcap: "Yes - benefit cap", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -80,14 +150,18 @@ RSpec.describe Form, type: :model do it "must be provided if main reason for leaving last settled home was given as other" do expect { CaseLog.create!(reason: "Other", - other_reason_for_leaving_last_settled_home: nil) + other_reason_for_leaving_last_settled_home: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "must not be provided if the main reason for leaving settled home is not other" do expect { CaseLog.create!(reason: "Repossession", - other_reason_for_leaving_last_settled_home: "the other reason provided") + other_reason_for_leaving_last_settled_home: "the other reason provided", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -96,14 +170,18 @@ RSpec.describe Form, type: :model do it "must be answered if tenant was a regular or reserve in armed forces" do expect { CaseLog.create!(armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)", - reservist: nil) + reservist: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "must be answered if tenant was not a regular or reserve in armed forces" do expect { CaseLog.create!(armedforces: "No", - reservist: "Yes") + reservist: "Yes", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -113,7 +191,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Yes", sex1: "Male", - age1: 20) + age1: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -121,7 +201,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Yes", sex1: "Female", - age1: 51) + age1: 51, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -129,7 +211,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Prefer not to say", sex1: "Male", - age1: 20) + age1: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -137,7 +221,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Yes", sex1: "Female", - age1: 20) + age1: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end @@ -146,7 +232,9 @@ RSpec.describe Form, type: :model do CaseLog.create!(preg_occ: "Yes", sex1: "Male", age1: 99, sex2: "Female", - age2: 20) + age2: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end end @@ -155,7 +243,9 @@ RSpec.describe Form, type: :model do it "you must have more than zero bedrooms" do expect { CaseLog.create!(unittype_gn: "Shared house", - beds: 0) + beds: 0, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -163,7 +253,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 8, - other_hhmemb: 1) + other_hhmemb: 1, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -171,21 +263,27 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 4, - other_hhmemb: 0) + other_hhmemb: 0, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "A bedsit must only have one room" do expect { CaseLog.create!(unittype_gn: "Bed-sit", - beds: 2) + beds: 2, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "A bedsit must only have one room" do expect { CaseLog.create!(unittype_gn: "Bed-sit", - beds: 0) + beds: 0, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -194,14 +292,18 @@ RSpec.describe Form, type: :model do it "must be anwered if answered yes to outstanding rent or charges" do expect { CaseLog.create!(hbrentshortfall: "Yes", - tshortfall: nil) + tshortfall: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "must be not be anwered if answered no to outstanding rent or charges" do expect { CaseLog.create!(hbrentshortfall: "No", - tshortfall: 99) + tshortfall: 99, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -209,19 +311,35 @@ RSpec.describe Form, type: :model do context "tenant’s income is from Universal Credit, state pensions or benefits" do it "Cannot be All if person 1 works full time" do expect { - CaseLog.create!(benefits: "All", ecstat1: "Full-time - 30 hours or more") + CaseLog.create!( + benefits: "All", + ecstat1: "Full-time - 30 hours or more", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) }.to raise_error(ActiveRecord::RecordInvalid) end it "Cannot be All if person 1 works part time" do expect { - CaseLog.create!(benefits: "All", ecstat1: "Part-time - Less than 30 hours") + CaseLog.create!( + benefits: "All", + ecstat1: "Part-time - Less than 30 hours", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) }.to raise_error(ActiveRecord::RecordInvalid) end it "Cannot be 1 All if any of persons 2-4 are person 1's partner and work part or full time" do expect { - CaseLog.create!(benefits: "All", relat2: "Partner", ecstat2: "Part-time - Less than 30 hours") + CaseLog.create!( + benefits: "All", + relat2: "Partner", + ecstat2: "Part-time - Less than 30 hours", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -230,46 +348,62 @@ RSpec.describe Form, type: :model do it "Must not be completed if Type of main tenancy is not responded with either Secure or Assured shorthold " do expect { CaseLog.create!(tenancy: "Other", - tenancylength: 10) + tenancylength: 10, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "Must be completed and between 2 and 99 if type of tenancy is Assured shorthold" do expect { CaseLog.create!(tenancy: "Assured Shorthold", - tenancylength: 1) + tenancylength: 1, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) expect { CaseLog.create!(tenancy: "Assured Shorthold", - tenancylength: nil) + tenancylength: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) expect { CaseLog.create!(tenancy: "Assured Shorthold", - tenancylength: 2) + tenancylength: 2, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end it "Must be empty or between 2 and 99 if type of tenancy is Secure" do expect { CaseLog.create!(tenancy: "Secure (including flexible)", - tenancylength: 1) + tenancylength: 1, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) expect { CaseLog.create!(tenancy: "Secure (including flexible)", - tenancylength: 100) + tenancylength: 100, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) expect { CaseLog.create!(tenancy: "Secure (including flexible)", - tenancylength: nil) + tenancylength: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error expect { CaseLog.create!(tenancy: "Secure (including flexible)", - tenancylength: 2) + tenancylength: 2, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end end @@ -278,14 +412,18 @@ RSpec.describe Form, type: :model do it "must be answered if ever served in the forces as a regular" do expect { CaseLog.create!(armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)", - leftreg: nil) + leftreg: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end it "must not be answered if not ever served as a regular" do expect { CaseLog.create!(armedforces: "No", - leftreg: "Yes") + leftreg: "Yes", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -294,42 +432,103 @@ RSpec.describe Form, type: :model do expect do CaseLog.create!(armedforces: "A current or former regular in the UK Armed Forces (exc. National Service)", leftreg: "Yes", - reservist: "Yes") + reservist: "Yes", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) end end end context "household_member_validations" do it "validate that persons aged under 16 must have relationship Child" do - expect { CaseLog.create!(age2: 14, relat2: "Partner") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 14, + relat2: "Partner", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that persons aged over 70 must be retired" do - expect { CaseLog.create!(age2: 71, ecstat2: "Full-time - 30 hours or more") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 71, + ecstat2: "Full-time - 30 hours or more", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that a male, retired persons must be over 65" do - expect { CaseLog.create!(age2: 64, sex2: "Male", ecstat2: "Retired") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 64, + sex2: "Male", + ecstat2: "Retired", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that a female, retired persons must be over 60" do - expect { CaseLog.create!(age2: 59, sex2: "Female", ecstat2: "Retired") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 59, + sex2: "Female", + ecstat2: "Retired", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that persons aged under 16 must be a child (economically speaking)" do - expect { CaseLog.create!(age2: 15, ecstat2: "Full-time - 30 hours or more") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 15, + ecstat2: "Full-time - 30 hours or more", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that persons aged between 16 and 19 that are a child must be a full time student or economic status refused" do - expect { CaseLog.create!(age2: 17, relat2: "Child - includes young adult and grown-up", ecstat2: "Full-time - 30 hours or more") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 17, + relat2: "Child - includes young adult and grown-up", + ecstat2: "Full-time - 30 hours or more", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that persons aged under 16 must be a child relationship" do - expect { CaseLog.create!(age2: 15, relat2: "Partner") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + age2: 15, + relat2: "Partner", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end it "validate that no more than 1 partner relationship exists" do - expect { CaseLog.create!(relat2: "Partner", relat3: "Partner") }.to raise_error(ActiveRecord::RecordInvalid) + expect { + CaseLog.create!( + relat2: "Partner", + relat3: "Partner", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, + ) + }.to raise_error(ActiveRecord::RecordInvalid) end end @@ -337,24 +536,32 @@ RSpec.describe Form, type: :model do it "must be provided if tenancy type was given as other" do expect { CaseLog.create!(tenancy: "Other", - tenancyother: nil) + tenancyother: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) expect { CaseLog.create!(tenancy: "Other", - tenancyother: "type") + tenancyother: "type", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end it "must not be provided if tenancy type is not other" do expect { CaseLog.create!(tenancy: "Secure (including flexible)", - tenancyother: "the other reason provided") + tenancyother: "the other reason provided", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) expect { CaseLog.create!(tenancy: "Secure (including flexible)", - tenancyother: nil) + tenancyother: nil, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end end @@ -366,6 +573,8 @@ RSpec.describe Form, type: :model do ecstat1: "Full-time - 30 hours or more", earnings: 5000, incfreq: "Weekly", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -376,6 +585,8 @@ RSpec.describe Form, type: :model do ecstat1: "Full-time - 30 hours or more", earnings: 1, incfreq: "Weekly", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -417,6 +628,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( mrcdate: Date.new(2020, 10, 10), startdate: Date.new(2020, 10, 9), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) @@ -424,6 +637,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( mrcdate: Date.new(2020, 10, 9), startdate: Date.new(2020, 10, 10), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.not_to raise_error end @@ -433,6 +648,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( mrcdate: Date.new(2020, 10, 10), rsnvac: "First let of newbuild property", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) @@ -440,6 +657,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( mrcdate: Date.new(2020, 10, 10), rsnvac: "First let of conversion/rehabilitation/acquired property", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) @@ -447,6 +666,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( mrcdate: Date.new(2020, 10, 10), rsnvac: "First let of leased property", + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -456,6 +677,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( startdate: Date.new(2020, 10, 10), mrcdate: Date.new(2017, 10, 10), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -467,6 +690,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( startdate: Date.new(2020, 10, 10), property_void_date: Date.new(2009, 10, 10), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) @@ -474,6 +699,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( startdate: Date.new(2020, 10, 10), property_void_date: Date.new(2015, 10, 10), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.not_to raise_error end @@ -483,6 +710,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( startdate: Date.new(2020, 10, 10), property_void_date: Date.new(2021, 10, 10), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) @@ -490,6 +719,8 @@ RSpec.describe Form, type: :model do CaseLog.create!( startdate: Date.new(2020, 10, 10), property_void_date: Date.new(2019, 10, 10), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.not_to raise_error end @@ -500,6 +731,8 @@ RSpec.describe Form, type: :model do startdate: Date.new(2020, 10, 10), mrcdate: Date.new(2019, 10, 10), property_void_date: Date.new(2019, 11, 11), + owning_organisation: owning_organisation, + managing_organisation: managing_organisation, ) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -510,7 +743,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Yes", sex1: "Male", - age1: 20) + age1: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -518,7 +753,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Yes", sex1: "Female", - age1: 51) + age1: 51, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -526,7 +763,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Prefer not to say", sex1: "Male", - age1: 20) + age1: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -534,7 +773,9 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(preg_occ: "Yes", sex1: "Female", - age1: 20) + age1: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end @@ -543,7 +784,9 @@ RSpec.describe Form, type: :model do CaseLog.create!(preg_occ: "Yes", sex1: "Male", age1: 99, sex2: "Female", - age2: 20) + age2: 20, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) }.not_to raise_error end end diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb new file mode 100644 index 000000000..c5f2aaffc --- /dev/null +++ b/spec/models/organisation_spec.rb @@ -0,0 +1,52 @@ +require "rails_helper" + +RSpec.describe Organisation, type: :model do + describe "#new" do + let(:user) { FactoryBot.create(:user) } + let(:organisation) { user.organisation } + + it "has expected fields" do + expect(organisation.attribute_names).to include("name", "phone", "org_type") + end + + it "has users" do + expect(organisation.users.first).to eq(user) + end + + context "case logs" do + let(:other_organisation) { FactoryBot.create(:organisation) } + let!(:owned_case_log) do + FactoryBot.create( + :case_log, + :completed, + owning_organisation: organisation, + managing_organisation: other_organisation, + ) + end + let!(:managed_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: other_organisation, + managing_organisation: organisation, + ) + end + + it "has owned case logs" do + expect(organisation.owned_case_logs.first).to eq(owned_case_log) + end + + it "has managed case logs" do + expect(organisation.managed_case_logs.first).to eq(managed_case_log) + end + + it "has case logs" do + expect(organisation.case_logs.to_a).to eq([owned_case_log, managed_case_log]) + end + + it "has case log status helper methods" do + expect(organisation.completed_case_logs.to_a).to eq([owned_case_log]) + expect(organisation.not_completed_case_logs.to_a).to eq([managed_case_log]) + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 000000000..bec457e7f --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe User, type: :model do + describe "#new" do + let(:user) { FactoryBot.create(:user) } + let(:other_organisation) { FactoryBot.create(:organisation) } + let!(:owned_case_log) do + FactoryBot.create( + :case_log, + :completed, + owning_organisation: user.organisation, + managing_organisation: other_organisation, + ) + end + let!(:managed_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: other_organisation, + managing_organisation: user.organisation, + ) + end + + it "belongs to an organisation" do + expect(user.organisation).to be_a(Organisation) + end + + it "has owned case logs through their organisation" do + expect(user.owned_case_logs.first).to eq(owned_case_log) + end + + it "has managed case logs through their organisation" do + expect(user.managed_case_logs.first).to eq(managed_case_log) + end + + it "has case logs through their organisation" do + expect(user.case_logs.to_a).to eq([owned_case_log, managed_case_log]) + end + + it "has case log status helper methods" do + expect(user.completed_case_logs.to_a).to eq([owned_case_log]) + expect(user.not_completed_case_logs.to_a).to eq([managed_case_log]) + end + end +end diff --git a/spec/requests/bulk_upload_controller_spec.rb b/spec/requests/bulk_upload_controller_spec.rb index 6b9ab16e0..b83288ad3 100644 --- a/spec/requests/bulk_upload_controller_spec.rb +++ b/spec/requests/bulk_upload_controller_spec.rb @@ -2,6 +2,10 @@ require "rails_helper" RSpec.describe BulkUploadController, type: :request do let(:url) { "/case_logs/bulk_upload" } + let(:organisation) { FactoryBot.create(:organisation) } + before do + allow(Organisation).to receive(:find).with(107_242).and_return(organisation) + end describe "GET #show" do before do diff --git a/spec/requests/case_log_controller_spec.rb b/spec/requests/case_log_controller_spec.rb index 443e22b75..aab5b02a9 100644 --- a/spec/requests/case_log_controller_spec.rb +++ b/spec/requests/case_log_controller_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe CaseLogsController, type: :request do + let(:owning_organisation) { FactoryBot.create(:organisation) } + let(:managing_organisation) { owning_organisation } let(:api_username) { "test_user" } let(:api_password) { "test_password" } let(:basic_credentials) do @@ -32,6 +34,8 @@ RSpec.describe CaseLogsController, type: :request do let(:params) do { + "owning_organisation_id": owning_organisation.id, + "managing_organisation_id": managing_organisation.id, "tenant_code": tenant_code, "age1": age1, "property_postcode": property_postcode, @@ -78,8 +82,17 @@ RSpec.describe CaseLogsController, type: :request do end context "complete case log submission" do + let(:org_params) do + { + "case_log" => { + "owning_organisation_id" => owning_organisation.id, + "managing_organisation_id" => managing_organisation.id, + }, + } + end + let(:case_log_params) { JSON.parse(File.open("spec/fixtures/complete_case_log.json").read) } let(:params) do - JSON.parse(File.open("spec/fixtures/complete_case_log.json").read) + case_log_params.merge(org_params) { |_k, a_val, b_val| a_val.merge(b_val) } end it "marks the record as completed" do @@ -101,27 +114,124 @@ RSpec.describe CaseLogsController, type: :request do end describe "GET" do - let(:case_log) { FactoryBot.create(:case_log, :completed) } - let(:id) { case_log.id } - - before do - get "/case_logs/#{id}", headers: headers + let(:user) { FactoryBot.create(:user) } + let(:organisation) { user.organisation } + let(:other_organisation) { FactoryBot.create(:organisation) } + let!(:case_log) do + FactoryBot.create( + :case_log, + owning_organisation: organisation, + managing_organisation: organisation, + ) end - - it "returns http success" do - expect(response).to have_http_status(:success) + let!(:unauthorized_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: other_organisation, + managing_organisation: other_organisation, + ) end - it "returns a serialized Case Log" do - json_response = JSON.parse(response.body) - expect(json_response["status"]).to eq(case_log.status) + context "collection" do + let(:headers) { { "Accept" => "text/html" } } + + before do + sign_in user + get "/case_logs", headers: headers, params: {} + end + + it "only shows case logs for your organisation" do + expected_case_row_log = "#{case_log.id}" + unauthorized_case_row_log = "#{unauthorized_case_log.id}" + expect(CGI.unescape_html(response.body)).to include(expected_case_row_log) + expect(CGI.unescape_html(response.body)).not_to include(unauthorized_case_row_log) + end end - context "invalid case log id" do - let(:id) { (CaseLog.order(:id).last&.id || 0) + 1 } + context "member" do + let(:completed_case_log) { FactoryBot.create(:case_log, :completed) } + let(:id) { completed_case_log.id } - it "returns 404" do - expect(response).to have_http_status(:not_found) + before do + get "/case_logs/#{id}", headers: headers + end + + it "returns http success" do + expect(response).to have_http_status(:success) + end + + it "returns a serialized Case Log" do + json_response = JSON.parse(response.body) + expect(json_response["status"]).to eq(completed_case_log.status) + end + + context "invalid case log id" do + let(:id) { (CaseLog.order(:id).last&.id || 0) + 1 } + + it "returns 404" do + expect(response).to have_http_status(:not_found) + end + end + + context "edit log" do + let(:headers) { { "Accept" => "text/html" } } + let(:form) { Form.new("spec/fixtures/forms/test_form.json") } + before do + allow(FormHandler.instance).to receive(:get_form).and_return(form) + end + + context "case logs that are owned or managed by your organisation" do + before do + sign_in user + get "/case_logs/#{case_log.id}", headers: headers, params: {} + end + + it "shows the tasklist for case logs you have access to" do + expect(response.body).to match("Tasklist for log") + expect(response.body).to match(case_log.id.to_s) + end + end + + context "case logs that are not owned or managed by your organisation" do + before do + sign_in user + get "/case_logs/#{unauthorized_case_log.id}", headers: headers, params: {} + end + + it "does not show the tasklist for case logs you don't have access to" do + expect(response).to have_http_status(:not_found) + end + end + end + + context "form pages" do + let(:headers) { { "Accept" => "text/html" } } + + context "case logs that are not owned or managed by your organisation" do + before do + sign_in user + get "/case_logs/#{unauthorized_case_log.id}/person_1_age", headers: headers, params: {} + end + + it "does not show form pages for case logs you don't have access to" do + expect(response).to have_http_status(:not_found) + end + end + end + + context "check answers pages" do + let(:headers) { { "Accept" => "text/html" } } + + context "case logs that are not owned or managed by your organisation" do + before do + sign_in user + get "/case_logs/#{unauthorized_case_log.id}/household_characteristics/check_answers", headers: headers, params: {} + end + + it "does not show a check answers for case logs you don't have access to" do + expect(response).to have_http_status(:not_found) + end + end end end end @@ -280,7 +390,14 @@ RSpec.describe CaseLogsController, type: :request do describe "Submit Form" do let(:user) { FactoryBot.create(:user) } let(:form) { Form.new("spec/fixtures/forms/test_form.json") } - let(:case_log) { FactoryBot.create(:case_log, :in_progress) } + let(:organisation) { user.organisation } + let(:case_log) do + FactoryBot.create( + :case_log, + owning_organisation: organisation, + managing_organisation: organisation, + ) + end let(:page_id) { "person_1_age" } let(:params) do { @@ -330,5 +447,26 @@ RSpec.describe CaseLogsController, type: :request do expect(case_log.age2).to be nil end end + + context "case logs that are not owned or managed by your organisation" do + let(:answer) { 25 } + let(:other_organisation) { FactoryBot.create(:organisation) } + let(:unauthorized_case_log) do + FactoryBot.create( + :case_log, + owning_organisation: other_organisation, + managing_organisation: other_organisation, + ) + end + + before do + sign_in user + post "/case_logs/#{unauthorized_case_log.id}/form", params: params + end + + it "does not let you post form answers to case logs you don't have access to" do + expect(response).to have_http_status(:not_found) + end + end end end diff --git a/spec/support/controller_macros.rb b/spec/support/controller_macros.rb index 5111be2b5..813af85f1 100644 --- a/spec/support/controller_macros.rb +++ b/spec/support/controller_macros.rb @@ -1,11 +1,4 @@ module ControllerMacros - # def login_admin - # before(:each) do - # @request.env["devise.mapping"] = Devise.mappings[:admin] - # sign_in FactoryBot.create(:admin) # Using factory bot as an example - # end - # end - def login_user before(:each) do @request.env["devise.mapping"] = Devise.mappings[:user]