Skip to content

Commit

Permalink
Merge pull request #4844 from DFE-Digital/7851-performance-banner-2
Browse files Browse the repository at this point in the history
[7851] Show the performance banner
  • Loading branch information
defong authored Dec 4, 2024
2 parents c37b8e2 + 66def27 commit c5cd264
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 35 deletions.
6 changes: 3 additions & 3 deletions app/components/performance_profile_banner/view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ def render?
end

def banner_heading_text
"The #{previous_academic_cycle_label} ITT performance profile sign off due"
"The #{previous_academic_cycle_label} ITT performance profile sign off is due"
end

delegate :label, :end_year, to: :previous_academic_cycle, prefix: true
delegate :label, :end_date_of_performance_profile, to: :previous_academic_cycle, prefix: true

def deadline_date
"28 February #{previous_academic_cycle_end_year + 1}"
previous_academic_cycle.end_date_of_performance_profile.strftime(Date::DATE_FORMATS[:govuk])
end

private
Expand Down
18 changes: 18 additions & 0 deletions app/models/academic_cycle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ def current?
(start_date.beginning_of_day..end_date.end_of_day).cover?(Time.zone.now)
end

def in_performance_profile_range?(date)
performance_profile_date_range.cover?(date)
end

def second_monday_of_january
Date.new(end_year + 1, 1, 1).next_week(:monday) + 7
end

def last_day_of_february
Date.new(end_year + 1, 2, -1)
end

alias_method :end_date_of_performance_profile, :last_day_of_february

def performance_profile_date_range
@performance_profile_date_range ||= second_monday_of_january..end_date_of_performance_profile
end

private

def start_date_before_end_date
Expand Down
25 changes: 15 additions & 10 deletions app/services/determine_sign_off_period.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
# frozen_string_literal: true

class DetermineSignOffPeriod
include ServicePattern

VALID_PERIODS = %i[census_period performance_period outside_period].freeze

def self.call
def initialize(previous_academic_cycle: AcademicCycle.previous)
@previous_academic_cycle = previous_academic_cycle
end

def call
return Settings.sign_off_period.to_sym if valid_sign_off_period?

current_date = Time.zone.today

return :census_period if census_range.cover?(current_date)

return :performance_period if in_performance_range?(current_date)
return :performance_period if in_performance_profile_range?(current_date)

:outside_period
end

def self.valid_sign_off_period?
private

attr_reader :previous_academic_cycle

def valid_sign_off_period?
return false if Settings.sign_off_period.blank?
return true if VALID_PERIODS.include?(Settings.sign_off_period.to_sym)

Sentry.capture_exception(StandardError.new("Invalid sign_off_period value: #{Settings.sign_off_period}"))
false
end

def self.census_range
def census_range
start_date = Date.new(Time.zone.today.year, 9, 1) # 1st September
end_date = Date.new(Time.zone.today.year, 11, 7) # 7th November

start_date..end_date
end

def self.in_performance_range?(date)
jan_to_feb_range = Date.new(Time.zone.today.year, 1, 1)..Date.new(Time.zone.today.year, 2, 7)
december_range = Date.new(Time.zone.today.year, 12, 1)..Date.new(Time.zone.today.year, 12, 31)

jan_to_feb_range.cover?(date) || december_range.cover?(date)
end
delegate :in_performance_profile_range?, to: :previous_academic_cycle
end
19 changes: 10 additions & 9 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
<%= canonical_tag %>

<%= tag.meta(name: "viewport", content: "width=device-width, initial-scale=1") %>
<%= tag.meta(property: "og:image", content: image_path('govuk-opengraph-image.png')) %>
<%= tag.meta(property: "og:image", content: image_path("govuk-opengraph-image.png")) %>
<%= tag.meta(name: "theme-color", content: "#0b0c0c") %>
<%= tag.meta(name: "format-detection", content: "telephone=no") %>

<%= favicon_link_tag image_path('favicon.ico'), type: nil, sizes: "48x48" %>
<%= favicon_link_tag image_path('favicon.svg'), type: 'image/svg+xml', sizes: "any" %>
<%= favicon_link_tag image_path('govuk-icon-mask.svg'), rel: 'mask-icon', color: "#0b0c0c", type: nil %>
<%= favicon_link_tag image_path('govuk-icon-180.png'), rel: 'apple-touch-icon', type: nil %>
<%= favicon_link_tag image_path("favicon.ico"), type: nil, sizes: "48x48" %>
<%= favicon_link_tag image_path("favicon.svg"), type: "image/svg+xml", sizes: "any" %>
<%= favicon_link_tag image_path("govuk-icon-mask.svg"), rel: "mask-icon", color: "#0b0c0c", type: nil %>
<%= favicon_link_tag image_path("govuk-icon-180.png"), rel: "apple-touch-icon", type: nil %>

