Browse Source

CLDC-1382: Add location and search to scheme locations (#756)

* Add search

* Add "Add location" button

* Add confirmed flag to schemes

* Show location tab is location is being added to an existing scheme

* Switch button text when scheme exists already

* Remove change links for confirmed schemes

* Fix spec after rebase

* added title showing search results and tests for it

Co-authored-by: JG <moarpheus@gmail.com>
pull/772/head
baarkerlounger 2 years ago committed by GitHub
parent
commit
610dad81a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      app/controllers/locations_controller.rb
  2. 6
      app/controllers/schemes_controller.rb
  3. 4
      app/models/location.rb
  4. 10
      app/views/locations/index.html.erb
  5. 31
      app/views/schemes/check_answers.html.erb
  6. 7
      db/migrate/20220719145718_add_confirmed_to_scheme.rb
  7. 1
      db/schema.rb
  8. 3
      db/seeds.rb
  9. 1
      spec/factories/scheme.rb
  10. 174
      spec/features/schemes_spec.rb
  11. 28
      spec/models/location_spec.rb
  12. 48
      spec/requests/locations_controller_spec.rb

16
app/controllers/locations_controller.rb

@ -6,9 +6,12 @@ class LocationsController < ApplicationController
before_action :find_scheme
before_action :authenticate_action!
include Modules::SearchFilter
def index
@pagy, @locations = pagy(@scheme.locations)
@pagy, @locations = pagy(filtered_collection(@scheme.locations, search_term))
@total_count = @scheme.locations.size
@searched = search_term.presence
end
def new
@ -19,7 +22,12 @@ class LocationsController < ApplicationController
if date_params_missing?(location_params) || valid_date_params?(location_params)
@location = Location.new(location_params)
if @location.save
location_params[:add_another_location] == "Yes" ? redirect_to(new_location_path(id: @scheme.id)) : redirect_to(scheme_check_answers_path(scheme_id: @scheme.id))
if location_params[:add_another_location] == "Yes"
redirect_to new_location_path(@scheme)
else
check_answers_path = @scheme.confirmed? ? scheme_check_answers_path(@scheme, anchor: "locations") : scheme_check_answers_path(@scheme)
redirect_to check_answers_path
end
else
render :new, status: :unprocessable_entity
end
@ -92,4 +100,8 @@ private
required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode]
required_params
end
def search_term
params["search"]
end
end

6
app/controllers/schemes_controller.rb

@ -47,7 +47,6 @@ class SchemesController < ApplicationController
page = params[:scheme][:page]
validation_errors scheme_params
if @scheme.errors.empty? && @scheme.update(scheme_params)
if check_answers
if confirm_secondary_page? page
@ -150,6 +149,8 @@ private
end
when "edit-name"
scheme_path(@scheme)
when "check-answers"
schemes_path(scheme_id: @scheme.id)
end
end
@ -166,7 +167,8 @@ private
:secondary_client_group,
:support_type,
:arrangement_type,
:intended_stay)
:intended_stay,
:confirmed)
full_params = required_params[:arrangement_type] == "D" && required_params[:owning_organisation_id].present? ? required_params.merge(managing_organisation_id: required_params[:owning_organisation_id]) : required_params

4
app/models/location.rb

@ -7,6 +7,10 @@ class Location < ApplicationRecord
attr_accessor :add_another_location
scope :search_by_postcode, ->(postcode) { where("postcode ILIKE ?", "%#{postcode.gsub(/\s+/, '')}%") }
scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }
scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) }
MOBILITY_TYPE = {
"Wheelchair-user standard": "W",
"Fitted with equipment and adaptations": "A",

10
app/views/locations/index.html.erb

@ -1,4 +1,5 @@
<% title = @scheme.service_name %>
<% item_label = format_label(@pagy.count, "location") %>
<% title = format_title(@searched, @scheme.service_name, current_user, item_label, @pagy.count, nil) %>
<% content_for :title, title %>
<% content_for :before_content do %>
@ -12,9 +13,13 @@
<%= render SubNavigationComponent.new(items: scheme_items(request.path, @scheme.id, "Locations")) %>
<%= render SearchComponent.new(current_user:, search_label: "Search by location name or postcode", value: @searched) %>
<%= govuk_section_break(visible: true, size: "m") %>
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %>
<strong><%= @scheme.locations.count %></strong> <%= @scheme.locations.count.eql?(1) ? "location" : "locations" %>
<%= render(SearchResultCaptionComponent.new(searched: @searched, count: @pagy.count, item_label:, total_count: @total_count, item: "locations", path: request.path)) %>
<% end %>
<%= table.head do |head| %>
<%= head.row do |row| %>
@ -47,5 +52,6 @@
<% end %>
<% end %>
<% end %>
<%= govuk_button_link_to "Add a location", new_location_path(id: @scheme.id), secondary: true %>
<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "locations" } %>

