Browse Source

Put validation behind feature flag

pull/1684/head
Jack S 3 years ago
parent
commit
c023a9f0bb
  1. 4
      app/components/create_log_actions_component.rb
  2. 11
      app/components/data_sharing_agreement_banner_component.rb
  3. 32
      app/controllers/organisations_controller.rb
  4. 28
      app/helpers/data_sharing_agreement_helper.rb
  5. 3
      app/models/log.rb
  6. 12
      app/models/organisation.rb
  7. 2
      app/services/feature_toggle.rb
  8. 2
      app/views/logs/_create_for_org_actions.html.erb
  9. 6
      app/views/organisations/data_sharing_agreement.html.erb
  10. 5
      db/migrate/20230609101144_drop_data_sharing_adreement_table.rb
  11. 18
      db/schema.rb
  12. 23
      db/seeds.rb
  13. 5
      spec/factories/data_protection_confirmation.rb
  14. 15
      spec/factories/data_sharing_agreement.rb
  15. 6
      spec/factories/organisation.rb
  16. 32
      spec/shared/shared_log_examples.rb

4
app/components/create_log_actions_component.rb

@ -13,10 +13,10 @@ class CreateLogActionsComponent < ViewComponent::Base
def display_actions?
return false if bulk_upload.present?
return true unless FeatureToggle.new_data_sharing_agreement?
return true unless FeatureToggle.new_data_protection_confirmation?
return true if user.support?
user.organisation.data_sharing_agreement.present?
user.organisation.data_protection_confirmation&.confirmed?
end
def create_button_href

11
app/components/data_sharing_agreement_banner_component.rb

@ -11,15 +11,14 @@ class DataSharingAgreementBannerComponent < ViewComponent::Base
end
def display_banner?
return false unless FeatureToggle.new_data_sharing_agreement?
return false unless FeatureToggle.new_data_protection_confirmation?
return false if user.is_dpo?
return false if user.support? && organisation.blank?
if organisation.present?
!DataSharingAgreement.exists?(organisation:)
else
!DataSharingAgreement.exists?(organisation: user.organisation)
end
!DataProtectionConfirmation.exists?(
organisation: (organisation.presence || user.organisation),
confirmed: true,
)
end
def data_sharing_agreement_href

32
app/controllers/organisations_controller.rb