<%= stylesheet_link_tag "accessible-autocomplete/dist/accessible-autocomplete.min" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
Expand Down Expand Up @@ -68,7 +68,7 @@
{ name: "Home", url: root_path },
({ name: "Draft trainees", url: drafts_path, current: active_link_for("drafts", @trainee) } if can_view_drafts?),
{ name: "Registered trainees", url: trainees_path, current: active_link_for("trainees", @trainee) },
({ name: "Bulk updates", url: bulk_update_path, current: active_link_for("bulk") } if can_bulk_update? ),
({ name: "Bulk updates", url: bulk_update_path, current: active_link_for("bulk") } if can_bulk_update?),
({ name: "Reports", url: reports_path, current: active_link_for("reports") } if can_view_reports?),
({ name: "Funding", url: funding_payment_schedule_path, current: active_link_for("funding") } if can_view_funding?),
({ name: current_user.organisation.name, url: organisations_path, align_right: true } if show_organisation_link?),
Expand Down Expand Up @@ -107,12 +107,13 @@
<div class="govuk-width-container">
<% if FeatureService.enabled?(:maintenance_banner) %>
<%= govuk_notification_banner(title_text: "Important") do |banner|
banner.heading(text: "Register will be unavailable on Wednesday 19 July from 5pm")
banner.heading(text: "Register will be unavailable on Wednesday 19 July from 5pm")

content_tag(:p, "You will be able to use the service from 9am on Thursday 20 July 2023.", class: "govuk-body")
end %>
content_tag(:p, "You will be able to use the service from 9am on Thursday 20 July 2023.", class: "govuk-body")
end %>
<% else %>
<%= render(YearChangeBanner::View.new) %>
<%= render(PerformanceProfileBanner::View.new(previous_academic_cycle: AcademicCycle.previous, sign_off_period: :performance_period, provider: @current_user.organisation)) if @current_user&.accredited_provider? && request.path == root_path %>
<% end %>

<%= render(FlashBanner::View.new(flash: flash, trainee: @trainee)) %>
Expand Down
2 changes: 2 additions & 0 deletions config/settings/review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ pagination:

environment:
name: review

sign_off_period: performance_period # census_period, performance_period, outside_period. See app/services/determine_sign_off_period.rb
2 changes: 1 addition & 1 deletion spec/components/performance_profile_banner/view_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

it "renders correctly" do
expect(@result).to have_css("#govuk-notification-banner-title", text: "Important")
expect(@result).to have_css(".govuk-notification-banner__heading", text: "The #{previous_academic_cycle_label} ITT performance profile sign off due")
expect(@result).to have_css(".govuk-notification-banner__heading", text: "The #{previous_academic_cycle_label} ITT performance profile sign off is due")
end

it "renders the link correctly" do
Expand Down
73 changes: 73 additions & 0 deletions spec/features/performance_profile_banner_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

require "rails_helper"

feature "performance profile banner" do
context "within the performance profile date range" do
background do
Timecop.freeze(AcademicCycle.previous.performance_profile_date_range.to_a.sample)
end

context "not logged in" do
scenario "performance profile banner is not shown" do
given_i_am_not_logged_in
when_i_am_on_the_root_page
then_i_do_not_see_the_performance_profile_banner
end
end

context "logged in as system admin" do
scenario "performance profile banner is not shown" do
given_i_am_authenticated_as_system_admin
when_i_am_on_the_root_page
then_i_do_not_see_the_performance_profile_banner
end
end

context "accredited provider user" do
scenario "performance profile banner is shown" do
given_i_am_authenticated
when_i_am_on_the_root_page
then_i_can_see_the_performance_profile_banner
and_i_click_on("Sign off your performance profile")
and_i_am_on_the_sign_off_your_performance_profile_page
end
end

context "lead provider user" do
scenario "performance profile banner is not shown" do
given_i_am_authenticated_as_a_lead_partner_user
when_i_am_on_the_root_page
then_i_do_not_see_the_performance_profile_banner
end
end
end

private

def when_i_am_on_the_root_page
visit "/"
end

def given_i_am_not_logged_in; end

