Browse Source

Implement search for logs feature (#608)

pull/619/head
JG 3 years ago committed by baarkerlounger
parent
commit
112c4974a7
  1. 1
      Gemfile
  2. 3
      Gemfile.lock
  3. 4
      app/components/search_component.rb
  4. 17
      app/controllers/case_logs_controller.rb
  5. 12
      app/controllers/organisations_controller.rb
  6. 2
      app/frontend/styles/_table-group.scss
  7. 11
      app/models/case_log.rb
  8. 4
      app/views/case_logs/_log_list.html.erb
  9. 23
      app/views/case_logs/index.html.erb
  10. 2
      app/views/organisations/_organisation_list.html.erb
  11. 23
      app/views/organisations/logs.html.erb
  12. 2
      app/views/users/_user_list.html.erb
  13. 1
      config/environments/test.rb
  14. 18
      spec/factories/case_log.rb
  15. 2
      spec/features/form/saving_data_spec.rb
  16. 59
      spec/features/log_spec.rb
  17. 47
      spec/features/organisation_spec.rb
  18. 96
      spec/models/case_log_spec.rb
  19. 121
      spec/requests/case_logs_controller_spec.rb
  20. 108
      spec/requests/organisations_controller_spec.rb
  21. 4
      spec/services/exports/case_log_export_service_spec.rb

1
Gemfile

@ -87,6 +87,7 @@ group :test do
gem "capybara", require: false
gem "capybara-lockstep"
gem "factory_bot_rails"
gem "faker"
gem "rspec-rails", require: false
gem "selenium-webdriver", require: false
gem "simplecov", require: false

3
Gemfile.lock

@ -169,6 +169,8 @@ GEM
factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0)
railties (>= 5.0.0)
faker (2.21.0)
i18n (>= 1.8.11, < 2)
ffi (1.15.5)
globalid (1.0.0)
activesupport (>= 5.0)
@ -437,6 +439,7 @@ DEPENDENCIES
dotenv-rails
erb_lint
factory_bot_rails
faker
govuk-components
govuk_design_system_formbuilder
govuk_markdown

4
app/components/search_component.rb

@ -11,8 +11,12 @@ class SearchComponent < ViewComponent::Base
def path(current_user)
if request.path.include?("users")
user_path(current_user)
elsif request.path.include?("organisations") && request.path.include?("logs")
request.path
elsif request.path.include?("organisations")
organisations_path
elsif request.path.include?("logs")
case_logs_path
end
end

17
app/controllers/case_logs_controller.rb

@ -1,6 +1,7 @@
class CaseLogsController < ApplicationController
include Pagy::Backend
include Modules::CaseLogsFilter
include Modules::SearchFilter
skip_before_action :verify_authenticity_token, if: :json_api_request?
before_action :authenticate, if: :json_api_request?
@ -10,7 +11,17 @@ class CaseLogsController < ApplicationController
def index
set_session_filters
@pagy, @case_logs = pagy(filtered_case_logs(current_user.case_logs))
all_logs = current_user.case_logs
@pagy, @case_logs = pagy(
filtered_case_logs(
filtered_collection(
all_logs, search_term
),
),
)
@searched = search_term.presence
@total_count = all_logs.size
respond_to do |format|
format.html
@ -85,6 +96,10 @@ private
API_ACTIONS = %w[create show update destroy].freeze
def search_term
params["search"]
end
def json_api_request?
API_ACTIONS.include?(request["action"]) && request.format.json?
end

12
app/controllers/organisations_controller.rb

@ -55,7 +55,17 @@ class OrganisationsController < ApplicationController
set_session_filters(specific_org: true)
organisation_logs = CaseLog.all.where(owning_organisation_id: @organisation.id)
@pagy, @case_logs = pagy(filtered_case_logs(organisation_logs))
@pagy, @case_logs = pagy(
filtered_case_logs(
filtered_collection(
organisation_logs, search_term
),
),
)
@searched = search_term.presence
@total_count = organisation_logs.size
render "logs", layout: "application"
else
redirect_to(case_logs_path)

2
app/frontend/styles/_table-group.scss

