Browse Source

Merge branch 'CLDC-3116-create-blank-homepage' into CLDC-2255-homepage-notifications

# Conflicts:
#	app/frontend/styles/application.scss
pull/2131/head
natdeanlewissoftwire 2 years ago
parent
commit
094ab9ea28
  1. 66
      app/frontend/styles/_data_box.scss
  2. 2
      app/frontend/styles/_document-list.scss
  3. 1
      app/frontend/styles/application.scss
  4. 20
      app/helpers/collection_time_helper.rb
  5. 71
      app/helpers/home_helper.rb
  6. 4
      app/models/form_handler.rb
  7. 9
      app/views/home/_data_box.html.erb
  8. 35
      app/views/home/_upcoming_deadlines.html.erb
  9. 57
      app/views/home/index.html.erb
  10. 115
      app/views/layouts/_collection_resources.html.erb
  11. 4
      app/views/organisations/show.html.erb
  12. 7
      app/views/start/index.html.erb
  13. 158
      spec/features/home_page_spec.rb
  14. 30
      spec/helpers/collection_time_helper_spec.rb
  15. 36
      spec/requests/organisations_controller_spec.rb
  16. 29
      spec/requests/start_controller_spec.rb

66
app/frontend/styles/_data_box.scss

@ -0,0 +1,66 @@
.app-data-box-group {
@include govuk-font($size: 19);
font-weight: bold;
white-space: nowrap;
}
@media (min-width: 54.0625em) {
.app-data-box-group-one-third {
display: flex;
justify-content: space-between;
column-gap: govuk-spacing(4);
width: 100%;
min-width: 733.33px;
}
}
@media (min-width: 54.0625em) {
.app-data-box-one-third {
width: 33.3333%;
float: left;
}
}
@media (min-width: 54.0625em) {
.app-data-box__underline {
min-width: 733.33px;
}
}
@media (min-width: 54.0625em) {
.app-data-box-group-one-half {
display: flex;
justify-content: space-between;
column-gap: govuk-spacing(4);
width: 100%;
min-width: 733.33px;
}
}
@media (min-width: 54.0625em) {
.app-data-box-one-half {
width: 50%;
float: left;
}
}
@media (min-width: 54.0625em) {
.app-data-box-one-half__underline {
min-width: 733.33px;
}
}
.app-data-box__upper {
@include govuk-responsive-margin(2, "bottom");
@include govuk-responsive-padding(4);
background-color: govuk-colour("light-grey");
color: govuk-colour("blue");
}
.app-data-box__lower {
@include govuk-responsive-margin(4, "bottom");
@include govuk-responsive-padding(4);
background-color: govuk-colour("blue");
}
.app-data-box__count {
font-size: 48px;
color: govuk-colour("blue");
}

2
app/frontend/styles/_document-list.scss

@ -12,7 +12,7 @@
}
.app-document-list__item-title {
@include govuk-font($size: 16, $weight: "bold");
@include govuk-font($size: 16);
margin: 0 0 govuk-spacing(1);
}

1
app/frontend/styles/application.scss

