diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb
index 797e79544..6cd40161f 100644
--- a/app/controllers/locations_controller.rb
+++ b/app/controllers/locations_controller.rb
@@ -21,7 +21,23 @@ class LocationsController < ApplicationController
def show; end
def deactivate
- render "toggle_active", locals: { action: "deactivate" }
+ if params[:location].blank?
+ render "toggle_active", locals: { action: "deactivate" }
+ elsif params[:location][:confirm].present? && params[:location][:deactivation_date].present?
+ confirm_deactivation
+ else
+ deactivation_date_errors
+ if @location.errors.present?
+ @location.deactivation_date_type = params[:location][:deactivation_date_type]
+ render "toggle_active", locals: { action: "deactivate" }, status: :unprocessable_entity
+ else
+ render "toggle_active_confirm", locals: { action: "deactivate", deactivation_date: }
+ end
+ end
+ end
+
+ def reactivate
+ render "toggle_active", locals: { action: "reactivate" }
end
def create
@@ -128,7 +144,7 @@ private
end
def authenticate_action!
- if %w[new edit update create index edit_name edit_local_authority].include?(action_name) && !((current_user.organisation == @scheme&.owning_organisation) || current_user.support?)
+ if %w[new edit update create index edit_name edit_local_authority deactivate].include?(action_name) && !((current_user.organisation == @scheme&.owning_organisation) || current_user.support?)
render_not_found and return
end
end
@@ -146,4 +162,49 @@ private
def valid_location_admin_district?(location_params)
location_params["location_admin_district"] != "Select an option"
end
+
+ def confirm_deactivation
+ if @location.update(deactivation_date: params[:location][:deactivation_date])
+ flash[:notice] = "#{@location.name || @location.postcode} has been deactivated"
+ end
+ redirect_to scheme_location_path(@scheme, @location)
+ end
+
+ def deactivation_date_errors
+ if params[:location][:deactivation_date].blank? && params[:location][:deactivation_date_type].blank?
+ @location.errors.add(:deactivation_date_type, message: I18n.t("validations.location.deactivation_date.not_selected"))
+ end
+
+ if params[:location][:deactivation_date_type] == "other"
+ day = params[:location]["deactivation_date(3i)"]
+ month = params[:location]["deactivation_date(2i)"]
+ year = params[:location]["deactivation_date(1i)"]
+
+ 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
+ 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))
+ @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.out_of_range", date: collection_start_date.to_formatted_s(:govuk_date)))
+ end
+ end
+ end
+
+ def deactivation_date
+ return if params[:location].blank?
+
+ collection_start_date = FormHandler.instance.current_collection_start_date
+ return collection_start_date if params[:location][:deactivation_date_type] == "default"
+ return params[:location][:deactivation_date] if params[:location][:deactivation_date_type].blank?
+
+ day = params[:location]["deactivation_date(3i)"]
+ month = params[:location]["deactivation_date(2i)"]
+ year = params[:location]["deactivation_date(1i)"]
+
+ Date.new(year.to_i, month.to_i, day.to_i)
+ end
end
diff --git a/app/frontend/controllers/conditional_question_controller.js b/app/frontend/controllers/conditional_question_controller.js
index fb52d07c1..d24d5c6c3 100644
--- a/app/frontend/controllers/conditional_question_controller.js
+++ b/app/frontend/controllers/conditional_question_controller.js
@@ -10,14 +10,14 @@ export default class extends Controller {
const selectedValue = this.element.value
const dataInfo = JSON.parse(this.element.dataset.info)
const conditionalFor = dataInfo.conditional_questions
- const logType = dataInfo.log_type
+ const type = dataInfo.type
Object.entries(conditionalFor).forEach(([targetQuestion, conditions]) => {
if (!conditions.map(String).includes(String(selectedValue))) {
- const textNumericInput = document.getElementById(`${logType}-log-${targetQuestion.replaceAll('_', '-')}-field`)
+ const textNumericInput = document.getElementById(`${type}-${targetQuestion.replaceAll('_', '-')}-field`)
if (textNumericInput == null) {
const dateInputs = [1, 2, 3].map((idx) => {
- return document.getElementById(`${logType}_log_${targetQuestion}_${idx}i`)
+ return document.getElementById(`${type.replaceAll('-', '_')}_${targetQuestion}_${idx}i`)
})
this.clearDateInputs(dateInputs)
} else {
diff --git a/app/helpers/question_attribute_helper.rb b/app/helpers/question_attribute_helper.rb
index 857ce5eb1..020ea1909 100644
--- a/app/helpers/question_attribute_helper.rb
+++ b/app/helpers/question_attribute_helper.rb
@@ -7,6 +7,14 @@ module QuestionAttributeHelper
merge_controller_attributes(*attribs)
end
+ def basic_conditional_html_attributes(conditional_for, type)
+ {
+ "data-controller": "conditional-question",
+ "data-action": "click->conditional-question#displayConditional",
+ "data-info": { conditional_questions: conditional_for, type: type }.to_json,
+ }
+ end
+
private
def numeric_question_html_attributes(question)
@@ -27,7 +35,7 @@ private
{
"data-controller": "conditional-question",
"data-action": "click->conditional-question#displayConditional",
- "data-info": { conditional_questions: question.conditional_for, log_type: question.form.type }.to_json,
+ "data-info": { conditional_questions: question.conditional_for, type: "#{question.form.type}-log" }.to_json,
}
end
end
diff --git a/app/helpers/tag_helper.rb b/app/helpers/tag_helper.rb
index 08b6180b3..2ea23a86a 100644
--- a/app/helpers/tag_helper.rb
+++ b/app/helpers/tag_helper.rb
@@ -7,6 +7,8 @@ module TagHelper
in_progress: "In progress",
completed: "Completed",
active: "Active",
+ deactivating_soon: "Deactivating soon",
+ deactivated: "Deactivated",
}.freeze
COLOUR = {
@@ -15,6 +17,8 @@ module TagHelper
in_progress: "blue",
completed: "green",
active: "green",
+ deactivating_soon: "yellow",
+ deactivated: "grey",
}.freeze
def status_tag(status, classes = [])
diff --git a/app/models/form_handler.rb b/app/models/form_handler.rb
index c6dde13ab..c080e6e9b 100644
--- a/app/models/form_handler.rb
+++ b/app/models/form_handler.rb
@@ -49,6 +49,10 @@ class FormHandler
today < window_end_date ? today.year - 1 : today.year
end
+ def current_collection_start_date
+ Time.utc(current_collection_start_year, 4, 1)
+ end
+
def form_name_from_start_year(year, type)
form_mappings = { 0 => "current_#{type}", 1 => "previous_#{type}", -1 => "next_#{type}" }
form_mappings[current_collection_start_year - year]
diff --git a/app/models/location.rb b/app/models/location.rb
index 0fdc24a8e..ab1c3620a 100644
--- a/app/models/location.rb
+++ b/app/models/location.rb
@@ -2,6 +2,7 @@ class Location < ApplicationRecord
validate :validate_postcode
validates :units, :type_of_unit, :mobility_type, presence: true
belongs_to :scheme
+ has_many :lettings_logs, class_name: "LettingsLog"
has_paper_trail
@@ -9,7 +10,7 @@ class Location < ApplicationRecord
auto_strip_attributes :name
- attr_accessor :add_another_location
+ attr_accessor :add_another_location, :deactivation_date_type
scope :search_by_postcode, ->(postcode) { where("REPLACE(postcode, ' ', '') ILIKE ?", "%#{postcode.delete(' ')}%") }
scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }
@@ -372,7 +373,9 @@ class Location < ApplicationRecord
end
def status
- "active"
+ return :active if deactivation_date.blank?
+ return :deactivating_soon if Time.zone.now < deactivation_date
+ return :deactivated if Time.zone.now >= deactivation_date
end
private
diff --git a/app/views/locations/show.html.erb b/app/views/locations/show.html.erb
index fdceb77ad..ccc0163c2 100644
--- a/app/views/locations/show.html.erb
+++ b/app/views/locations/show.html.erb
@@ -24,5 +24,9 @@
<% if FeatureToggle.location_toggle_enabled? %>
- <%= govuk_button_link_to "Deactivate this location", scheme_location_deactivate_path(scheme_id: @scheme.id, location_id: @location.id), warning: true %>
+ <% if @location.status == :active %>
+ <%= govuk_button_link_to "Deactivate this location", scheme_location_deactivate_path(scheme_id: @scheme.id, location_id: @location.id), warning: true %>
+ <% else %>
+ <%= govuk_button_link_to "Reactivate this location", scheme_location_reactivate_path(scheme_id: @scheme.id, location_id: @location.id) %>
+ <% end %>
<% end %>
diff --git a/app/views/locations/toggle_active.html.erb b/app/views/locations/toggle_active.html.erb
index e69de29bb..96cda6daa 100644
--- a/app/views/locations/toggle_active.html.erb
+++ b/app/views/locations/toggle_active.html.erb
@@ -0,0 +1,39 @@
+<% title = "#{action.humanize} #{@location.postcode}" %>
+<% content_for :title, title %>
+
+<% content_for :before_content do %>
+ <%= govuk_back_link(
+ text: "Back",
+ href: scheme_location_path(scheme_id: @location.scheme.id, id: @location.id),
+ ) %>
+<% end %>
+
+<%= form_with model: @location, url: scheme_location_deactivate_path(scheme_id: @location.scheme.id, location_id: @location.id), method: "patch", local: true do |f| %>
+
+
+ <% collection_start_date = FormHandler.instance.current_collection_start_date %>
+ <%= f.govuk_error_summary %>
+ <%= f.govuk_radio_buttons_fieldset :deactivation_date_type,
+ legend: { text: I18n.t("questions.location.deactivation.apply_from") },
+ caption: { text: "Deactivate #{@location.postcode}" },
+ hint: { text: I18n.t("hints.location.deactivation", date: collection_start_date.to_formatted_s(:govuk_date)) } do %>
+ <%= govuk_warning_text text: I18n.t("warnings.location.deactivation.existing_logs") %>
+ <%= f.govuk_radio_button :deactivation_date_type,
+ "default",
+ label: { text: "From the start of the current collection period (#{collection_start_date.to_formatted_s(:govuk_date)})" } %>
+
+ <%= f.govuk_radio_button :deactivation_date_type,
+ "other",
+ label: { text: "For tenancies starting after a certain date" },
+ **basic_conditional_html_attributes({ "deactivation_date" => %w[other] }, "location") do %>
+ <%= f.govuk_date_field :deactivation_date,
+ legend: { text: "Date", size: "m" },
+ hint: { text: "For example, 27 3 2008" },
+ width: 20 %>
+ <% end %>
+ <% end %>
+
+ <%= f.govuk_submit "Continue" %>
+
+
+<% end %>
diff --git a/app/views/locations/toggle_active_confirm.html.erb b/app/views/locations/toggle_active_confirm.html.erb
new file mode 100644
index 000000000..452d66e48
--- /dev/null
+++ b/app/views/locations/toggle_active_confirm.html.erb
@@ -0,0 +1,16 @@
+<%= form_with model: @location, url: scheme_location_deactivate_path(@location), method: "patch", local: true do |f| %>
+ <% content_for :before_content do %>
+ <%= govuk_back_link(href: :back) %>
+ <% end %>
+
+ <%= @location.postcode %>
+ <%= "This change will affect #{@location.lettings_logs.count} logs" %>
+
+ <%= govuk_warning_text text: I18n.t("warnings.location.deactivation.review_logs") %>
+ <%= f.hidden_field :confirm, value: true %>
+ <%= f.hidden_field :deactivation_date, value: deactivation_date %>
+
+ <%= f.govuk_submit "Deactivate this location" %>
+ <%= govuk_button_link_to "Cancel", scheme_location_path(scheme_id: @scheme, id: @location.id), html: { method: :get }, secondary: true %>
+
+ <% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 9a45d96dd..3c4808696 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -312,6 +312,13 @@ en:
declaration:
missing: "You must show the DLUHC privacy notice to the tenant before you can submit this log."
+ location:
+ deactivation_date:
+ not_selected: "Select one of the options"
+ not_entered: "Enter a %{period}"
+ invalid: "Enter a valid date"
+ out_of_range: "The date must be on or after the %{date}"
+
soft_validations:
net_income:
title_text: "Net income is outside the expected range based on the lead tenant’s working situation"
@@ -362,6 +369,8 @@ en:
startdate: "When did the first property in this location become available under this scheme? (optional)"
add_another_location: "Do you want to add another location?"
mobility_type: "What are the mobility standards for the majority of units in this location?"
+ deactivation:
+ apply_from: "When should this change apply?"
descriptions:
location:
mobility_type:
@@ -374,6 +383,13 @@ en:
postcode: "For example, SW1P 4DF."
name: "This is how you refer to this location within your organisation"
units: "A unit can be a bedroom in a shared house or flat, or a house with 4 bedrooms. Do not include bedrooms used for wardens, managers, volunteers or sleep-in staff."
+ deactivation: "If the date is before %{date}, select ‘From the start of the current collection period’ because the previous period has now closed."
+
+ warnings:
+ location:
+ deactivation:
+ existing_logs: "It will not be possible to add logs with this location if their tenancy start date is on or after the date you enter. Any existing logs may be affected."
+ review_logs: "Your data providers will need to review these logs and answer a few questions again. We’ll email each log creator with a list of logs that need updating."
test:
one_argument: "This is based on the tenant’s work situation: %{ecstat1}"
diff --git a/config/routes.rb b/config/routes.rb
index ad088fe11..8bd78d6e6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -54,6 +54,8 @@ Rails.application.routes.draw do
get "edit-name", to: "locations#edit_name"
get "edit-local-authority", to: "locations#edit_local_authority"
get "deactivate", to: "locations#deactivate"
+ get "reactivate", to: "locations#reactivate"
+ patch "deactivate", to: "locations#deactivate"
end
end
diff --git a/db/migrate/20221109122033_add_deactivation_date_to_locations.rb b/db/migrate/20221109122033_add_deactivation_date_to_locations.rb
new file mode 100644
index 000000000..3360bfc7c
--- /dev/null
+++ b/db/migrate/20221109122033_add_deactivation_date_to_locations.rb
@@ -0,0 +1,5 @@
+class AddDeactivationDateToLocations < ActiveRecord::Migration[7.0]
+ def change
+ add_column :locations, :deactivation_date, :datetime
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 43fc94775..ea4b59670 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2022_10_19_082625) do
+ActiveRecord::Schema[7.0].define(version: 2022_11_09_122033) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -260,6 +260,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_10_19_082625) do
t.datetime "startdate", precision: nil
t.string "location_admin_district"
t.boolean "confirmed"
+ t.datetime "deactivation_date"
t.index ["old_id"], name: "index_locations_on_old_id", unique: true
t.index ["scheme_id"], name: "index_locations_on_scheme_id"
end
diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb
index 9a4550912..f2a5a67a5 100644
--- a/spec/helpers/locations_helper_spec.rb
+++ b/spec/helpers/locations_helper_spec.rb
@@ -60,7 +60,7 @@ RSpec.describe LocationsHelper do
{ name: "Mobility type", value: location.mobility_type },
{ name: "Code", value: location.location_code },
{ name: "Availability", value: "Available from 8 August 2022" },
- { name: "Status", value: "active" },
+ { name: "Status", value: :active },
]
expect(display_attributes(location)).to eq(attributes)
diff --git a/spec/helpers/question_attribute_helper_spec.rb b/spec/helpers/question_attribute_helper_spec.rb
index 2be903535..9d769cdf6 100644
--- a/spec/helpers/question_attribute_helper_spec.rb
+++ b/spec/helpers/question_attribute_helper_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe QuestionAttributeHelper do
"data-action": "input->numeric-question#calculateFields click->conditional-question#displayConditional",
"data-target": "lettings-log-#{question.result_field.to_s.dasherize}-field",
"data-calculated": question.fields_to_add.to_json,
- "data-info": { conditional_questions: question.conditional_for, log_type: "lettings" }.to_json,
+ "data-info": { conditional_questions: question.conditional_for, type: "lettings-log" }.to_json,
}
end
diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb
index 81a9b1c45..c6a47c107 100644
--- a/spec/models/form_handler_spec.rb
+++ b/spec/models/form_handler_spec.rb
@@ -118,6 +118,10 @@ RSpec.describe FormHandler do
it "returns the correct next sales form name" do
expect(form_handler.form_name_from_start_year(2023, "sales")).to eq("next_sales")
end
+
+ it "returns the correct current start date" do
+ expect(form_handler.current_collection_start_date).to eq(Time.utc(2022, 4, 1))
+ end
end
context "with the date before 1st of April" do
diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb
index 856575932..8f9f452bc 100644
--- a/spec/models/location_spec.rb
+++ b/spec/models/location_spec.rb
@@ -111,4 +111,36 @@ RSpec.describe Location, type: :model do
end
end
end
+
+ describe "status" do
+ let(:location) { FactoryBot.build(:location) }
+
+ before do
+ Timecop.freeze(2022, 6, 7)
+ end
+
+ it "returns active if the location is not deactivated" do
+ location.deactivation_date = nil
+ location.save!
+ expect(location.status).to eq(:active)
+ end
+
+ it "returns deactivating soon if deactivation_date is in the future" do
+ location.deactivation_date = Time.zone.local(2022, 8, 8)
+ location.save!
+ expect(location.status).to eq(:deactivating_soon)
+ end
+
+ it "returns deactivated if deactivation_date is in the past" do
+ location.deactivation_date = Time.zone.local(2022, 4, 8)
+ location.save!
+ expect(location.status).to eq(:deactivated)
+ end
+
+ it "returns deactivated if deactivation_date is today" do
+ location.deactivation_date = Time.zone.local(2022, 6, 7)
+ location.save!
+ expect(location.status).to eq(:deactivated)
+ end
+ end
end
diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb
index 96b3d1b21..feeae2b99 100644
--- a/spec/requests/locations_controller_spec.rb
+++ b/spec/requests/locations_controller_spec.rb
@@ -1212,4 +1212,189 @@ RSpec.describe LocationsController, 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/locations/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/locations/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}/locations/#{location.id}/deactivate", params:
+ end
+
+ context "with default date" do
+ let(:params) { { location: { 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 #{location.lettings_logs.count} logs")
+ end
+ end
+
+ context "with other date" do
+ let(:params) { { location: { 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 #{location.lettings_logs.count} logs")
+ end
+ end
+
+ context "when confirming deactivation" do
+ let(:params) { { location: { deactivation_date:, confirm: true } } }
+
+ it "updates existing location with valid deactivation date and renders location page" do
+ follow_redirect!
+ expect(response).to have_http_status(:ok)
+ expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success")
+ location.reload
+ expect(location.deactivation_date).to eq(deactivation_date)
+ end
+ end
+
+ context "when the date is not selected" do
+ let(:params) { { location: { "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.location.deactivation_date.not_selected"))
+ end
+ end
+
+ context "when invalid date is entered" do
+ let(:params) { { location: { 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.location.deactivation_date.invalid"))
+ end
+ end
+
+ context "when the date is entered is before the beginning of current collection window" do
+ let(:params) { { location: { 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.location.deactivation_date.out_of_range", date: "1 April 2022"))
+ end
+ end
+
+ context "when the day is not entered" do
+ let(:params) { { location: { 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.location.deactivation_date.not_entered", period: "day"))
+ end
+ end
+
+ context "when the month is not entered" do
+ let(:params) { { location: { 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.location.deactivation_date.not_entered", period: "month"))
+ end
+ end
+
+ context "when the year is not entered" do
+ let(:params) { { location: { 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.location.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/locations/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/locations/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
+ location.deactivation_date = deactivation_date
+ location.save!
+ get "/schemes/#{scheme.id}/locations/#{location.id}"
+ end
+
+ context "with active location" do
+ let(:deactivation_date) { nil }
+
+ it "renders deactivate this location" do
+ expect(response).to have_http_status(:ok)
+ expect(page).to have_link("Deactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/deactivate")
+ end
+ end
+
+ context "with deactivated location" do
+ let(:deactivation_date) { Time.utc(2022, 10, 9) }
+
+ it "renders reactivate this location" do
+ expect(response).to have_http_status(:ok)
+ expect(page).to have_link("Reactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/reactivate")
+ end
+ end
+
+ context "with location that's deactivating soon" do
+ let(:deactivation_date) { Time.utc(2022, 10, 12) }
+
+ it "renders reactivate this location" do
+ expect(response).to have_http_status(:ok)
+ expect(page).to have_link("Reactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/reactivate")
+ end
+ end
+ end
+ end
end