@ -2,7 +2,7 @@
overflow-x: auto;
overflow-y: hidden;
margin: govuk-spacing(-3) govuk-spacing(-3) govuk-spacing(3);
padding: 0 govuk-spacing(3);
padding: govuk-spacing(3) govuk-spacing(3);
scrollbar-color: $govuk-text-colour govuk-colour("light-grey");
.govuk-table {

11
app/models/case_log.rb

@ -51,6 +51,17 @@ class CaseLog < ApplicationRecord
end
}
scope :filter_by_id, ->(id) { where(id:) }
scope :filter_by_tenant_code, ->(code) { where("lower(tenant_code) = ?", code.downcase) }
scope :filter_by_propcode, ->(code) { where("lower(propcode) = ?", code.downcase) }
scope :filter_by_postcode, ->(code) { where(postcode_full: code.upcase.gsub(/\s+/, "")) }
scope :search_by, lambda { |param|
filter_by_id(param)
.or(filter_by_tenant_code(param))
.or(filter_by_propcode(param))
.or(filter_by_postcode(param))
}
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze
OPTIONAL_FIELDS = %w[first_time_property_let_as_social_housing tenant_code propcode].freeze
RENT_TYPE_MAPPING = { 0 => 1, 1 => 2, 2 => 2, 3 => 3, 4 => 3, 5 => 3 }.freeze

4
app/views/case_logs/_log_list.html.erb

@ -2,7 +2,11 @@
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular], id: title.dasherize) do |caption| %>
<span class="govuk-!-margin-right-4">
<% if defined?(searched) && searched.present? %>
<strong><%= pagy.count %></strong> <%= item_label %> found matching ‘<%= searched %>’ of <strong><%= total_count %></strong> total <%= title.downcase %>. <%= govuk_link_to("Clear search", request.path) %>
<% else %>
<strong><%= pagy.count %></strong> total <%= title.downcase %>
<% end %>
</span>
<%= govuk_link_to "Download (CSV)", "/logs.csv", type: "text/csv" %>
<% end %>

23
app/views/case_logs/index.html.erb