@ -157,28 +157,36 @@ class OrganisationsController < ApplicationController
end
def data_sharing_agreement
return render_not_found unless FeatureToggle.new_data_sharing_agreement?
return render_not_found unless FeatureToggle.new_data_protection_confirmation?
@data_sharing_agreement = current_user.organisation.data_sharing_agreement
@data_protection_confirmation = current_user.organisation.data_protection_confirmation
end
def confirm_data_sharing_agreement
return render_not_found unless FeatureToggle.new_data_sharing_agreement?
return render_not_found unless FeatureToggle.new_data_protection_confirmation?
return render_not_found unless current_user.is_dpo?
return render_not_found if @organisation.data_sharing_agreement.present?
return render_not_found if @organisation.latest_data_protection_confirmation&.confirmed?
data_sharing_agreement = DataSharingAgreement.new(
if @organisation.latest_data_protection_confirmation
@organisation.latest_data_protection_confirmation.update!(
confirmed: true,
data_protection_officer: current_user,
# When it was signed
created_at: Time.zone.now,
)
dpo.confirmed = true
dpo.data_protection_officer = current_user
dpo.save!
data_protection_confirmation = DataProtectionConfirmation.new(
organisation: current_user.organisation,
signed_at: Time.zone.now,
confirmed: true,
data_protection_officer: current_user,
organisation_name: @organisation.name,
organisation_address: @organisation.address_row,
organisation_phone_number: @organisation.phone,
dpo_email: current_user.email,
dpo_name: current_user.name,
)
if data_sharing_agreement.save
if data_protection_confirmation.save
flash[:notice] = "You have accepted the Data Sharing Agreement"
flash[:notification_banner_body] = "Your organisation can now submit logs."

28
app/helpers/data_sharing_agreement_helper.rb

@ -31,22 +31,22 @@ module DataSharingAgreementHelper
end
end
def org_name_for_data_sharing_agreement(data_sharing_agreement, user)
if data_sharing_agreement.present?
data_sharing_agreement.organisation_name
def org_name_for_data_sharing_agreement(data_protection_confirmation, user)
if data_protection_confirmation&.confirmed?
data_protection_confirmation.organisation.name
else
user.organisation.name
end
end
# rubocop:disable Rails/HelperInstanceVariable
def section_12_2(data_sharing_agreement:, user:, organisation:)
if data_sharing_agreement
@org_address = data_sharing_agreement.organisation_address
@org_name = data_sharing_agreement.organisation_name
@org_phone = data_sharing_agreement.organisation_phone_number
@dpo_name = data_sharing_agreement.dpo_name
@dpo_email = data_sharing_agreement.dpo_email
def section_12_2(data_protection_confirmation:, user:, organisation:)
if data_protection_confirmation&.confirmed?
@org_address = data_protection_confirmation.organisation.address_row
@org_name = data_protection_confirmation.organisation.name
@org_phone = data_protection_confirmation.organisation.phone
@dpo_name = data_protection_confirmation.data_protection_officer.name
@dpo_email = data_protection_confirmation.data_protection_officer.email
else
@org_name = organisation.name
@org_address = organisation.address_row
@ -68,18 +68,18 @@ module DataSharingAgreementHelper
private
def data_sharing_agreement_first_line(organisation:, user:)
return "Not accepted" if organisation.data_sharing_agreement.blank?
return "Not accepted" if organisation.data_protection_confirmation&.confirmed?
if user.support?
"Accepted #{organisation.data_sharing_agreement.signed_at.strftime('%d/%m/%Y')}"
"Accepted #{organisation.data_protection_confirmation.created_at.strftime('%d/%m/%Y')}"
else
"Accepted"
end
end
def data_sharing_agreement_second_line(organisation:, user:)
if organisation.data_sharing_agreement.present?
organisation.data_sharing_agreement.dpo_name if user.support?
if organisation.data_protection_confirmation&.confirmed?
organisation.data_sharing_agreement.data_protection_officer.name if user.support?
else
"Data protection officer must sign" unless user.is_dpo?
end

3
app/models/log.rb

@ -179,8 +179,9 @@ class Log < ApplicationRecord
private
def verify_dsa_signed
return unless FeatureToggle.new_data_protection_confirmation?
return unless owning_organisation
return if owning_organisation.data_sharing_agreement.present?
return if owning_organisation.data_protection_confirmation&.confirmed?
errors.add :owning_organisation, I18n.t("validations.organisation.data_sharing_agreement_not_signed")
end

12
app/models/organisation.rb

@ -3,8 +3,7 @@ class Organisation < ApplicationRecord
has_many :owned_lettings_logs, class_name: "LettingsLog", foreign_key: "owning_organisation_id", dependent: :delete_all
has_many :managed_lettings_logs, class_name: "LettingsLog", foreign_key: "managing_organisation_id"
has_many :owned_sales_logs, class_name: "SalesLog", foreign_key: "owning_organisation_id", dependent: :delete_all
has_many :data_protection_confirmations
has_one :data_sharing_agreement
has_one :data_protection_confirmation
has_many :organisation_rent_periods
has_many :owned_schemes, class_name: "Scheme", foreign_key: "owning_organisation_id", dependent: :delete_all
has_many :parent_organisation_relationships, foreign_key: :child_organisation_id, class_name: "OrganisationRelationship"
@ -103,7 +102,7 @@ class Organisation < ApplicationRecord
end
def display_organisation_attributes
[
attrs = [
{ name: "Name", value: name, editable: true },
{ name: "Address", value: address_string, editable: true },
{ name: "Telephone_number", value: phone, editable: true },
@ -111,8 +110,13 @@ class Organisation < ApplicationRecord
{ name: "Registration number", value: housing_registration_no || "", editable: false },
{ name: "Rent_periods", value: rent_period_labels, editable: false, format: :bullet },
{ name: "Owns housing stock", value: holds_own_stock ? "Yes" : "No", editable: false },
{ name: "Data protection agreement", value: data_protection_agreement_string, editable: false },
].compact
unless FeatureToggle.new_data_protection_confirmation?
attrs << { name: "Data protection agreement", value: data_protection_agreement_string, editable: false }
end
attrs
end
def has_managing_agents?

2
app/services/feature_toggle.rb

@ -42,7 +42,7 @@ class FeatureToggle
!Rails.env.production?
end
def self.new_data_sharing_agreement?
def self.new_data_protection_confirmation?
!Rails.env.production?
end
end

2
app/views/logs/_create_for_org_actions.html.erb

@ -1,5 +1,5 @@
<div class="govuk-button-group app-filter-toggle">
<% if !FeatureToggle.new_data_sharing_agreement? || @organisation.data_sharing_agreement.present? %>
<% if !FeatureToggle.new_data_protection_confirmation? || @organisation.data_protection_confirmation.&confirmed? %>
<% if current_page?(controller: 'organisations', action: 'lettings_logs') %>
<%= govuk_button_to "Create a new lettings log for this organisation", lettings_logs_path(lettings_log: { owning_organisation_id: @organisation.id }, method: :post) %>
<% end %>

6
app/views/organisations/data_sharing_agreement.html.erb

@ -6,8 +6,8 @@
<%= org_name_for_data_sharing_agreement(@data_sharing_agreement, current_user) %> and Department for Levelling Up, Housing and Communities
</h2>
<p class="govuk-body-m">
<% if @data_sharing_agreement %>
This agreement is made the <%= @data_sharing_agreement.signed_at.day.ordinalize %> day of <%= @data_sharing_agreement.signed_at.strftime("%B") %> <%= @data_sharing_agreement.signed_at.year %>
<% if @data_sharing_agreement&.confirmed? %>
This agreement is made the <%= @data_sharing_agreement.created_at.day.ordinalize %> day of <%= @data_sharing_agreement.created_at.strftime("%B") %> <%= @data_sharing_agreement.created_at.year %>
<% elsif current_user.is_dpo? %>
This agreement is made the <%= Time.zone.now.day.ordinalize %> day of <%= Time.zone.now.strftime("%B") %> <%= Time.zone.now.year %>
<% else %>
@ -134,7 +134,7 @@
<li>Title: Deputy Director</li>
</ul>
<% if current_user.is_dpo? && @organisation.data_sharing_agreement.nil? %>
<% if current_user.is_dpo? && !(@organisation.data_sharing_agreement&.confirmed?) %>
<div class="govuk-button-group govuk-!-margin-top-9">
<%= govuk_button_to("Accept this agreement", data_sharing_agreement_organisation_path(@organisation), method: :post) %>
<%= govuk_button_link_to("Cancel", details_organisation_path(@organisation), secondary: true) %>

5
db/migrate/20230609101144_drop_data_sharing_adreement_table.rb

@ -0,0 +1,5 @@
class DropDataSharingAdreementTable < ActiveRecord::Migration[7.0]
def change
drop_table :data_sharing_agreements # rubocop:disable Rails/ReversibleMigration
end
end

18
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: 2023_05_30_094653) do
ActiveRecord::Schema[7.0].define(version: 2023_06_09_101144) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -56,22 +56,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_30_094653) do
t.index ["organisation_id"], name: "index_data_protection_confirmations_on_organisation_id"
end
create_table "data_sharing_agreements", force: :cascade do |t|
t.bigint "organisation_id"
t.bigint "data_protection_officer_id"
t.datetime "signed_at", null: false
t.string "organisation_name", null: false
t.string "organisation_address", null: false
t.string "organisation_phone_number"
t.string "dpo_email", null: false
t.string "dpo_name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["data_protection_officer_id"], name: "index_data_sharing_agreements_on_data_protection_officer_id"
t.index ["organisation_id", "data_protection_officer_id"], name: "data_sharing_agreements_unique", unique: true
t.index ["organisation_id"], name: "index_data_sharing_agreements_on_organisation_id"
end
create_table "la_rent_ranges", force: :cascade do |t|
t.integer "ranges_rent_id"
t.integer "lettype"

