diff --git a/app/frontend/styles/_data_box.scss b/app/frontend/styles/_data_box.scss new file mode 100644 index 000000000..0844ffa51 --- /dev/null +++ b/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"); +} diff --git a/app/frontend/styles/_document-list.scss b/app/frontend/styles/_document-list.scss index 47936a365..e8cef0625 100644 --- a/app/frontend/styles/_document-list.scss +++ b/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); } diff --git a/app/frontend/styles/application.scss b/app/frontend/styles/application.scss index 272310b5b..6309425de 100644 --- a/app/frontend/styles/application.scss +++ b/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"; diff --git a/app/helpers/collection_time_helper.rb b/app/helpers/collection_time_helper.rb index ea7601c70..6f8ef62fc 100644 --- a/app/helpers/collection_time_helper.rb +++ b/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 diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100644 index 000000000..38891466e --- /dev/null +++ b/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 diff --git a/app/models/form_handler.rb b/app/models/form_handler.rb index 83bfb0f8a..d9a3d4a35 100644 --- a/app/models/form_handler.rb +++ b/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 diff --git a/app/views/home/_data_box.html.erb b/app/views/home/_data_box.html.erb new file mode 100644 index 000000000..f1d04fb2f --- /dev/null +++ b/app/views/home/_data_box.html.erb @@ -0,0 +1,9 @@ +
+
+ <%= govuk_link_to data_count(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state govuk-link--no-underline" %> +
+ <%= govuk_link_to data_subheading(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state" %> +
+
+ <%= govuk_link_to view_all_text(type), view_all_path(type), class: "govuk-link--inverse" %> +
diff --git a/app/views/home/_upcoming_deadlines.html.erb b/app/views/home/_upcoming_deadlines.html.erb new file mode 100644 index 000000000..ffed67ca1 --- /dev/null +++ b/app/views/home/_upcoming_deadlines.html.erb @@ -0,0 +1,35 @@ +

Upcoming deadlines

+ +<% 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? %> +

End of year deadline - <%= formatted_deadline %>: 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) %>

+<% end %> + +<% current_quarter = quarter_for_date(date: Time.zone.now) %> +<% if current_quarter.present? %> +

<%= "#{current_quarter.quarter} - #{current_quarter.cutoff_date.strftime('%A')} #{current_quarter.cutoff_date.to_formatted_s(:govuk_date)}" %>: 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) %>.

+<% end %> + +<% if !FormHandler.instance.in_crossover_period? %> +

Try to complete your logs for each quarter by the cut-off date.

+

You can still create logs for a previous quarter after its cut-off date, as long as you complete them by the end-of-year deadline: <%= formatted_deadline %>.

+<% end %> + +<% if FormHandler.instance.in_crossover_period? %> +<% previous_lettings_form = FormHandler.instance.previous_lettings_form %> +

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.

+<% end %> + +<%= govuk_details(summary_text: "Quarterly cut-off dates for 2023 to 2024") do %> +

The 2023 to 2024 quarterly cut-off dates are:

+ +

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.

+

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.

+

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.

+<% end %> diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index e691b3e5b..87e058969 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -1 +1,56 @@ -

<%= "Welcome back, #{@current_user.name}" %>

+
+
+
+
+ <%= "Welcome back, #{@current_user.name}" %> +

<%= heading_for_user_role(@current_user) %>

+
+
+
+ <% if @current_user.support? || (@current_user.data_coordinator? && @current_user.sales_logs.present?) %> +
+
+ <%= render partial: "home/data_box", locals: { type: "lettings" } %> +
+
+ <%= render partial: "home/data_box", locals: { type: "sales" } %> +
+
+ <%= render partial: "home/data_box", locals: { type: "schemes" } %> +
+
+ <% else %> +
+
+ <%= render partial: "home/data_box", locals: { type: "lettings" } %> +
+ <% if @current_user.data_coordinator? %> +
+ <%= render partial: "home/data_box", locals: { type: "schemes" } %> +
+ <% elsif @current_user.sales_logs.present? %> +
+ <%= render partial: "home/data_box", locals: { type: "sales" } %> +
+ <% else %> +
+ <%= render partial: "home/data_box", locals: { type: "misc" } %> +
+ <% end %> +
+ <% end %> +
+
+
+
+
+
+
+
+ <%= render partial: "layouts/collection_resources" %> +
+ <%= render partial: "home/upcoming_deadlines" %> +
+
+
+
diff --git a/app/views/layouts/_collection_resources.html.erb b/app/views/layouts/_collection_resources.html.erb index e2d56e4a5..0c084596e 100644 --- a/app/views/layouts/_collection_resources.html.erb +++ b/app/views/layouts/_collection_resources.html.erb @@ -1,94 +1,59 @@ -
+<% if current_user %> +

Collection resources

+

<%= govuk_link_to "Guidance for submitting social housing lettings and sales data (CORE)", guidance_path %>

+<% else %>

Collection resources

-

For lettings starting during 1 April 2023 to 31 March 2024 and sales completing during the same period, use the 2023/24 forms.

- +<% end %> +

Use the 2023 to 2024 forms for lettings that start and sales that complete between 1 April 2023 and 31 March 2024.

+<%= 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 %> -

Lettings 2023/24

- <%= 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"), }, - ]) %> - -

Sales 2023/24

- <%= 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 %> -

Lettings 2022/23

- <%= 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"), - }, - ]) %> - -

Sales 2022/23

- <%= 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 %> -
+<% end %> diff --git a/app/views/organisations/show.html.erb b/app/views/organisations/show.html.erb index 9cfecda26..93b47fb03 100644 --- a/app/views/organisations/show.html.erb +++ b/app/views/organisations/show.html.erb @@ -41,8 +41,4 @@ <% end %> <%= render partial: "organisations/merged_organisation_details" %> - -
- <%= render partial: "layouts/collection_resources" %> -
diff --git a/app/views/start/index.html.erb b/app/views/start/index.html.erb index d6ec6d392..17e15d34e 100644 --- a/app/views/start/index.html.erb +++ b/app/views/start/index.html.erb @@ -16,14 +16,19 @@ href: start_path, ) %> +
+

Before you start

Use your account details to sign in.

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) %>.

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.

<%= govuk_link_to guidance_path do %>Guidance for submitting social housing lettings and sales data (CORE)<% end %>

+ -

+
+
+
<%= render partial: "layouts/collection_resources" %>
diff --git a/spec/features/home_page_spec.rb b/spec/features/home_page_spec.rb new file mode 100644 index 000000000..908961e33 --- /dev/null +++ b/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 diff --git a/spec/helpers/collection_time_helper_spec.rb b/spec/helpers/collection_time_helper_spec.rb index 3eef01b5e..859431c57 100644 --- a/spec/helpers/collection_time_helper_spec.rb +++ b/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 diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index 97665f8ca..68de93c51 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/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 diff --git a/spec/requests/start_controller_spec.rb b/spec/requests/start_controller_spec.rb index 1bfd2b4b9..2287280dc 100644 --- a/spec/requests/start_controller_spec.rb +++ b/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