Browse Source

create presenter class to hold all the db calls and data for showing the home page

plus tests, some changes to factoreis and helpers necessary
this should avoid an overly bloated controller method or calling the DB from a view helper
pull/2408/head
Arthur Campbell 10 months ago
parent
commit
10ef59ccbd
  1. 110
      app/presenters/homepage_presenter.rb
  2. 12
      spec/factories/lettings_log.rb
  3. 9
      spec/factories/sales_log.rb
  4. 4
      spec/factories/user.rb
  5. 309
      spec/presenters/homepage_presenter_spec.rb
  6. 3
      spec/request_helper.rb

110
app/presenters/homepage_presenter.rb

@ -0,0 +1,110 @@
class HomepagePresenter
include Rails.application.routes.url_helpers
attr_reader :current_year_in_progress_lettings_data, :current_year_completed_lettings_data, :current_year_in_progress_sales_data, :current_year_completed_sales_data, :last_year_in_progress_lettings_data, :last_year_completed_lettings_data, :last_year_in_progress_sales_data, :last_year_completed_sales_data, :incomplete_schemes_data
def initialize(user)
@user = user
@organisation_logs_sales = organisation_has_ever_logged_sales?
@in_crossover_period = FormHandler.instance.in_crossover_period?
@current_year = FormHandler.instance.current_lettings_form.start_date.year
@current_year_in_progress_lettings_data = data_box_data(:lettings, @current_year, :in_progress)
@current_year_completed_lettings_data = data_box_data(:lettings, @current_year, :completed)
@current_year_in_progress_sales_data = data_box_data(:sales, @current_year, :in_progress) if organisation_logs_sales?
@current_year_completed_sales_data = data_box_data(:sales, @current_year, :completed) if organisation_logs_sales?
@last_year = @current_year - 1
@last_year_in_progress_lettings_data = data_box_data(:lettings, @last_year, :in_progress) if in_crossover_period?
@last_year_completed_lettings_data = data_box_data(:lettings, @last_year, :completed)
@last_year_in_progress_sales_data = data_box_data(:sales, @last_year, :in_progress) if in_crossover_period? && organisation_logs_sales?
@last_year_completed_sales_data = data_box_data(:sales, @last_year, :completed) if organisation_logs_sales?
if display_schemes?
@incomplete_schemes_data = {
count: @user.schemes.incomplete.count,
text: data_box_text(type: :schemes, status: :incomplete),
path: schemes_path(status: [:incomplete], owning_organisation_select: "all"),
}
end
end
def title_text_for_user
if @user.support?
"Manage all data"
elsif @user.data_coordinator?
"Manage your organisation's logs"
else
"Manage logs assigned to you"
end
end
def organisation_logs_sales?
@organisation_logs_sales
end
def in_crossover_period?
@in_crossover_period
end
def subheading_for_current_year
subheading_from_year @current_year
end
def subheading_for_last_year
subheading = subheading_from_year @last_year
in_crossover_period? ? subheading : "#{subheading} (Closed collection year)"
end
def display_schemes?
!@user.data_provider?
end
private
def subheading_from_year(year)
return "AAAAH" if year.nil?
"#{year} to #{year + 1} Logs"
end
def data_box_data(type, year, status)
{
count: logs_count(type:, year:, status:),
text: data_box_text(type:, status:),
path: logs_link(type:, year:, status:),
}
end
def data_box_text(type:, status:)
text = [status, type]
text.reverse! if status == :in_progress
text.join(" ").humanize
end
def logs_link(type:, year:, status:)
params = {
status: [status],
years: [year],
assigned_to: @user.data_provider? ? "you" : "all",
owning_organisation_select: "all",
managing_organisation_select: "all",
}
case type
when :lettings then lettings_logs_path(params)
when :sales then sales_logs_path(params)
end
end
def logs_count(type:, year:, status:)
query = case type
when :lettings then @user.lettings_logs
when :sales then @user.sales_logs
end
query = query.where(created_by: @user) if @user.data_provider?
query.filter_by_year(year)
.where(status:)
.count
end
def organisation_has_ever_logged_sales?
@user.organisation.sales_logs.exists?
end
end

12
spec/factories/lettings_log.rb