@ -1,8 +1,17 @@
<% content_for :title, "Logs" %>
<% item_label = @pagy.count > 1 ? "logs" : "log" %>
<% if @searched.present? %>
<% title = "Logs (search results for ‘#{@searched}’#{@pagy.last > 1 ? ", page #{@pagy.page} of #{@pagy.last}" : ''}) - Submit social housing and sales data (CORE) - GOV.UK" %>
<% else %>
<% title = "Logs #{@pagy.last > 1 ? "(page #{@pagy.page} of #{@pagy.last}) " : ''}- Submit social housing and sales data (CORE) - GOV.UK" %>
<% end %>
<% content_for :title, title %>
<% content_for :tab_title do %>
<%= "Logs" %>
<% end %>
<h1 class="govuk-heading-l">
<%= content_for(:title) %>
</h1>
<div class="app-filter-layout" data-controller="filter-layout">
<div class="govuk-button-group app-filter-toggle">
<%= govuk_button_to "Create a new lettings log", case_logs_path %>
@ -10,10 +19,10 @@
</div>
<%= render partial: "log_filters" %>
<% if @case_logs.present? %>
<div class="app-filter-layout__content">
<%= render partial: "log_list", locals: { case_logs: @case_logs, title: "Logs", pagy: @pagy } %>
<%= render SearchComponent.new(current_user:, search_label: "Search by log ID, tenant code, property reference or postcode", value: @searched) %>
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<%= render partial: "log_list", locals: { case_logs: @case_logs, title: "Logs", pagy: @pagy, searched: @searched, item_label:, total_count: @total_count } %>
<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %>
</div>
<% end %>
</div>

2
app/views/organisations/_organisation_list.html.erb

@ -1,3 +1,4 @@
<section class="app-table-group" tabindex="0" aria-labelledby="<%= title.dasherize %>">
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %>
<% if searched.present? %>
@ -33,3 +34,4 @@
<% end %>
<% end %>
<% end %>
</section>

23
app/views/organisations/logs.html.erb

@ -1,9 +1,16 @@
<% content_for :title, "Logs" %>
<% item_label = @pagy.count > 1 ? "logs" : "log" %>
<h1 class="govuk-heading-l">
<span class="govuk-caption-l"><%= @organisation.name %></span>
<%= content_for(:title) %>
</h1>
<% if @searched.present? %>
<% title = "Logs (search results for ‘#{@searched}’#{@pagy.last > 1 ? ", page #{@pagy.page} of #{@pagy.last}" : ''}) - Submit social housing and sales data (CORE) - GOV.UK" %>
<% else %>
<% title = "Logs #{@pagy.last > 1 ? "(page #{@pagy.page} of #{@pagy.last}) " : ''}- Submit social housing and sales data (CORE) - GOV.UK" %>
<% end %>
<% content_for :title, title %>
<% content_for :tab_title do %>
<%= "Logs" %>
<% end %>
<%= render SubNavigationComponent.new(
items: secondary_items(request.path, @organisation.id),
@ -11,10 +18,10 @@
<div class="app-filter-layout" data-controller="filter-layout">
<%= render partial: "case_logs/log_filters" %>
<% if @case_logs.present? %>
<div class="app-filter-layout__content">
<%= render partial: "case_logs/log_list", locals: { case_logs: @case_logs, title: "Logs", pagy: @pagy } %>
<%= render SearchComponent.new(current_user:, search_label: "Search by log ID, tenant code, property reference or postcode", value: @searched) %>
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<%= render partial: "case_logs/log_list", locals: { case_logs: @case_logs, title: "Logs", pagy: @pagy, searched: @searched, item_label:, total_count: @total_count } %>
<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %>
</div>
<% end %>
</div>

2
app/views/users/_user_list.html.erb

@ -1,3 +1,4 @@
<section class="app-table-group" tabindex="0" aria-labelledby="<%= title.dasherize %>">
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %>
<span class="govuk-!-margin-right-4">
@ -52,3 +53,4 @@
<% end %>
<% end %>
<% end %>
</section>

1
config/environments/test.rb

@ -60,4 +60,5 @@ Rails.application.configure do
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
Faker::Config.locale = "en-GB"
end

18
spec/factories/case_log.rb

@ -11,9 +11,9 @@ FactoryBot.define do
end
trait :in_progress do
status { 1 }
tenant_code { "TH356" }
postcode_full { "PO5 3TE" }
ppostcode_full { "SW2 6HI" }
tenant_code { Faker::Name.initials(number: 10) }
postcode_full { Faker::Address.postcode }
ppostcode_full { Faker::Address.postcode }
age1 { 17 }
age2 { 19 }
end
@ -24,7 +24,7 @@ FactoryBot.define do
incfreq { 1 }
end
trait :conditional_section_complete do
tenant_code { "TH356" }
tenant_code { Faker::Name.initials(number: 10) }
age1 { 34 }
sex1 { "M" }
ethnic { 2 }
@ -34,7 +34,7 @@ FactoryBot.define do
end
trait :completed do
status { 2 }
tenant_code { "BZ737" }
tenant_code { Faker::Name.initials(number: 10) }
age1 { 35 }
sex1 { "F" }
ethnic { 2 }
@ -52,11 +52,11 @@ FactoryBot.define do
reservist { 0 }
illness { 1 }
preg_occ { 2 }
tenancy_code { "BZ757" }
tenancy_code { Faker::Name.initials(number: 10) }
startertenancy { 0 }
tenancylength { 5 }
tenancy { 1 }
ppostcode_full { "SE2 6RT" }
ppostcode_full { Faker::Address.postcode }
rsnvac { 6 }
unittype_gn { 7 }
beds { 3 }
@ -74,7 +74,7 @@ FactoryBot.define do
tcharge { 325 }
layear { 2 }
waityear { 1 }
postcode_full { "NW1 5TY" }
postcode_full { Faker::Address.postcode }
reasonpref { 1 }
cbl { 1 }
chr { 1 }
@ -112,7 +112,7 @@ FactoryBot.define do
needstype { 1 }
purchaser_code { 798_794 }
reason { 4 }
propcode { "123" }
propcode { Faker::Name.initials(number: 10) }
majorrepairs { 1 }
la { "E09000003" }
prevloc { "E07000105" }

2
spec/features/form/saving_data_spec.rb

@ -73,7 +73,7 @@ RSpec.describe "Form Saving Data" do
it "displays number answers in inputs if they are already saved" do
visit("/logs/#{id}/property-postcode")
expect(page).to have_field("case-log-postcode-full-field", with: "PO53TE")
expect(page).to have_field("case-log-postcode-full-field", with: case_log.postcode_full)
end
it "displays text answers in inputs if they are already saved" do

59
spec/features/log_spec.rb

@ -0,0 +1,59 @@
require "rails_helper"
RSpec.describe "Log Features" do
context "when searching for specific logs" do
context "when I am logged in and there are logs in the database" do
let(:user) { FactoryBot.create(:user, last_sign_in_at: Time.zone.now) }
let!(:log_to_search) { FactoryBot.create(:case_log, owning_organisation: user.organisation) }
let!(:same_organisation_log) { FactoryBot.create(:case_log, owning_organisation: user.organisation) }
let!(:another_organisation_log) { FactoryBot.create(:case_log) }
before do
visit("/logs")
fill_in("user[email]", with: user.email)
fill_in("user[password]", with: user.password)
click_button("Sign in")
end
it "displays the logs belonging to the same organisation" do
expect(page).to have_content(log_to_search.id)
expect(page).to have_content(same_organisation_log.id)
expect(page).not_to have_content(another_organisation_log.id)
end
context "when I search for a specific log" do
it "there is a search bar with a message and search button for logs" do
expect(page).to have_field("search")
expect(page).to have_content("Search by log ID, tenant code, property reference or postcode")
expect(page).to have_button("Search")
end
context "when I fill in search information and press the search button" do
before do
fill_in("search", with: log_to_search.id)
click_button("Search")
end
it "displays log matching the log ID" do
expect(page).to have_content(log_to_search.id)
expect(page).not_to have_content(same_organisation_log.id)
expect(page).not_to have_content(another_organisation_log.id)
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 the logs belonging to the same organisation after I clear the search result after I clear the search resultss" do
click_link("Clear search")
expect(page).to have_content(log_to_search.id)
expect(page).to have_content(same_organisation_log.id)
expect(page).not_to have_content(another_organisation_log.id)
end
end
end
end
end
end
end

47
spec/features/organisation_spec.rb

@ -84,12 +84,13 @@ RSpec.describe "User Features" do
context "when user is support user" do
context "when viewing logs for specific organisation" do
let(:user) { FactoryBot.create(:user, :support) }
let(:number_of_case_logs) { 4 }
let(:first_log) { organisation.case_logs.first }
let(:otp) { "999111" }
let!(:log_to_search) { FactoryBot.create(:case_log, owning_organisation: user.organisation, managing_organisation_id: organisation.id) }
let!(:other_logs) { FactoryBot.create_list(:case_log, 4, owning_organisation_id: organisation.id, managing_organisation_id: organisation.id) }
let(:number_of_case_logs) { CaseLog.count }
before do
FactoryBot.create_list(:case_log, number_of_case_logs, owning_organisation_id: organisation.id, managing_organisation_id: organisation.id)
first_log.update!(startdate: Time.utc(2022, 6, 2, 10, 36, 49))
allow(SecureRandom).to receive(:random_number).and_return(otp)
click_link("Sign out")
@ -99,6 +100,48 @@ RSpec.describe "User Features" do
visit("/organisations/#{org_id}/logs")
end
context "when searching for specific logs" do
it "displays the logs belonging to the same organisation" do
expect(page).to have_content(log_to_search.id)
other_logs.each do |log|
expect(page).to have_content(log.id)
end
end
context "when I search for a specific log" do
it "there is a search bar with a message and search button for logs" do
expect(page).to have_field("search")
expect(page).to have_content("Search by log ID, tenant code, property reference or postcode")
expect(page).to have_button("Search")
end
context "when I fill in search information and press the search button" do
before do
fill_in("search", with: log_to_search.id)
click_button("Search")
end
it "displays log matching the log ID" do
expect(page).to have_content(log_to_search.id)
other_logs.each do |log|
expect(page).not_to have_content(log.id)
end
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 the logs belonging to the same organisation after I clear the search result after I clear the search resultss" do
click_link("Clear search")
expect(page).to have_content(log_to_search.id)
end
end
end
end
end
it "can filter case logs" do
expect(page).to have_content("#{number_of_case_logs} total logs")
organisation.case_logs.map(&:id).each do |case_log_id|

96
spec/models/case_log_spec.rb

@ -1871,6 +1871,102 @@ RSpec.describe CaseLog do
FactoryBot.create(:case_log, startdate: Time.utc(2022, 6, 3))
end
context "when searching logs" do
let!(:case_log_to_search) { FactoryBot.create(:case_log, :completed) }
before do
FactoryBot.create_list(:case_log, 5, :completed)
end
describe "#filter_by_id" do
it "allows searching by a log ID" do
result = described_class.filter_by_id(case_log_to_search.id.to_s)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
end
describe "#filter_by_tenant_code" do
it "allows searching by a Tenant Code" do
result = described_class.filter_by_tenant_code(case_log_to_search.tenant_code)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
context "when tenant_code has lower case letters" do
let(:matching_tenant_code_lower_case) { case_log_to_search.tenant_code.downcase }
it "allows searching by a Tenant Code" do
result = described_class.filter_by_tenant_code(matching_tenant_code_lower_case)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
end
end
describe "#filter_by_propcode" do
it "allows searching by a Property Reference" do
result = described_class.filter_by_propcode(case_log_to_search.propcode)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
context "when propcode has lower case letters" do
let(:matching_propcode_lower_case) { case_log_to_search.propcode.downcase }
it "allows searching by a Property Reference" do
result = described_class.filter_by_propcode(matching_propcode_lower_case)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
end
end
describe "#filter_by_postcode" do
it "allows searching by a Property Postcode" do
result = described_class.filter_by_postcode(case_log_to_search.postcode_full)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
end
describe "#search_by" do
it "allows searching using ID" do
result = described_class.search_by(case_log_to_search.id.to_s)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
it "allows searching using tenancy code" do
result = described_class.search_by(case_log_to_search.tenant_code)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
it "allows searching by a Property Reference" do
result = described_class.search_by(case_log_to_search.propcode)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
it "allows searching by a Property Postcode" do
result = described_class.search_by(case_log_to_search.postcode_full)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
context "when postcode has spaces and lower case letters" do
let(:matching_postcode_lower_case_with_spaces) { case_log_to_search.postcode_full.downcase.chars.insert(3, " ").join }
it "allows searching by a Property Postcode" do
result = described_class.search_by(matching_postcode_lower_case_with_spaces)
expect(result.count).to eq(1)
expect(result.first.id).to eq case_log_to_search.id
end
end
end
end
context "when filtering by year" do
it "allows filtering on a single year" do
expect(described_class.filter_by_years(%w[2021]).count).to eq(2)

121
spec/requests/case_logs_controller_spec.rb

@ -184,6 +184,17 @@ RSpec.describe CaseLogsController, type: :request do
expect(page).to have_content("UA984")
end
context "when there are no logs in the database" do
before do
CaseLog.destroy_all
end
it "page has correct title" do
get "/logs", headers: headers, params: {}
expect(page).to have_title("Logs - Submit social housing and sales data (CORE) - GOV.UK")
end
end
context "when filtering" do
context "with status filter" do
let(:organisation_2) { FactoryBot.create(:organisation) }
@ -308,6 +319,110 @@ RSpec.describe CaseLogsController, type: :request do
expect(page).not_to have_content("Managing organisation")
end
context "when using a search query" do
let(:logs) { FactoryBot.create_list(:case_log, 3, :completed, owning_organisation: user.organisation) }
let(:log_to_search) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation) }
it "has search results in the title" do
get "/logs?search=#{log_to_search.id}", headers: headers, params: {}
expect(page).to have_content("Logs (search results for ‘#{log_to_search.id}’) - Submit social housing and sales data (CORE) - GOV.UK")
end
it "shows case logs matching the id" do
get "/logs?search=#{log_to_search.id}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
it "shows case logs matching the tenant code" do
get "/logs?search=#{log_to_search.tenant_code}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
it "shows case logs matching the property reference" do
get "/logs?search=#{log_to_search.propcode}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
it "shows case logs matching the property postcode" do
get "/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
context "when more than one results with matching postcode" do
let!(:matching_postcode_log) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation, postcode_full: log_to_search.postcode_full) }
it "displays all matching logs" do
get "/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
expect(page).to have_content(matching_postcode_log.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
end
context "when there are more than 1 page of search results" do
let(:logs) { FactoryBot.create_list(:case_log, 30, :completed, owning_organisation: user.organisation, postcode_full: "XX1 1YY") }
it "has title with pagination details for page 1" do
get "/logs?search=#{logs[0].postcode_full}", headers: headers, params: {}
expect(page).to have_content("Logs (search results for ‘#{logs[0].postcode_full}’, page 1 of 2) - Submit social housing and sales data (CORE) - GOV.UK")
end
it "has title with pagination details for page 2" do
get "/logs?search=#{logs[0].postcode_full}&page=2", headers: headers, params: {}
expect(page).to have_content("Logs (search results for ‘#{logs[0].postcode_full}’, page 2 of 2) - Submit social housing and sales data (CORE) - GOV.UK")
end
end
context "when search query doesn't match any logs" do
it "doesn't display any logs" do
get "/logs?search=foobar", headers:, params: {}
logs.each do |log|
expect(page).not_to have_content(log.id)
end
expect(page).not_to have_content(log_to_search.id)
end
end
context "when search query is empty" do
it "doesn't display any logs" do
get "/logs?search=", headers:, params: {}
logs.each do |log|
expect(page).not_to have_content(log.id)
end
expect(page).not_to have_content(log_to_search.id)
end
end
context "when search and filter is present" do
let(:matching_postcode) { log_to_search.postcode_full }
let(:matching_status) { "in_progress" }
let!(:log_matching_filter_and_search) { FactoryBot.create(:case_log, :in_progress, owning_organisation: user.organisation, postcode_full: matching_postcode) }
it "shows only logs matching both search and filters" do
get "/logs?search=#{matching_postcode}&status[]=#{matching_status}", headers: headers, params: {}
expect(page).to have_content(log_matching_filter_and_search.id)
expect(page).not_to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
end
end
context "when there are less than 20 logs" do
before do
get "/logs", headers:, params: {}
@ -348,7 +463,7 @@ RSpec.describe CaseLogsController, type: :request do
end
it "does not have pagination in the title" do
expect(page).to have_title("Logs")
expect(page).to have_title("Logs - Submit social housing and sales data (CORE) - GOV.UK")
end
it "shows the download csv link" do
@ -424,7 +539,7 @@ RSpec.describe CaseLogsController, type: :request do
end
it "has pagination in the title" do
expect(page).to have_title("Logs (page 1 of 2)")
expect(page).to have_title("Logs (page 1 of 2) - Submit social housing and sales data (CORE) - GOV.UK")
end
end
@ -449,7 +564,7 @@ RSpec.describe CaseLogsController, type: :request do
end
it "has pagination in the title" do
expect(page).to have_title("Logs (page 2 of 2)")
expect(page).to have_title("Logs (page 2 of 2) - Submit social housing and sales data (CORE) - GOV.UK")
end
end
end

108
spec/requests/organisations_controller_spec.rb

@ -379,10 +379,6 @@ RSpec.describe OrganisationsController, type: :request do
get "/organisations/#{organisation.id}/logs", headers:, params: {}
end
it "displays the name of the organisation in the header" do
expect(CGI.unescape_html(response.body)).to match("<span class=\"govuk-caption-l\">#{organisation.name}</span>")
end
it "only shows logs for that organisation" do
expect(page).to have_content("#{number_of_org1_case_logs} total logs")
organisation.case_logs.map(&:id).each do |case_log_id|
@ -407,6 +403,110 @@ RSpec.describe OrganisationsController, type: :request do
expect(page).to have_css(".app-sub-navigation")
expect(page).to have_content("About this organisation")
end
context "when using a search query" do
let(:logs) { FactoryBot.create_list(:case_log, 3, :completed, owning_organisation: user.organisation) }
let(:log_to_search) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation) }
it "has search results in the title" do
get "/organisations/#{organisation.id}/logs?search=#{log_to_search.id}", headers: headers, params: {}
expect(page).to have_content("Logs (search results for ‘#{log_to_search.id}’) - Submit social housing and sales data (CORE) - GOV.UK")
end
it "shows case logs matching the id" do
get "/organisations/#{organisation.id}/logs?search=#{log_to_search.id}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
it "shows case logs matching the tenant code" do
get "/organisations/#{organisation.id}/logs?search=#{log_to_search.tenant_code}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
it "shows case logs matching the property reference" do
get "/organisations/#{organisation.id}/logs?search=#{log_to_search.propcode}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
it "shows case logs matching the property postcode" do
get "/organisations/#{organisation.id}/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
context "when more than one results with matching postcode" do
let!(:matching_postcode_log) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation, postcode_full: log_to_search.postcode_full) }
it "displays all matching logs" do
get "/organisations/#{organisation.id}/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {}
expect(page).to have_content(log_to_search.id)
expect(page).to have_content(matching_postcode_log.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
end
context "when there are more than 1 page of search results" do
let(:logs) { FactoryBot.create_list(:case_log, 30, :completed, owning_organisation: user.organisation, postcode_full: "XX1 1YY") }
it "has title with pagination details for page 1" do
get "/organisations/#{organisation.id}/logs?search=#{logs[0].postcode_full}", headers: headers, params: {}
expect(page).to have_content("Logs (search results for ‘#{logs[0].postcode_full}’, page 1 of 2) - Submit social housing and sales data (CORE) - GOV.UK")
end
it "has title with pagination details for page 2" do
get "/organisations/#{organisation.id}/logs?search=#{logs[0].postcode_full}&page=2", headers: headers, params: {}
expect(page).to have_content("Logs (search results for ‘#{logs[0].postcode_full}’, page 2 of 2) - Submit social housing and sales data (CORE) - GOV.UK")
end
end
context "when search query doesn't match any logs" do
it "doesn't display any logs" do
get "/organisations/#{organisation.id}/logs?search=foobar", headers:, params: {}
logs.each do |log|
expect(page).not_to have_content(log.id)
end
expect(page).not_to have_content(log_to_search.id)
end
end
context "when search query is empty" do
it "doesn't display any logs" do
get "/organisations/#{organisation.id}/logs?search=", headers:, params: {}
logs.each do |log|
expect(page).not_to have_content(log.id)
end
expect(page).not_to have_content(log_to_search.id)
end
end
context "when search and filter is present" do
let(:matching_postcode) { log_to_search.postcode_full }
let(:matching_status) { "in_progress" }
let!(:log_matching_filter_and_search) { FactoryBot.create(:case_log, :in_progress, owning_organisation: user.organisation, postcode_full: matching_postcode) }
it "shows only logs matching both search and filters" do
get "/organisations/#{organisation.id}/logs?search=#{matching_postcode}&status[]=#{matching_status}", headers: headers, params: {}
expect(page).to have_content(log_matching_filter_and_search.id)
expect(page).not_to have_content(log_to_search.id)
logs.each do |log|
expect(page).not_to have_content(log.id)
end
end
end
end
end
context "when viewing a specific organisation details" do

4
spec/services/exports/case_log_export_service_spec.rb

@ -47,7 +47,7 @@ RSpec.describe Exports::CaseLogExportService do
end
context "and one case log is available for export" do
let!(:case_log) { FactoryBot.create(:case_log, :completed) }
let!(:case_log) { FactoryBot.create(:case_log, :completed, tenancy_code: "BZ757", propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenant_code: "BZ737") }
let(:expected_data_filename) { "core_2021_2022_jan_mar_f0001_inc0001_pt001.xml" }
it "generates a ZIP export file with the expected filename" do
@ -226,7 +226,7 @@ RSpec.describe Exports::CaseLogExportService do
let(:csv_export_file) { File.open("spec/fixtures/exports/case_logs.csv", "r:UTF-8") }
let(:expected_csv_filename) { "export_2022_05_01.csv" }
let(:case_log) { FactoryBot.create(:case_log, :completed) }
let(:case_log) { FactoryBot.create(:case_log, :completed, tenancy_code: "BZ757", propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenant_code: "BZ737") }
it "generates an CSV export file with the expected content" do
expected_content = replace_entity_ids(case_log, csv_export_file.read)

Loading…
Cancel
Save