Browse Source

CLDC-1307 Cust Support and Coordinators can view the details of a service (#656)

* added steps to view links to indiividual schemes

* testing there are links to the schemes not just names

* testing there are links to the schemes not just names -2

* added links failing due to no route

* looks per spec

* failing spec for tab helper

* added new attributes to the scheme

* added test for scheme.primary_client_group

* testing clicking to individual scheme

* empty template for show

* testing users not signed in

* testing I can see scheme details on the page

* converting int to strings in scheme model

* better view, seeds and factory

* highlight supported housing for support user

* simplified and extended sab nab logic

* rubocop and redundant check removed

* tests and code to make sure users are highlighted

* tests and code to make sure supported housing is highlighted

* full feature for support user to visit scheme show page

* extended features and filing feature when coordinator viewing scheme for a different org

* returning not found if coordinator user tries to see unrelated scheme

* rubocop

* fixed typos etc

* fixed types for schemes

* Trigger WF

* correct expectation
pull/664/head
J G 3 years ago committed by GitHub
parent
commit
ae377b9084
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      app/controllers/schemes_controller.rb
  2. 10
      app/helpers/navigation_items_helper.rb
  3. 5
      app/helpers/tab_nav_helper.rb
  4. 100
      app/models/scheme.rb
  5. 2
      app/views/schemes/_scheme_list.html.erb
  6. 17
      app/views/schemes/show.html.erb
  7. 2
      config/routes.rb
  8. 14
      db/migrate/20220613094847_add_missing_attributes_to_scheme.rb
  9. 10
      db/schema.rb
  10. 24
      db/seeds.rb
  11. 8
      spec/factories/scheme.rb
  12. 59
      spec/features/schemes_spec.rb
  13. 60
      spec/helpers/navigation_items_helper_spec.rb
  14. 8
      spec/helpers/tab_nav_helper_spec.rb
  15. 86
      spec/requests/schemes_controller_spec.rb

5
app/controllers/schemes_controller.rb

@ -14,6 +14,11 @@ class SchemesController < ApplicationController
@total_count = all_schemes.size @total_count = all_schemes.size
end 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 private
def search_term def search_term

10
app/helpers/navigation_items_helper.rb

@ -41,23 +41,23 @@ private
end end
def users_current?(path) def users_current?(path)
path == "/users" path == "/users" || path.include?("/users/")
end end
def supported_housing_current?(path) def supported_housing_current?(path)
path == "/supported-housing" path == "/supported-housing" || path.include?("/supported-housing/")
end end
def organisations_current?(path) 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 end
def subnav_supported_housing_path?(path) 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 end
def subnav_users_path?(path) def subnav_users_path?(path)
path.include?("/organisations") && path.include?("/users") (path.include?("/organisations") && path.include?("/users")) || path.include?("/users/")
end end
def subnav_logs_path?(path) def subnav_logs_path?(path)

5
app/helpers/tab_nav_helper.rb

@ -6,6 +6,11 @@ module TabNavHelper
[govuk_link_to(link_text, user), "<span class=\"govuk-visually-hidden\">User </span><span class=\"govuk-!-font-weight-regular app-!-colour-muted\">#{user.email}</span>"].join("\n") [govuk_link_to(link_text, user), "<span class=\"govuk-visually-hidden\">User </span><span class=\"govuk-!-font-weight-regular app-!-colour-muted\">#{user.email}</span>"].join("\n")
end end
def scheme_cell(scheme)
link_text = scheme.service_name.presence
[govuk_link_to(link_text, scheme), "<span class=\"govuk-visually-hidden\">Scheme </span><span class=\"govuk-!-font-weight-regular app-!-colour-muted\">#{scheme.primary_client_group_display}</span>"].join("\n")
end
def org_cell(user) def org_cell(user)
role = "<span class=\"app-!-colour-muted\">#{user.role.to_s.humanize}</span>" role = "<span class=\"app-!-colour-muted\">#{user.role.to_s.humanize}</span>"
[user.organisation.name, role].join("\n") [user.organisation.name, role].join("\n")

100
app/models/scheme.rb

@ -4,4 +4,104 @@ class Scheme < ApplicationRecord
scope :search_by_code, ->(code) { where("code ILIKE ?", "%#{code}%") } scope :search_by_code, ->(code) { where("code ILIKE ?", "%#{code}%") }
scope :search_by_service_name, ->(name) { where("service_name ILIKE ?", "%#{name}%") } 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)) } 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 end

2
app/views/schemes/_scheme_list.html.erb

@ -29,7 +29,7 @@
<%= table.body do |body| %> <%= table.body do |body| %>
<%= body.row do |row| %> <%= body.row do |row| %>
<% row.cell(text: scheme.code) %> <% 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.organisation.name) %>
<% row.cell(text: scheme.created_at.to_formatted_s(:govuk_date)) %> <% row.cell(text: scheme.created_at.to_formatted_s(:govuk_date)) %>
<% end %> <% end %>

17
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 } %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= 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 %>
</div>
</div>

2
config/routes.rb