@ -87,7 +87,7 @@ FactoryBot.define do
rsnvac { 6 } rsnvac { 6 }
unittype_gn { 7 } unittype_gn { 7 }
beds { 3 } beds { 3 }
voiddate { 2.days.ago } voiddate { startdate - 2.days }
offered { 2 } offered { 2 }
wchair { 1 } wchair { 1 }
earnings { 268 } earnings { 268 }
@ -154,7 +154,7 @@ FactoryBot.define do
hbrentshortfall { 1 } hbrentshortfall { 1 }
tshortfall { 12 } tshortfall { 12 }
property_relet { 0 } property_relet { 0 }
mrcdate { 1.day.ago } mrcdate { startdate - 1.day }
incref { 0 } incref { 0 }
armedforces { 1 } armedforces { 1 }
builtype { 1 } builtype { 1 }
@ -171,6 +171,14 @@ FactoryBot.define do
ppcodenk { 1 } ppcodenk { 1 }
tshortfall_known { 1 } tshortfall_known { 1 }
end end
trait :completed2024 do
completed
address_line1_input { address_line1 }
postcode_full_input { postcode_full }
nationality_all_group { 826 }
uprn { 1 }
uprn_selection { 1 }
end
trait :export do trait :export do
tenancycode { "987654" } tenancycode { "987654" }
ppostcode_full { "LE5 1QP" } ppostcode_full { "LE5 1QP" }

9
spec/factories/sales_log.rb

@ -154,6 +154,15 @@ FactoryBot.define do
buy2living { 3 } buy2living { 3 }
proplen_asked { 1 } proplen_asked { 1 }
end end
trait :completed2024 do
completed
address_line1_input { address_line1 }
postcode_full_input { postcode_full }
nationality_all_group { 826 }
nationality_all_buyer2_group { 826 }
uprn { 1 }
uprn_selection { 1 }
end
trait :with_uprn do trait :with_uprn do
uprn { rand(999_999_999_999).to_s } uprn { rand(999_999_999_999).to_s }
uprn_known { 1 } uprn_known { 1 }

4
spec/factories/user.rb

@ -1,9 +1,9 @@
FactoryBot.define do FactoryBot.define do
factory :user do factory :user do
sequence(:email) { |i| "test#{i}@example.com" } sequence(:email) { "test#{SecureRandom.hex}@example.com" }
name { "Danny Rojas" } name { "Danny Rojas" }
password { "pAssword1" } password { "pAssword1" }
organisation organisation { association :organisation }
role { "data_provider" } role { "data_provider" }
phone { "1234512345123" } phone { "1234512345123" }
trait :data_coordinator do trait :data_coordinator do

309
spec/presenters/homepage_presenter_spec.rb

