Skip to content

Commit

Permalink
resolve merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-coggin committed Jul 13, 2023
2 parents dc3b80c + 6a264f3 commit 30caa25
Show file tree
Hide file tree
Showing 96 changed files with 2,531 additions and 365 deletions.
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,16 @@ GEM
ast (2.4.2)
backports (3.23.0)
bcrypt (3.1.18)
better_errors (2.9.1)
coderay (>= 1.0.0)
better_errors (2.10.1)
erubi (>= 1.0.0)
rack (>= 0.9.0)
rouge (>= 1.0.0)
bindex (0.8.1)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
brakeman (5.4.1)
brakeman (6.0.0)
builder (3.2.4)
byebug (11.1.3)
capybara (3.39.0)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def show
# TODO: potential for CMS entry to control this
# @return [Boolean]
def restricted?
%w[whats-new].include? page_params[:id]
%w[whats-new email-preferences].include? page_params[:id]
end

# TODO: deprecate @module_item required for #html_title
Expand Down
25 changes: 25 additions & 0 deletions app/controllers/registration/early_years_emails_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class Registration::EarlyYearsEmailsController < Registration::BaseController
def edit
@user_form = Users::EarlyYearsEmailsForm.new(user: current_user, early_years_emails: current_user.early_years_emails)
end

def update
@user_form = Users::EarlyYearsEmailsForm.new(user_params.merge(user: current_user))

if @user_form.save
if current_user.registration_complete?
redirect_to my_modules_path, notice: t('.complete_update')
else
complete_registration
end
else
render :edit, status: :unprocessable_entity
end
end

private

def user_params
params.require(:user).permit(:early_years_emails)
end
end
6 changes: 4 additions & 2 deletions app/controllers/registration/role_type_others_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ def update
@user_form = Users::RoleTypeOtherForm.new(user_params.merge(user: current_user))

if @user_form.save
if current_user.registration_complete?
redirect_to user_path, notice: t('.complete_update')
if Rails.configuration.feature_email_prefs
redirect_to edit_registration_training_emails_path
elsif current_user.registration_complete?
redirect_to my_modules_path, notice: t('.complete_update')
else
complete_registration
end
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/registration/role_types_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ def update
@user_form = Users::RoleTypeForm.new(user_params.merge(user: current_user))

if @user_form.save
if current_user.registration_complete?
redirect_to user_path, notice: t('.complete_update')
if Rails.configuration.feature_email_prefs
redirect_to edit_registration_training_emails_path
elsif current_user.registration_complete?
redirect_to my_modules_path, notice: t('.complete_update')
else
complete_registration
end
Expand Down
25 changes: 25 additions & 0 deletions app/controllers/registration/training_emails_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class Registration::TrainingEmailsController < Registration::BaseController
def edit
@user_form = Users::TrainingEmailsForm.new(user: current_user, training_emails: current_user.training_emails)
end

def update
@user_form = Users::TrainingEmailsForm.new(user_params.merge(user: current_user))

if @user_form.save
if current_user.registration_complete?
redirect_to my_modules_path, notice: t('.complete_update')
else
complete_registration
end
else
render :edit, status: :unprocessable_entity
end
end

private

def user_params
params.require(:user).permit(:training_emails)
end
end
2 changes: 1 addition & 1 deletion app/controllers/static_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def show

# @return [Boolean]
def restricted?
%w[whats-new].include? page_params[:id]
%w[whats-new email-preferences].include? page_params[:id]
end

def template_valid?
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def after_sign_in_path_for(resource)
resource.display_whats_new = false
resource.save!
static_path('whats-new')
elsif !resource.email_preferences_complete?
static_path('email-preferences')
else
my_modules_path
end
Expand Down
37 changes: 37 additions & 0 deletions app/decorators/coercion_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class CoercionDecorator
extend Dry::Initializer

param :input, type: Types::Strict::Array.of(Types::Strict::Hash)

# @return [Array<Hash>]
def call
input.each { |row| row.map { |key, value| row[key] = format_value(key, value) } }
end

private

# @param key [Symbol]
# @param value [Mixed]
# @return [Mixed]
def format_value(key, value)
if value.is_a?(Time) || value.is_a?(DateTime)
format_datetime(value)
elsif key.to_s.include?('percentage')
format_percentage(value)
else
value
end
end

# @param value [Numeric]
# @return [String]
def format_percentage(value)
"#{(value * 100).round(2)}%"
end

# @param value [Time, DateTime]
# @return [String]
def format_datetime(value)
value.strftime('%Y-%m-%d %H:%M:%S')
end
end
19 changes: 19 additions & 0 deletions app/forms/users/early_years_emails_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Users
class EarlyYearsEmailsForm < BaseForm
attr_accessor :early_years_emails

validates :early_years_emails, presence: true

def name
'early_years_emails'
end

def save
if valid?
user.update!(
early_years_emails: early_years_emails,
)
end
end
end
end
19 changes: 19 additions & 0 deletions app/forms/users/training_emails_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Users
class TrainingEmailsForm < BaseForm
attr_accessor :training_emails

