Browse Source

Remove stuff

pull/611/head
baarkerlounger 3 years ago
parent
commit
c408fd93cf
  1. 37
      app/admin/admin_users.rb
  2. 20
      app/admin/case_logs.rb
  3. 32
      app/admin/dashboard.rb
  4. 31
      app/admin/organisations.rb
  5. 42
      app/admin/users.rb
  6. 0
      app/concerns/.keep
  7. 15
      app/concerns/admin/paper_trail.rb
  8. 4
      app/controllers/auth/sessions_controller.rb
  9. 7
      app/frontend/active_admin.js
  10. 17
      app/frontend/styles/active_admin.scss
  11. 36
      app/models/admin_user.rb
  12. 339
      config/initializers/active_admin.rb
  13. 78
      spec/controllers/admin/admin_users_controller_spec.rb
  14. 92
      spec/controllers/admin/case_logs_controller_spec.rb
  15. 44
      spec/controllers/admin/dashboard_controller_spec.rb
  16. 78
      spec/controllers/admin/organisations_controller_spec.rb
  17. 97
      spec/controllers/admin/users_controller_spec.rb
  18. 162
      spec/features/admin_panel_spec.rb
  19. 84
      spec/models/admin_user_spec.rb
  20. 72
      spec/requests/auth/passwords_controller_spec.rb

37
app/admin/admin_users.rb

@ -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

20
app/admin/case_logs.rb

@ -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

32
app/admin/dashboard.rb

@ -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

31
app/admin/organisations.rb

@ -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

42
app/admin/users.rb

@ -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

0
app/concerns/.keep

15
app/concerns/admin/paper_trail.rb

@ -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

4
app/controllers/auth/sessions_controller.rb

@ -2,7 +2,7 @@ class Auth::SessionsController < Devise::SessionsController
include Helpers::Email
def create
self.resource = resource_class.new
self.resource = User.new
if params.dig(resource_class_name, "email").empty?
resource.errors.add :email, "Enter an email address"
elsif !email_valid?(params.dig(resource_class_name, "email"))
@ -21,7 +21,7 @@ class Auth::SessionsController < Devise::SessionsController
private
def resource_class
request.path.include?("admin") ? AdminUser : User
User
end
def resource_class_name

7
app/frontend/active_admin.js

@ -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"

17
app/frontend/styles/active_admin.scss

@ -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; }

36
app/models/admin_user.rb

@ -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

339
config/initializers/active_admin.rb

@ -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

78
spec/controllers/admin/admin_users_controller_spec.rb

@ -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

92
spec/controllers/admin/case_logs_controller_spec.rb

@ -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

44
spec/controllers/admin/dashboard_controller_spec.rb

@ -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

78
spec/controllers/admin/organisations_controller_spec.rb

@ -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

97
spec/controllers/admin/users_controller_spec.rb

@ -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

162
spec/features/admin_panel_spec.rb

@ -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

84
spec/models/admin_user_spec.rb

@ -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

72
spec/requests/auth/passwords_controller_spec.rb

@ -73,78 +73,6 @@ RSpec.describe Auth::PasswordsController, type: :request do
end
end
context "when an admin user" do
let(:admin_user) { FactoryBot.create(:admin_user) }
describe "reset password" do
let(:new_value) { "new-password" }
before do
allow(DeviseNotifyMailer).to receive(:notify_client).and_return(notify_client)
allow(notify_client).to receive(:send_email).and_return(true)
end
it "renders the user edit password view" do
_raw, enc = Devise.token_generator.generate(AdminUser, :reset_password_token)
get "/admin/password/edit?reset_password_token=#{enc}"
expect(page).to have_css("h1", text: I18n.t("user.reset_password"))
end
context "when passwords entered don't match" do
let(:raw) { admin_user.send_reset_password_instructions }
let(:params) do
{
id: admin_user.id,
admin_user: {
password: new_value,
password_confirmation: "something_else",
reset_password_token: raw,
},
}
end
it "shows an error" do
put "/admin/password", headers: headers, params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(page).to have_content("doesn’t match new password")
end
end
context "when passwords is reset" do
let(:raw) { admin_user.send_reset_password_instructions }
let(:params) do
{
id: admin_user.id,
admin_user: {
password: new_value,
password_confirmation: new_value,
reset_password_token: raw,
},
}
end
it "updates the password" do
expect {
put "/admin/password", headers: headers, params: params
admin_user.reload
}.to change(admin_user, :encrypted_password)
end
it "sends you to the 2FA page and does not allow bypassing 2FA code" do
put "/admin/password", headers: headers, params: params
expect(response).to redirect_to("/admin/two-factor-authentication")
get "/admin/case_logs", headers: headers
expect(response).to redirect_to("/admin/two-factor-authentication")
end
it "triggers an email" do
expect(notify_client).to receive(:send_email)
put "/admin/password", headers:, params:
end
end
end
end
context "when a customer support user" do
let(:support_user) { FactoryBot.create(:user, :support) }

Loading…
Cancel
Save