@ -25,6 +25,7 @@ $govuk-breakpoints: (
@import "accessible-autocomplete";
@import "button";
@import "card";
@import "data_box";
@import "delete-logs-table";
@import "document-list";
@import "errors";

20
app/helpers/collection_time_helper.rb

@ -45,4 +45,24 @@ module CollectionTimeHelper
def previous_collection_start_date
current_collection_start_date - 1.year
end
def quarter_for_date(date: Time.zone.now)
quarters = [
{ quarter: "Q3", cutoff_date: Time.zone.local(2024, 1, 12), start_date: Time.zone.local(2023, 10, 1), end_date: Time.zone.local(2023, 12, 31) },
{ quarter: "Q1", cutoff_date: Time.zone.local(2024, 7, 12), start_date: Time.zone.local(2024, 4, 1), end_date: Time.zone.local(2024, 6, 30) },
{ quarter: "Q2", cutoff_date: Time.zone.local(2024, 10, 11), start_date: Time.zone.local(2024, 7, 1), end_date: Time.zone.local(2024, 9, 30) },
{ quarter: "Q3", cutoff_date: Time.zone.local(2025, 1, 10), start_date: Time.zone.local(2024, 10, 1), end_date: Time.zone.local(2024, 12, 31) },
]
quarter = quarters.find { |q| date.between?(q[:start_date], q[:cutoff_date] + 1.day) }
return unless quarter
OpenStruct.new(
quarter: quarter[:quarter],
cutoff_date: quarter[:cutoff_date],
quarter_start_date: quarter[:start_date],
quarter_end_date: quarter[:end_date],
)
end
end

71
app/helpers/home_helper.rb

@ -0,0 +1,71 @@
module HomeHelper
def data_count(user, type)
if user.data_provider?
case type
when "lettings" then user.lettings_logs.in_progress.where(created_by: user).count
when "sales" then user.sales_logs.in_progress.where(created_by: user).count
when "misc" then user.lettings_logs.completed.where(created_by: user).count
end
else
case type
when "lettings" then user.lettings_logs.in_progress.count
when "sales" then user.sales_logs.in_progress.count
when "schemes" then user.schemes.incomplete.count
end
end
end
def heading_for_user_role(user)
ROLE_HEADINGS[user.role]
end
def data_subheading(user, type)
case type
when "schemes"
"Incomplete schemes"
when "misc"
"Your completed lettings"
else
"#{user.role == 'data_provider' ? :"Your " : nil}#{type} in progress".capitalize
end
end
def data_path(user, type)
if user.data_provider?
case type
when "lettings" then lettings_logs_path(status: [:in_progress], assigned_to: "you")
when "sales" then sales_logs_path(status: [:in_progress], assigned_to: "you")
when "misc" then lettings_logs_path(status: [:completed], assigned_to: "you")
end
else
case type
when "lettings" then lettings_logs_path(status: [:in_progress])
when "sales" then sales_logs_path(status: [:in_progress])
when "schemes" then schemes_path(status: [:incomplete])
end
end
end
def view_all_path(type)
case type
when "lettings" then clear_filters_path(filter_type: "lettings_logs")
when "sales" then clear_filters_path(filter_type: "sales_logs")
when "schemes" then clear_filters_path(filter_type: "schemes")
when "misc" then clear_filters_path(filter_type: "schemes")
end
end
def view_all_text(type)
if type == "misc"
"View all schemes"
else
"View all #{type}"
end
end
ROLE_HEADINGS = {
"data_provider" => "Complete your logs",
"data_coordinator" => "Manage your data",
"support" => "Manage all data",
}.freeze
end

4
app/models/form_handler.rb

@ -28,6 +28,10 @@ class FormHandler
forms["current_lettings"]
end
def previous_lettings_form
forms["previous_lettings"]
end
def current_sales_form
forms["current_sales"]
end

9
app/views/home/_data_box.html.erb

@ -0,0 +1,9 @@
<div class="app-data-box__upper">
<div class="app-data-box__count">
<%= govuk_link_to data_count(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state govuk-link--no-underline" %>
</div>
<%= govuk_link_to data_subheading(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state" %>
</div>
<div class="app-data-box__lower">
<%= govuk_link_to view_all_text(type), view_all_path(type), class: "govuk-link--inverse" %>
</div>

35
app/views/home/_upcoming_deadlines.html.erb

@ -0,0 +1,35 @@
<h1 class="govuk-heading-l">Upcoming deadlines</h1>
<% current_lettings_form = FormHandler.instance.in_crossover_period? ? FormHandler.instance.previous_lettings_form : FormHandler.instance.current_lettings_form %>
<% formatted_deadline = "#{current_lettings_form.submission_deadline.strftime('%A')} #{current_lettings_form.submission_deadline.to_formatted_s(:govuk_date)}" %>
<% if FormHandler.instance.in_crossover_period? %>
<p class="govuk-body govuk-body-m"><strong>End of year deadline - <%= formatted_deadline %>:</strong> Deadline to submit logs for tenancies starting between <%= collection_start_date(Time.zone.now).to_formatted_s(:govuk_date) %> to <%= collection_end_date(Time.zone.now).to_formatted_s(:govuk_date) %></p>
<% end %>
<% current_quarter = quarter_for_date(date: Time.zone.now) %>
<% if current_quarter.present? %>
<p class="govuk-body govuk-body-m"><strong><%= "#{current_quarter.quarter} - #{current_quarter.cutoff_date.strftime('%A')} #{current_quarter.cutoff_date.to_formatted_s(:govuk_date)}" %>:</strong> Quarterly cut off date for tenancies and sales starting between <%= current_quarter.quarter_start_date.to_formatted_s(:govuk_date) %> and <%= current_quarter.quarter_end_date.to_formatted_s(:govuk_date) %>.</p>
<% end %>
<% if !FormHandler.instance.in_crossover_period? %>
<p class="govuk-body govuk-body-m">Try to complete your logs for each quarter by the cut-off date.</p>
<p class="govuk-body govuk-body-m">You can still create logs for a previous quarter after its cut-off date, as long as you complete them by the <strong>end-of-year deadline: <%= formatted_deadline %>.</strong></p>
<% end %>
<% if FormHandler.instance.in_crossover_period? %>
<% previous_lettings_form = FormHandler.instance.previous_lettings_form %>
<p class="govuk-body govuk-body-m">Prioritise completing logs for the closing collection year. You must complete all <%= previous_lettings_form.start_date.year %> to <%= previous_lettings_form.submission_deadline.year %> logs must by the end-of-year deadline. You can still create <%= current_lettings_form.start_date.year %> to <%= current_lettings_form.submission_deadline.year %> logs for this quarter after the quarterly cut-off date.</p>
<% end %>
<%= govuk_details(summary_text: "Quarterly cut-off dates for 2023 to 2024") do %>
<p class="govuk-body govuk-body-m">The 2023 to 2024 quarterly cut-off dates are:</p>
<ul class="govuk-list govuk-list--bullet">
<li class="govuk-!-padding-bottom-4"><strong>Q1 - Friday 14 July 2023:</strong> Quarterly cut-off date for tenancies and sales starting between 1 April 2023 and 30 June 2023.</li>
<li class="govuk-!-padding-bottom-4"><strong>Q2 - Friday 13 October 2023:</strong> Quarterly cut-off date for tenancies and sales starting between 1 July 2023 and 30 September 2023.</li>
<li class="govuk-!-padding-bottom-4"><strong>Q3 - Friday 12 January 2024:</strong> Quarterly cut-off date for tenancies and sales starting between 1 October 2023 and 31 December 2023.</li>
<li class="govuk-!-padding-bottom-4"><strong>End of year deadline - Friday 7 June 2024:</strong> Deadline for tenancies and sales starting between 1 January 2024 and 31 March 2024, plus any late submissions for the 2023 to 2024 collection year.</li>
</ul>
<p class="govuk-body govuk-body-m">It is important that you meet these cut-off dates because we submit data to the Office for National Statistics quarterly, helping them create essential inflation statistics.</p>
<p class="govuk-body govuk-body-m">Meeting these cut-off dates also gives you more accurate data for your own analysis, and reduces the burden at the end of the year.</p>
<p class="govuk-body govuk-body-m">If you are not able to meet these quarterly dates, submit your logs as soon as you can so that they can be included in the annual data.</p>
<% end %>

57
app/views/home/index.html.erb

@ -1 +1,56 @@
<p class="govuk-body-l"><%= "Welcome back, #{@current_user.name}" %></p>
<div class="govuk-grid-row">
<div class="govuk-width-container">
<div class="govuk-grid-column-two-thirds">
<div class="govuk-grid-row govuk-!-margin-bottom-7">
<span class="govuk-body-l"><%= "Welcome back, #{@current_user.name}" %></span>
<h1 class="govuk-heading-l"><%= heading_for_user_role(@current_user) %></h1>
</div>
<div class="govuk-grid-row">
<div class="app-data-box-group">
<% if @current_user.support? || (@current_user.data_coordinator? && @current_user.sales_logs.present?) %>
<div class="app-data-box-group-one-third">
<div class="app-data-box-one-third">
<span><%= render partial: "home/data_box", locals: { type: "lettings" } %></span>
</div>
<div class="app-data-box-one-third">
<span><%= render partial: "home/data_box", locals: { type: "sales" } %></span>
</div>
<div class="app-data-box-one-third">
<span><%= render partial: "home/data_box", locals: { type: "schemes" } %></span>
</div>
</div>
<% else %>
<div class="app-data-box-group-one-half">
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "lettings" } %></span>
</div>
<% if @current_user.data_coordinator? %>
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "schemes" } %></span>
</div>
<% elsif @current_user.sales_logs.present? %>
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "sales" } %></span>
</div>
<% else %>
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "misc" } %></span>
</div>
<% end %>
</div>
<% end %>
</div>
</div>
<div class="govuk-grid-row">
<div class="app-data-box__underline">
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
</div>
</div>
<div class="govuk-grid-row">
<%= render partial: "layouts/collection_resources" %>
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<%= render partial: "home/upcoming_deadlines" %>
</div>
</div>
</div>
</div>