def then_i_do_not_see_the_performance_profile_banner
expect(page).not_to have_css("#govuk-notification-banner-title", text: "Important")
expect(page).not_to have_css(".govuk-notification-banner__heading", text: "The #{previous_academic_cycle_label} ITT performance profile sign off is due")
end

def then_i_can_see_the_performance_profile_banner
expect(page).to have_css("#govuk-notification-banner-title", text: "Important")
expect(page).to have_css(".govuk-notification-banner__heading", text: "The #{previous_academic_cycle_label} ITT performance profile sign off is due")
end

def previous_academic_cycle_label
AcademicCycle.previous.label
end

def and_i_am_on_the_sign_off_your_performance_profile_page
expect(page).to have_current_path("/")
end

alias_method :and_i_click_on, :click_on
end
30 changes: 29 additions & 1 deletion spec/models/academic_cycle_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
require "rails_helper"

describe AcademicCycle do
subject { build(:academic_cycle) }
let(:academic_cycle) { build(:academic_cycle) }

subject { academic_cycle }

before do
allow(Trainees::SetAcademicCycles).to receive(:call) # deactivate so it doesn't override factories
Expand Down Expand Up @@ -179,4 +181,30 @@
it { expect(subject).to eq(past_academic_year) }
end
end

describe "#in_performance_profile_range?" do
it "returns whether a date is in the performance profile range" do
expect(academic_cycle.in_performance_profile_range?(academic_cycle.second_monday_of_january)).to be true
expect(academic_cycle.in_performance_profile_range?(academic_cycle.last_day_of_february)).to be true
expect(academic_cycle.in_performance_profile_range?(academic_cycle.second_monday_of_january - 1.day)).to be false
expect(academic_cycle.in_performance_profile_range?(academic_cycle.last_day_of_february + 1.day)).to be false
end
end

describe "#second_monday_of_january" do
subject { academic_cycle.second_monday_of_january }

it { expect(subject.month).to eq 1 }
it { expect(subject.wday).to eq 1 }
it { expect(subject.day).to be_between(8, 14) }
it { expect(subject).to be_a(Date) }
end

describe "#last_day_of_february" do
subject { academic_cycle.last_day_of_february }

it { expect(subject.month).to eq 2 }
it { expect(subject.day).to be_between(28, 29) }
it { expect(subject).to be_a(Date) }
end
end
31 changes: 20 additions & 11 deletions spec/services/determine_sign_off_period_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

describe DetermineSignOffPeriod do
describe ".call" do
subject { described_class.call }
subject { described_class.call(previous_academic_cycle: academic_cycle) }

let(:academic_cycle) { create(:academic_cycle) }

before do
allow(Settings).to receive(:sign_off_period).and_return(nil)
Expand All @@ -18,13 +20,15 @@
all_dates = [*Date.new(current_year, 1, 1)..Date.new(current_year, 12, 31)]
outside_dates = all_dates - census_period_range - performance_period_range

context "with a valid manual override" do
before do
allow(Settings).to receive(:sign_off_period).and_return(:census_period)
end
%i[census_period performance_period outside_period].each do |sign_off_period|
context "with a valid manual override" do
before do
allow(Settings).to receive(:sign_off_period).and_return(sign_off_period)
end

it "returns the manual override value" do
expect(subject).to eq(:census_period)
it "returns the manual override value #{sign_off_period}" do
expect(subject).to eq(sign_off_period)
end
end
end

Expand All @@ -38,10 +42,15 @@
subject
expect(Sentry).to have_received(:capture_exception).with(instance_of(StandardError))
end
end

census_period_range.each do |census_date|
context "on #{census_date} the census sign off period" do
before do
allow(Time.zone).to receive(:today).and_return(census_date)
end

census_period_range.each do |census_period|
it "for #{census_period} it defaults back to the calculated behaviour" do
allow(Time.zone).to receive(:today).and_return(census_period)
it "returns :census_period" do
expect(subject).to eq(:census_period)
end
end
Expand All @@ -51,6 +60,7 @@
context "on #{performance_date} the performance profiles sign off period" do
before do
allow(Time.zone).to receive(:today).and_return(performance_date)
allow(academic_cycle).to receive(:in_performance_profile_range?).with(performance_date).and_return(true)
end

it "returns :performance_period" do
Expand All @@ -66,7 +76,6 @@
end

it "returns :outside_period" do
pp subject if subject != :outside_period
expect(subject).to eq(:outside_period)
end
end
Expand Down

0 comments on commit c5cd264

Please sign in to comment.