From d22afe5897f702c1952a4a18a2b259986dfa7317 Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire Date: Fri, 11 Nov 2022 17:14:29 +0000 Subject: [PATCH] feat: add tests ("updates existing scheme with valid deactivation date and renders scheme page" still wip) and add new partially nil date behaviour to locations controller --- app/controllers/locations_controller.rb | 5 +- app/helpers/schemes_helper.rb | 4 +- config/routes.rb | 1 - spec/helpers/schemes_helper_spec.rb | 27 ++++ spec/models/scheme_spec.rb | 32 ++++ spec/requests/schemes_controller_spec.rb | 186 +++++++++++++++++++++++ 6 files changed, 249 insertions(+), 6 deletions(-) create mode 100644 spec/helpers/schemes_helper_spec.rb diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index 6cd40161f..8f663ae80 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -29,6 +29,7 @@ class LocationsController < ApplicationController deactivation_date_errors if @location.errors.present? @location.deactivation_date_type = params[:location][:deactivation_date_type] + @location.deactivation_date = nil render "toggle_active", locals: { action: "deactivate" }, status: :unprocessable_entity else render "toggle_active_confirm", locals: { action: "deactivate", deactivation_date: } @@ -183,9 +184,7 @@ private collection_start_date = FormHandler.instance.current_collection_start_date if [day, month, year].any?(&:blank?) - { day:, month:, year: }.each do |period, value| - @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.not_entered", period: period.to_s)) if value.blank? - end + @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.not_entered", period: period.to_s)) elsif !Date.valid_date?(year.to_i, month.to_i, day.to_i) @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.invalid")) elsif !Date.new(year.to_i, month.to_i, day.to_i).between?(collection_start_date, Date.new(2200, 1, 1)) diff --git a/app/helpers/schemes_helper.rb b/app/helpers/schemes_helper.rb index 444a3b936..8662e4a4e 100644 --- a/app/helpers/schemes_helper.rb +++ b/app/helpers/schemes_helper.rb @@ -14,8 +14,8 @@ module SchemesHelper { name: "Secondary client group", value: scheme.secondary_client_group }, { name: "Level of support given", value: scheme.support_type }, { name: "Intended length of stay", value: scheme.intended_stay }, - { name: "Availability", value: availability_text(scheme)}, - { name: "Status", value: status_tag(scheme_status(scheme)) }, + { name: "Availability", value: "Available from #{scheme.available_from.to_formatted_s(:govuk_date)}"}, + { name: "Status", value: scheme.status }, ] if scheme.arrangement_type_same? diff --git a/config/routes.rb b/config/routes.rb index 58890b4c0..4c6619c87 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -52,7 +52,6 @@ Rails.application.routes.draw do get "deactivate", to: "schemes#deactivate" get "reactivate", to: "schemes#reactivate" patch "deactivate", to: "schemes#deactivate" - patch "reactivate", to: "schemes#reactivate" resources :locations do get "edit-name", to: "locations#edit_name" diff --git a/spec/helpers/schemes_helper_spec.rb b/spec/helpers/schemes_helper_spec.rb new file mode 100644 index 000000000..4410620a9 --- /dev/null +++ b/spec/helpers/schemes_helper_spec.rb @@ -0,0 +1,27 @@ +require "rails_helper" + +RSpec.describe SchemesHelper do + describe "display_attributes" do + let!(:scheme) { FactoryBot.create(:scheme, created_at: Time.zone.local(2022, 8, 8)) } + + it "returns correct display attributes" do + attributes = [ + { name: "Scheme code", value: scheme.id_to_display }, + { name: "Name", value: scheme.service_name, edit: true }, + { name: "Confidential information", value: scheme.sensitive, edit: true }, + { name: "Type of scheme", value: scheme.scheme_type }, + { name: "Registered under Care Standards Act 2000", value: scheme.registered_under_care_act }, + { name: "Housing stock owned by", value: scheme.owning_organisation.name, edit: true }, + { name: "Support services provided by", value: scheme.arrangement_type }, + { name: "Primary client group", value: scheme.primary_client_group }, + { name: "Has another client group", value: scheme.has_other_client_group }, + { name: "Secondary client group", value: scheme.secondary_client_group }, + { name: "Level of support given", value: scheme.support_type }, + { name: "Intended length of stay", value: scheme.intended_stay }, + { name: "Availability", value: "Available from 8 August 2022" }, + { name: "Status", value: :active }, + ] + expect(display_attributes(scheme)).to eq(attributes) + end + end +end diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb index 9d17d888c..b69629ba5 100644 --- a/spec/models/scheme_spec.rb +++ b/spec/models/scheme_spec.rb @@ -91,4 +91,36 @@ RSpec.describe Scheme, type: :model do end end end + + describe "status" do + let(:scheme) { FactoryBot.build(:scheme) } + + before do + Timecop.freeze(2022, 6, 7) + end + + it "returns active if the scheme is not deactivated" do + scheme.deactivation_date = nil + scheme.save! + expect(scheme.status).to eq(:active) + end + + it "returns deactivating soon if deactivation_date is in the future" do + scheme.deactivation_date = Time.zone.local(2022, 8, 8) + scheme.save! + expect(scheme.status).to eq(:deactivating_soon) + end + + it "returns deactivated if deactivation_date is in the past" do + scheme.deactivation_date = Time.zone.local(2022, 4, 8) + scheme.save! + expect(scheme.status).to eq(:deactivated) + end + + it "returns deactivated if deactivation_date is today" do + scheme.deactivation_date = Time.zone.local(2022, 6, 7) + scheme.save! + expect(scheme.status).to eq(:deactivated) + end + end end diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index a5c0b6e4f..de2e14b83 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -1698,4 +1698,190 @@ RSpec.describe SchemesController, type: :request do end end end + + describe "#deactivate" do + context "when not signed in" do + it "redirects to the sign in page" do + patch "/schemes/1/deactivate" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + patch "/schemes/1/deactivate" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) } + let!(:location) { FactoryBot.create(:location, scheme:) } + let(:startdate) { Time.utc(2021, 1, 2) } + let(:deactivation_date) { Time.utc(2022, 10, 10) } + + before do + Timecop.freeze(Time.utc(2022, 10, 10)) + sign_in user + patch "/schemes/#{scheme.id}/deactivate", params: + end + + context "with default date" do + let(:params) { { scheme: { deactivation_date_type: "default" } } } + + it "renders the confirmation page" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("This change will affect #{scheme.lettings_logs.count} logs") + end + end + + context "with other date" do + let(:params) { { scheme: { deactivation_date: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } } + + it "renders the confirmation page" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("This change will affect #{scheme.lettings_logs.count} logs") + end + end + + context "when confirming deactivation" do + let(:params) { { scheme: { deactivation_date:, confirm: true } } } + + it "updates existing scheme with valid deactivation date and renders scheme page" do + follow_redirect! + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") + scheme.reload + expect(scheme.deactivation_date).to eq(deactivation_date) + end + end + + context "when the date is not selected" do + let(:params) { { scheme: { "deactivation_date": "" } } } + + it "displays the new page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.scheme.deactivation_date.not_selected")) + end + end + + context "when invalid date is entered" do + let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } } + + it "displays the new page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.scheme.deactivation_date.invalid")) + end + end + + context "when the date is entered is before the beginning of current collection window" do + let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } } + + it "displays the new page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.scheme.deactivation_date.out_of_range", date: "1 April 2022")) + end + end + + context "when the day is not entered" do + let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } } + + it "displays page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.scheme.deactivation_date.not_entered", period: "day")) + end + end + + context "when the month is not entered" do + let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } } + + it "displays page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.scheme.deactivation_date.not_entered", period: "month")) + end + end + + context "when the year is not entered" do + let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } } + + it "displays page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.scheme.deactivation_date.not_entered", period: "year")) + end + end + end + end + + describe "#show" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) } + let!(:location) { FactoryBot.create(:location, scheme:) } + + before do + Timecop.freeze(Time.utc(2022, 10, 10)) + sign_in user + scheme.deactivation_date = deactivation_date + scheme.save! + get "/schemes/#{scheme.id}" + end + + context "with active scheme" do + let(:deactivation_date) { nil } + + it "renders deactivate this scheme" do + expect(response).to have_http_status(:ok) + expect(page).to have_link("Deactivate this scheme", href: "/schemes/#{scheme.id}/deactivate") + end + end + + context "with deactivated scheme" do + let(:deactivation_date) { Time.utc(2022, 10, 9) } + + it "renders reactivate this scheme" do + expect(response).to have_http_status(:ok) + expect(page).to have_link("Reactivate this scheme", href: "/schemes/#{scheme.id}/reactivate") + end + end + + context "with scheme that's deactivating soon" do + let(:deactivation_date) { Time.utc(2022, 10, 12) } + + it "renders reactivate this scheme" do + expect(response).to have_http_status(:ok) + expect(page).to have_link("Reactivate this scheme", href: "/schemes/#{scheme.id}/reactivate") + end + end + end + end end