23
db/seeds.rb

@ -8,15 +8,24 @@
# rubocop:disable Rails/Output
def create_dpo(org)
User.find_or_create_by!(
name: "#{org.name} User",
email: "#{org.name}@example.com",
organisation: standalone_owns_stock,
role: "data_provider",
is_dpo: true,
) do |user|
user.password = "password"
user.confirmed_at = Time.zone.now
end
end
def create_dsa(org)
DataSharingAgreement.find_or_create_by!(
dpo_name: "DPO Name",
dpo_email: "dpo@example.com",
DataProtectionConfirmation.find_or_create_by!(
organisation: org,
organisation_address: org.address_row,
organisation_phone_number: org.phone,
organisation_name: org.name,
signed_at: Time.zone.now,
confirmed: true,
data_protection_officer: create_dpo(org),
)
end

5
spec/factories/data_protection_confirmation.rb

@ -1,7 +1,8 @@
FactoryBot.define do
factory :data_protection_confirmation do
organisation
data_protection_officer { FactoryBot.create(:user, :data_protection_officer) }
organisation { association :organisation, data_sharing_agreement: instance }
data_protection_officer { association :user, :data_protection_officer, organisation: (instance.organisation || organisation) }
confirmed { true }
old_org_id { "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618" }
old_id { "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618" }

15
spec/factories/data_sharing_agreement.rb

@ -1,15 +0,0 @@
FactoryBot.define do
factory :data_sharing_agreement do
organisation { association :organisation, data_sharing_agreement: instance }
signed_at { Time.zone.now }
created_at { Time.zone.now }
updated_at { Time.zone.now }
dpo_name { data_protection_officer&.name || "DPO Name" }
dpo_email { data_protection_officer&.email || "test@example.com" }
organisation_address { organisation }
organisation_phone_number { organisation }
organisation_name { organisation }
end
end

6
spec/factories/organisation.rb

@ -19,11 +19,7 @@ FactoryBot.define do
create(
:data_sharing_agreement,
organisation: org,
dpo_name: "DPO Name",
dpo_email: "test@email.com",
organisation_address: "address 123",
organisation_phone_number: "123456789",
organisation_name: "Organisation Name",
data_protection_officer: org.users.any? ? org.users.first : create(:user, :data_protection_officer, organisation: org),
)
end
end

32
spec/shared/shared_log_examples.rb

@ -106,17 +106,38 @@ RSpec.shared_examples "shared log examples" do |log_type|
end
describe "#verify_dsa_signed" do
before do
allow(FeatureToggle).to receive(:new_data_sharing_agreement?).and_return(false)
end
it "is valid if the DSA is signed" do
log = build(log_type, :in_progress, owning_organisation: create(:organisation))
expect(log).to be_valid
end
it "is valid when owning_organisation nil" do
log = build(log_type, owning_organisation: nil)
expect(log).to be_valid
end
it "is not valid if the DSA is not signed" do
log = build(log_type, owning_organisation: create(:organisation, :without_dsa))
expect(log).not_to be_valid
expect(log.errors[:owning_organisation]).to eq(["Your organisation must accept the Data Sharing Agreement before you can create any logs."])
expect(log).to be_valid
end
end
context "when flag enabled" do
before do
allow(FeatureToggle).to receive(:new_data_sharing_agreement?).and_return(true)
end
it "is valid if the DSA is signed" do
log = build(log_type, :in_progress, owning_organisation: create(:organisation))
expect(log).to be_valid
end
it "is valid when owning_organisation nil" do
@ -124,6 +145,13 @@ RSpec.shared_examples "shared log examples" do |log_type|
expect(log).to be_valid
end
it "is not valid if the DSA is not signed" do
log = build(log_type, owning_organisation: create(:organisation, :without_dsa))
expect(log).not_to be_valid
expect(log.errors[:owning_organisation]).to eq(["Your organisation must accept the Data Sharing Agreement before you can create any logs."])
end
end
end
# rubocop:enable RSpec/AnyInstance

Loading…
Cancel
Save