31
app/views/schemes/check_answers.html.erb

@ -11,66 +11,78 @@
<%= summary_list.row do |row| %>
<% row.key { attr[:name].to_s } %>
<% row.value { details_html(attr) } %>
<% unless @scheme.confirmed? && attr[:name] != "Name" %>
<% row.action(
text: "Change",
href: scheme_details_path(scheme_id: @scheme.id, check_answers: true),
href: scheme_details_path(@scheme, check_answers: true),
) %>
<% end %>
<% end %>
<% end %>
<% @scheme.check_support_services_provider_attributes.each do |attr| %>
<%= summary_list.row do |row| %>
<% row.key { attr[:name].to_s } %>
<% row.value { details_html(attr) } %>
<% unless @scheme.confirmed? %>
<% row.action(
text: "Change",
href: scheme_support_services_provider_path(scheme_id: @scheme.id, check_answers: true),
href: scheme_support_services_provider_path(@scheme, check_answers: true),
) %>
<% end %>
<% end %>
<% end %>
<% @scheme.check_primary_client_attributes.each do |attr| %>
<%= summary_list.row do |row| %>
<% row.key { attr[:name].to_s } %>
<% row.value { details_html(attr) } %>
<% unless @scheme.confirmed? %>
<% row.action(
text: "Change",
href: scheme_primary_client_group_path(scheme_id: @scheme.id, check_answers: true),
href: scheme_primary_client_group_path(@scheme, check_answers: true),
) %>
<% end %>
<% end %>
<% end %>
<% @scheme.check_secondary_client_confirmation_attributes.each do |attr| %>
<%= summary_list.row do |row| %>
<% row.key { attr[:name].to_s } %>
<% row.value { details_html(attr) } %>
<% unless @scheme.confirmed? %>
<% row.action(
text: "Change",
href: scheme_confirm_secondary_client_group_path(scheme_id: @scheme.id, check_answers: true),
href: scheme_confirm_secondary_client_group_path(@scheme, check_answers: true),
) %>
<% end %>
<% end %>
<% end %>
<% if @scheme.has_other_client_group == "Yes" %>
<% @scheme.check_secondary_client_attributes.each do |attr| %>
<%= summary_list.row do |row| %>
<% row.key { attr[:name].to_s } %>
<% row.value { details_html(attr) } %>
<% unless @scheme.confirmed? %>
<% row.action(
text: "Change",
href: scheme_secondary_client_group_path(scheme_id: @scheme.id, check_answers: true),
href: scheme_secondary_client_group_path(@scheme, check_answers: true),
) %>
<% end %>
<% end %>
<% end %>
<% end %>
<% @scheme.check_support_attributes.each do |attr| %>
<%= summary_list.row do |row| %>
<% row.key { attr[:name].to_s } %>
<% row.value { details_html(attr) } %>
<% unless @scheme.confirmed? %>
<% row.action(
text: "Change",
href: scheme_support_path(scheme_id: @scheme.id, check_answers: true),
href: scheme_support_path(@scheme, check_answers: true),
) %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% component.tab(label: "Locations") do %>
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %>
@ -113,4 +125,9 @@
</div>
</div>
<%= govuk_button_link_to "Create scheme", schemes_path(scheme_id: @scheme.id), html: { method: :get } %>
<%= form_for(@scheme, as: :scheme, method: :patch) do |f| %>
<%= f.hidden_field :page, value: "check-answers" %>
<%= f.hidden_field :confirmed, value: "true" %>
<% button_label = @scheme.confirmed? ? "Save" : "Create scheme" %>
<%= f.govuk_submit button_label %>
<% end %>

7
db/migrate/20220719145718_add_confirmed_to_scheme.rb

