diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb
index 83bff5542..d9dccab5d 100644
--- a/app/controllers/schemes_controller.rb
+++ b/app/controllers/schemes_controller.rb
@@ -14,6 +14,11 @@ class SchemesController < ApplicationController
@total_count = all_schemes.size
end
+ def show
+ @scheme = Scheme.find_by(id: params[:id])
+ render_not_found and return unless (current_user.organisation == @scheme.organisation) || current_user.support?
+ end
+
private
def search_term
diff --git a/app/helpers/navigation_items_helper.rb b/app/helpers/navigation_items_helper.rb
index c0b55c674..369428053 100644
--- a/app/helpers/navigation_items_helper.rb
+++ b/app/helpers/navigation_items_helper.rb
@@ -41,23 +41,23 @@ private
end
def users_current?(path)
- path == "/users"
+ path == "/users" || path.include?("/users/")
end
def supported_housing_current?(path)
- path == "/supported-housing"
+ path == "/supported-housing" || path.include?("/supported-housing/")
end
def organisations_current?(path)
- path == "/organisations" || subnav_users_path?(path) || subnav_logs_path?(path) || subnav_details_path?(path) || subnav_supported_housing_path?(path)
+ path == "/organisations" || path.include?("/organisations/")
end
def subnav_supported_housing_path?(path)
- path.include?("/organisations") && path.include?("/supported-housing")
+ path.include?("/organisations") && path.include?("/supported-housing") || path.include?("/supported-housing/")
end
def subnav_users_path?(path)
- path.include?("/organisations") && path.include?("/users")
+ (path.include?("/organisations") && path.include?("/users")) || path.include?("/users/")
end
def subnav_logs_path?(path)
diff --git a/app/helpers/tab_nav_helper.rb b/app/helpers/tab_nav_helper.rb
index 1157b83e6..bb163ddd8 100644
--- a/app/helpers/tab_nav_helper.rb
+++ b/app/helpers/tab_nav_helper.rb
@@ -6,6 +6,11 @@ module TabNavHelper
[govuk_link_to(link_text, user), "User #{user.email}"].join("\n")
end
+ def scheme_cell(scheme)
+ link_text = scheme.service_name.presence
+ [govuk_link_to(link_text, scheme), "Scheme #{scheme.primary_client_group_display}"].join("\n")
+ end
+
def org_cell(user)
role = "#{user.role.to_s.humanize}"
[user.organisation.name, role].join("\n")
diff --git a/app/models/scheme.rb b/app/models/scheme.rb
index 7f6ec337e..096706018 100644
--- a/app/models/scheme.rb
+++ b/app/models/scheme.rb
@@ -4,4 +4,104 @@ class Scheme < ApplicationRecord
scope :search_by_code, ->(code) { where("code ILIKE ?", "%#{code}%") }
scope :search_by_service_name, ->(name) { where("service_name ILIKE ?", "%#{name}%") }
scope :search_by, ->(param) { search_by_code(param).or(search_by_service_name(param)) }
+
+ SCHEME_TYPE = {
+ 0 => "Missings",
+ 4 => "Foyer",
+ 5 => "Direct Access Hostel",
+ 6 => "Other Supported Housing",
+ 7 => "Housing for older people",
+ }.freeze
+
+ PRIMARY_CLIENT_GROUP = {
+ "O" => "Homeless families with support needs",
+ "H" => "Offenders & people at risk of offending",
+ "M" => "Older people with support needs",
+ "L" => "People at risk of domestic violence",
+ "A" => "People with a physical or sensory disability",
+ "G" => "People with alcohol problems",
+ "F" => "People with drug problems",
+ "B" => "People with HIV or AIDS",
+ "D" => "People with learning disabilities",
+ "E" => "People with mental health problems",
+ "I" => "Refugees (permanent)",
+ "S" => "Rough sleepers",
+ "N" => "Single homeless people with support needs",
+ "R" => "Teenage parents",
+ "Q" => "Young people at risk",
+ "P" => "Young people leaving care",
+ "X" => "Missing",
+ }.freeze
+
+ SUPPORT_TYPE = {
+ 0 => "Missing",
+ 1 => "Resettlement Support",
+ 2 => "Low levels of support",
+ 3 => "Medium levels of support",
+ 4 => "High levels of care and support",
+ 5 => "Nursing care services to a care home",
+ 6 => "Floating Support",
+ }.freeze
+
+ INTENDED_STAY = {
+ "M" => "Medium stay",
+ "P" => "Permanent",
+ "S" => "Short Stay",
+ "V" => "Very short stay",
+ "X" => "Missing",
+ }.freeze
+
+ REGISTERED_UNDER_CARE_ACT = {
+ 0 => "No",
+ 1 => "Yes – part registered as a care home",
+ }.freeze
+
+ SENSITIVE = {
+ 0 => "No",
+ 1 => "Yes",
+ }.freeze
+
+ def display_attributes
+ [
+ { name: "Service code", value: code },
+ { name: "Name", value: service_name },
+ { name: "Confidential information", value: sensitive_display },
+ { name: "Managing agent", value: organisation.name },
+ { name: "Type of service", value: scheme_type_display },
+ { name: "Registered under Care Standards Act 2000", value: registered_under_care_act_display },
+ { name: "Total number of units", value: total_units },
+ { name: "Primary client group", value: primary_client_group_display },
+ { name: "Secondary client group", value: secondary_client_group_display },
+ { name: "Level of support given", value: support_type_display },
+ { name: "Intended length of stay", value: intended_stay_display },
+ ]
+ end
+
+ def scheme_type_display
+ SCHEME_TYPE[scheme_type]
+ end
+
+ def sensitive_display
+ SENSITIVE[sensitive]
+ end
+
+ def registered_under_care_act_display
+ REGISTERED_UNDER_CARE_ACT[registered_under_care_act]
+ end
+
+ def primary_client_group_display
+ PRIMARY_CLIENT_GROUP[primary_client_group]
+ end
+
+ def secondary_client_group_display
+ PRIMARY_CLIENT_GROUP[secondary_client_group]
+ end
+
+ def support_type_display
+ SUPPORT_TYPE[support_type]
+ end
+
+ def intended_stay_display
+ INTENDED_STAY[intended_stay]
+ end
end
diff --git a/app/views/schemes/_scheme_list.html.erb b/app/views/schemes/_scheme_list.html.erb
index 002a215b4..8d6ef7a72 100644
--- a/app/views/schemes/_scheme_list.html.erb
+++ b/app/views/schemes/_scheme_list.html.erb
@@ -29,7 +29,7 @@
<%= table.body do |body| %>
<%= body.row do |row| %>
<% row.cell(text: scheme.code) %>
- <% row.cell(text: scheme.service_name) %>
+ <% row.cell(text: simple_format(scheme_cell(scheme), { class: "govuk-!-font-weight-bold" }, wrapper_tag: "div")) %>
<% row.cell(text: scheme.organisation.name) %>
<% row.cell(text: scheme.created_at.to_formatted_s(:govuk_date)) %>
<% end %>
diff --git a/app/views/schemes/show.html.erb b/app/views/schemes/show.html.erb
new file mode 100644
index 000000000..bb883d0e9
--- /dev/null
+++ b/app/views/schemes/show.html.erb
@@ -0,0 +1,17 @@
+<% title = @scheme.service_name %>
+<% content_for :title, title %>
+
+<%= render partial: "organisations/headings", locals: { main: @scheme.service_name, sub: nil } %>
+
+
+
+ <%= govuk_summary_list do |summary_list| %>
+ <% @scheme.display_attributes.each do |attr| %>
+ <%= summary_list.row do |row| %>
+ <% row.key { attr[:name].to_s.humanize } %>
+ <% row.value { details_html(attr) } %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+
diff --git a/config/routes.rb b/config/routes.rb
index c7b3df36e..3e4492127 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -35,7 +35,7 @@ Rails.application.routes.draw do
get "edit/password", to: "users#edit_password"
end
- resources :schemes, path: "/supported-housing", only: [:index]
+ resources :schemes, path: "/supported-housing", only: %i[index show]
resources :users do
member do
diff --git a/db/migrate/20220613094847_add_missing_attributes_to_scheme.rb b/db/migrate/20220613094847_add_missing_attributes_to_scheme.rb
new file mode 100644
index 000000000..ca0121d3d
--- /dev/null
+++ b/db/migrate/20220613094847_add_missing_attributes_to_scheme.rb
@@ -0,0 +1,14 @@
+class AddMissingAttributesToScheme < ActiveRecord::Migration[7.0]
+ def change
+ change_table :schemes, bulk: true do |t|
+ t.string :primary_client_group
+ t.string :secondary_client_group
+ t.integer :sensitive
+ t.integer :total_units
+ t.integer :scheme_type
+ t.integer :registered_under_care_act
+ t.integer :support_type
+ t.string :intended_stay
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index cd132897d..6a4e5f2ea 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2022_06_08_144156) do
+ActiveRecord::Schema[7.0].define(version: 2022_06_13_094847) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -283,6 +283,14 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_08_144156) do
t.bigint "organisation_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "primary_client_group"
+ t.string "secondary_client_group"
+ t.integer "sensitive"
+ t.integer "total_units"
+ t.integer "scheme_type"
+ t.integer "registered_under_care_act"
+ t.integer "support_type"
+ t.string "intended_stay"
t.index ["organisation_id"], name: "index_schemes_on_organisation_id"
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 356e020b4..ad1fc1ac4 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -73,6 +73,14 @@ unless Rails.env.test?
Scheme.create!(
code: "S878",
service_name: "Beulahside Care",
+ sensitive: 0,
+ registered_under_care_act: 0,
+ support_type: 1,
+ scheme_type: 4,
+ total_units: 5,
+ intended_stay: "M",
+ primary_client_group: "O",
+ secondary_client_group: "H",
organisation: org,
created_at: Time.zone.now,
)
@@ -80,6 +88,14 @@ unless Rails.env.test?
Scheme.create!(
code: "S312",
service_name: "Abdullahview Point",
+ sensitive: 0,
+ registered_under_care_act: 1,
+ support_type: 1,
+ scheme_type: 5,
+ total_units: 2,
+ intended_stay: "S",
+ primary_client_group: "D",
+ secondary_client_group: "E",
organisation: org,
created_at: Time.zone.now,
)
@@ -87,6 +103,14 @@ unless Rails.env.test?
Scheme.create!(
code: "7XYZ",
service_name: "Caspermouth Center",
+ sensitive: 1,
+ registered_under_care_act: 1,
+ support_type: 4,
+ scheme_type: 7,
+ total_units: 7,
+ intended_stay: "X",
+ primary_client_group: "G",
+ secondary_client_group: "R",
organisation: dummy_org,
created_at: Time.zone.now,
)
diff --git a/spec/factories/scheme.rb b/spec/factories/scheme.rb
index 8d15032fe..6c3537146 100644
--- a/spec/factories/scheme.rb
+++ b/spec/factories/scheme.rb
@@ -2,6 +2,14 @@ FactoryBot.define do
factory :scheme do
code { Faker::Name.initials(number: 4) }
service_name { Faker::Name.name_with_middle }
+ sensitive { Faker::Number.within(range: 0..1) }
+ registered_under_care_act { Faker::Number.within(range: 0..1) }
+ support_type { Faker::Number.within(range: 0..6) }
+ scheme_type { 0 }
+ total_units { Faker::Number.number(digits: 2) }
+ intended_stay { %w[M P S V X].sample }
+ primary_client_group { %w[O H M L A G F B D E I S N R Q P X].sample }
+ secondary_client_group { %w[O H M L A G F B D E I S N R Q P X].sample }
organisation
created_at { Time.zone.now }
end
diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb
index b1fe131fe..f772a24c8 100644
--- a/spec/features/schemes_spec.rb
+++ b/spec/features/schemes_spec.rb
@@ -2,7 +2,7 @@ require "rails_helper"
RSpec.describe "Supported housing scheme Features" do
context "when viewing list of schemes" do
- context "when I am signed as a support user in there are schemes in the database" do
+ context "when I am signed as a support user and there are schemes in the database" do
let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) }
let!(:schemes) { FactoryBot.create_list(:scheme, 5) }
let!(:scheme_to_search) { FactoryBot.create(:scheme) }
@@ -75,4 +75,61 @@ RSpec.describe "Supported housing scheme Features" do
end
end
end
+
+ context "when viewing individual scheme" do
+ context "when I am signed as a support user and there are schemes in the database" do
+ let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) }
+ let!(:schemes) { FactoryBot.create_list(:scheme, 5) }
+ let(:notify_client) { instance_double(Notifications::Client) }
+ let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" }
+ let(:devise_notify_mailer) { DeviseNotifyMailer.new }
+ let(:otp) { "999111" }
+
+ before do
+ allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer)
+ allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client)
+ allow(Devise).to receive(:friendly_token).and_return(confirmation_token)
+ allow(notify_client).to receive(:send_email).and_return(true)
+ allow(SecureRandom).to receive(:random_number).and_return(otp)
+ visit("/logs")
+ fill_in("user[email]", with: user.email)
+ fill_in("user[password]", with: user.password)
+ click_button("Sign in")
+ fill_in("code", with: otp)
+ click_button("Submit")
+ end
+
+ context "when I visit supported housing page" do
+ before do
+ visit("supported-housing")
+ end
+
+ it "shows list of links to schemes" do
+ schemes.each do |scheme|
+ expect(page).to have_link(scheme.service_name)
+ expect(page).to have_content(scheme.primary_client_group_display)
+ end
+ end
+
+ context "when I click to see individual scheme" do
+ before do
+ click_link(schemes.first.service_name)
+ end
+
+ it "shows me details about the selected scheme" do
+ expect(page).to have_content(schemes.first.code)
+ expect(page).to have_content(schemes.first.service_name)
+ expect(page).to have_content(schemes.first.sensitive_display)
+ expect(page).to have_content(schemes.first.scheme_type_display)
+ expect(page).to have_content(schemes.first.registered_under_care_act_display)
+ expect(page).to have_content(schemes.first.total_units)
+ expect(page).to have_content(schemes.first.primary_client_group_display)
+ expect(page).to have_content(schemes.first.secondary_client_group_display)
+ expect(page).to have_content(schemes.first.support_type_display)
+ expect(page).to have_content(schemes.first.intended_stay_display)
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/helpers/navigation_items_helper_spec.rb b/spec/helpers/navigation_items_helper_spec.rb
index 8aa02eb82..52ad582c5 100644
--- a/spec/helpers/navigation_items_helper_spec.rb
+++ b/spec/helpers/navigation_items_helper_spec.rb
@@ -67,6 +67,36 @@ RSpec.describe NavigationItemsHelper do
expect(primary_items("/account", current_user)).to eq(expected_navigation_items)
end
end
+
+ context "when the user is on the individual user's page" do
+ let(:expected_navigation_items) do
+ [
+ NavigationItemsHelper::NavigationItem.new("Logs", "/logs", false),
+ NavigationItemsHelper::NavigationItem.new("Supported housing", "/supported-housing", false),
+ NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", true),
+ NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
+ ]
+ end
+
+ it "returns navigation items with the users item set as current" do
+ expect(primary_items("/users/1", current_user)).to eq(expected_navigation_items)
+ end
+ end
+
+ context "when the user is on the individual scheme's page" do
+ let(:expected_navigation_items) do
+ [
+ NavigationItemsHelper::NavigationItem.new("Logs", "/logs", false),
+ NavigationItemsHelper::NavigationItem.new("Supported housing", "/supported-housing", true),
+ NavigationItemsHelper::NavigationItem.new("Users", "/organisations/#{current_user.organisation.id}/users", false),
+ NavigationItemsHelper::NavigationItem.new("About your organisation", organisation_path, false),
+ ]
+ end
+
+ it "returns navigation items with supported housing item set as current" do
+ expect(primary_items("/supported-housing/1", current_user)).to eq(expected_navigation_items)
+ end
+ end
end
context "when the user is a support user" do
@@ -132,6 +162,36 @@ RSpec.describe NavigationItemsHelper do
end
end
+ context "when the user is on the individual user's page" do
+ let(:expected_navigation_items) do
+ [
+ NavigationItemsHelper::NavigationItem.new("Organisations", "/organisations", false),
+ NavigationItemsHelper::NavigationItem.new("Users", "/users", true),
+ NavigationItemsHelper::NavigationItem.new("Logs", "/logs", false),
+ NavigationItemsHelper::NavigationItem.new("Supported housing", "/supported-housing", false),
+ ]
+ end
+
+ it "returns navigation items with the users item set as current" do
+ expect(primary_items("/users/1", current_user)).to eq(expected_navigation_items)
+ end
+ end
+
+ context "when the user is on the individual scheme's page" do
+ let(:expected_navigation_items) do
+ [
+ NavigationItemsHelper::NavigationItem.new("Organisations", "/organisations", false),
+ NavigationItemsHelper::NavigationItem.new("Users", "/users", false),
+ NavigationItemsHelper::NavigationItem.new("Logs", "/logs", false),
+ NavigationItemsHelper::NavigationItem.new("Supported housing", "/supported-housing", true),
+ ]
+ end
+
+ it "returns navigation items with supported housing item set as current" do
+ expect(primary_items("/supported-housing/1", current_user)).to eq(expected_navigation_items)
+ end
+ end
+
context "when the user is on the specific organisation's page" do
context "when the user is on organisation logs page" do
let(:required_sub_path) { "logs" }
diff --git a/spec/helpers/tab_nav_helper_spec.rb b/spec/helpers/tab_nav_helper_spec.rb
index b59bb5d05..ba2dd3174 100644
--- a/spec/helpers/tab_nav_helper_spec.rb
+++ b/spec/helpers/tab_nav_helper_spec.rb
@@ -3,6 +3,7 @@ require "rails_helper"
RSpec.describe TabNavHelper do
let(:organisation) { FactoryBot.create(:organisation) }
let(:user) { FactoryBot.build(:user, organisation:) }
+ let(:scheme) { FactoryBot.build(:scheme) }
describe "#user_cell" do
it "returns user link and email separated by a newline character" do
@@ -18,6 +19,13 @@ RSpec.describe TabNavHelper do
end
end
+ describe "#scheme_cell" do
+ it "returns the scheme link service name and primary user group separated by a newline character" do
+ expected_html = "#{scheme.service_name}\nScheme #{scheme.primary_client_group_display}"
+ expect(scheme_cell(scheme)).to match(expected_html)
+ end
+ end
+
describe "#tab_items" do
context "when user is a data_coordinator" do
let(:user) { FactoryBot.build(:user, :data_coordinator, organisation:) }
diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb
index 13e612c46..4d5c248d5 100644
--- a/spec/requests/schemes_controller_spec.rb
+++ b/spec/requests/schemes_controller_spec.rb
@@ -160,4 +160,90 @@ RSpec.describe SchemesController, type: :request do
end
end
end
+
+ describe "#show" do
+ let(:specific_scheme) { schemes.first }
+
+ context "when not signed in" do
+ it "redirects to the sign in page" do
+ get "/supported-housing/#{specific_scheme.id}"
+ expect(response).to redirect_to("/account/sign-in")
+ end
+ end
+
+ context "when signed in as a data provider user" do
+ let(:user) { FactoryBot.create(:user) }
+
+ before do
+ sign_in user
+ get "/supported-housing/#{specific_scheme.id}"
+ end
+
+ it "returns 401 unauthorized" do
+ request
+ expect(response).to have_http_status(:unauthorized)
+ end
+ end
+
+ context "when signed in as a data coordinator user" do
+ let(:user) { FactoryBot.create(:user, :data_coordinator) }
+ let!(:specific_scheme) { FactoryBot.create(:scheme, organisation: user.organisation) }
+
+ before do
+ sign_in user
+ end
+
+ it "has page heading" do
+ get "/supported-housing/#{specific_scheme.id}"
+ expect(page).to have_content(specific_scheme.code)
+ expect(page).to have_content(specific_scheme.service_name)
+ expect(page).to have_content(specific_scheme.organisation.name)
+ expect(page).to have_content(specific_scheme.sensitive_display)
+ expect(page).to have_content(specific_scheme.code)
+ expect(page).to have_content(specific_scheme.service_name)
+ expect(page).to have_content(specific_scheme.sensitive_display)
+ expect(page).to have_content(specific_scheme.scheme_type_display)
+ expect(page).to have_content(specific_scheme.registered_under_care_act_display)
+ expect(page).to have_content(specific_scheme.total_units)
+ expect(page).to have_content(specific_scheme.primary_client_group_display)
+ expect(page).to have_content(specific_scheme.secondary_client_group_display)
+ expect(page).to have_content(specific_scheme.support_type_display)
+ expect(page).to have_content(specific_scheme.intended_stay_display)
+ end
+
+ context "when coordinator attempts to see scheme belogning to a different organisation" do
+ let!(:specific_scheme) { FactoryBot.create(:scheme) }
+
+ it "returns 404 not found" do
+ get "/supported-housing/#{specific_scheme.id}"
+ expect(response).to have_http_status(:not_found)
+ end
+ end
+ end
+
+ context "when signed in as a support user" do
+ before do
+ allow(user).to receive(:need_two_factor_authentication?).and_return(false)
+ sign_in user
+ get "/supported-housing/#{specific_scheme.id}"
+ end
+
+ it "has page heading" do
+ expect(page).to have_content(specific_scheme.code)
+ expect(page).to have_content(specific_scheme.service_name)
+ expect(page).to have_content(specific_scheme.organisation.name)
+ expect(page).to have_content(specific_scheme.sensitive_display)
+ expect(page).to have_content(specific_scheme.code)
+ expect(page).to have_content(specific_scheme.service_name)
+ expect(page).to have_content(specific_scheme.sensitive_display)
+ expect(page).to have_content(specific_scheme.scheme_type_display)
+ expect(page).to have_content(specific_scheme.registered_under_care_act_display)
+ expect(page).to have_content(specific_scheme.total_units)
+ expect(page).to have_content(specific_scheme.primary_client_group_display)
+ expect(page).to have_content(specific_scheme.secondary_client_group_display)
+ expect(page).to have_content(specific_scheme.support_type_display)
+ expect(page).to have_content(specific_scheme.intended_stay_display)
+ end
+ end
+ end
end