115
app/views/layouts/_collection_resources.html.erb

@ -1,94 +1,59 @@
<div class="app-card">
<% if current_user %>
<h1 class="govuk-heading-l">Collection resources</h1>
<p class="govuk-body"><strong><%= govuk_link_to "Guidance for submitting social housing lettings and sales data (CORE)", guidance_path %></strong></p>
<% else %>
<h2 class="govuk-heading-m">Collection resources</h2>
<p class="govuk-body-s">For lettings starting during 1 April 2023 to 31 March 2024 and sales completing during the same period, use the 2023/24 forms.</p>
<% end %>
<p class="govuk-body">Use the 2023 to 2024 forms for lettings that start and sales that complete between 1 April 2023 and 31 March 2024.</p>
<%= govuk_tabs(title: "Collection resources") do |c| %>
<% if FormHandler.instance.lettings_form_for_start_year(2023) && FormHandler.instance.lettings_form_for_start_year(2023).edit_end_date > Time.zone.today %>
<h3 class="govuk-heading-s">Lettings 2023/24</h3>
<%= render DocumentListComponent.new(items: [
<% c.with_tab(label: "Lettings 2023/24") do %>
<%= render DocumentListComponent.new(items: [
{
name: "Lettings log for tenants (2023/24)",
name: "Download the lettings log for tenants (2023 to 2024)",
href: download_23_24_lettings_form_path,
metadata: file_type_size_and_pages("2023_24_lettings_paper_form.pdf", number_of_pages: 8),
},
{
name: "Lettings bulk upload template (2023/24) – New question ordering",
name: "Download the lettings bulk upload template (2023 to 2024) – New question ordering",
href: download_23_24_lettings_bulk_upload_template_path,
metadata: file_type_size_and_pages("bulk-upload-lettings-template-2023-24.xlsx"),
},
{
name: "Lettings bulk upload template (2023/24)",
name: "Download the lettings bulk upload template (2023 to 2024) – Legacy version",
href: download_23_24_lettings_bulk_upload_legacy_template_path,
metadata: file_type_size_and_pages("bulk-upload-lettings-legacy-template-2023-24.xlsx"),
},
{
name: "Lettings bulk upload specification (2023/24)",
name: "Download the lettings bulk upload specification (2023 to 2024)",
href: download_23_24_lettings_bulk_upload_specification_path,
metadata: file_type_size_and_pages("bulk-upload-lettings-specification-2023-24.xlsx"),
},
]) %>
<h3 class="govuk-heading-s">Sales 2023/24</h3>
<%= render DocumentListComponent.new(items: [
{
name: "Sales log for buyers (2023/24)",
href: download_23_24_sales_form_path,
metadata: file_type_size_and_pages("2023_24_sales_paper_form.pdf", number_of_pages: 8),
},
{
name: "Sales bulk upload template (2023/24) – New question ordering",
href: download_23_24_sales_bulk_upload_template_path,
metadata: file_type_size_and_pages("bulk-upload-sales-template-2023-24.xlsx"),
},
{
name: "Sales bulk upload template (2023/24)",
href: download_23_24_sales_bulk_upload_legacy_template_path,
metadata: file_type_size_and_pages("bulk-upload-sales-legacy-template-2023-24.xlsx"),
},
{
name: "Sales bulk upload specification (2023/24)",
href: download_23_24_sales_bulk_upload_specification_path,
metadata: file_type_size_and_pages("bulk-upload-sales-specification-2023-24.xlsx"),
},
]) %>
<% end %>
<% if FormHandler.instance.lettings_form_for_start_year(2022) && FormHandler.instance.lettings_form_for_start_year(2022).edit_end_date > Time.zone.today %>
<h3 class="govuk-heading-s">Lettings 2022/23</h3>
<%= render DocumentListComponent.new(items: [
{
name: "Lettings log for tenants (2022/23)",
href: download_22_23_lettings_form_path,
metadata: file_type_size_and_pages("2022_23_lettings_paper_form.pdf", number_of_pages: 4),
},
{
name: "Lettings bulk upload template (2022/23)",
href: download_22_23_lettings_bulk_upload_template_path,
metadata: file_type_size_and_pages("bulk-upload-lettings-template-2022-23.xlsx"),
},
{
name: "Lettings bulk upload specification (2022/23)",
href: download_22_23_lettings_bulk_upload_specification_path,
metadata: file_type_size_and_pages("bulk-upload-lettings-specification-2022-23.xlsx"),
},
]) %>
<h3 class="govuk-heading-s">Sales 2022/23</h3>
<%= render DocumentListComponent.new(items: [
{
name: "Sales log for buyers (2022/23)",
href: download_22_23_sales_form_path,
metadata: file_type_size_and_pages("2022_23_sales_paper_form.pdf", number_of_pages: 5),
},
{
name: "Sales bulk upload template (2022/23)",
href: download_22_23_sales_bulk_upload_template_path,
metadata: file_type_size_and_pages("bulk-upload-sales-template-2022-23.xlsx"),
},
{
name: "Sales bulk upload specification (2022/23)",
href: download_22_23_sales_bulk_upload_specification_path,
metadata: file_type_size_and_pages("bulk-upload-sales-template-2022-23.xlsx"),
},
]) %>
]) %>
<% end %>
<% c.with_tab(label: "Sales 2023/24") do %>
<%= render DocumentListComponent.new(items: [
{
name: "Download the sales log for buyers (2023 to 2024)",
href: download_23_24_sales_form_path,
metadata: file_type_size_and_pages("2023_24_sales_paper_form.pdf", number_of_pages: 8),
},
{
name: "Download the sales bulk upload template (2023 to 2024) – New question ordering",
href: download_23_24_sales_bulk_upload_template_path,
metadata: file_type_size_and_pages("bulk-upload-sales-template-2023-24.xlsx"),
},
{
name: "Download the sales bulk upload template (2023 to 2024) – Legacy version",
href: download_23_24_sales_bulk_upload_legacy_template_path,
metadata: file_type_size_and_pages("bulk-upload-sales-legacy-template-2023-24.xlsx"),
},
{
name: "Download the sales bulk upload specification (2023 to 2024)",
href: download_23_24_sales_bulk_upload_specification_path,
metadata: file_type_size_and_pages("bulk-upload-sales-specification-2023-24.xlsx"),
},
]) %>
<% end %>
<% end %>
</div>
<% end %>