@ -0,0 +1,7 @@
class AddConfirmedToScheme < ActiveRecord::Migration[7.0]
def change
change_table :schemes, bulk: true do |t|
t.column :confirmed, :boolean
end
end
end

1
db/schema.rb

@ -320,6 +320,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_20_111635) do
t.string "old_id"
t.integer "old_visible_id"
t.integer "total_units"
t.boolean "confirmed"
t.index ["managing_organisation_id"], name: "index_schemes_on_managing_organisation_id"
t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id"
end

3
db/seeds.rb

@ -80,6 +80,7 @@ unless Rails.env.test?
primary_client_group: "O",
secondary_client_group: "H",
owning_organisation: org,
confirmed: true,
created_at: Time.zone.now,
)
@ -93,6 +94,7 @@ unless Rails.env.test?
primary_client_group: "D",
secondary_client_group: "E",
owning_organisation: org,
confirmed: true,
created_at: Time.zone.now,
)
@ -106,6 +108,7 @@ unless Rails.env.test?
primary_client_group: "G",
secondary_client_group: "R",
owning_organisation: dummy_org,
confirmed: true,
created_at: Time.zone.now,
)

1
spec/factories/scheme.rb

@ -10,6 +10,7 @@ FactoryBot.define do
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 }
owning_organisation { FactoryBot.create(:organisation) }
confirmed { true }
created_at { Time.zone.now }
trait :export do
sensitive { 1 }

174
spec/features/schemes_spec.rb

@ -202,6 +202,91 @@ RSpec.describe "Schemes scheme Features" do
end
end
end
context "when I search for a specific location" do
before do
click_link("Locations")
end
it "there is a search bar with a message and search button for locations" do
expect(page).to have_field("search")
expect(page).to have_content("Search by location name or postcode")
expect(page).to have_button("Search")
end
context "when I fill in search information and press the search button" do
let(:postcode_to_search) { "NW38RR" }
let(:location_name_to_search) { "search name location" }
let(:location_to_search) { FactoryBot.create(:location, postcode: postcode_to_search, name: location_name_to_search, scheme:) }
before do
fill_in("search", with: location_to_search.name)
click_button("Search")
end
it "displays scheme matching the location name" do
expect(page).to have_content(location_name_to_search)
end
context "when I want to clear results" do
it "there is link to clear the search results" do
expect(page).to have_link("Clear search")
end
it "displays all schemes after I clear the search results" do
click_link("Clear search")
Location.all.each do |location|
expect(page).to have_content(location.name)
end
end
end
end
end
context "when the user clicks add location" do
before do
click_link("Locations")
click_link("Add a location")
end
it "shows the new location form" do
expect(page).to have_content("Add a location to this scheme")
end
context "when the user completes the new location form" do
let(:location_name) { "Area 42" }
before do
fill_in "Postcode", with: "NW1L 5DP"
fill_in "Location name (optional)", with: location_name
fill_in "Total number of units at this location", with: 1
choose "Bungalow"
choose "location-mobility-type-none-field"
choose "location-add-another-location-no-field"
click_button "Save and continue"
end
it "shows the check answers page location tab" do
expect(page.current_url.split("/").last).to eq("check-answers#locations")
expect(page).to have_content(location_name)
end
it "has the correct action button text" do
expect(page).to have_button("Save")
expect(page).not_to have_button("Create scheme")
end
context "when you click to view the scheme details" do
before do
click_link("Scheme")
end
it "does not let you change details other than the name" do
assert_selector "a", text: "Change", count: 1
end
end
end
end
end
end
end
@ -457,7 +542,7 @@ RSpec.describe "Schemes scheme Features" do
before do
create_and_save_a_scheme
fill_in_and_save_location
click_link "Create scheme"
click_button "Create scheme"
end
it "adds scheme to the list of schemes" do
@ -465,7 +550,7 @@ RSpec.describe "Schemes scheme Features" do
expect(page).to have_content scheme.id_to_display
expect(page).to have_content scheme.service_name
expect(page).to have_content scheme.owning_organisation.name
expect(page).to have_content "#{scheme.owning_organisation.name} has been created."
expect(page).to have_content "#{scheme.service_name} has been created."
end
end
@ -641,6 +726,91 @@ RSpec.describe "Schemes scheme Features" do
end
end
end
context "when I search for a specific location" do
before do
click_link("Locations")
end
it "there is a search bar with a message and search button for locations" do
expect(page).to have_field("search")
expect(page).to have_content("Search by location name or postcode")
expect(page).to have_button("Search")
end
context "when I fill in search information and press the search button" do
let(:postcode_to_search) { "NW38RR" }
let(:location_name_to_search) { "search name location" }
let(:location_to_search) { FactoryBot.create(:location, postcode: postcode_to_search, name: location_name_to_search, scheme:) }
before do
fill_in("search", with: location_to_search.name)
click_button("Search")
end
it "displays scheme matching the location name" do
expect(page).to have_content(location_name_to_search)
end
context "when I want to clear results" do
it "there is link to clear the search results" do
expect(page).to have_link("Clear search")
end
it "displays all schemes after I clear the search results" do
click_link("Clear search")
Location.all.each do |location|
expect(page).to have_content(location.name)
end
end
end
end
end
context "when the user clicks add location" do
before do
click_link("Locations")
click_link("Add a location")
end
it "shows the new location form" do
expect(page).to have_content("Add a location to this scheme")
end
context "when the user completes the new location form" do
let(:location_name) { "Area 42" }
before do
fill_in "Postcode", with: "NW1L 5DP"
fill_in "Location name (optional)", with: location_name
fill_in "Total number of units at this location", with: 1
choose "Bungalow"
choose "location-mobility-type-none-field"
choose "location-add-another-location-no-field"
click_button "Save and continue"
end
it "shows the check answers page location tab" do
expect(page.current_url.split("/").last).to eq("check-answers#locations")
expect(page).to have_content(location_name)
end
it "has the correct action button text" do
expect(page).to have_button("Save")
expect(page).not_to have_button("Create scheme")
end
context "when you click to view the scheme details" do
before do
click_link("Scheme")
end
it "does not let you change details other than the name" do
assert_selector "a", text: "Change", count: 1
end
end
end
end
end
end
end