@ -0,0 +1,309 @@
require "rails_helper"
RSpec.describe HomepagePresenter do
let(:organisation) { create(:organisation) }
let(:user) { create(:user, organisation:) }
let(:in_crossover_period) { true }
let(:presenter) { described_class.new(user) }
let(:date_this_year) { Time.zone.today }
let(:date_last_year) { Time.zone.today - 1.year }
let(:expected_count) { rand 1..10 }
before do
allow(FormHandler.instance).to receive(:in_crossover_period?).and_return(in_crossover_period)
end
context "when the user is support" do
let(:user) { create(:user, :support) }
it "sets the correct title" do
expect(presenter.title_text_for_user).to eq "Manage all data"
end
it "returns that schemes should be displayed" do
expect(presenter.display_schemes?).to be true
end
end
context "when the user is a data coordinator" do
let(:user) { create(:user, :data_coordinator) }
it "sets the correct title" do
expect(presenter.title_text_for_user).to eq "Manage your organisation's logs"
end
it "returns that schemes should be displayed" do
expect(presenter.display_schemes?).to be true
end
end
context "when the user is a data provider" do
let(:user) { create(:user, :data_provider) }
it "sets the correct title" do
expect(presenter.title_text_for_user).to eq "Manage logs assigned to you"
end
it "returns that schemes should not be displayed" do
expect(presenter.display_schemes?).to be false
end
end
context "when the user's organisation has never submitted sales logs" do
it "shows the user's organisation does not log sales" do
expect(presenter.organisation_logs_sales?).to be false
end
context "when in the crossover period" do
let(:in_crossover_period) { true }
it "leaves all sales related data as nil" do
sales_data = [
presenter.current_year_in_progress_sales_data,
presenter.current_year_completed_sales_data,
presenter.last_year_in_progress_sales_data,
presenter.last_year_completed_sales_data,
]
expect(sales_data).to all be nil
end
end
context "when not in the crossover period" do
let(:in_crossover_period) { false }
it "leaves all sales related data as nil" do
sales_data = [
presenter.current_year_in_progress_sales_data,
presenter.current_year_completed_sales_data,
presenter.last_year_in_progress_sales_data,
presenter.last_year_completed_sales_data,
]
expect(sales_data).to all be nil
end
end
end
context "when the user's organisation has submitted sales logs" do
before do
create(:sales_log, created_by: user)
end
it "shows the user's organisation logs sales" do
expect(presenter.organisation_logs_sales?).to be true
end
context "when in the crossover period" do
let(:in_crossover_period) { true }
it "populates all sales related data" do
sales_data = [
presenter.current_year_in_progress_sales_data,
presenter.current_year_completed_sales_data,
presenter.last_year_in_progress_sales_data,
presenter.last_year_completed_sales_data,
]
expect(sales_data).to all be_an_instance_of(Hash)
end
end
context "when not in the crossover period" do
let(:in_crossover_period) { false }
it "populates all relevant sales related data" do
sales_data = [
presenter.current_year_in_progress_sales_data,
presenter.current_year_completed_sales_data,
presenter.last_year_completed_sales_data,
]
expect(sales_data).to all be_an_instance_of(Hash)
end
it "does not populate data for last year's in progress logs" do
last_year_in_progress_data = [
presenter.last_year_in_progress_lettings_data,
presenter.last_year_in_progress_sales_data,
]
expect(last_year_in_progress_data).to all be nil
end
end
end
context "when in the crossover period" do
let(:in_crossover_period) { true }
it "returns that we are in the crossover period" do
expect(presenter.in_crossover_period?).to be true
end
end
context "when not in the crossover period" do
let(:in_crossover_period) { false }
it "returns that we are in the crossover period" do
expect(presenter.in_crossover_period?).to be false
end
end
context "when testing the data collected and exposed by the presenter" do
context "with lettings logs" do
let(:type) { :lettings_log }
context "with in progress status" do
let(:status) { :in_progress }
context "and the current year" do
let(:startdate) { date_this_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, status, created_by: user, startdate:)
data = presenter.current_year_in_progress_lettings_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Lettings in progress"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_this_year.year.to_s]
end
end
context "and the last year" do
let(:startdate) { date_last_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, status, created_by: user, startdate:)
data = presenter.last_year_in_progress_lettings_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Lettings in progress"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_last_year.year.to_s]
end
end
end
context "with completed status" do
let(:status) { :completed }
context "and the current year" do
let(:startdate) { date_this_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, :completed2024, created_by: user, startdate:)
data = presenter.current_year_completed_lettings_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Completed lettings"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_this_year.year.to_s]
end
end
context "and the last year" do
let(:startdate) { date_last_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, status, created_by: user, startdate:)
data = presenter.last_year_completed_lettings_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Completed lettings"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_last_year.year.to_s]
end
end
end
end
context "with sales logs" do
let(:type) { :sales_log }
context "with in progress status" do
let(:status) { :in_progress }
context "and the current year" do
let(:saledate) { date_this_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, status, created_by: user, saledate:)
data = presenter.current_year_in_progress_sales_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Sales in progress"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_this_year.year.to_s]
end
end
context "and the last year" do
let(:saledate) { date_last_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, status, created_by: user, saledate:)
data = presenter.last_year_in_progress_sales_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Sales in progress"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_last_year.year.to_s]
end
end
end
context "with completed status" do
let(:status) { :completed }
context "and the current year" do
let(:saledate) { date_this_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, :completed2024, created_by: user, saledate:)
data = presenter.current_year_completed_sales_data
binding.pry
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Completed sales"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_this_year.year.to_s]
end
end
context "and the last year" do
let(:saledate) { date_last_year }
it "exposes the correct data for the data box" do
create_list(type, expected_count, status, created_by: user, saledate:)
data = presenter.last_year_completed_sales_data
expect(data[:count]).to be expected_count
expect(data[:text]).to eq "Completed sales"
uri = URI.parse(data[:path])
expect(uri.path).to eq "/#{type.to_s.dasherize}s"
query_params = CGI.parse(uri.query)
expect(query_params["status[]"]).to eq [status.to_s]
expect(query_params["years[]"]).to eq [date_last_year.year.to_s]
end
end
end
end
end
end

3
spec/request_helper.rb

@ -83,6 +83,9 @@ module RequestHelper
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=1234567890123") WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=1234567890123")
.to_return(status: 404, body: "", headers: {}) .to_return(status: 404, body: "", headers: {})
WebMock.stub_request(:get, /api\.os\.uk/)
.to_return(status: 200, body: { results: [{ DPA: { MATCH: 0.9, BUILDING_NAME: "result address line 1", POST_TOWN: "result town or city", POSTCODE: "AA1 1AA", UPRN: "1" } }] }.to_json, headers: {})
end end
def self.real_http_requests def self.real_http_requests

Loading…
Cancel
Save