4
app/views/organisations/show.html.erb

@ -41,8 +41,4 @@
<% end %>
<%= render partial: "organisations/merged_organisation_details" %>
</div>
<div class="govuk-grid-column-one-third-from-desktop">
<%= render partial: "layouts/collection_resources" %>
</div>
</div>

7
app/views/start/index.html.erb

@ -16,14 +16,19 @@
href: start_path,
) %>
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<h2 class="govuk-heading-m">Before you start</h2>
<p class="govuk-body">Use your account details to sign in.</p>
<p class="govuk-body">If you need to set up a new account, speak to your organisation’s CORE data coordinator. If you don’t know who that is, <%= govuk_link_to("contact the helpdesk", GlobalConstants::HELPDESK_URL) %>.</p>
<p class="govuk-body">You can <%= govuk_mail_to("dluhc.digital-services@levellingup.gov.uk", "request an account", subject: "CORE: Request a new account") %> if your organisation doesn’t have one.</p>
<p class="govuk-body"><strong><%= govuk_link_to guidance_path do %>Guidance for submitting social housing lettings and sales data (CORE)<% end %></strong><p>
</div>
</div>
<div class="govuk-grid-column-one-third-from-desktop">
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= render partial: "layouts/collection_resources" %>
</div>
</div>

158
spec/features/home_page_spec.rb

