75 changed files with 2484 additions and 2195 deletions
@ -1,37 +0,0 @@
|
||||
ActiveAdmin.register AdminUser do |
||||
permit_params :email, :phone, :password, :password_confirmation |
||||
|
||||
controller do |
||||
def update_resource(object, attributes) |
||||
update_method = attributes.first[:password].present? ? :update : :update_without_password |
||||
object.send(update_method, *attributes) |
||||
end |
||||
end |
||||
|
||||
index do |
||||
selectable_column |
||||
id_column |
||||
column :email |
||||
column "Phone Number", :phone |
||||
column :current_sign_in_at |
||||
column :sign_in_count |
||||
column :created_at |
||||
actions |
||||
end |
||||
|
||||
filter :email |
||||
filter :phone |
||||
filter :current_sign_in_at |
||||
filter :sign_in_count |
||||
filter :created_at |
||||
|
||||
form do |f| |
||||
f.inputs do |
||||
f.input :email |
||||
f.input :phone |
||||
f.input :password |
||||
f.input :password_confirmation |
||||
end |
||||
f.actions |
||||
end |
||||
end |
||||
@ -1,20 +0,0 @@
|
||||
ActiveAdmin.register CaseLog do |
||||
# See permitted parameters documentation: |
||||
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters |
||||
permit_params do |
||||
CaseLog.editable_fields |
||||
end |
||||
|
||||
index do |
||||
selectable_column |
||||
id_column |
||||
column :created_at |
||||
column :updated_at |
||||
column :status |
||||
column :tenant_code |
||||
column :postcode_full |
||||
column :owning_organisation |
||||
column :managing_organisation |
||||
actions |
||||
end |
||||
end |
||||
@ -1,32 +0,0 @@
|
||||
ActiveAdmin.register_page "Dashboard" do |
||||
menu priority: 1, label: proc { I18n.t("active_admin.dashboard") } |
||||
|
||||
content title: proc { I18n.t("active_admin.dashboard") } do |
||||
columns do |
||||
column do |
||||
panel "Recent logs" do |
||||
table_for CaseLog.order(updated_at: :desc).limit(10) do |
||||
column :id |
||||
column :created_at |
||||
column :updated_at |
||||
column :status |
||||
column :tenant_code |
||||
column :postcode_full |
||||
end |
||||
end |
||||
end |
||||
|
||||
column do |
||||
panel "Total logs in progress" do |
||||
para CaseLog.in_progress.size |
||||
end |
||||
panel "Total logs completed" do |
||||
para CaseLog.completed.size |
||||
end |
||||
panel "Total logs completed" do |
||||
pie_chart CaseLog.group(:status).size |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
@ -1,31 +0,0 @@
|
||||
ActiveAdmin.register Organisation do |
||||
permit_params do |
||||
permitted = %i[name |
||||
phone |
||||
provider_type |
||||
address_line1 |
||||
address_line2 |
||||
postcode |
||||
local_authorities |
||||
holds_own_stock |
||||
other_stock_owners |
||||
managing_agents] |
||||
permitted |
||||
end |
||||
|
||||
index do |
||||
selectable_column |
||||
id_column |
||||
column :name |
||||
column "Org type", :provider_type |
||||
column "Address Line 1", :address_line1 |
||||
column "Address Line 2", :address_line2 |
||||
column :postcode |
||||
column "Phone Number", :phone |
||||
column :local_authorities |
||||
column :holds_own_stock |
||||
column :other_stock_owners |
||||
column :managing_agents |
||||
actions |
||||
end |
||||
end |
||||
@ -1,42 +0,0 @@
|
||||
ActiveAdmin.register User do |
||||
permit_params :name, :email, :password, :password_confirmation, :organisation_id, :role |
||||
|
||||
controller do |
||||
def update_resource(object, attributes) |
||||
update_method = attributes.first[:password].present? ? :update : :update_without_password |
||||
object.send(update_method, *attributes) |
||||
end |
||||
end |
||||
|
||||
index do |
||||
selectable_column |
||||
id_column |
||||
column :name |
||||
column :email |
||||
column :organisation |
||||
column(:role) { |u| u.role.to_s.humanize } |
||||
column :current_sign_in_at |
||||
column :sign_in_count |
||||
column :created_at |
||||
actions |
||||
end |
||||
|
||||
filter :email |
||||
filter :name |
||||
filter :organisation |
||||
filter :current_sign_in_at |
||||
filter :sign_in_count |
||||
filter :created_at |
||||
|
||||
form do |f| |
||||
f.inputs do |
||||
f.input :name |
||||
f.input :email |
||||
f.input :password |
||||
f.input :password_confirmation |
||||
f.input :organisation |
||||
f.input :role |
||||
end |
||||
f.actions |
||||
end |
||||
end |
||||
@ -1,15 +0,0 @@
|
||||
module Admin |
||||
module PaperTrail |
||||
extend ActiveSupport::Concern |
||||
|
||||
included do |
||||
before_action :set_paper_trail_whodunnit |
||||
end |
||||
|
||||
protected |
||||
|
||||
def user_for_paper_trail |
||||
current_admin_user |
||||
end |
||||
end |
||||
end |
||||
@ -1,7 +0,0 @@
|
||||
// Load Active Admin's styles into Webpacker,
|
||||
// see `active_admin.scss` for customization.
|
||||
import "./styles/active_admin.scss"; |
||||
|
||||
import "@activeadmin/activeadmin"; |
||||
|
||||
import "chartkick/chart.js" |
||||
@ -1,17 +0,0 @@
|
||||
// Sass variable overrides must be declared before loading up Active Admin's styles. |
||||
// |
||||
// To view the variables that Active Admin provides, take a look at |
||||
// `app/assets/stylesheets/active_admin/mixins/_variables.scss` in the |
||||
// Active Admin source. |
||||
// |
||||
// For example, to change the sidebar width: |
||||
// $sidebar-width: 242px; |
||||
|
||||
// Active Admin's got SASS! |
||||
@import "@activeadmin/activeadmin/src/scss/mixins"; |
||||
@import "@activeadmin/activeadmin/src/scss/base"; |
||||
|
||||
// Overriding any non-variable Sass must be done after the fact. |
||||
// For example, to change the default status-tag color: |
||||
// |
||||
// .status_tag { background: #6090DB; } |
||||
@ -1,36 +0,0 @@
|
||||
class AdminUser < ApplicationRecord |
||||
# Include default devise modules. Others available are: |
||||
# :confirmable, :timeoutable, :omniauthable |
||||
devise :two_factor_authenticatable, :database_authenticatable, :recoverable, |
||||
:rememberable, :validatable, :trackable, :lockable |
||||
|
||||
has_one_time_password(encrypted: true) |
||||
|
||||
has_paper_trail ignore: %w[last_sign_in_at |
||||
current_sign_in_at |
||||
current_sign_in_ip |
||||
last_sign_in_ip |
||||
failed_attempts |
||||
unlock_token |
||||
locked_at |
||||
reset_password_token |
||||
reset_password_sent_at |
||||
remember_created_at |
||||
sign_in_count |
||||
updated_at] |
||||
|
||||
validates :phone, presence: true, numericality: true |
||||
|
||||
MFA_TEMPLATE_ID = "6bdf5ee1-8e01-4be1-b1f9-747061d8a24c".freeze |
||||
RESET_PASSWORD_TEMPLATE_ID = "fbb2d415-b9b1-4507-ba0a-6e542fa3504d".freeze |
||||
|
||||
def send_two_factor_authentication_code(code) |
||||
template_id = MFA_TEMPLATE_ID |
||||
personalisation = { otp: code } |
||||
DeviseNotifyMailer.new.send_email(email, template_id, personalisation) |
||||
end |
||||
|
||||
def reset_password_notify_template |
||||
RESET_PASSWORD_TEMPLATE_ID |
||||
end |
||||
end |
||||
@ -0,0 +1,35 @@
|
||||
module Imports |
||||
class CaseLogsFieldImportService < ImportService |
||||
def update_field(field, folder) |
||||
case field |
||||
when "tenant_code" |
||||
import_from(folder, :update_tenant_code) |
||||
else |
||||
raise "Updating #{field} is not supported by the field import service" |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def update_tenant_code(xml_doc) |
||||
old_id = field_value(xml_doc, "meta", "document-id") |
||||
record = CaseLog.find_by(old_id:) |
||||
|
||||
if record.present? |
||||
tenant_code = string_or_nil(xml_doc, "_2bTenCode") |
||||
if tenant_code.present? && record.tenant_code.blank? |
||||
record.update!(tenant_code:) |
||||
else |
||||
@logger.info("Case Log #{record.id} has a value for tenant_code, skipping update") |
||||
end |
||||
else |
||||
@logger.warn("Could not find record matching legacy ID #{old_id}") |
||||
end |
||||
end |
||||
|
||||
def string_or_nil(xml_doc, attribute) |
||||
str = field_value(xml_doc, "xmlns", attribute) |
||||
str.presence |
||||
end |
||||
end |
||||
end |
||||
@ -1,35 +1,37 @@
|
||||
<%= govuk_table do |table| %> |
||||
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %> |
||||
<% if searched.present? %> |
||||
<strong><%= pagy.count %></strong> <%= item_label %> found matching ‘<%= searched %>’ of <strong><%= total_count %></strong> total organisations. <%= govuk_link_to("Clear search", request.path) %> |
||||
<% else %> |
||||
<strong><%= pagy.count %></strong> total organisations. |
||||
<section class="app-table-group" tabindex="0" aria-labelledby="<%= title.dasherize %>"> |
||||
<%= govuk_table do |table| %> |
||||
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %> |
||||
<% if searched.present? %> |
||||
<strong><%= pagy.count %></strong> <%= item_label %> found matching ‘<%= searched %>’ of <strong><%= total_count %></strong> total organisations. <%= govuk_link_to("Clear search", request.path) %> |
||||
<% else %> |
||||
<strong><%= pagy.count %></strong> total organisations. |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<%= table.head do |head| %> |
||||
<%= head.row do |row| %> |
||||
<% row.cell(header: true, text: "Name", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Registration number", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Type", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<%= table.head do |head| %> |
||||
<%= head.row do |row| %> |
||||
<% row.cell(header: true, text: "Name", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Registration number", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Type", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% @organisations.each do |organisation| %> |
||||
<%= table.body do |body| %> |
||||
<%= body.row do |row| %> |
||||
<% row.cell(header: true, html_attributes: { |
||||
scope: "row", |
||||
}) do %> |
||||
<%= govuk_link_to(organisation.name, "organisations/#{organisation.id}/logs") %> |
||||
<% @organisations.each do |organisation| %> |
||||
<%= table.body do |body| %> |
||||
<%= body.row do |row| %> |
||||
<% row.cell(header: true, html_attributes: { |
||||
scope: "row", |
||||
}) do %> |
||||
<%= govuk_link_to(organisation.name, "organisations/#{organisation.id}/logs") %> |
||||
<% end %> |
||||
<% row.cell(text: organisation.housing_registration_no) %> |
||||
<% row.cell(text: organisation.display_provider_type) %> |
||||
<% end %> |
||||
<% row.cell(text: organisation.housing_registration_no) %> |
||||
<% row.cell(text: display_provider_type(organisation.provider_type)) %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
</section> |
||||
|
||||
@ -1,54 +1,56 @@
|
||||
<%= govuk_table do |table| %> |
||||
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %> |
||||
<span class="govuk-!-margin-right-4"> |
||||
<% if searched.present? %> |
||||
<strong><%= pagy.count %></strong> <%= item_label %> found matching ‘<%= searched %>’ of <strong><%= total_count %></strong> total users. <%= govuk_link_to("Clear search", request.path) %> |
||||
<% else %> |
||||
<strong><%= pagy.count %></strong> total users. |
||||
<section class="app-table-group" tabindex="0" aria-labelledby="<%= title.dasherize %>"> |
||||
<%= govuk_table do |table| %> |
||||
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %> |
||||
<span class="govuk-!-margin-right-4"> |
||||
<% if searched.present? %> |
||||
<strong><%= pagy.count %></strong> <%= item_label %> found matching ‘<%= searched %>’ of <strong><%= total_count %></strong> total users. <%= govuk_link_to("Clear search", request.path) %> |
||||
<% else %> |
||||
<strong><%= pagy.count %></strong> total users. |
||||
<% end %> |
||||
</span> |
||||
<% if current_user.support? %> |
||||
<% query = searched.present? ? "?search=#{searched}" : nil %> |
||||
<%= govuk_link_to "Download (CSV)", "/users.csv#{query}", type: "text/csv" %> |
||||
<% end %> |
||||
</span> |
||||
<% if current_user.support? %> |
||||
<% query = searched.present? ? "?search=#{searched}" : nil %> |
||||
<%= govuk_link_to "Download (CSV)", "/users.csv#{query}", type: "text/csv" %> |
||||
<% end %> |
||||
<% end %> |
||||
<%= table.head do |head| %> |
||||
<%= head.row do |row| %> |
||||
<% row.cell(header: true, text: "Name and email adress", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Organisation and role", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Last logged in", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<%= table.head do |head| %> |
||||
<%= head.row do |row| %> |
||||
<% row.cell(header: true, text: "Name and email adress", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Organisation and role", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% row.cell(header: true, text: "Last logged in", html_attributes: { |
||||
scope: "col", |
||||
}) %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% users.each do |user| %> |
||||
<%= table.body do |body| %> |
||||
<%= body.row do |row| %> |
||||
<% row.cell(header: true, html_attributes: { |
||||
scope: "row", |
||||
}) do %> |
||||
<%= simple_format(user_cell(user), {}, wrapper_tag: "span") %> |
||||
<% if user.is_data_protection_officer? || user.is_key_contact? %> |
||||
<br> |
||||
<% users.each do |user| %> |
||||
<%= table.body do |body| %> |
||||
<%= body.row do |row| %> |
||||
<% row.cell(header: true, html_attributes: { |
||||
scope: "row", |
||||
}) do %> |
||||
<%= simple_format(user_cell(user), {}, wrapper_tag: "span") %> |
||||
<% if user.is_data_protection_officer? || user.is_key_contact? %> |
||||
<br> |
||||
<% end %> |
||||
<%= user.is_data_protection_officer? ? govuk_tag( |
||||
classes: "app-tag--small", |
||||
colour: "turquoise", |
||||
text: "Data protection officer", |
||||
) : "" %> |
||||
<%= user.is_key_contact? ? govuk_tag( |
||||
classes: "app-tag--small", |
||||
colour: "turquoise", |
||||
text: "Key contact", |
||||
) : "" %> |
||||
<% end %> |
||||
<% row.cell(text: simple_format(org_cell(user), {}, wrapper_tag: "div")) %> |
||||
<% row.cell(text: user.active? ? user.last_sign_in_at&.to_formatted_s(:govuk_date) : "Deactivated") %> |
||||
<% end %> |
||||
<%= user.is_data_protection_officer? ? govuk_tag( |
||||
classes: "app-tag--small", |
||||
colour: "turquoise", |
||||
text: "Data protection officer", |
||||
) : "" %> |
||||
<%= user.is_key_contact? ? govuk_tag( |
||||
classes: "app-tag--small", |
||||
colour: "turquoise", |
||||
text: "Key contact", |
||||
) : "" %> |
||||
<% end %> |
||||
<% row.cell(text: simple_format(org_cell(user), {}, wrapper_tag: "div")) %> |
||||
<% row.cell(text: user.active? ? user.last_sign_in_at&.to_formatted_s(:govuk_date) : "Deactivated") %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
</section> |
||||
|
||||
@ -1,339 +0,0 @@
|
||||
ActiveAdmin.setup do |config| |
||||
# == Site Title |
||||
# |
||||
# Set the title that is displayed on the main layout |
||||
# for each of the active admin pages. |
||||
# |
||||
config.site_title = "DLUHC CORE" |
||||
|
||||
# Set the link url for the title. For example, to take |
||||
# users to your main site. Defaults to no link. |
||||
# |
||||
# config.site_title_link = "/" |
||||
|
||||
# Set an optional image to be displayed for the header |
||||
# instead of a string (overrides :site_title) |
||||
# |
||||
# Note: Aim for an image that's 21px high so it fits in the header. |
||||
# |
||||
# config.site_title_image = "logo.png" |
||||
|
||||
# == Default Namespace |
||||
# |
||||
# Set the default namespace each administration resource |
||||
# will be added to. |
||||
# |
||||
# eg: |
||||
# config.default_namespace = :hello_world |
||||
# |
||||
# This will create resources in the HelloWorld module and |
||||
# will namespace routes to /hello_world/* |
||||
# |
||||
# To set no namespace by default, use: |
||||
# config.default_namespace = false |
||||
# |
||||
# Default: |
||||
# config.default_namespace = :admin |
||||
# |
||||
# You can customize the settings for each namespace by using |
||||
# a namespace block. For example, to change the site title |
||||
# within a namespace: |
||||
# |
||||
# config.namespace :admin do |admin| |
||||
# admin.site_title = "Custom Admin Title" |
||||
# end |
||||
# |
||||
# This will ONLY change the title for the admin section. Other |
||||
# namespaces will continue to use the main "site_title" configuration. |
||||
|
||||
# == User Authentication |
||||
# |
||||
# Active Admin will automatically call an authentication |
||||
# method in a before filter of all controller actions to |
||||
# ensure that there is a currently logged in admin user. |
||||
# |
||||
# This setting changes the method which Active Admin calls |
||||
# within the application controller. |
||||
config.authentication_method = :authenticate_admin_user! |
||||
|
||||
# == User Authorization |
||||
# |
||||
# Active Admin will automatically call an authorization |
||||
# method in a before filter of all controller actions to |
||||
# ensure that there is a user with proper rights. You can use |
||||
# CanCanAdapter or make your own. Please refer to documentation. |
||||
# config.authorization_adapter = ActiveAdmin::CanCanAdapter |
||||
|
||||
# In case you prefer Pundit over other solutions you can here pass |
||||
# the name of default policy class. This policy will be used in every |
||||
# case when Pundit is unable to find suitable policy. |
||||
# config.pundit_default_policy = "MyDefaultPunditPolicy" |
||||
|
||||
# If you wish to maintain a separate set of Pundit policies for admin |
||||
# resources, you may set a namespace here that Pundit will search |
||||
# within when looking for a resource's policy. |
||||
# config.pundit_policy_namespace = :admin |
||||
|
||||
# You can customize your CanCan Ability class name here. |
||||
# config.cancan_ability_class = "Ability" |
||||
|
||||
# You can specify a method to be called on unauthorized access. |
||||
# This is necessary in order to prevent a redirect loop which happens |
||||
# because, by default, user gets redirected to Dashboard. If user |
||||
# doesn't have access to Dashboard, he'll end up in a redirect loop. |
||||
# Method provided here should be defined in application_controller.rb. |
||||
# config.on_unauthorized_access = :access_denied |
||||
|
||||
# == Current User |
||||
# |
||||
# Active Admin will associate actions with the current |
||||
# user performing them. |
||||
# |
||||
# This setting changes the method which Active Admin calls |
||||
# (within the application controller) to return the currently logged in user. |
||||
config.current_user_method = :current_admin_user |
||||
|
||||
# == Logging Out |
||||
# |
||||
# Active Admin displays a logout link on each screen. These |
||||
# settings configure the location and method used for the link. |
||||
# |
||||
# This setting changes the path where the link points to. If it's |
||||
# a string, the strings is used as the path. If it's a Symbol, we |
||||
# will call the method to return the path. |
||||
# |
||||
# Default: |
||||
config.logout_link_path = :destroy_admin_user_session_path |
||||
|
||||
# This setting changes the http method used when rendering the |
||||
# link. For example :get, :delete, :put, etc.. |
||||
# |
||||
# Default: |
||||
# config.logout_link_method = :get |
||||
|
||||
# == Root |
||||
# |
||||
# Set the action to call for the root path. You can set different |
||||
# roots for each namespace. |
||||
# |
||||
# Default: |
||||
# config.root_to = 'dashboard#index' |
||||
|
||||
# == Admin Comments |
||||
# |
||||
# This allows your users to comment on any resource registered with Active Admin. |
||||
# |
||||
# You can completely disable comments: |
||||
config.comments = false |
||||
# |
||||
# You can change the name under which comments are registered: |
||||
# config.comments_registration_name = 'AdminComment' |
||||
# |
||||
# You can change the order for the comments and you can change the column |
||||
# to be used for ordering: |
||||
# config.comments_order = 'created_at ASC' |
||||
# |
||||
# You can disable the menu item for the comments index page: |
||||
# config.comments_menu = false |
||||
# |
||||
# You can customize the comment menu: |
||||
# config.comments_menu = { parent: 'Admin', priority: 1 } |
||||
|
||||
# == Batch Actions |
||||
# |
||||
# Enable and disable Batch Actions |
||||
# |
||||
config.batch_actions = true |
||||
|
||||
# == Controller Filters |
||||
# |
||||
# You can add before, after and around filters to all of your |
||||
# Active Admin resources and pages from here. |
||||
# |
||||
# config.before_action :do_something_awesome |
||||
|
||||
# == Attribute Filters |
||||
# |
||||
# You can exclude possibly sensitive model attributes from being displayed, |
||||
# added to forms, or exported by default by ActiveAdmin |
||||
# |
||||
config.filter_attributes = %i[encrypted_password password password_confirmation] |
||||
|
||||
# == Localize Date/Time Format |
||||
# |
||||
# Set the localize format to display dates and times. |
||||
# To understand how to localize your app with I18n, read more at |
||||
# https://guides.rubyonrails.org/i18n.html |
||||
# |
||||
# You can run `bin/rails runner 'puts I18n.t("date.formats")'` to see the |
||||
# available formats in your application. |
||||
# |
||||
config.localize_format = :long |
||||
|
||||
# == Setting a Favicon |
||||
# |
||||
# config.favicon = 'favicon.ico' |
||||
|
||||
# == Meta Tags |
||||
# |
||||
# Add additional meta tags to the head element of active admin pages. |
||||
# |
||||
# Add tags to all pages logged in users see: |
||||
# config.meta_tags = { author: 'My Company' } |
||||
|
||||
# By default, sign up/sign in/recover password pages are excluded |
||||
# from showing up in search engine results by adding a robots meta |
||||
# tag. You can reset the hash of meta tags included in logged out |
||||
# pages: |
||||
# config.meta_tags_for_logged_out_pages = {} |
||||
|
||||
# == Removing Breadcrumbs |
||||
# |
||||
# Breadcrumbs are enabled by default. You can customize them for individual |
||||
# resources or you can disable them globally from here. |
||||
# |
||||
# config.breadcrumb = false |
||||
|
||||
# == Create Another Checkbox |
||||
# |
||||
# Create another checkbox is disabled by default. You can customize it for individual |
||||
# resources or you can enable them globally from here. |
||||
# |
||||
# config.create_another = true |
||||
|
||||
# == Register Stylesheets & Javascripts |
||||
# |
||||
# We recommend using the built in Active Admin layout and loading |
||||
# up your own stylesheets / javascripts to customize the look |
||||
# and feel. |
||||
# |
||||
# To load a stylesheet: |
||||
# config.register_stylesheet 'my_stylesheet.css' |
||||
# |
||||
# You can provide an options hash for more control, which is passed along to stylesheet_link_tag(): |
||||
# config.register_stylesheet 'my_print_stylesheet.css', media: :print |
||||
# |
||||
# To load a javascript file: |
||||
# config.register_javascript 'my_javascript.js' |
||||
|
||||
# == CSV options |
||||
# |
||||
# Set the CSV builder separator |
||||
# config.csv_options = { col_sep: ';' } |
||||
# |
||||
# Force the use of quotes |
||||
# config.csv_options = { force_quotes: true } |
||||
|
||||
# == Menu System |
||||
# |
||||
# You can add a navigation menu to be used in your application, or configure a provided menu |
||||
# |
||||
# To change the default utility navigation to show a link to your website & a logout btn |
||||
# |
||||
# config.namespace :admin do |admin| |
||||
# admin.build_menu :utility_navigation do |menu| |
||||
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } |
||||
# admin.add_logout_button_to_menu menu |
||||
# end |
||||
# end |
||||
# |
||||
# If you wanted to add a static menu item to the default menu provided: |
||||
# |
||||
# config.namespace :admin do |admin| |
||||
# admin.build_menu :default do |menu| |
||||
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } |
||||
# end |
||||
# end |
||||
|
||||
# == Download Links |
||||
# |
||||
# You can disable download links on resource listing pages, |
||||
# or customize the formats shown per namespace/globally |
||||
# |
||||
# To disable/customize for the :admin namespace: |
||||
# |
||||
# config.namespace :admin do |admin| |
||||
# |
||||
# # Disable the links entirely |
||||
# admin.download_links = false |
||||
# |
||||
# # Only show XML & PDF options |
||||
# admin.download_links = [:xml, :pdf] |
||||
# |
||||
# # Enable/disable the links based on block |
||||
# # (for example, with cancan) |
||||
# admin.download_links = proc { can?(:view_download_links) } |
||||
# |
||||
# end |
||||
|
||||
# == Pagination |
||||
# |
||||
# Pagination is enabled by default for all resources. |
||||
# You can control the default per page count for all resources here. |
||||
# |
||||
# config.default_per_page = 30 |
||||
# |
||||
# You can control the max per page count too. |
||||
# |
||||
# config.max_per_page = 10_000 |
||||
|
||||
# == Filters |
||||
# |
||||
# By default the index screen includes a "Filters" sidebar on the right |
||||
# hand side with a filter for each attribute of the registered model. |
||||
# You can enable or disable them for all resources here. |
||||
# |
||||
# config.filters = true |
||||
# |
||||
# By default the filters include associations in a select, which means |
||||
# that every record will be loaded for each association (up |
||||
# to the value of config.maximum_association_filter_arity). |
||||
# You can enabled or disable the inclusion |
||||
# of those filters by default here. |
||||
# |
||||
# config.include_default_association_filters = true |
||||
|
||||
# config.maximum_association_filter_arity = 256 # default value of :unlimited will change to 256 in a future version |
||||
# config.filter_columns_for_large_association = [ |
||||
# :display_name, |
||||
# :full_name, |
||||
# :name, |
||||
# :username, |
||||
# :login, |
||||
# :title, |
||||
# :email, |
||||
# ] |
||||
# config.filter_method_for_large_association = '_starts_with' |
||||
|
||||
# == Head |
||||
# |
||||
# You can add your own content to the site head like analytics. Make sure |
||||
# you only pass content you trust. |
||||
# |
||||
# config.head = ''.html_safe |
||||
|
||||
# == Footer |
||||
# |
||||
# By default, the footer shows the current Active Admin version. You can |
||||
# override the content of the footer here. |
||||
# |
||||
# config.footer = 'my custom footer text' |
||||
|
||||
# == Sorting |
||||
# |
||||
# By default ActiveAdmin::OrderClause is used for sorting logic |
||||
# You can inherit it with own class and inject it for all resources |
||||
# |
||||
# config.order_clause = MyOrderClause |
||||
|
||||
# == Webpacker |
||||
# |
||||
# By default, Active Admin uses Sprocket's asset pipeline. |
||||
# You can switch to using Webpacker here. |
||||
# |
||||
# config.use_webpacker = true |
||||
end |
||||
|
||||
Rails.application.config.after_initialize do |
||||
ActiveAdmin::BaseController.include Admin::PaperTrail |
||||
end |
||||
@ -0,0 +1,36 @@
|
||||
class DropAdminUsers < ActiveRecord::Migration[7.0] |
||||
def up |
||||
drop_table :admin_users |
||||
end |
||||
|
||||
def down |
||||
create_table "admin_users", force: :cascade do |t| |
||||
t.string "email", default: "", null: false |
||||
t.string "encrypted_password", default: "", null: false |
||||
t.string "reset_password_token" |
||||
t.datetime "reset_password_sent_at", precision: nil |
||||
t.datetime "remember_created_at", precision: nil |
||||
t.datetime "created_at", null: false |
||||
t.datetime "updated_at", null: false |
||||
t.integer "second_factor_attempts_count", default: 0 |
||||
t.string "encrypted_otp_secret_key" |
||||
t.string "encrypted_otp_secret_key_iv" |
||||
t.string "encrypted_otp_secret_key_salt" |
||||
t.string "direct_otp" |
||||
t.datetime "direct_otp_sent_at", precision: nil |
||||
t.datetime "totp_timestamp", precision: nil |
||||
t.string "phone" |
||||
t.string "name" |
||||
t.integer "sign_in_count", default: 0, null: false |
||||
t.datetime "current_sign_in_at", precision: nil |
||||
t.datetime "last_sign_in_at", precision: nil |
||||
t.string "current_sign_in_ip" |
||||
t.string "last_sign_in_ip" |
||||
t.integer "failed_attempts", default: 0 |
||||
t.string "unlock_token" |
||||
t.datetime "locked_at", precision: nil |
||||
t.index %w[encrypted_otp_secret_key], name: "index_admin_users_on_encrypted_otp_secret_key", unique: true |
||||
t.index %w[unlock_token], name: "index_admin_users_on_unlock_token", unique: true |
||||
end |
||||
end |
||||
end |
||||
@ -0,0 +1,18 @@
|
||||
namespace :core do |
||||
desc "Update database field from data XMLs provided by Softwire" |
||||
task :data_import_field, %i[field path] => :environment do |_task, args| |
||||
field = args[:field] |
||||
path = args[:path] |
||||
raise "Usage: rake core:data_import_field['field','path/to/xml_files']" if path.blank? || field.blank? |
||||
|
||||
storage_service = StorageService.new(PaasConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"]) |
||||
|
||||
# We only allow a reduced list of known fields to be updatable |
||||
case field |
||||
when "tenant_code" |
||||
Imports::CaseLogsFieldImportService.new(storage_service).update_field(field, path) |
||||
else |
||||
raise "Field #{field} cannot be updated by data_import_field" |
||||
end |
||||
end |
||||
end |
||||
@ -1,78 +0,0 @@
|
||||
require "rails_helper" |
||||
require_relative "../../support/devise" |
||||
|
||||
describe Admin::AdminUsersController, type: :controller do |
||||
render_views |
||||
let(:page) { Capybara::Node::Simple.new(response.body) } |
||||
let(:resource_title) { "Admin Users" } |
||||
let(:valid_session) { {} } |
||||
let(:signed_in_admin_user) { FactoryBot.create(:admin_user) } |
||||
|
||||
before do |
||||
sign_in signed_in_admin_user |
||||
end |
||||
|
||||
describe "Get admin users" do |
||||
before do |
||||
get :index, session: valid_session |
||||
end |
||||
|
||||
it "returns a table of admin users" do |
||||
expect(page).to have_content(resource_title) |
||||
expect(page).to have_table("index_table_admin_users") |
||||
expect(page).to have_link(AdminUser.first.id.to_s) |
||||
end |
||||
end |
||||
|
||||
describe "Create admin users" do |
||||
let(:params) { { admin_user: { email: "test2@example.com", password: "pAssword1", phone: "07566126368" } } } |
||||
|
||||
it "creates a new admin user" do |
||||
expect { post :create, session: valid_session, params: }.to change(AdminUser, :count).by(1) |
||||
end |
||||
|
||||
it "tracks who created the record" do |
||||
post(:create, session: valid_session, params:) |
||||
created_id = response.location.match(/[0-9]+/)[0] |
||||
whodunnit_actor = AdminUser.find_by(id: created_id).versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(signed_in_admin_user.id) |
||||
end |
||||
end |
||||
|
||||
describe "Update admin users" do |
||||
context "when viewing the form" do |
||||
before do |
||||
get :edit, session: valid_session, params: { id: AdminUser.first.id } |
||||
end |
||||
|
||||
it "shows the correct fields" do |
||||
expect(page).to have_field("admin_user_email") |
||||
expect(page).to have_field("admin_user_password") |
||||
expect(page).to have_field("admin_user_password_confirmation") |
||||
end |
||||
end |
||||
|
||||
context "when updating an admin user" do |
||||
let(:admin_user) { FactoryBot.create(:admin_user) } |
||||
let(:email) { "new_email@example.com" } |
||||
let(:params) { { id: admin_user.id, admin_user: { email: } } } |
||||
|
||||
before do |
||||
patch :update, session: valid_session, params: |
||||
end |
||||
|
||||
it "updates the user without needing to input a password" do |
||||
admin_user.reload |
||||
expect(admin_user.email).to eq(email) |
||||
end |
||||
|
||||
it "tracks who updated the record" do |
||||
admin_user.reload |
||||
whodunnit_actor = admin_user.versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(signed_in_admin_user.id) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
@ -1,92 +0,0 @@
|
||||
require "rails_helper" |
||||
require_relative "../../support/devise" |
||||
|
||||
describe Admin::CaseLogsController, type: :controller do |
||||
before do |
||||
sign_in admin_user |
||||
end |
||||
|
||||
render_views |
||||
let(:page) { Capybara::Node::Simple.new(response.body) } |
||||
let(:resource_title) { "Logs" } |
||||
let(:valid_session) { {} } |
||||
let(:admin_user) { FactoryBot.create(:admin_user) } |
||||
let(:user) { FactoryBot.create(:user) } |
||||
|
||||
describe "Get case logs" do |
||||
let!(:case_log) { FactoryBot.create(:case_log, :in_progress) } |
||||
|
||||
before do |
||||
get :index, session: valid_session |
||||
end |
||||
|
||||
it "returns a table of case logs" do |
||||
expect(page).to have_content(resource_title) |
||||
expect(page).to have_table("index_table_case_logs") |
||||
expect(page).to have_link(case_log.id.to_s) |
||||
expect(page).to have_link(case_log.owning_organisation.name.to_s) |
||||
end |
||||
end |
||||
|
||||
describe "Create case logs" do |
||||
let(:owning_organisation) { FactoryBot.create(:organisation) } |
||||
let(:managing_organisation) { owning_organisation } |
||||
let(:params) do |
||||
{ |
||||
"case_log": { |
||||
"owning_organisation_id": owning_organisation.id, |
||||
"managing_organisation_id": managing_organisation.id, |
||||
"created_by_id": user.id, |
||||
}, |
||||
} |
||||
end |
||||
|
||||
it "creates a new case log" do |
||||
expect { post :create, session: valid_session, params: }.to change(CaseLog, :count).by(1) |
||||
end |
||||
|
||||
it "tracks who created the record" do |
||||
post(:create, session: valid_session, params:) |
||||
created_id = response.location.match(/[0-9]+/)[0] |
||||
whodunnit_actor = CaseLog.find_by(id: created_id).versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(admin_user.id) |
||||
end |
||||
end |
||||
|
||||
describe "Update case log" do |
||||
let!(:case_log) { FactoryBot.create(:case_log, :in_progress) } |
||||
|
||||
context "when viewing the edit form" do |
||||
before do |
||||
get :edit, session: valid_session, params: { id: case_log.id } |
||||
end |
||||
|
||||
it "has the correct fields" do |
||||
expect(page).to have_field("case_log_age1") |
||||
expect(page).to have_field("case_log_tenant_code") |
||||
end |
||||
end |
||||
|
||||
context "when updating the case_log" do |
||||
let(:tenant_code) { "New tenant code by Admin" } |
||||
let(:params) { { id: case_log.id, case_log: { tenant_code: } } } |
||||
|
||||
before do |
||||
patch :update, session: valid_session, params: |
||||
end |
||||
|
||||
it "updates the case log" do |
||||
case_log.reload |
||||
expect(case_log.tenant_code).to eq(tenant_code) |
||||
end |
||||
|
||||
it "tracks who updated the record" do |
||||
case_log.reload |
||||
whodunnit_actor = case_log.versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(admin_user.id) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
@ -1,44 +0,0 @@
|
||||
require "rails_helper" |
||||
require_relative "../../support/devise" |
||||
|
||||
describe Admin::DashboardController, type: :controller do |
||||
before do |
||||
sign_in admin_user |
||||
end |
||||
|
||||
render_views |
||||
let(:page) { Capybara::Node::Simple.new(response.body) } |
||||
let(:resource_title) { "Dashboard" } |
||||
let(:valid_session) { {} } |
||||
let(:admin_user) { FactoryBot.create(:admin_user) } |
||||
|
||||
describe "Get case logs" do |
||||
before do |
||||
2.times { |_| FactoryBot.create(:case_log, :in_progress) } |
||||
FactoryBot.create(:case_log, :completed) |
||||
get :index, session: valid_session |
||||
end |
||||
|
||||
it "returns a dashboard page" do |
||||
expect(page).to have_content(resource_title) |
||||
end |
||||
|
||||
it "returns a panel of recent case logs" do |
||||
expect(page).to have_xpath("//div[contains(@class, 'panel') and contains(//h3, 'Recent logs')]") |
||||
end |
||||
|
||||
it "returns a panel of in progress case logs" do |
||||
panel_xpath = "//div[@class='panel' and .//h3[contains(., 'Total logs in progress')]]" |
||||
panel_content_xpath = "#{panel_xpath}//div[@class='panel_contents' and .//p[contains(., 2)]]" |
||||
expect(page).to have_xpath(panel_xpath) |
||||
expect(page).to have_xpath(panel_content_xpath) |
||||
end |
||||
|
||||
it "returns a panel of completed case logs" do |
||||
panel_xpath = "//div[@class='panel' and .//h3[contains(., 'Total logs completed')]]" |
||||
panel_content_xpath = "#{panel_xpath}//div[@class='panel_contents' and .//p[contains(., 1)]]" |
||||
expect(page).to have_xpath(panel_xpath) |
||||
expect(page).to have_xpath(panel_content_xpath) |
||||
end |
||||
end |
||||
end |
||||
@ -1,78 +0,0 @@
|
||||
require "rails_helper" |
||||
require_relative "../../support/devise" |
||||
|
||||
describe Admin::OrganisationsController, type: :controller do |
||||
render_views |
||||
let(:page) { Capybara::Node::Simple.new(response.body) } |
||||
let(:resource_title) { "Organisations" } |
||||
let(:valid_session) { {} } |
||||
let!(:organisation) { FactoryBot.create(:organisation) } |
||||
let!(:admin_user) { FactoryBot.create(:admin_user) } |
||||
|
||||
before do |
||||
sign_in admin_user |
||||
end |
||||
|
||||
describe "Organisations" do |
||||
before do |
||||
get :index, session: valid_session |
||||
end |
||||
|
||||
it "returns a table of admin users" do |
||||
expect(page).to have_content(resource_title) |
||||
expect(page).to have_table("index_table_organisations") |
||||
expect(page).to have_link(organisation.id.to_s) |
||||
end |
||||
end |
||||
|
||||
describe "Create organisation" do |
||||
let(:params) { { organisation: { name: "DLUHC", provider_type: "LA" } } } |
||||
|
||||
it "creates a organisation" do |
||||
expect { post :create, session: valid_session, params: }.to change(Organisation, :count).by(1) |
||||
end |
||||
|
||||
it "tracks who created the record" do |
||||
post(:create, session: valid_session, params:) |
||||
created_id = response.location.match(/[0-9]+/)[0] |
||||
whodunnit_actor = Organisation.find_by(id: created_id).versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(admin_user.id) |
||||
end |
||||
end |
||||
|
||||
describe "Update organisation" do |
||||
context "when viewing the edit form" do |
||||
before do |
||||
get :edit, session: valid_session, params: { id: organisation.id } |
||||
end |
||||
|
||||
it "has the correct fields" do |
||||
expect(page).to have_field("organisation_name") |
||||
expect(page).to have_field("organisation_provider_type") |
||||
expect(page).to have_field("organisation_phone") |
||||
end |
||||
end |
||||
|
||||
context "when updating the organisation" do |
||||
let(:name) { "New Org Name by Admin" } |
||||
let(:params) { { id: organisation.id, organisation: { name: } } } |
||||
|
||||
before do |
||||
patch :update, session: valid_session, params: |
||||
end |
||||
|
||||
it "updates the organisation" do |
||||
organisation.reload |
||||
expect(organisation.name).to eq(name) |
||||
end |
||||
|
||||
it "tracks who updated the record" do |
||||
organisation.reload |
||||
whodunnit_actor = organisation.versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(admin_user.id) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
@ -1,97 +0,0 @@
|
||||
require "rails_helper" |
||||
require_relative "../../support/devise" |
||||
|
||||
describe Admin::UsersController, type: :controller do |
||||
render_views |
||||
let!(:user) { FactoryBot.create(:user) } |
||||
let(:organisation) { FactoryBot.create(:organisation) } |
||||
let(:page) { Capybara::Node::Simple.new(response.body) } |
||||
let(:resource_title) { "Users" } |
||||
let(:valid_session) { {} } |
||||
let!(:admin_user) { FactoryBot.create(:admin_user) } |
||||
let(:notify_client) { instance_double(Notifications::Client) } |
||||
let(:devise_notify_mailer) { DeviseNotifyMailer.new } |
||||
|
||||
before do |
||||
allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) |
||||
allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) |
||||
allow(notify_client).to receive(:send_email).and_return(true) |
||||
sign_in admin_user |
||||
end |
||||
|
||||
describe "Get users" do |
||||
before do |
||||
get :index, session: valid_session |
||||
end |
||||
|
||||
it "returns a table of users" do |
||||
expect(page).to have_content(resource_title) |
||||
expect(page).to have_table("index_table_users") |
||||
expect(page).to have_link(user.id.to_s) |
||||
end |
||||
end |
||||
|
||||
describe "Create users" do |
||||
let(:params) do |
||||
{ |
||||
user: { |
||||
email: "somethin5@example.com", |
||||
name: "Jane", |
||||
password: "pAssword1", |
||||
organisation_id: organisation.id, |
||||
role: "data_coordinator", |
||||
}, |
||||
} |
||||
end |
||||
|
||||
it "creates a new user" do |
||||
expect { post :create, session: valid_session, params: }.to change(User, :count).by(1) |
||||
end |
||||
|
||||
it "tracks who created the record" do |
||||
post(:create, session: valid_session, params:) |
||||
created_id = response.location.match(/[0-9]+/)[0] |
||||
whodunnit_actor = User.find_by(id: created_id).versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(admin_user.id) |
||||
end |
||||
end |
||||
|
||||
describe "Update users" do |
||||
context "when viewing the edit form" do |
||||
before do |
||||
get :edit, session: valid_session, params: { id: user.id } |
||||
end |
||||
|
||||
it "has the correct fields" do |
||||
expect(page).to have_field("user_email") |
||||
expect(page).to have_field("user_name") |
||||
expect(page).to have_field("user_organisation_id") |
||||
expect(page).to have_field("user_role") |
||||
expect(page).to have_field("user_password") |
||||
expect(page).to have_field("user_password_confirmation") |
||||
end |
||||
end |
||||
|
||||
context "when updating the user" do |
||||
let(:name) { "Pete" } |
||||
let(:params) { { id: user.id, user: { name: } } } |
||||
|
||||
before do |
||||
patch :update, session: valid_session, params: |
||||
end |
||||
|
||||
it "updates the user without needing to input a password" do |
||||
user.reload |
||||
expect(user.name).to eq(name) |
||||
end |
||||
|
||||
it "tracks who updated the record" do |
||||
user.reload |
||||
whodunnit_actor = user.versions.last.actor |
||||
expect(whodunnit_actor).to be_a(AdminUser) |
||||
expect(whodunnit_actor.id).to eq(admin_user.id) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
@ -1,162 +0,0 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe "Admin Panel" do |
||||
let!(:admin) { FactoryBot.create(:admin_user) } |
||||
let(:devise_notify_mailer) { DeviseNotifyMailer.new } |
||||
let(:notify_client) { instance_double(Notifications::Client) } |
||||
let(:mfa_template_id) { AdminUser::MFA_TEMPLATE_ID } |
||||
let(:otp) { "999111" } |
||||
|
||||
before do |
||||
allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) |
||||
allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) |
||||
allow(notify_client).to receive(:send_email).and_return(true) |
||||
end |
||||
|
||||
it "shows the admin sign in page" do |
||||
visit("/admin") |
||||
expect(page).to have_current_path("/admin/sign-in") |
||||
expect(page).to have_content("Sign in to your CORE administration account") |
||||
end |
||||
|
||||
context "with a valid 2FA code" do |
||||
before do |
||||
allow(SecureRandom).to receive(:random_number).and_return(otp) |
||||
visit("/admin") |
||||
fill_in("admin_user[email]", with: admin.email) |
||||
fill_in("admin_user[password]", with: admin.password) |
||||
end |
||||
|
||||
it "authenticates successfully" do |
||||
expect(notify_client).to receive(:send_email).with( |
||||
{ |
||||
email_address: admin.email, |
||||
template_id: mfa_template_id, |
||||
personalisation: { otp: }, |
||||
}, |
||||
) |
||||
click_button("Sign in") |
||||
fill_in("code", with: otp) |
||||
click_button("Submit") |
||||
expect(page).to have_content("Dashboard") |
||||
expect(page).to have_content(I18n.t("devise.two_factor_authentication.success")) |
||||
end |
||||
|
||||
context "but it is more than 15 minutes old" do |
||||
it "does not authenticate successfully" do |
||||
click_button("Sign in") |
||||
admin.update!(direct_otp_sent_at: 16.minutes.ago) |
||||
fill_in("code", with: otp) |
||||
click_button("Submit") |
||||
expect(page).to have_content("Check your email") |
||||
expect(page).to have_http_status(:unprocessable_entity) |
||||
expect(page).to have_title("Error") |
||||
expect(page).to have_selector("#error-summary-title") |
||||
end |
||||
end |
||||
end |
||||
|
||||
context "with an invalid 2FA code" do |
||||
it "does not authenticate successfully" do |
||||
visit("/admin") |
||||
fill_in("admin_user[email]", with: admin.email) |
||||
fill_in("admin_user[password]", with: admin.password) |
||||
click_button("Sign in") |
||||
fill_in("code", with: otp) |
||||
click_button("Submit") |
||||
expect(page).to have_content("Check your email") |
||||
expect(page).to have_http_status(:unprocessable_entity) |
||||
expect(page).to have_title("Error") |
||||
expect(page).to have_selector("#error-summary-title") |
||||
end |
||||
end |
||||
|
||||
context "when the 2FA code needs to be resent" do |
||||
before do |
||||
visit("/admin") |
||||
fill_in("admin_user[email]", with: admin.email) |
||||
fill_in("admin_user[password]", with: admin.password) |
||||
click_button("Sign in") |
||||
end |
||||
|
||||
it "displays the resend view" do |
||||
click_link("Not received an email?") |
||||
expect(page).to have_button("Resend security code") |
||||
end |
||||
|
||||
it "send a new OTP code and redirects back to the 2FA view" do |
||||
click_link("Not received an email?") |
||||
expect { click_button("Resend security code") }.to(change { admin.reload.direct_otp }) |
||||
expect(page).to have_current_path("/admin/two-factor-authentication") |
||||
end |
||||
end |
||||
|
||||
context "when logging out and in again" do |
||||
before do |
||||
allow(SecureRandom).to receive(:random_number).and_return(otp) |
||||
end |
||||
|
||||
it "requires the 2FA code on each login" do |
||||
visit("/admin") |
||||
fill_in("admin_user[email]", with: admin.email) |
||||
fill_in("admin_user[password]", with: admin.password) |
||||
click_button("Sign in") |
||||
fill_in("code", with: otp) |
||||
click_button("Submit") |
||||
click_link("Logout") |
||||
visit("/admin") |
||||
fill_in("admin_user[email]", with: admin.email) |
||||
fill_in("admin_user[password]", with: admin.password) |
||||
click_button("Sign in") |
||||
expect(page).to have_content("Check your email") |
||||
end |
||||
end |
||||
|
||||
context "when the admin has forgotten their password" do |
||||
let!(:admin_user) { FactoryBot.create(:admin_user, last_sign_in_at: Time.zone.now) } |
||||
let(:reset_password_token) { "MCDH5y6Km-U7CFPgAMVS" } |
||||
|
||||
before do |
||||
allow(Devise.token_generator).to receive(:generate).and_return(reset_password_token) |
||||
end |
||||
|
||||
it " is redirected to the reset password page when they click the reset password link" do |
||||
visit("/admin") |
||||
click_link("reset your password") |
||||
expect(page).to have_current_path("/admin/password/new") |
||||
end |
||||
|
||||
it " is shown an error message if they submit without entering an email address" do |
||||
visit("/admin/password/new") |
||||
click_button("Send email") |
||||
expect(page).to have_selector("#error-summary-title") |
||||
expect(page).to have_selector("#user-email-field-error") |
||||
expect(page).to have_title("Error") |
||||
end |
||||
|
||||
it " is redirected to admin login page after reset email is sent" do |
||||
visit("/admin/password/new") |
||||
fill_in("admin_user[email]", with: admin_user.email) |
||||
click_button("Send email") |
||||
expect(page).to have_content("Check your email") |
||||
end |
||||
|
||||
it " is sent a reset password email via Notify" do |
||||
expect(notify_client).to receive(:send_email).with( |
||||
{ |
||||
email_address: admin_user.email, |
||||
template_id: admin_user.reset_password_notify_template, |
||||
personalisation: { |
||||
name: admin_user.email, |
||||
email: admin_user.email, |
||||
organisation: "", |
||||
link: "http://localhost:3000/admin/password/edit?reset_password_token=#{reset_password_token}", |
||||
}, |
||||
}, |
||||
) |
||||
visit("/admin/password/new") |
||||
fill_in("admin_user[email]", with: admin_user.email) |
||||
click_button("Send email") |
||||
end |
||||
end |
||||
end |
||||
@ -0,0 +1,59 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe "Log Features" do |
||||
context "when searching for specific logs" do |
||||
context "when I am logged in and there are logs in the database" do |
||||
let(:user) { FactoryBot.create(:user, last_sign_in_at: Time.zone.now) } |
||||
let!(:log_to_search) { FactoryBot.create(:case_log, owning_organisation: user.organisation) } |
||||
let!(:same_organisation_log) { FactoryBot.create(:case_log, owning_organisation: user.organisation) } |
||||
let!(:another_organisation_log) { FactoryBot.create(:case_log) } |
||||
|
||||
before do |
||||
visit("/logs") |
||||
fill_in("user[email]", with: user.email) |
||||
fill_in("user[password]", with: user.password) |
||||
click_button("Sign in") |
||||
end |
||||
|
||||
it "displays the logs belonging to the same organisation" do |
||||
expect(page).to have_link(log_to_search.id.to_s) |
||||
expect(page).to have_link(same_organisation_log.id.to_s) |
||||
expect(page).not_to have_link(another_organisation_log.id.to_s) |
||||
end |
||||
|
||||
context "when I search for a specific log" do |
||||
it "there is a search bar with a message and search button for logs" do |
||||
expect(page).to have_field("search") |
||||
expect(page).to have_content("Search by log ID, tenant code, property reference or postcode") |
||||
expect(page).to have_button("Search") |
||||
end |
||||
|
||||
context "when I fill in search information and press the search button" do |
||||
before do |
||||
fill_in("search", with: log_to_search.id) |
||||
click_button("Search") |
||||
end |
||||
|
||||
it "displays log matching the log ID" do |
||||
expect(page).to have_link(log_to_search.id.to_s) |
||||
expect(page).not_to have_link(same_organisation_log.id.to_s) |
||||
expect(page).not_to have_link(another_organisation_log.id.to_s) |
||||
end |
||||
|
||||
context "when I want to clear results" do |
||||
it "there is link to clear the search results" do |
||||
expect(page).to have_link("Clear search") |
||||
end |
||||
|
||||
it "displays the logs belonging to the same organisation after I clear the search results" do |
||||
click_link("Clear search") |
||||
expect(page).to have_link(log_to_search.id.to_s) |
||||
expect(page).to have_link(same_organisation_log.id.to_s) |
||||
expect(page).not_to have_link(another_organisation_log.id.to_s) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
@ -0,0 +1,514 @@
|
||||
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-IR-GN" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile"> |
||||
<meta:form-name>2021-CORE-IR-GN</meta:form-name> |
||||
<meta:document-id>5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd</meta:document-id> |
||||
<meta:owner-user-id>e29c492473446dca4d50224f2bb7cf965a261d6f</meta:owner-user-id> |
||||
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id> |
||||
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id> |
||||
<meta:created-date>2022-04-11T13:46:23.953121Z</meta:created-date> |
||||
<meta:modified-date>2022-04-11T13:46:23.953121Z</meta:modified-date> |
||||
<meta:status>submitted-valid</meta:status> |
||||
<meta:reporting-year>2021</meta:reporting-year> |
||||
<meta:upload-method>Manual Entry</meta:upload-method> |
||||
<meta:schema assert-valid="true"/> |
||||
<meta:rules assert-valid="true"/> |
||||
</meta:metadata> |
||||
<Group> |
||||
<Qdp>Yes</Qdp> |
||||
<IRProduct>2 London Living Rent</IRProduct> |
||||
<IRProductOther/> |
||||
<KeyDate>2021-11-10</KeyDate> |
||||
<FORM>300072</FORM> |
||||
<Landlord source-value="9">1 Private Registered Provider</Landlord> |
||||
<Group> |
||||
<_1btenagree>1 This Landlord</_1btenagree> |
||||
<_1bifanother/> |
||||
<_1bCOREcode/> |
||||
</Group> |
||||
</Group> |
||||
<Group> |
||||
<_2a>2 No</_2a> |
||||
<Q2b>2 Assured</Q2b> |
||||
<Q2ba/> |
||||
<_2bTenCode>TEN0021</_2bTenCode> |
||||
<_2cYears/> |
||||
</Group> |
||||
<Group> |
||||
<P1Age override-field="">37</P1Age> |
||||
<P1AR/> |
||||
<P1Sex override-field="">Female</P1Sex> |
||||
<P1Eco>1) Full Time</P1Eco> |
||||
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth> |
||||
<P1Nat>1 UK national resident in UK</P1Nat> |
||||
<P2Age override-field="">34</P2Age> |
||||
<P2AR/> |
||||
<P2Sex override-field="">Female</P2Sex> |
||||
<P2Rel>Other</P2Rel> |
||||
<P2Eco>1) Full Time</P2Eco> |
||||
<P3Age override-field=""/> |
||||
<P3AR/> |
||||
<P3Sex override-field=""/> |
||||
<P3Rel/> |
||||
<P3Eco/> |
||||
<P4Age override-field=""/> |
||||
<P4AR/> |
||||
<P4Sex override-field=""/> |
||||
<P4Rel/> |
||||
<P4Eco/> |
||||
<P5Age override-field=""/> |
||||
<P5AR/> |
||||
<P5Sex override-field=""/> |
||||
<P5Rel/> |
||||
<P5Eco/> |
||||
<P6Age override-field=""/> |
||||
<P6AR/> |
||||
<P6Sex override-field=""/> |
||||
<P6Rel/> |
||||
<P6Eco/> |
||||
<P7Age override-field=""/> |
||||
<P7AR/> |
||||
<P7Sex override-field=""/> |
||||
<P7Rel/> |
||||
<P7Eco/> |
||||
<P8Age override-field=""/> |
||||
<P8AR/> |
||||
<P8Sex override-field=""/> |
||||
<P8Rel/> |
||||
<P8Eco/> |
||||
<Group> |
||||
<ArmedF>2 No</ArmedF> |
||||
<LeftAF/> |
||||
<Inj/> |
||||
<Preg override-field="">2 No</Preg> |
||||
</Group> |
||||
<Group> |
||||
<Q6Ben>7 UC – without housing element (not in receipt of HB and tenants not eligible for housing support e.g. residential care home)</Q6Ben> |
||||
</Group> |
||||
<Group> |
||||
<Q7Ben>3 None</Q7Ben> |
||||
<Q8Refused/> |
||||
<Q8Money override-field=""/> |
||||
<Q8a/> |
||||
</Group> |
||||
<Group> |
||||
<Q9a>8 (Non-violent) relationship breakdown with partner</Q9a> |
||||
<Q9aa/> |
||||
</Group> |
||||
<Group> |
||||
<_9b override-field="">2 No</_9b> |
||||
<Q10-a/> |
||||
<Q10-b/> |
||||
<Q10-c/> |
||||
<Q10-f/> |
||||
<Q10-g>Yes</Q10-g> |
||||
<Q10-h/> |
||||
<Q10ia>1 Yes</Q10ia> |
||||
<Q10ib-1/> |
||||
<Q10ib-2/> |
||||
<Q10ib-3/> |
||||
<Q10ib-4>Yes</Q10ib-4> |
||||
<Q10ib-5/> |
||||
<Q10ib-6/> |
||||
<Q10ib-7/> |
||||
<Q10ib-8/> |
||||
<Q10ib-9/> |
||||
<Q10ib-10/> |
||||
<Q11 override-field="">28 Living with friends or family</Q11> |
||||
<Q12a>Blackpool</Q12a> |
||||
<Q12aONS>E09000009</Q12aONS> |
||||
<Q12b override-field="">FY1 1JD</Q12b> |
||||
<Q12bnot/> |
||||
<Q12c>1 Just moved to Local Authority area</Q12c> |
||||
<Q12d>1 Just moved to Local Authority area</Q12d> |
||||
</Group> |
||||
<Group> |
||||
<Q13>1 Not homeless</Q13> |
||||
<Q14a>2 No</Q14a> |
||||
<Q14b1/> |
||||
<Q14b2/> |
||||
<Q14b3/> |
||||
<Q14b4/> |
||||
<Q14b5/> |
||||
</Group> |
||||
<Group> |
||||
<Q15CBL>2 No</Q15CBL> |
||||
<Q15CHR>2 No</Q15CHR> |
||||
<Q15CAP>2 No</Q15CAP> |
||||
</Group> |
||||
<Group> |
||||
<Q16>10 Other social landlord</Q16> |
||||
</Group> |
||||
</Group> |
||||
<Group> |
||||
<Q17>1 Weekly for 52 weeks</Q17> |
||||
<Q18ai override-field="">100.00</Q18ai> |
||||
<Q18aii override-field=""/> |
||||
<Q18aiii override-field=""/> |
||||
<Q18aiv override-field=""/> |
||||
<Q18av override-field="">100.00</Q18av> |
||||
<Q18d/> |
||||
<Q18dyes override-field=""/> |
||||
<Q19void>2021-04-15</Q19void> |
||||
<Q19repair/> |
||||
<Q20 override-field="">0</Q20> |
||||
<Q21a>PROPREF0042</Q21a> |
||||
</Group> |
||||
<Group> |
||||
<Q22 override-field=""/> |
||||
<Q23>1 Flat / maisonette</Q23> |
||||
<Q24>1 Purpose built</Q24> |
||||
<Q25>2 No</Q25> |
||||
<Q26>4 An Intermediate Rent basis</Q26> |
||||
<Q27>10 Relet - tenant evicted due to arrears</Q27> |
||||
</Group> |
||||
<Group> |
||||
<Q28Auth>Basingstoke & Deane</Q28Auth> |
||||
<Q28ONS>E07000084</Q28ONS> |
||||
<Q28pc override-field="">RG21 3HU</Q28pc> |
||||
</Group> |
||||
<Group> |
||||
<F1Age>1</F1Age> |
||||
<F2Age>1</F2Age> |
||||
<F3Age>0</F3Age> |
||||
<F4Age>0</F4Age> |
||||
<F5Age>0</F5Age> |
||||
<F6Age>0</F6Age> |
||||
<F7Age>0</F7Age> |
||||
<F8Age>0</F8Age> |
||||
<FAge>2</FAge> |
||||
<F1>1</F1> |
||||
<F2>1</F2> |
||||
<F3>0</F3> |
||||
<F4>0</F4> |
||||
<F5>0</F5> |
||||
<F6>0</F6> |
||||
<F7>0</F7> |
||||
<F8>0</F8> |
||||
<F>2</F> |
||||
<P1100>0</P1100> |
||||
<P2100>0</P2100> |
||||
<P3100>0</P3100> |
||||
<P4100>0</P4100> |
||||
<P5100>0</P5100> |
||||
<P6100>0</P6100> |
||||
<P7100>0</P7100> |
||||
<P8100>0</P8100> |
||||
<_100>0</_100> |
||||
<P170>0</P170> |
||||
<P270>0</P270> |
||||
<P370>0</P370> |
||||
<P470>0</P470> |
||||
<P570>0</P570> |
||||
<P670>0</P670> |
||||
<P770>0</P770> |
||||
<P870>0</P870> |
||||
<_70>0</_70> |
||||
<P1PT>0</P1PT> |
||||
<P2PT>0</P2PT> |
||||
<P3PT>0</P3PT> |
||||
<P4PT>0</P4PT> |
||||
<P5PT>0</P5PT> |
||||
<P6PT>0</P6PT> |
||||
<P7PT>0</P7PT> |
||||
<P8PT>0</P8PT> |
||||
<PT>0</PT> |
||||
<P1FT>1</P1FT> |
||||
<P2FT>1</P2FT> |
||||
<P3FT>0</P3FT> |
||||
<P4FT>0</P4FT> |
||||
<P5FT>0</P5FT> |
||||
<P6FT>0</P6FT> |
||||
<P7FT>0</P7FT> |
||||
<P8FT>0</P8FT> |
||||
<FT>2</FT> |
||||
<P1Stud>0</P1Stud> |
||||
<P2Stud>0</P2Stud> |
||||
<P3Stud>0</P3Stud> |
||||
<P4Stud>0</P4Stud> |
||||
<P5Stud>0</P5Stud> |
||||
<P6Stud>0</P6Stud> |
||||
<P7Stud>0</P7Stud> |
||||
<P8Stud>0</P8Stud> |
||||
<Stud>0</Stud> |
||||
<P2Child>0</P2Child> |
||||
<P3Child>0</P3Child> |
||||
<P4Child>0</P4Child> |
||||
<P5Child>0</P5Child> |
||||
<P6Child>0</P6Child> |
||||
<P7Child>0</P7Child> |
||||
<P8Child>0</P8Child> |
||||
<Child>0</Child> |
||||
<P2Partner>0</P2Partner> |
||||
<P3Partner>0</P3Partner> |
||||
<P4Partner>0</P4Partner> |
||||
<P5Partner>0</P5Partner> |
||||
<P6Partner>0</P6Partner> |
||||
<P7Partner>0</P7Partner> |
||||
<P8Partner>0</P8Partner> |
||||
<Partner>0</Partner> |
||||
<Q1bV1>0</Q1bV1> |
||||
<Q1bV2>0</Q1bV2> |
||||
<Q1bV3>1</Q1bV3> |
||||
<Q1bVT>1</Q1bVT> |
||||
<P1Adult>1</P1Adult> |
||||
<P2Adult>1</P2Adult> |
||||
<P3Adult>0</P3Adult> |
||||
<P4Adult>0</P4Adult> |
||||
<P5Adult>0</P5Adult> |
||||
<P6Adult>0</P6Adult> |
||||
<P7Adult>0</P7Adult> |
||||
<P8Adult>0</P8Adult> |
||||
<PAdultT>2</PAdultT> |
||||
<P2PAge>0</P2PAge> |
||||
<P3PAge>0</P3PAge> |
||||
<P4PAge>0</P4PAge> |
||||
<P5PAge>0</P5PAge> |
||||
<P6PAge>0</P6PAge> |
||||
<P7PAge>0</P7PAge> |
||||
<P8PAge>0</P8PAge> |
||||
<PAGE>37</PAGE> |
||||
<P2ChildAge>0</P2ChildAge> |
||||
<P3ChildAge>0</P3ChildAge> |
||||
<P4ChildAge>0</P4ChildAge> |
||||
<P5ChildAge>0</P5ChildAge> |
||||
<P6ChildAge>0</P6ChildAge> |
||||
<P7ChildAge>0</P7ChildAge> |
||||
<P8ChildAge>0</P8ChildAge> |
||||
<ChildAgeMin>0</ChildAgeMin> |
||||
<AgeDiff1>37</AgeDiff1> |
||||
<AgeDiff2>0</AgeDiff2> |
||||
<AgeDiff3>37</AgeDiff3> |
||||
<TODAY>2022-04-12Z</TODAY> |
||||
<FutureLimit>2022-04-27Z</FutureLimit> |
||||
<minmax1/> |
||||
<minmax2/> |
||||
<minmax3/> |
||||
<minmax4/> |
||||
<minmax5/> |
||||
<minmax6/> |
||||
<minmax7/> |
||||
<minmax8/> |
||||
<minmax9/> |
||||
<minmax0/> |
||||
<minmax10/> |
||||
<minmaxT/> |
||||
<Q10av>0</Q10av> |
||||
<Q10bv>0</Q10bv> |
||||
<Q10cv>0</Q10cv> |
||||
<Q10fv>0</Q10fv> |
||||
<Q10gv>20</Q10gv> |
||||
<Q10hv>0</Q10hv> |
||||
<Q10Validate>20</Q10Validate> |
||||
<Q2bv>C</Q2bv> |
||||
<P2Agev>1</P2Agev> |
||||
<P2Sexv>1</P2Sexv> |
||||
<P2Relv>1</P2Relv> |
||||
<P2Ecov>1</P2Ecov> |
||||
<P2valid>4</P2valid> |
||||
<P3Agev>0</P3Agev> |
||||
<P3Sexv>0</P3Sexv> |
||||
<P3Relv>0</P3Relv> |
||||
<P3Ecov>0</P3Ecov> |
||||
<P3valid>0</P3valid> |
||||
<P4Agev>0</P4Agev> |
||||
<P4Sexv>0</P4Sexv> |
||||
<P4Relv>0</P4Relv> |
||||
<P4Ecov>0</P4Ecov> |
||||
<P4valid>0</P4valid> |
||||
<P5Agev>0</P5Agev> |
||||
<P5Sexv>0</P5Sexv> |
||||
<P5Relv>0</P5Relv> |
||||
<P5Ecov>0</P5Ecov> |
||||
<P5valid>0</P5valid> |
||||
<P6Agev>0</P6Agev> |
||||
<P6Sexv>0</P6Sexv> |
||||
<P6Relv>0</P6Relv> |
||||
<P6Ecov>0</P6Ecov> |
||||
<P6valid>0</P6valid> |
||||
<P7Agev>0</P7Agev> |
||||
<P7Sexv>0</P7Sexv> |
||||
<P7Relv>0</P7Relv> |
||||
<P7Ecov>0</P7Ecov> |
||||
<P7valid>0</P7valid> |
||||
<P8Agev>0</P8Agev> |
||||
<P8Sexv>0</P8Sexv> |
||||
<P8Relv>0</P8Relv> |
||||
<P8Ecov>0</P8Ecov> |
||||
<P8valid>0</P8valid> |
||||
<Q14b1v>0</Q14b1v> |
||||
<Q14b2v>0</Q14b2v> |
||||
<Q14b3v>0</Q14b3v> |
||||
<Q14b4v>0</Q14b4v> |
||||
<Q14b5v>0</Q14b5v> |
||||
<Q14bv>0</Q14bv> |
||||
<P2Other>1</P2Other> |
||||
<P3Other>0</P3Other> |
||||
<P4Other>0</P4Other> |
||||
<P5Other>0</P5Other> |
||||
<P6Other>0</P6Other> |
||||
<P7Other>0</P7Other> |
||||
<P8Other>0</P8Other> |
||||
<Other>1</Other> |
||||
<P2ARefused>0</P2ARefused> |
||||
<P3ARefused>0</P3ARefused> |
||||
<P4ARefused>0</P4ARefused> |
||||
<P5ARefused>0</P5ARefused> |
||||
<P6ARefused>0</P6ARefused> |
||||
<P7ARefused>0</P7ARefused> |
||||
<P8ARefused>0</P8ARefused> |
||||
<TAREUSED>0</TAREUSED> |
||||
<P2RRefused>0</P2RRefused> |
||||
<P3RRefused>0</P3RRefused> |
||||
<P4RRefused>0</P4RRefused> |
||||
<P5RRefused>0</P5RRefused> |
||||
<P6RRefused>0</P6RRefused> |
||||
<P7RRefused>0</P7RRefused> |
||||
<P8RRefused>0</P8RRefused> |
||||
<TotRRefused>0</TotRRefused> |
||||
<TOTREFUSED>0</TOTREFUSED> |
||||
</Group> |
||||
<Group> |
||||
<TOTADULT>2</TOTADULT> |
||||
<NEW_OLD>2 Existing Tenant</NEW_OLD> |
||||
<Q18aValid>1</Q18aValid> |
||||
<Q18Valid>1</Q18Valid> |
||||
<VACDAYS>209</VACDAYS> |
||||
<HHMEMB>2</HHMEMB> |
||||
<HHTYPEP1A>1</HHTYPEP1A> |
||||
<HHTYPEP2A>1</HHTYPEP2A> |
||||
<HHTYPEP3A>0</HHTYPEP3A> |
||||
<HHTYPEP4A>0</HHTYPEP4A> |
||||
<HHTYPEP5A>0</HHTYPEP5A> |
||||
<HHTYPEP6A>0</HHTYPEP6A> |
||||
<HHTYPEP7A>0</HHTYPEP7A> |
||||
<HHTYPEP8A>0</HHTYPEP8A> |
||||
<TADULT>2</TADULT> |
||||
<HHTYPEP1E>0</HHTYPEP1E> |
||||
<HHTYPEP2E>0</HHTYPEP2E> |
||||
<HHTYPEP3E>0</HHTYPEP3E> |
||||
<HHTYPEP4E>0</HHTYPEP4E> |
||||
<HHTYPEP5E>0</HHTYPEP5E> |
||||
<HHTYPEP6E>0</HHTYPEP6E> |
||||
<HHTYPEP7E>0</HHTYPEP7E> |
||||
<HHTYPEP8E>0</HHTYPEP8E> |
||||
<TELDER>0</TELDER> |
||||
<HHTYPEP1C>0</HHTYPEP1C> |
||||
<HHTYPEP2C>0</HHTYPEP2C> |
||||
<HHTYPEP3C>0</HHTYPEP3C> |
||||
<HHTYPEP4C>0</HHTYPEP4C> |
||||
<HHTYPEP5C>0</HHTYPEP5C> |
||||
<HHTYPEP6C>0</HHTYPEP6C> |
||||
<HHTYPEP7C>0</HHTYPEP7C> |
||||
<HHTYPEP8C>0</HHTYPEP8C> |
||||
<TCHILD>0</TCHILD> |
||||
<HHTYPE>4 = 2 adults</HHTYPE> |
||||
<WEEKLYINC>200.00</WEEKLYINC> |
||||
<INCOME>200.00</INCOME> |
||||
<TYPEHB>13</TYPEHB> |
||||
<AFFRATE/> |
||||
<Weekinc>200.00</Weekinc> |
||||
<LETTYPE>1 Private Registered Provider</LETTYPE> |
||||
<PLOACODE/> |
||||
<OACODE/> |
||||
<GOVREG>E12000008</GOVREG> |
||||
<OWNINGORGID>1</OWNINGORGID> |
||||
<OWNINGORGNAME>DLUHC</OWNINGORGNAME> |
||||
<MANINGORGNAME>DLUHC</MANINGORGNAME> |
||||
<HCNUM>655</HCNUM> |
||||
<MANHCNUM>655</MANHCNUM> |
||||
<LAHA/> |
||||
<MANINGORGID>1</MANINGORGID> |
||||
<HBTYPE1/> |
||||
<HBTYPE2/> |
||||
<HBTYPE3/> |
||||
<HBTYPE4/> |
||||
<HBTYPE5/> |
||||
<HBTYPE6/> |
||||
<HBTYPE7/> |
||||
<HBTYPE8/> |
||||
<HBTYPE9/> |
||||
<HBTYPE10/> |
||||
<HBTYPE11/> |
||||
<HBTYPE12/> |
||||
<HBTYPE13>13</HBTYPE13> |
||||
<HBTYPE14/> |
||||
<HBTYPE15/> |
||||
<HBTYPE>13</HBTYPE> |
||||
<P1R>0</P1R> |
||||
<P2R>0</P2R> |
||||
<P3R>0</P3R> |
||||
<P4R>0</P4R> |
||||
<P5R>0</P5R> |
||||
<P6R>0</P6R> |
||||
<P7R>0</P7R> |
||||
<P8R>0</P8R> |
||||
<REFUSEDTOT>0</REFUSEDTOT> |
||||
<REFUSED/> |
||||
<WTSHORTFALL/> |
||||
<WRENT>100.00</WRENT> |
||||
<WTCHARGE>100.00</WTCHARGE> |
||||
<WSCHARGE/> |
||||
<WPSCHRGE/> |
||||
<WSUPCHRG/> |
||||
<ChildBen>0.00</ChildBen> |
||||
<WTSHORTFALL1/> |
||||
<WTSHORTFALLHB/> |
||||
<WTSHORTFALLHE/> |
||||
<WRENT1>100.00</WRENT1> |
||||
<WTCHARGE1>100.00</WTCHARGE1> |
||||
<WSCHARGE1/> |
||||
<WPSCHRGE1/> |
||||
<WSUPCHRG1/> |
||||
<ChildBen1>0</ChildBen1> |
||||
</Group> |
||||
<Group> |
||||
<BSa>0</BSa> |
||||
<BSb>2</BSb> |
||||
<BSc>0</BSc> |
||||
<BScm>0</BScm> |
||||
<BScf>0</BScf> |
||||
<BSd>0</BSd> |
||||
<BSdm>0</BSdm> |
||||
<BSdf>0</BSdf> |
||||
<BSe>0</BSe> |
||||
<BSem>0</BSem> |
||||
<BSef>0</BSef> |
||||
<BSf>0</BSf> |
||||
<BSfm>0</BSfm> |
||||
<BSff>0</BSff> |
||||
<BSfmx>0</BSfmx> |
||||
<BSffx>0</BSffx> |
||||
<BEDROOMSTAND>2</BEDROOMSTAND> |
||||
<BEDMINUSBEDS>0</BEDMINUSBEDS> |
||||
<WRENTreduced>100.00</WRENTreduced> |
||||
<NonDepDeduct>23.35</NonDepDeduct> |
||||
<RENTHB/> |
||||
<ChildAllowan>0</ChildAllowan> |
||||
<PrsnlAllowan>0</PrsnlAllowan> |
||||
<HousBenDisAl>0</HousBenDisAl> |
||||
<PAIDHB/> |
||||
<HCNETAF/> |
||||
<ChldAlloCat1>0</ChldAlloCat1> |
||||
<ChldAlloCat2>0</ChldAlloCat2> |
||||
<P2NnDepDedct>23.35</P2NnDepDedct> |
||||
<P3NnDepDedct>0</P3NnDepDedct> |
||||
<P4NnDepDedct>0</P4NnDepDedct> |
||||
<P5NnDepDedct>0</P5NnDepDedct> |
||||
<P6NnDepDedct>0</P6NnDepDedct> |
||||
<P7NnDepDedct>0</P7NnDepDedct> |
||||
<P8NnDepDedct>0</P8NnDepDedct> |
||||
<DAY>10</DAY> |
||||
<MONTH>11</MONTH> |
||||
<YEAR>2021</YEAR> |
||||
<VDAY>15</VDAY> |
||||
<VMONTH>4</VMONTH> |
||||
<VYEAR>2021</VYEAR> |
||||
<MRCDAY/> |
||||
<MRCMONTH/> |
||||
<MRCYEAR/> |
||||
<PPOSTC1>FY1</PPOSTC1> |
||||
<PPOSTC2>1JD</PPOSTC2> |
||||
<POSTCODE/> |
||||
<POSTCOD2/> |
||||
</Group> |
||||
</Group> |
||||
@ -0,0 +1,514 @@
|
||||
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-IR-GN" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile"> |
||||
<meta:form-name>2021-CORE-IR-GN</meta:form-name> |
||||
<meta:document-id>893ufj2s-lq77-42m4-rty6-ej09gh585uy1</meta:document-id> |
||||
<meta:owner-user-id>e29c492473446dca4d50224f2bb7cf965a261d6f</meta:owner-user-id> |
||||
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id> |
||||
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id> |
||||
<meta:created-date>2022-04-11T13:46:23.953121Z</meta:created-date> |
||||
<meta:modified-date>2022-04-11T13:46:23.953121Z</meta:modified-date> |
||||
<meta:status>submitted-valid</meta:status> |
||||
<meta:reporting-year>2021</meta:reporting-year> |
||||
<meta:upload-method>Manual Entry</meta:upload-method> |
||||
<meta:schema assert-valid="true"/> |
||||
<meta:rules assert-valid="true"/> |
||||
</meta:metadata> |
||||
<Group> |
||||
<Qdp>Yes</Qdp> |
||||
<IRProduct>2 London Living Rent</IRProduct> |
||||
<IRProductOther/> |
||||
<KeyDate>2021-11-10</KeyDate> |
||||
<FORM>300072</FORM> |
||||
<Landlord source-value="9">1 Private Registered Provider</Landlord> |
||||
<Group> |
||||
<_1btenagree>1 This Landlord</_1btenagree> |
||||
<_1bifanother/> |
||||
<_1bCOREcode/> |
||||
</Group> |
||||
</Group> |
||||
<Group> |
||||
<_2a>2 No</_2a> |
||||
<Q2b>2 Assured</Q2b> |
||||
<Q2ba/> |
||||
<_2bTenCode>TEN0021</_2bTenCode> |
||||
<_2cYears/> |
||||
</Group> |
||||
<Group> |
||||
<P1Age override-field="">37</P1Age> |
||||
<P1AR/> |
||||
<P1Sex override-field="">Female</P1Sex> |
||||
<P1Eco>1) Full Time</P1Eco> |
||||
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth> |
||||
<P1Nat>1 UK national resident in UK</P1Nat> |
||||
<P2Age override-field="">34</P2Age> |
||||
<P2AR/> |
||||
<P2Sex override-field="">Female</P2Sex> |
||||
<P2Rel>Other</P2Rel> |
||||
<P2Eco>1) Full Time</P2Eco> |
||||
<P3Age override-field=""/> |
||||
<P3AR/> |
||||
<P3Sex override-field=""/> |
||||
<P3Rel/> |
||||
<P3Eco/> |
||||
<P4Age override-field=""/> |
||||
<P4AR/> |
||||
<P4Sex override-field=""/> |
||||
<P4Rel/> |
||||
<P4Eco/> |
||||
<P5Age override-field=""/> |
||||
<P5AR/> |
||||
<P5Sex override-field=""/> |
||||
<P5Rel/> |
||||
<P5Eco/> |
||||
<P6Age override-field=""/> |
||||
<P6AR/> |
||||
<P6Sex override-field=""/> |
||||
<P6Rel/> |
||||
<P6Eco/> |
||||
<P7Age override-field=""/> |
||||
<P7AR/> |
||||
<P7Sex override-field=""/> |
||||
<P7Rel/> |
||||
<P7Eco/> |
||||
<P8Age override-field=""/> |
||||
<P8AR/> |
||||
<P8Sex override-field=""/> |
||||
<P8Rel/> |
||||
<P8Eco/> |
||||
<Group> |
||||
<ArmedF>2 No</ArmedF> |
||||
<LeftAF/> |
||||
<Inj/> |
||||
<Preg override-field="">2 No</Preg> |
||||
</Group> |
||||
<Group> |
||||
<Q6Ben>7 UC – without housing element (not in receipt of HB and tenants not eligible for housing support e.g. residential care home)</Q6Ben> |
||||
</Group> |
||||
<Group> |
||||
<Q7Ben>3 None</Q7Ben> |
||||
<Q8Refused/> |
||||
<Q8Money override-field=""/> |
||||
<Q8a/> |
||||
</Group> |
||||
<Group> |
||||
<Q9a>8 (Non-violent) relationship breakdown with partner</Q9a> |
||||
<Q9aa/> |
||||
</Group> |
||||
<Group> |
||||
<_9b override-field="">2 No</_9b> |
||||
<Q10-a/> |
||||
<Q10-b/> |
||||
<Q10-c/> |
||||
<Q10-f/> |
||||
<Q10-g>Yes</Q10-g> |
||||
<Q10-h/> |
||||
<Q10ia>1 Yes</Q10ia> |
||||
<Q10ib-1/> |
||||
<Q10ib-2/> |
||||
<Q10ib-3/> |
||||
<Q10ib-4>Yes</Q10ib-4> |
||||
<Q10ib-5/> |
||||
<Q10ib-6/> |
||||
<Q10ib-7/> |
||||
<Q10ib-8/> |
||||
<Q10ib-9/> |
||||
<Q10ib-10/> |
||||
<Q11 override-field="">28 Living with friends or family</Q11> |
||||
<Q12a>Blackpool</Q12a> |
||||
<Q12aONS>E09000009</Q12aONS> |
||||
<Q12b override-field="">FY1 1JD</Q12b> |
||||
<Q12bnot/> |
||||
<Q12c>1 Just moved to Local Authority area</Q12c> |
||||
<Q12d>1 Just moved to Local Authority area</Q12d> |
||||
</Group> |
||||
<Group> |
||||
<Q13>1 Not homeless</Q13> |
||||
<Q14a>2 No</Q14a> |
||||
<Q14b1/> |
||||
<Q14b2/> |
||||
<Q14b3/> |
||||
<Q14b4/> |
||||
<Q14b5/> |
||||
</Group> |
||||
<Group> |
||||
<Q15CBL>2 No</Q15CBL> |
||||
<Q15CHR>2 No</Q15CHR> |
||||
<Q15CAP>2 No</Q15CAP> |
||||
</Group> |
||||
<Group> |
||||
<Q16>10 Other social landlord</Q16> |
||||
</Group> |
||||
</Group> |
||||
<Group> |
||||
<Q17>1 Weekly for 52 weeks</Q17> |
||||
<Q18ai override-field="">100.00</Q18ai> |
||||
<Q18aii override-field=""/> |
||||
<Q18aiii override-field=""/> |
||||
<Q18aiv override-field=""/> |
||||
<Q18av override-field="">100.00</Q18av> |
||||
<Q18d/> |
||||
<Q18dyes override-field=""/> |
||||
<Q19void>2021-04-15</Q19void> |
||||
<Q19repair/> |
||||
<Q20 override-field="">0</Q20> |
||||
<Q21a>PROPREF0042</Q21a> |
||||
</Group> |
||||
<Group> |
||||
<Q22 override-field=""/> |
||||
<Q23>1 Flat / maisonette</Q23> |
||||
<Q24>1 Purpose built</Q24> |
||||
<Q25>2 No</Q25> |
||||
<Q26>4 An Intermediate Rent basis</Q26> |
||||
<Q27>10 Relet - tenant evicted due to arrears</Q27> |
||||
</Group> |
||||
<Group> |
||||
<Q28Auth>Basingstoke & Deane</Q28Auth> |
||||
<Q28ONS>E07000084</Q28ONS> |
||||
<Q28pc override-field="">RG21 3HU</Q28pc> |
||||
</Group> |
||||
<Group> |
||||
<F1Age>1</F1Age> |
||||
<F2Age>1</F2Age> |
||||
<F3Age>0</F3Age> |
||||
<F4Age>0</F4Age> |
||||
<F5Age>0</F5Age> |
||||
<F6Age>0</F6Age> |
||||
<F7Age>0</F7Age> |
||||
<F8Age>0</F8Age> |
||||
<FAge>2</FAge> |
||||
<F1>1</F1> |
||||
<F2>1</F2> |
||||
<F3>0</F3> |
||||
<F4>0</F4> |
||||
<F5>0</F5> |
||||
<F6>0</F6> |
||||
<F7>0</F7> |
||||
<F8>0</F8> |
||||
<F>2</F> |
||||
<P1100>0</P1100> |
||||
<P2100>0</P2100> |
||||
<P3100>0</P3100> |
||||
<P4100>0</P4100> |
||||
<P5100>0</P5100> |
||||
<P6100>0</P6100> |
||||
<P7100>0</P7100> |
||||
<P8100>0</P8100> |
||||
<_100>0</_100> |
||||
<P170>0</P170> |
||||
<P270>0</P270> |
||||
<P370>0</P370> |
||||
<P470>0</P470> |
||||
<P570>0</P570> |
||||
<P670>0</P670> |
||||
<P770>0</P770> |
||||
<P870>0</P870> |
||||
<_70>0</_70> |
||||
<P1PT>0</P1PT> |
||||
<P2PT>0</P2PT> |
||||
<P3PT>0</P3PT> |
||||
<P4PT>0</P4PT> |
||||
<P5PT>0</P5PT> |
||||
<P6PT>0</P6PT> |
||||
<P7PT>0</P7PT> |
||||
<P8PT>0</P8PT> |
||||
<PT>0</PT> |
||||
<P1FT>1</P1FT> |
||||
<P2FT>1</P2FT> |
||||
<P3FT>0</P3FT> |
||||
<P4FT>0</P4FT> |
||||
<P5FT>0</P5FT> |
||||
<P6FT>0</P6FT> |
||||
<P7FT>0</P7FT> |
||||
<P8FT>0</P8FT> |
||||
<FT>2</FT> |
||||
<P1Stud>0</P1Stud> |
||||
<P2Stud>0</P2Stud> |
||||
<P3Stud>0</P3Stud> |
||||
<P4Stud>0</P4Stud> |
||||
<P5Stud>0</P5Stud> |
||||
<P6Stud>0</P6Stud> |
||||
<P7Stud>0</P7Stud> |
||||
<P8Stud>0</P8Stud> |
||||
<Stud>0</Stud> |
||||
<P2Child>0</P2Child> |
||||
<P3Child>0</P3Child> |
||||
<P4Child>0</P4Child> |
||||
<P5Child>0</P5Child> |
||||
<P6Child>0</P6Child> |
||||
<P7Child>0</P7Child> |
||||
<P8Child>0</P8Child> |
||||
<Child>0</Child> |
||||
<P2Partner>0</P2Partner> |
||||
<P3Partner>0</P3Partner> |
||||
<P4Partner>0</P4Partner> |
||||
<P5Partner>0</P5Partner> |
||||
<P6Partner>0</P6Partner> |
||||
<P7Partner>0</P7Partner> |
||||
<P8Partner>0</P8Partner> |
||||
<Partner>0</Partner> |
||||
<Q1bV1>0</Q1bV1> |
||||
<Q1bV2>0</Q1bV2> |
||||
<Q1bV3>1</Q1bV3> |
||||
<Q1bVT>1</Q1bVT> |
||||
<P1Adult>1</P1Adult> |
||||
<P2Adult>1</P2Adult> |
||||
<P3Adult>0</P3Adult> |
||||
<P4Adult>0</P4Adult> |
||||
<P5Adult>0</P5Adult> |
||||
<P6Adult>0</P6Adult> |
||||
<P7Adult>0</P7Adult> |
||||
<P8Adult>0</P8Adult> |
||||
<PAdultT>2</PAdultT> |
||||
<P2PAge>0</P2PAge> |
||||
<P3PAge>0</P3PAge> |
||||
<P4PAge>0</P4PAge> |
||||
<P5PAge>0</P5PAge> |
||||
<P6PAge>0</P6PAge> |
||||
<P7PAge>0</P7PAge> |
||||
<P8PAge>0</P8PAge> |
||||
<PAGE>37</PAGE> |
||||
<P2ChildAge>0</P2ChildAge> |
||||
<P3ChildAge>0</P3ChildAge> |
||||
<P4ChildAge>0</P4ChildAge> |
||||
<P5ChildAge>0</P5ChildAge> |
||||
<P6ChildAge>0</P6ChildAge> |
||||
<P7ChildAge>0</P7ChildAge> |
||||
<P8ChildAge>0</P8ChildAge> |
||||
<ChildAgeMin>0</ChildAgeMin> |
||||
<AgeDiff1>37</AgeDiff1> |
||||
<AgeDiff2>0</AgeDiff2> |
||||
<AgeDiff3>37</AgeDiff3> |
||||
<TODAY>2022-04-12Z</TODAY> |
||||
<FutureLimit>2022-04-27Z</FutureLimit> |
||||
<minmax1/> |
||||
<minmax2/> |
||||
<minmax3/> |
||||
<minmax4/> |
||||
<minmax5/> |
||||
<minmax6/> |
||||
<minmax7/> |
||||
<minmax8/> |
||||
<minmax9/> |
||||
<minmax0/> |
||||
<minmax10/> |
||||
<minmaxT/> |
||||
<Q10av>0</Q10av> |
||||
<Q10bv>0</Q10bv> |
||||
<Q10cv>0</Q10cv> |
||||
<Q10fv>0</Q10fv> |
||||
<Q10gv>20</Q10gv> |
||||
<Q10hv>0</Q10hv> |
||||
<Q10Validate>20</Q10Validate> |
||||
<Q2bv>C</Q2bv> |
||||
<P2Agev>1</P2Agev> |
||||
<P2Sexv>1</P2Sexv> |
||||
<P2Relv>1</P2Relv> |
||||
<P2Ecov>1</P2Ecov> |
||||
<P2valid>4</P2valid> |
||||
<P3Agev>0</P3Agev> |
||||
<P3Sexv>0</P3Sexv> |
||||
<P3Relv>0</P3Relv> |
||||
<P3Ecov>0</P3Ecov> |
||||
<P3valid>0</P3valid> |
||||
<P4Agev>0</P4Agev> |
||||
<P4Sexv>0</P4Sexv> |
||||
<P4Relv>0</P4Relv> |
||||
<P4Ecov>0</P4Ecov> |
||||
<P4valid>0</P4valid> |
||||
<P5Agev>0</P5Agev> |
||||
<P5Sexv>0</P5Sexv> |
||||
<P5Relv>0</P5Relv> |
||||
<P5Ecov>0</P5Ecov> |
||||
<P5valid>0</P5valid> |
||||
<P6Agev>0</P6Agev> |
||||
<P6Sexv>0</P6Sexv> |
||||
<P6Relv>0</P6Relv> |
||||
<P6Ecov>0</P6Ecov> |
||||
<P6valid>0</P6valid> |
||||
<P7Agev>0</P7Agev> |
||||
<P7Sexv>0</P7Sexv> |
||||
<P7Relv>0</P7Relv> |
||||
<P7Ecov>0</P7Ecov> |
||||
<P7valid>0</P7valid> |
||||
<P8Agev>0</P8Agev> |
||||
<P8Sexv>0</P8Sexv> |
||||
<P8Relv>0</P8Relv> |
||||
<P8Ecov>0</P8Ecov> |
||||
<P8valid>0</P8valid> |
||||
<Q14b1v>0</Q14b1v> |
||||
<Q14b2v>0</Q14b2v> |
||||
<Q14b3v>0</Q14b3v> |
||||
<Q14b4v>0</Q14b4v> |
||||
<Q14b5v>0</Q14b5v> |
||||
<Q14bv>0</Q14bv> |
||||
<P2Other>1</P2Other> |
||||
<P3Other>0</P3Other> |
||||
<P4Other>0</P4Other> |
||||
<P5Other>0</P5Other> |
||||
<P6Other>0</P6Other> |
||||
<P7Other>0</P7Other> |
||||
<P8Other>0</P8Other> |
||||
<Other>1</Other> |
||||
<P2ARefused>0</P2ARefused> |
||||
<P3ARefused>0</P3ARefused> |
||||
<P4ARefused>0</P4ARefused> |
||||
<P5ARefused>0</P5ARefused> |
||||
<P6ARefused>0</P6ARefused> |
||||
<P7ARefused>0</P7ARefused> |
||||
<P8ARefused>0</P8ARefused> |
||||
<TAREUSED>0</TAREUSED> |
||||
<P2RRefused>0</P2RRefused> |
||||
<P3RRefused>0</P3RRefused> |
||||
<P4RRefused>0</P4RRefused> |
||||
<P5RRefused>0</P5RRefused> |
||||
<P6RRefused>0</P6RRefused> |
||||
<P7RRefused>0</P7RRefused> |
||||
<P8RRefused>0</P8RRefused> |
||||
<TotRRefused>0</TotRRefused> |
||||
<TOTREFUSED>0</TOTREFUSED> |
||||
</Group> |
||||
<Group> |
||||
<TOTADULT>2</TOTADULT> |
||||
<NEW_OLD>2 Existing Tenant</NEW_OLD> |
||||
<Q18aValid>1</Q18aValid> |
||||
<Q18Valid>1</Q18Valid> |
||||
<VACDAYS>209</VACDAYS> |
||||
<HHMEMB>2</HHMEMB> |
||||
<HHTYPEP1A>1</HHTYPEP1A> |
||||
<HHTYPEP2A>1</HHTYPEP2A> |
||||
<HHTYPEP3A>0</HHTYPEP3A> |
||||
<HHTYPEP4A>0</HHTYPEP4A> |
||||
<HHTYPEP5A>0</HHTYPEP5A> |
||||
<HHTYPEP6A>0</HHTYPEP6A> |
||||
<HHTYPEP7A>0</HHTYPEP7A> |
||||
<HHTYPEP8A>0</HHTYPEP8A> |
||||
<TADULT>2</TADULT> |
||||
<HHTYPEP1E>0</HHTYPEP1E> |
||||
<HHTYPEP2E>0</HHTYPEP2E> |
||||
<HHTYPEP3E>0</HHTYPEP3E> |
||||
<HHTYPEP4E>0</HHTYPEP4E> |
||||
<HHTYPEP5E>0</HHTYPEP5E> |
||||
<HHTYPEP6E>0</HHTYPEP6E> |
||||
<HHTYPEP7E>0</HHTYPEP7E> |
||||
<HHTYPEP8E>0</HHTYPEP8E> |
||||
<TELDER>0</TELDER> |
||||
<HHTYPEP1C>0</HHTYPEP1C> |
||||
<HHTYPEP2C>0</HHTYPEP2C> |
||||
<HHTYPEP3C>0</HHTYPEP3C> |
||||
<HHTYPEP4C>0</HHTYPEP4C> |
||||
<HHTYPEP5C>0</HHTYPEP5C> |
||||
<HHTYPEP6C>0</HHTYPEP6C> |
||||
<HHTYPEP7C>0</HHTYPEP7C> |
||||
<HHTYPEP8C>0</HHTYPEP8C> |
||||
<TCHILD>0</TCHILD> |
||||
<HHTYPE>4 = 2 adults</HHTYPE> |
||||
<WEEKLYINC>200.00</WEEKLYINC> |
||||
<INCOME>200.00</INCOME> |
||||
<TYPEHB>13</TYPEHB> |
||||
<AFFRATE/> |
||||
<Weekinc>200.00</Weekinc> |
||||
<LETTYPE>1 Private Registered Provider</LETTYPE> |
||||
<PLOACODE/> |
||||
<OACODE/> |
||||
<GOVREG>E12000008</GOVREG> |
||||
<OWNINGORGID>1</OWNINGORGID> |
||||
<OWNINGORGNAME>DLUHC</OWNINGORGNAME> |
||||
<MANINGORGNAME>DLUHC</MANINGORGNAME> |
||||
<HCNUM>655</HCNUM> |
||||
<MANHCNUM>655</MANHCNUM> |
||||
<LAHA/> |
||||
<MANINGORGID>1</MANINGORGID> |
||||
<HBTYPE1/> |
||||
<HBTYPE2/> |
||||
<HBTYPE3/> |
||||
<HBTYPE4/> |
||||
<HBTYPE5/> |
||||
<HBTYPE6/> |
||||
<HBTYPE7/> |
||||
<HBTYPE8/> |
||||
<HBTYPE9/> |
||||
<HBTYPE10/> |
||||
<HBTYPE11/> |
||||
<HBTYPE12/> |
||||
<HBTYPE13>13</HBTYPE13> |
||||
<HBTYPE14/> |
||||
<HBTYPE15/> |
||||
<HBTYPE>13</HBTYPE> |
||||
<P1R>0</P1R> |
||||
<P2R>0</P2R> |
||||
<P3R>0</P3R> |
||||
<P4R>0</P4R> |
||||
<P5R>0</P5R> |
||||
<P6R>0</P6R> |
||||
<P7R>0</P7R> |
||||
<P8R>0</P8R> |
||||
<REFUSEDTOT>0</REFUSEDTOT> |
||||
<REFUSED/> |
||||
<WTSHORTFALL/> |
||||
<WRENT>100.00</WRENT> |
||||
<WTCHARGE>100.00</WTCHARGE> |
||||
<WSCHARGE/> |
||||
<WPSCHRGE/> |
||||
<WSUPCHRG/> |
||||
<ChildBen>0.00</ChildBen> |
||||
<WTSHORTFALL1/> |
||||
<WTSHORTFALLHB/> |
||||
<WTSHORTFALLHE/> |
||||
<WRENT1>100.00</WRENT1> |
||||
<WTCHARGE1>100.00</WTCHARGE1> |
||||
<WSCHARGE1/> |
||||
<WPSCHRGE1/> |
||||
<WSUPCHRG1/> |
||||
<ChildBen1>0</ChildBen1> |
||||
</Group> |
||||
<Group> |
||||
<BSa>0</BSa> |
||||
<BSb>2</BSb> |
||||
<BSc>0</BSc> |
||||
<BScm>0</BScm> |
||||
<BScf>0</BScf> |
||||
<BSd>0</BSd> |
||||
<BSdm>0</BSdm> |
||||
<BSdf>0</BSdf> |
||||
<BSe>0</BSe> |
||||
<BSem>0</BSem> |
||||
<BSef>0</BSef> |
||||
<BSf>0</BSf> |
||||
<BSfm>0</BSfm> |
||||
<BSff>0</BSff> |
||||
<BSfmx>0</BSfmx> |
||||
<BSffx>0</BSffx> |
||||
<BEDROOMSTAND>2</BEDROOMSTAND> |
||||
<BEDMINUSBEDS>0</BEDMINUSBEDS> |
||||
<WRENTreduced>100.00</WRENTreduced> |
||||
<NonDepDeduct>23.35</NonDepDeduct> |
||||
<RENTHB/> |
||||
<ChildAllowan>0</ChildAllowan> |
||||
<PrsnlAllowan>0</PrsnlAllowan> |
||||
<HousBenDisAl>0</HousBenDisAl> |
||||
<PAIDHB/> |
||||
<HCNETAF/> |
||||
<ChldAlloCat1>0</ChldAlloCat1> |
||||
<ChldAlloCat2>0</ChldAlloCat2> |
||||
<P2NnDepDedct>23.35</P2NnDepDedct> |
||||
<P3NnDepDedct>0</P3NnDepDedct> |
||||
<P4NnDepDedct>0</P4NnDepDedct> |
||||
<P5NnDepDedct>0</P5NnDepDedct> |
||||
<P6NnDepDedct>0</P6NnDepDedct> |
||||
<P7NnDepDedct>0</P7NnDepDedct> |
||||
<P8NnDepDedct>0</P8NnDepDedct> |
||||
<DAY>10</DAY> |
||||
<MONTH>11</MONTH> |
||||
<YEAR>2021</YEAR> |
||||
<VDAY>15</VDAY> |
||||
<VMONTH>4</VMONTH> |
||||
<VYEAR>2021</VYEAR> |
||||
<MRCDAY/> |
||||
<MRCMONTH/> |
||||
<MRCYEAR/> |
||||
<PPOSTC1>FY1</PPOSTC1> |
||||
<PPOSTC2>1JD</PPOSTC2> |
||||
<POSTCODE/> |
||||
<POSTCOD2/> |
||||
</Group> |
||||
</Group> |
||||
@ -0,0 +1,57 @@
|
||||
require "rails_helper" |
||||
require "rake" |
||||
|
||||
describe "rake core:data_import_field", type: :task do |
||||
subject(:task) { Rake::Task["core:data_import_field"] } |
||||
|
||||
let(:instance_name) { "paas_import_instance" } |
||||
let(:storage_service) { instance_double(StorageService) } |
||||
let(:paas_config_service) { instance_double(PaasConfigurationService) } |
||||
|
||||
before do |
||||
Rake.application.rake_require("tasks/data_import_field") |
||||
Rake::Task.define_task(:environment) |
||||
task.reenable |
||||
|
||||
allow(StorageService).to receive(:new).and_return(storage_service) |
||||
allow(PaasConfigurationService).to receive(:new).and_return(paas_config_service) |
||||
allow(ENV).to receive(:[]) |
||||
allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name) |
||||
end |
||||
|
||||
context "when importing a case log field" do |
||||
let(:import_service) { instance_double(Imports::CaseLogsFieldImportService) } |
||||
let(:fixture_path) { "spec/fixtures/softwire_imports/case_logs" } |
||||
|
||||
before do |
||||
allow(Imports::CaseLogsFieldImportService).to receive(:new).and_return(import_service) |
||||
allow(import_service).to receive(:update_field) |
||||
end |
||||
|
||||
context "and we update the tenant_code field" do |
||||
let(:field) { "tenant_code" } |
||||
|
||||
it "properly configures the storage service" do |
||||
expect(StorageService).to receive(:new).with(paas_config_service, instance_name) |
||||
task.invoke(field, fixture_path) |
||||
end |
||||
|
||||
it "calls the expected update method with parameters" do |
||||
expect(import_service).to receive(:update_field).with(field, fixture_path) |
||||
task.invoke(field, fixture_path) |
||||
end |
||||
end |
||||
|
||||
it "raises an exception if no parameters are provided" do |
||||
expect { task.invoke }.to raise_error(/Usage/) |
||||
end |
||||
|
||||
it "raises an exception if a single parameter is provided" do |
||||
expect { task.invoke("one_parameter") }.to raise_error(/Usage/) |
||||
end |
||||
|
||||
it "raises an exception if the field is not supported" do |
||||
expect { task.invoke("random_field", "my_path") }.to raise_error("Field random_field cannot be updated by data_import_field") |
||||
end |
||||
end |
||||
end |
||||
@ -1,84 +0,0 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe AdminUser, type: :model do |
||||
describe "#new" do |
||||
it "requires a phone number" do |
||||
expect { |
||||
described_class.create!( |
||||
email: "admin_test@example.com", |
||||
password: "password123", |
||||
) |
||||
}.to raise_error(ActiveRecord::RecordInvalid) |
||||
end |
||||
|
||||
it "requires a numerical phone number" do |
||||
expect { |
||||
described_class.create!( |
||||
email: "admin_test@example.com", |
||||
password: "password123", |
||||
phone: "string", |
||||
) |
||||
}.to raise_error(ActiveRecord::RecordInvalid) |
||||
end |
||||
|
||||
it "requires an email" do |
||||
expect { |
||||
described_class.create!( |
||||
password: "password123", |
||||
phone: "075752137", |
||||
) |
||||
}.to raise_error(ActiveRecord::RecordInvalid) |
||||
end |
||||
|
||||
it "requires a password" do |
||||
expect { |
||||
described_class.create!( |
||||
email: "admin_test@example.com", |
||||
phone: "075752137", |
||||
) |
||||
}.to raise_error(ActiveRecord::RecordInvalid) |
||||
end |
||||
|
||||
it "can be created" do |
||||
expect { |
||||
described_class.create!( |
||||
email: "admin_test@example.com", |
||||
password: "password123", |
||||
phone: "075752137", |
||||
) |
||||
}.to change(described_class, :count).by(1) |
||||
end |
||||
end |
||||
|
||||
describe "paper trail" do |
||||
let(:admin_user) { FactoryBot.create(:admin_user) } |
||||
|
||||
it "creates a record of changes to a log" do |
||||
expect { admin_user.update!(phone: "09673867853") }.to change(admin_user.versions, :count).by(1) |
||||
end |
||||
|
||||
it "allows case logs to be restored to a previous version" do |
||||
admin_user.update!(phone: "09673867853") |
||||
expect(admin_user.paper_trail.previous_version.phone).to eq("07563867654") |
||||
end |
||||
|
||||
it "signing in does not create a new version" do |
||||
expect { |
||||
admin_user.update!( |
||||
last_sign_in_at: Time.zone.now, |
||||
current_sign_in_at: Time.zone.now, |
||||
current_sign_in_ip: "127.0.0.1", |
||||
last_sign_in_ip: "127.0.0.1", |
||||
failed_attempts: 3, |
||||
unlock_token: "dummy", |
||||
locked_at: Time.zone.now, |
||||
reset_password_token: "dummy", |
||||
reset_password_sent_at: Time.zone.now, |
||||
remember_created_at: Time.zone.now, |
||||
sign_in_count: 5, |
||||
updated_at: Time.zone.now, |
||||
) |
||||
}.not_to change(admin_user.versions, :count) |
||||
end |
||||
end |
||||
end |
||||
@ -0,0 +1,76 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Imports::CaseLogsFieldImportService do |
||||
subject(:import_service) { described_class.new(storage_service, logger) } |
||||
|
||||
let(:storage_service) { instance_double(StorageService) } |
||||
let(:logger) { instance_double(ActiveSupport::Logger) } |
||||
|
||||
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022") } |
||||
let(:fixture_directory) { "spec/fixtures/softwire_imports/case_logs" } |
||||
|
||||
def open_file(directory, filename) |
||||
File.open("#{directory}/#{filename}.xml") |
||||
end |
||||
|
||||
before do |
||||
# Owning and Managing organisations |
||||
FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") |
||||
|
||||
# Created by users |
||||
FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa") |
||||
|
||||
# Stub the form handler to use the real form |
||||
allow(FormHandler.instance).to receive(:get_form).with("2021_2022").and_return(real_2021_2022_form) |
||||
|
||||
WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/) |
||||
.to_return(status: 200, body: '{"status":200,"result":{"codes":{"admin_district":"E08000035"}}}', headers: {}) |
||||
end |
||||
|
||||
context "when updating a specific log value" do |
||||
let(:case_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" } |
||||
let(:case_log_file) { open_file(fixture_directory, case_log_id) } |
||||
let(:case_log_xml) { Nokogiri::XML(case_log_file) } |
||||
let(:remote_folder) { "case_logs" } |
||||
let(:field) { "tenant_code" } |
||||
|
||||
before do |
||||
# Stub the S3 file listing and download |
||||
allow(storage_service).to receive(:list_files) |
||||
.and_return(["#{remote_folder}/#{case_log_id}.xml"]) |
||||
allow(storage_service).to receive(:get_file_io) |
||||
.with("#{remote_folder}/#{case_log_id}.xml") |
||||
.and_return(case_log_file) |
||||
end |
||||
|
||||
context "and the case log was previously imported" do |
||||
let(:case_log) { CaseLog.find_by(old_id: case_log_id) } |
||||
|
||||
before do |
||||
Imports::CaseLogsImportService.new(storage_service, logger).create_logs(fixture_directory) |
||||
case_log_file.rewind |
||||
end |
||||
|
||||
it "logs that the tenant_code already has a value and does not update the case_log" do |
||||
expect(logger).to receive(:info).with(/Case Log \d+ has a value for tenant_code, skipping update/) |
||||
expect { import_service.send(:update_field, field, remote_folder) } |
||||
.not_to(change { case_log.reload.tenant_code }) |
||||
end |
||||
end |
||||
|
||||
context "and the case log was previously imported with empty fields" do |
||||
let(:case_log) { CaseLog.find_by(old_id: case_log_id) } |
||||
|
||||
before do |
||||
Imports::CaseLogsImportService.new(storage_service, logger).create_logs(fixture_directory) |
||||
case_log_file.rewind |
||||
case_log.update!(tenant_code: nil) |
||||
end |
||||
|
||||
it "updates the case_log" do |
||||
expect { import_service.send(:update_field, field, remote_folder) } |
||||
.to(change { case_log.reload.tenant_code }) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
Loading…
Reference in new issue