@ -35,7 +35,7 @@ Rails.application.routes.draw do
get "edit/password", to: "users#edit_password" get "edit/password", to: "users#edit_password"
end end
resources :schemes, path: "/supported-housing", only: [:index] resources :schemes, path: "/supported-housing", only: %i[index show]
resources :users do resources :users do
member do member do

14
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

10
db/schema.rb

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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 # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" 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.bigint "organisation_id", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_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" t.index ["organisation_id"], name: "index_schemes_on_organisation_id"
end end

24
db/seeds.rb

@ -73,6 +73,14 @@ unless Rails.env.test?
Scheme.create!( Scheme.create!(
code: "S878", code: "S878",
service_name: "Beulahside Care", 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, organisation: org,
created_at: Time.zone.now, created_at: Time.zone.now,
) )
@ -80,6 +88,14 @@ unless Rails.env.test?
Scheme.create!( Scheme.create!(
code: "S312", code: "S312",
service_name: "Abdullahview Point", 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, organisation: org,
created_at: Time.zone.now, created_at: Time.zone.now,
) )
@ -87,6 +103,14 @@ unless Rails.env.test?
Scheme.create!( Scheme.create!(
code: "7XYZ", code: "7XYZ",
service_name: "Caspermouth Center", 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, organisation: dummy_org,
created_at: Time.zone.now, created_at: Time.zone.now,
) )

8
spec/factories/scheme.rb

@ -2,6 +2,14 @@ FactoryBot.define do
factory :scheme do factory :scheme do
code { Faker::Name.initials(number: 4) } code { Faker::Name.initials(number: 4) }
service_name { Faker::Name.name_with_middle } 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 organisation
created_at { Time.zone.now } created_at { Time.zone.now }
end end

59
spec/features/schemes_spec.rb

@ -2,7 +2,7 @@ require "rails_helper"
RSpec.describe "Supported housing scheme Features" do RSpec.describe "Supported housing scheme Features" do
context "when viewing list of schemes" 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(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) }
let!(:schemes) { FactoryBot.create_list(:scheme, 5) } let!(:schemes) { FactoryBot.create_list(:scheme, 5) }
let!(:scheme_to_search) { FactoryBot.create(:scheme) } let!(:scheme_to_search) { FactoryBot.create(:scheme) }
@ -75,4 +75,61 @@ RSpec.describe "Supported housing scheme Features" do
end end
end end
end end
context "when viewing individual scheme" do
context "when I am signed as a support user and there are schemes in the database" do
let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now) }
let!(:schemes) { FactoryBot.create_list(:scheme, 5) }
let(:notify_client) { instance_double(Notifications::Client) }
let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" }
let(:devise_notify_mailer) { DeviseNotifyMailer.new }
let(:otp) { "999111" }
before do
allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer)
allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client)
allow(Devise).to receive(:friendly_token).and_return(confirmation_token)
allow(notify_client).to receive(:send_email).and_return(true)
allow(SecureRandom).to receive(:random_number).and_return(otp)
visit("/logs")
fill_in("user[email]", with: user.email)
fill_in("user[password]", with: user.password)
click_button("Sign in")
fill_in("code", with: otp)
click_button("Submit")
end
context "when 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 end

60
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) expect(primary_items("/account", current_user)).to eq(expected_navigation_items)
end end
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 end
context "when the user is a support user" do context "when the user is a support user" do
@ -132,6 +162,36 @@ RSpec.describe NavigationItemsHelper do
end end
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 the specific organisation's page" do
context "when the user is on organisation logs page" do context "when the user is on organisation logs page" do
let(:required_sub_path) { "logs" } let(:required_sub_path) { "logs" }

8
spec/helpers/tab_nav_helper_spec.rb

@ -3,6 +3,7 @@ require "rails_helper"
RSpec.describe TabNavHelper do RSpec.describe TabNavHelper do
let(:organisation) { FactoryBot.create(:organisation) } let(:organisation) { FactoryBot.create(:organisation) }
let(:user) { FactoryBot.build(:user, organisation:) } let(:user) { FactoryBot.build(:user, organisation:) }
let(:scheme) { FactoryBot.build(:scheme) }
describe "#user_cell" do describe "#user_cell" do
it "returns user link and email separated by a newline character" do it "returns user link and email separated by a newline character" do
@ -18,6 +19,13 @@ RSpec.describe TabNavHelper do
end end
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 = "<a class=\"govuk-link\" href=\"/supported-housing\">#{scheme.service_name}</a>\n<span class=\"govuk-visually-hidden\">Scheme </span><span class=\"govuk-!-font-weight-regular app-!-colour-muted\">#{scheme.primary_client_group_display}</span>"
expect(scheme_cell(scheme)).to match(expected_html)
end
end
describe "#tab_items" do describe "#tab_items" do
context "when user is a data_coordinator" do context "when user is a data_coordinator" do
let(:user) { FactoryBot.build(:user, :data_coordinator, organisation:) } let(:user) { FactoryBot.build(:user, :data_coordinator, organisation:) }

86
spec/requests/schemes_controller_spec.rb

@ -160,4 +160,90 @@ RSpec.describe SchemesController, type: :request do
end end
end 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 end

Loading…
Cancel
Save