@ -0,0 +1,158 @@
require "rails_helper"
require_relative "form/helpers"
RSpec.describe "Home Page Features" do
include Helpers
context "when the user is a data provider" do
let(:user) { FactoryBot.create(:user, name: "Provider") }
before do
create_list(:lettings_log, 6, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 2, :in_progress, owning_organisation: user.organisation)
create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 2, :completed)
sign_in user
visit("/")
end
it "displays the correct welcome text" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back, Provider")
expect(page).to have_content("Complete your logs")
end
context "when their organisation has submitted sales logs" do
before do
create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:sales_log, 3, :completed, owning_organisation: user.organisation, created_by: user)
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-half")
expect(data_boxes.count).to eq(2)
expect(data_boxes[0].all("a").map(&:text)).to eq(["6", "Your lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress], assigned_to: "you"), lettings_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["5", "Your sales in progress", "View all sales"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress], assigned_to: "you"), sales_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "sales_logs")])
end
end
context "when their organisation has never submitted sales logs" do
before do
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-half")
expect(data_boxes.count).to eq(2)
expect(data_boxes[0].all("a").map(&:text)).to eq(["6", "Your lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress], assigned_to: "you"), lettings_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["4", "Your completed lettings", "View all schemes"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:completed], assigned_to: "you"), lettings_logs_path(status: [:completed], assigned_to: "you"), clear_filters_path(filter_type: "schemes")])
end
end
end
context "when the user is a data coordinator" do
before do
create_list(:lettings_log, 6, :in_progress, owning_organisation: user.organisation)
create_list(:lettings_log, 2, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation)
create_list(:lettings_log, 2, :completed)
create_list(:scheme, 1, :incomplete, owning_organisation: user.organisation)
sign_in user
visit("/")
end
let(:user) { FactoryBot.create(:user, :data_coordinator, name: "Coordinator") }
it "displays the correct welcome text" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back, Coordinator")
expect(page).to have_content("Manage your data")
end
context "when their organisation has submitted sales logs" do
before do
create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation)
create_list(:sales_log, 3, :completed, owning_organisation: user.organisation)
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-third")
expect(data_boxes.count).to eq(3)
expect(data_boxes[0].all("a").map(&:text)).to eq(["8", "Lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["5", "Sales in progress", "View all sales"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress]), sales_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "sales_logs")])
expect(data_boxes[2].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"])
expect(data_boxes[2].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")])
end
end
context "when their organisation has never submitted sales logs" do
before do
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-half")
expect(data_boxes.count).to eq(2)
expect(data_boxes[0].all("a").map(&:text)).to eq(["8", "Lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")])
end
end
end
context "when the user is a support user" do
let(:support_user) { FactoryBot.create(:user, :support, name: "Support") }
let(:notify_client) { instance_double(Notifications::Client) }
let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" }
let(:devise_notify_mailer) { DeviseNotifyMailer.new }
let(:otp) { "999111" }
before do
create_list(:lettings_log, 2, :in_progress)
create_list(:lettings_log, 1, :completed)
create_list(:sales_log, 3, :in_progress)
create_list(:sales_log, 1, :completed)
create_list(:scheme, 1, :incomplete)
completed_scheme = create(:scheme)
create(:location, scheme: completed_scheme)
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("/lettings-logs")
fill_in("user[email]", with: support_user.email)
fill_in("user[password]", with: support_user.password)
click_button("Sign in")
fill_in("code", with: otp)
click_button("Submit")
visit("/")
end
it "displays the correct welcome text" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back, Support")
expect(page).to have_content("Manage all data")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-third")
expect(data_boxes.count).to eq(3)
expect(data_boxes[0].all("a").map(&:text)).to eq(["2", "Lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["3", "Sales in progress", "View all sales"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress]), sales_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "sales_logs")])
expect(data_boxes[2].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"])
expect(data_boxes[2].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")])
end
end
end

30
spec/helpers/collection_time_helper_spec.rb

@ -109,4 +109,34 @@ RSpec.describe CollectionTimeHelper do
end
end
end
describe "#quarter_for_date" do
it "returns correct cutoff date for curent quarter" do
quarter = quarter_for_date(date: Time.zone.local(2023, 10, 1))
expect(quarter.cutoff_date).to eq(Time.zone.local(2024, 1, 12))
expect(quarter.quarter_start_date).to eq(Time.zone.local(2023, 10, 1))
expect(quarter.quarter_end_date).to eq(Time.zone.local(2023, 12, 31))
end
it "returns correct cutoff date for the first quarter of 2024/25" do
quarter = quarter_for_date(date: Time.zone.local(2024, 4, 1))
expect(quarter.cutoff_date).to eq(Time.zone.local(2024, 7, 12))
expect(quarter.quarter_start_date).to eq(Time.zone.local(2024, 4, 1))
expect(quarter.quarter_end_date).to eq(Time.zone.local(2024, 6, 30))
end
it "returns correct cutoff date for the second quarter of 2024/25" do
quarter = quarter_for_date(date: Time.zone.local(2024, 9, 30))
expect(quarter.cutoff_date).to eq(Time.zone.local(2024, 10, 11))
expect(quarter.quarter_start_date).to eq(Time.zone.local(2024, 7, 1))
expect(quarter.quarter_end_date).to eq(Time.zone.local(2024, 9, 30))
end
it "returns correct cutoff date for the third quarter of 2024/25" do
quarter = quarter_for_date(date: Time.zone.local(2024, 10, 25))
expect(quarter.cutoff_date).to eq(Time.zone.local(2025, 1, 10))
expect(quarter.quarter_start_date).to eq(Time.zone.local(2024, 10, 1))
expect(quarter.quarter_end_date).to eq(Time.zone.local(2024, 12, 31))
end
end
end

36
spec/requests/organisations_controller_spec.rb

@ -310,42 +310,6 @@ RSpec.describe OrganisationsController, type: :request do
it "redirects to details" do
expect(response).to have_http_status(:redirect)
end
context "and 2022 collection window is open" do
let(:set_time) { allow(Time).to receive(:now).and_return(Time.zone.local(2023, 1, 1)) }
it "displays correct resources for 2022/23 and 2023/24 collection years" do
follow_redirect!
expect(page).to have_content("Lettings 2023/24")
expect(page).to have_content("Sales 2023/24")
expect(page).to have_content("Lettings 2022/23")
expect(page).to have_content("Sales 2022/23")
end
end
context "and 2022 collection window is closed for editing" do
let(:set_time) { allow(Time).to receive(:now).and_return(Time.zone.local(2024, 1, 1)) }
it "displays correct resources for 2022/23 and 2023/24 collection years" do
follow_redirect!
expect(page).to have_content("Lettings 2023/24")
expect(page).to have_content("Sales 2023/24")
expect(page).not_to have_content("Lettings 2022/23")
expect(page).not_to have_content("Sales 2022/23")
end
end
context "and 2023 collection window is closed for editing" do
let(:set_time) { allow(Time).to receive(:now).and_return(Time.zone.local(2025, 1, 1)) }
it "displays correct resources for 2022/23 and 2023/24 collection years" do
follow_redirect!
expect(page).not_to have_content("Lettings 2023/24")
expect(page).not_to have_content("Sales 2023/24")
expect(page).not_to have_content("Lettings 2022/23")
expect(page).not_to have_content("Sales 2022/23")
end
end
end
context "with an organisation that are not in scope for the user, i.e. that they do not belong to" do

29
spec/requests/start_controller_spec.rb

@ -31,6 +31,35 @@ RSpec.describe StartController, type: :request do
get "/", headers:, params: {}
expect(page).to have_content("Welcome back")
end
context "and 2023 collection window is open for editing" do
before do
allow(Time).to receive(:now).and_return(Time.zone.local(2024, 1, 1))
end
it "displays correct resources for 2022/23 and 2023/24 collection years" do
get "/", headers: headers, params: {}
expect(page).to have_content("Lettings 2023/24")
expect(page).to have_content("Sales 2023/24")
end
end
context "and 2023 collection window is closed for editing" do
before do
allow(Time).to receive(:now).and_return(Time.zone.local(2025, 1, 1))
end
it "displays correct resources for 2022/23 and 2023/24 collection years" do
get "/", headers: headers, params: {}
expect(page).not_to have_content("Lettings 2023/24")
expect(page).not_to have_content("Sales 2023/24")
end
end
it "shows guidance link" do
get "/", headers: headers, params: {}
expect(page).to have_content("Guidance for submitting social housing lettings and sales data (CORE)")
end
end
end

Loading…
Cancel
Save