28
spec/models/location_spec.rb

@ -55,4 +55,32 @@ RSpec.describe Location, type: :model do
.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Type of unit Select the most common type of unit at this location")
end
end
describe "scopes" do
before do
FactoryBot.create(:location, name: "ABC", postcode: "NW18RR")
FactoryBot.create(:location, name: "XYZ", postcode: "SE16HJ")
end
context "when searching by name" do
it "returns case insensitive matching records" do
expect(described_class.search_by_name("abc").count).to eq(1)
expect(described_class.search_by_name("AbC").count).to eq(1)
end
end
context "when searching by postcode" do
it "returns case insensitive matching records" do
expect(described_class.search_by_postcode("se1 6hj").count).to eq(1)
expect(described_class.search_by_postcode("SE1 6HJ").count).to eq(1)
end
end
context "when searching by all searchable field" do
it "returns case insensitive matching records" do
expect(described_class.search_by("aBc").count).to eq(1)
expect(described_class.search_by("nw18rr").count).to eq(1)
end
end
end
end

48
spec/requests/locations_controller_spec.rb

@ -864,6 +864,30 @@ RSpec.describe LocationsController, type: :request do
end
end
end
context "when searching" do
let(:searched_location) { locations.first }
let(:search_param) { searched_location.name }
before do
get "/schemes/#{scheme.id}/locations?search=#{search_param}"
end
it "returns matching results" do
expect(page).to have_content(searched_location.name)
locations[1..].each do |location|
expect(page).not_to have_content(location.name)
end
end
it "updates the table caption" do
expect(page).to have_content("1 location found matching ‘#{search_param}")
end
it "has search in the title" do
expect(page).to have_title("#{scheme.service_name} (1 location matching ‘#{search_param}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
end
end
end
context "when signed in as a support user" do
@ -942,6 +966,30 @@ RSpec.describe LocationsController, type: :request do
end
end
end
context "when searching" do
let(:searched_location) { locations.first }
let(:search_param) { searched_location.name }
before do
get "/schemes/#{scheme.id}/locations?search=#{search_param}"
end
it "returns matching results" do
expect(page).to have_content(searched_location.name)
locations[1..].each do |location|
expect(page).not_to have_content(location.name)
end
end
it "updates the table caption" do
expect(page).to have_content("1 location found matching ‘#{search_param}")
end
it "has search in the title" do
expect(page).to have_title("#{scheme.service_name} (1 location matching ‘#{search_param}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
end
end
end
end

Loading…
Cancel
Save