validates :training_emails, presence: true

def name
'training_emails'
end

def save
if valid?
user.update!(
training_emails: training_emails,
)
end
end
end
end
33 changes: 18 additions & 15 deletions app/models/concerns/to_csv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,38 @@ module ToCsv
extend ActiveSupport::Concern

class_methods do
# Returns an array of strings representing the column names for the data export
# @return [Array<String>]
def column_names
super
rescue NoMethodError
raise NoMethodError, 'ToCsv.to_csv a column names method must be defined for bespoke data export models to serve as csv column headers'
end

# Returns an array of hashes representing the rows of data to be exported or an ActiveRecord::Relation
# @return [ActiveRecord::Relation, Array<Hash{Symbol => Mixed}>]
def dashboard
all
rescue NoMethodError
raise NoMethodError, 'ToCsv.to_csv a dashboard method must be defined for bespoke data export models to serve as csv data'
end

# @return [String]
def to_csv
# @param batch_size [Integer]
def to_csv(batch_size: 1_000)
CSV.generate(headers: true) do |csv|
csv << column_names

dashboard.find_each(batch_size: 1_000) { |record| csv << record.dashboard_attributes.values }
unformatted = dashboard.is_a?(Array) ? dashboard : dashboard.find_each(batch_size: batch_size).map(&:dashboard_attributes)
formatted = CoercionDecorator.new(unformatted).call
formatted.each { |row| csv << row.values }
end
end
end

included do
# Timestamps in the format "2023-01-11 12:52:22"
# @return [Hash] coerce attributes prior to export
def dashboard_attributes
params = data_attributes.dup

params.each do |key, value|
params[key] = value.strftime('%Y-%m-%d %H:%M:%S') if value.is_a?(Time)
end
end

private

# @return [Hash] default to database fields
def data_attributes
def dashboard_attributes
attributes
end
end
Expand Down
23 changes: 23 additions & 0 deletions app/models/data/average_pass_scores.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Data
class AveragePassScores
include ToCsv

class << self
# @return [Array<String>]
def column_names
['Module', 'Average Pass Score']
end

# TODO: Upcoming changes to UserAssessment will make this type coercion unnecessary
# @return [Array<Hash{Symbol => Mixed}>]
def dashboard
UserAssessment.summative.passes.group(:module).average('CAST(score AS float)').map do |module_name, score|
{
module_name: module_name,
pass_score: score,
}
end
end
end
end
end
58 changes: 58 additions & 0 deletions app/models/data/high_fail_questions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module Data
class HighFailQuestions
include ToCsv

class << self
# @return [Array<String>]
def column_names
['Module', 'Question', 'Failure Rate Percentage']
end

# @return [Array<Hash{Symbol => Mixed}>]
def dashboard
high_fail_questions.map do |(module_name, question_name), fail_rate|
{
module_name: module_name,
question_name: question_name,
fail_rate_percentage: fail_rate,
}
end
end

private

# @return [Hash{Array<String, String> => Integer}]
def question_attempts
UserAnswer.summative.group(:module, :name).count
end

# @return [Hash{Array<String, String> => Integer}]
def question_failures
UserAnswer.summative.where(correct: false).group(:module, :name).count
end

# @return [Integer]
def total_attempts
question_attempts.values.sum
end

# @return [Hash{Symbol => Mixed}]
def high_fail_questions
average_fail_rate = question_failures.values.sum / total_attempts.to_f

high_fail_questions = {}

question_failures.each do |(module_name, question_name), fail_count|
total_count = question_attempts[[module_name, question_name]]
fail_rate = fail_count / total_count

if fail_rate > average_fail_rate
high_fail_questions[[module_name, question_name]] = fail_rate.to_f
end
end

{ average: average_fail_rate }.merge(high_fail_questions)
end
end
end
end
39 changes: 21 additions & 18 deletions app/models/data/local_authority_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,33 @@ module Data
class LocalAuthorityUser
include ToCsv

def self.to_csv
new.generate_csv
end
class << self
# @return [String]
def column_names
['Local Authority', 'Users']
end

# @return [String]
def generate_csv
CSV.generate do |csv|
csv << ['Local Authority', 'Users']
count_by_local_authority.each do |local_authority, count|
csv << [local_authority, count]
# @return [Array<Hash{Symbol => Mixed}>]
def dashboard
count_by_local_authority.map do |authority, count|
{
local_authority: authority,
users: count,
}
end
end
end

private

# @return [Hash{Symbol=>Integer}]
def count_by_local_authority
public_beta_users.group(:local_authority).count
end
# @return [Hash{Symbol=>Integer}]
def count_by_local_authority
public_beta_users.group(:local_authority).count
end

# @return [ActiveRecord::Relation<User>]
def public_beta_users
User.since_public_beta.with_local_authority
end
# @return [ActiveRecord::Relation<User>]
def public_beta_users
User.since_public_beta.with_local_authority
end
end
end
end
Loading

0 comments on commit 30caa25

Please sign in to comment.