mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
Add scales to framework. Change calculations to first group and then
average those groupings and the way up the framework. Likert scores for a survey_item are averaged. Then all the survey_items in a scale are averaged. Then student scales in a measure are averaged. And teacher scales in a measure are averaged. Then the average of those two calculations becomes the score for a measure. Then the measures in a subcategory are averaged.
This commit is contained in:
parent
1ca88bf6d1
commit
d4df7cbc06
44 changed files with 1053 additions and 856 deletions
|
|
@ -26,10 +26,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
- Bump ruby version to 3.1.0
|
- Bump ruby version to 3.1.0
|
||||||
- Add previous year data.
|
- Add previous year data.
|
||||||
remove AcademicYear "2021-22"
|
- Add scale to framework. Calculations for scores bubble up through the framework.
|
||||||
`ay = AcademicYear.find_by_range("2021-22") `
|
|
||||||
`ay.destroy`
|
|
||||||
seed database with new AcademicYear
|
|
||||||
`bundle exec rake db:seed`
|
|
||||||
load previous year survey responses
|
|
||||||
`bundle exec rake data:load_survey_responses`
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ class OverviewController < SqmApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def presenter_for_measure(measure)
|
def presenter_for_measure(measure)
|
||||||
score = SurveyItemResponse.score_for_measure(measure: measure, school: @school, academic_year: @academic_year)
|
score = measure.score(school: @school, academic_year: @academic_year)
|
||||||
|
|
||||||
VarianceChartRowPresenter.new(measure: measure, score: score)
|
VarianceChartRowPresenter.new(measure: measure, score: score)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class SqmApplicationController < ApplicationController
|
||||||
@schools = School.includes([:district]).where(district: @district).order(:name)
|
@schools = School.includes([:district]).where(district: @district).order(:name)
|
||||||
@academic_year = AcademicYear.find_by_range params[:year]
|
@academic_year = AcademicYear.find_by_range params[:year]
|
||||||
@academic_years = AcademicYear.all.order(range: :desc)
|
@academic_years = AcademicYear.all.order(range: :desc)
|
||||||
@has_empty_dataset = Measure.none_meet_threshold? school: @school, academic_year: @academic_year
|
@has_empty_dataset = Measure.all.all? do |measure| measure.none_meet_threshold? school: @school, academic_year: @academic_year end
|
||||||
end
|
end
|
||||||
|
|
||||||
def district_slug
|
def district_slug
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ require 'csv'
|
||||||
class Seeder
|
class Seeder
|
||||||
def seed_academic_years(*academic_year_ranges)
|
def seed_academic_years(*academic_year_ranges)
|
||||||
academic_year_ranges.each do |range|
|
academic_year_ranges.each do |range|
|
||||||
AcademicYear.find_or_create_by! range: range
|
AcademicYear.find_or_create_by! range:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -89,8 +89,11 @@ class Seeder
|
||||||
measure.save!
|
measure.save!
|
||||||
|
|
||||||
data_item_id = row['Survey Item ID'].strip
|
data_item_id = row['Survey Item ID'].strip
|
||||||
|
scale_id = data_item_id.split('-')[0..1].join('-')
|
||||||
|
scale = Scale.find_or_create_by! scale_id: scale_id, measure: measure
|
||||||
|
|
||||||
if %w[Teachers Students].include? row['Source']
|
if %w[Teachers Students].include? row['Source']
|
||||||
survey_item = SurveyItem.find_or_create_by! survey_item_id: data_item_id, measure: measure
|
survey_item = SurveyItem.where(survey_item_id: data_item_id, scale:).first_or_create
|
||||||
survey_item.watch_low_benchmark = watch_low if watch_low
|
survey_item.watch_low_benchmark = watch_low if watch_low
|
||||||
survey_item.growth_low_benchmark = growth_low if growth_low
|
survey_item.growth_low_benchmark = growth_low if growth_low
|
||||||
survey_item.approval_low_benchmark = approval_low if approval_low
|
survey_item.approval_low_benchmark = approval_low if approval_low
|
||||||
|
|
@ -99,7 +102,7 @@ class Seeder
|
||||||
end
|
end
|
||||||
|
|
||||||
if row['Source'] == 'Admin Data'
|
if row['Source'] == 'Admin Data'
|
||||||
admin_data_item = AdminDataItem.find_or_create_by! admin_data_item_id: data_item_id, measure: measure
|
admin_data_item = AdminDataItem.where(admin_data_item_id: data_item_id, scale:).first_or_create
|
||||||
admin_data_item.watch_low_benchmark = watch_low if watch_low
|
admin_data_item.watch_low_benchmark = watch_low if watch_low
|
||||||
admin_data_item.growth_low_benchmark = growth_low if growth_low
|
admin_data_item.growth_low_benchmark = growth_low if growth_low
|
||||||
admin_data_item.approval_low_benchmark = approval_low if approval_low
|
admin_data_item.approval_low_benchmark = approval_low if approval_low
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
class AdminDataItem < ActiveRecord::Base
|
class AdminDataItem < ActiveRecord::Base
|
||||||
belongs_to :measure
|
belongs_to :scale
|
||||||
|
|
||||||
scope :for_measures, ->(measure) {
|
scope :for_measures, lambda { |measures|
|
||||||
joins(:measure).where('admin_data_items.measure': measure)
|
joins(:scale).where('scale.measure': measures)
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :non_hs_items_for_measures, ->(measure) {
|
scope :non_hs_items_for_measures, lambda { |measure|
|
||||||
for_measures(measure).where(hs_only_item: false)
|
for_measures(measure).where(hs_only_item: false)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,40 @@
|
||||||
class Measure < ActiveRecord::Base
|
class Measure < ActiveRecord::Base
|
||||||
belongs_to :subcategory
|
belongs_to :subcategory
|
||||||
has_many :survey_items
|
has_many :scales
|
||||||
has_many :admin_data_items
|
has_many :admin_data_items, through: :scales
|
||||||
|
has_many :survey_items, through: :scales
|
||||||
has_many :survey_item_responses, through: :survey_items
|
has_many :survey_item_responses, through: :survey_items
|
||||||
|
|
||||||
def self.none_meet_threshold?(school:, academic_year:)
|
def none_meet_threshold?(school:, academic_year:)
|
||||||
none? do |measure|
|
!sufficient_data?(school:, academic_year:)
|
||||||
SurveyItemResponse.sufficient_data?(measure: measure, school: school, academic_year: academic_year)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def teacher_survey_items
|
def teacher_survey_items
|
||||||
@teacher_survey_items ||= survey_items.where("survey_item_id LIKE 't-%'")
|
@teacher_survey_items ||= survey_items.teacher_survey_items
|
||||||
end
|
end
|
||||||
|
|
||||||
def student_survey_items
|
def student_survey_items
|
||||||
@student_survey_items ||= survey_items.where("survey_item_id LIKE 's-%'")
|
@student_survey_items ||= survey_items.student_survey_items
|
||||||
|
end
|
||||||
|
|
||||||
|
def teacher_scales
|
||||||
|
@teacher_scales ||= scales.teacher_scales
|
||||||
|
end
|
||||||
|
|
||||||
|
def student_scales
|
||||||
|
@student_scales ||= scales.student_scales
|
||||||
end
|
end
|
||||||
|
|
||||||
def includes_teacher_survey_items?
|
def includes_teacher_survey_items?
|
||||||
@includes_teacher_survey_items ||= teacher_survey_items.any?
|
teacher_survey_items.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def includes_student_survey_items?
|
def includes_student_survey_items?
|
||||||
@includes_student_survey_items ||= student_survey_items.any?
|
student_survey_items.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def includes_admin_data_items?
|
def includes_admin_data_items?
|
||||||
@includes_admin_data_items ||= admin_data_items.any?
|
admin_data_items.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def sources
|
def sources
|
||||||
|
|
@ -39,32 +45,61 @@ class Measure < ActiveRecord::Base
|
||||||
sources
|
sources
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def score(school:, academic_year:)
|
||||||
|
@score ||= Hash.new do |memo|
|
||||||
|
meets_student_threshold = sufficient_student_data?(school:, academic_year:)
|
||||||
|
meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:)
|
||||||
|
next Score.new(nil, false, false) if !meets_student_threshold && !meets_teacher_threshold
|
||||||
|
|
||||||
|
scores = []
|
||||||
|
scores << teacher_scales.map { |scale| scale.score(school:, academic_year:) }.average if meets_teacher_threshold
|
||||||
|
scores << student_scales.map { |scale| scale.score(school:, academic_year:) }.average if meets_student_threshold
|
||||||
|
memo[[school, academic_year]] = Score.new(scores.average, meets_teacher_threshold, meets_student_threshold)
|
||||||
|
end
|
||||||
|
|
||||||
|
@score[[school, academic_year]]
|
||||||
|
end
|
||||||
|
|
||||||
def warning_low_benchmark
|
def warning_low_benchmark
|
||||||
1
|
1
|
||||||
end
|
end
|
||||||
|
|
||||||
def watch_low_benchmark
|
def watch_low_benchmark
|
||||||
return @watch_low_benchmark unless @watch_low_benchmark.nil?
|
@watch_low_benchmark ||= benchmark(:watch_low_benchmark)
|
||||||
|
|
||||||
@watch_low_benchmark = benchmark(:watch_low_benchmark)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def growth_low_benchmark
|
def growth_low_benchmark
|
||||||
return @growth_low_benchmark unless @growth_low_benchmark.nil?
|
@growth_low_benchmark ||= benchmark(:growth_low_benchmark)
|
||||||
|
|
||||||
@growth_low_benchmark = benchmark(:growth_low_benchmark)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def approval_low_benchmark
|
def approval_low_benchmark
|
||||||
return @approval_low_benchmark unless @approval_low_benchmark.nil?
|
@approval_low_benchmark ||= benchmark(:approval_low_benchmark)
|
||||||
|
|
||||||
@approval_low_benchmark = benchmark(:approval_low_benchmark)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ideal_low_benchmark
|
def ideal_low_benchmark
|
||||||
return @ideal_low_benchmark unless @ideal_low_benchmark.nil?
|
@ideal_low_benchmark ||= benchmark(:ideal_low_benchmark)
|
||||||
|
end
|
||||||
|
|
||||||
@ideal_low_benchmark = benchmark(:ideal_low_benchmark)
|
def sufficient_student_data?(school:, academic_year:)
|
||||||
|
return false unless includes_student_survey_items?
|
||||||
|
|
||||||
|
average_response_count = student_survey_items.map do |survey_item|
|
||||||
|
survey_item.survey_item_responses.where(school:, academic_year:).count
|
||||||
|
end.average
|
||||||
|
average_response_count >= SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD
|
||||||
|
end
|
||||||
|
|
||||||
|
def sufficient_teacher_data?(school:, academic_year:)
|
||||||
|
return false unless includes_teacher_survey_items?
|
||||||
|
|
||||||
|
average_response_count = teacher_survey_items.map do |survey_item|
|
||||||
|
survey_item.survey_item_responses.where(school:, academic_year:).count
|
||||||
|
end.average
|
||||||
|
average_response_count >= SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD
|
||||||
|
end
|
||||||
|
|
||||||
|
def sufficient_data?(school:, academic_year:)
|
||||||
|
sufficient_student_data?(school:, academic_year:) || sufficient_teacher_data?(school:, academic_year:)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
class ResponseRate
|
module ResponseRate
|
||||||
def initialize(subcategory:, school:, academic_year:)
|
def initialize(subcategory:, school:, academic_year:)
|
||||||
@subcategory = subcategory
|
@subcategory = subcategory
|
||||||
@school = school
|
@school = school
|
||||||
|
|
|
||||||
21
app/models/scale.rb
Normal file
21
app/models/scale.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
class Scale < ApplicationRecord
|
||||||
|
belongs_to :measure
|
||||||
|
has_many :survey_items
|
||||||
|
has_many :admin_data_items
|
||||||
|
|
||||||
|
def score(school:, academic_year:)
|
||||||
|
@score ||= Hash.new do |memo|
|
||||||
|
memo[[school, academic_year]] = survey_items.map do |survey_item|
|
||||||
|
survey_item.score(school:, academic_year:)
|
||||||
|
end.average
|
||||||
|
end
|
||||||
|
@score[[school, academic_year]]
|
||||||
|
end
|
||||||
|
|
||||||
|
scope :teacher_scales, lambda {
|
||||||
|
where("scale_id LIKE 't-%'")
|
||||||
|
}
|
||||||
|
scope :student_scales, lambda {
|
||||||
|
where("scale_id LIKE 's-%'")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
class StudentResponseRate < ResponseRate
|
class StudentResponseRate
|
||||||
def rate
|
include ResponseRate
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def survey_item_count
|
def survey_item_count
|
||||||
@student_survey_item_count ||= SurveyItem.student_survey_items_for_measures(@subcategory.measures).count
|
@student_survey_item_count ||= @subcategory.measures.map { |measure| measure.student_survey_items.count }.sum
|
||||||
end
|
end
|
||||||
|
|
||||||
def response_count
|
def response_count
|
||||||
@student_response_count ||= SurveyItemResponse.student_responses_for_measures(@subcategory.measures, @school,
|
@student_response_count ||= @subcategory.measures.map do |measure|
|
||||||
@academic_year).count
|
measure.student_survey_items.map do |survey_item|
|
||||||
|
survey_item.survey_item_responses.where(school: @school, academic_year: @academic_year).count
|
||||||
|
end.sum
|
||||||
|
end.sum
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_possible_responses
|
def total_possible_responses
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,12 @@ class Subcategory < ActiveRecord::Base
|
||||||
belongs_to :category
|
belongs_to :category
|
||||||
|
|
||||||
has_many :measures
|
has_many :measures
|
||||||
|
|
||||||
|
def score(school:, academic_year:)
|
||||||
|
scores = measures.includes([:survey_items]).map do |measure|
|
||||||
|
measure.score(school:, academic_year:).average
|
||||||
|
end
|
||||||
|
scores = scores.reject(&:nil?)
|
||||||
|
scores.average
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,21 @@
|
||||||
class SurveyItem < ActiveRecord::Base
|
class SurveyItem < ActiveRecord::Base
|
||||||
belongs_to :measure
|
belongs_to :scale
|
||||||
|
has_one :measure, through: :scale
|
||||||
|
|
||||||
has_many :survey_item_responses
|
has_many :survey_item_responses
|
||||||
|
|
||||||
scope :student_survey_items_for_measures, lambda { |measures|
|
def score(school:, academic_year:)
|
||||||
joins(:measure).where(measure: measures).where("survey_item_id LIKE 's-%'")
|
@score ||= Hash.new do |memo|
|
||||||
|
memo[[school, academic_year]] = survey_item_responses.where(school:, academic_year:).average(:likert_score).to_f
|
||||||
|
end
|
||||||
|
|
||||||
|
@score[[school, academic_year]]
|
||||||
|
end
|
||||||
|
|
||||||
|
scope :student_survey_items, lambda {
|
||||||
|
where("survey_item_id LIKE 's-%'")
|
||||||
}
|
}
|
||||||
scope :teacher_survey_items_for_measures, lambda { |measures|
|
scope :teacher_survey_items, lambda {
|
||||||
joins(:measure).where(measure: measures).where("survey_item_id LIKE 't-%'")
|
where("survey_item_id LIKE 't-%'")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,100 +5,4 @@ class SurveyItemResponse < ActiveRecord::Base
|
||||||
belongs_to :academic_year
|
belongs_to :academic_year
|
||||||
belongs_to :school
|
belongs_to :school
|
||||||
belongs_to :survey_item
|
belongs_to :survey_item
|
||||||
|
|
||||||
def self.score_for_subcategory(subcategory:, school:, academic_year:)
|
|
||||||
measures = measures_with_sufficient_data(subcategory: subcategory, school: school, academic_year: academic_year)
|
|
||||||
|
|
||||||
return nil unless measures.size.positive?
|
|
||||||
|
|
||||||
measures.map do |measure|
|
|
||||||
responses_for_measure(measure: measure, school: school, academic_year: academic_year).average(:likert_score)
|
|
||||||
end.average
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.measures_with_sufficient_data(subcategory:, school:, academic_year:)
|
|
||||||
subcategory.measures.select do |measure|
|
|
||||||
sufficient_data?(measure: measure, school: school, academic_year: academic_year)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.responses_for_measure(measure:, school:, academic_year:)
|
|
||||||
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
|
|
||||||
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
|
|
||||||
meets_all_thresholds = meets_teacher_threshold && meets_student_threshold
|
|
||||||
|
|
||||||
if meets_all_thresholds
|
|
||||||
SurveyItemResponse.for_measure(measure, school, academic_year)
|
|
||||||
elsif meets_teacher_threshold
|
|
||||||
SurveyItemResponse.teacher_responses_for_measure(measure, school, academic_year)
|
|
||||||
elsif meets_student_threshold
|
|
||||||
SurveyItemResponse.student_responses_for_measure(measure, school, academic_year)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.score_for_measure(measure:, school:, academic_year:)
|
|
||||||
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
|
|
||||||
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
|
|
||||||
|
|
||||||
survey_item_responses = responses_for_measure(measure: measure, school: school, academic_year: academic_year)
|
|
||||||
|
|
||||||
score_for_measure = survey_item_responses.average(:likert_score) unless survey_item_responses.nil?
|
|
||||||
|
|
||||||
Score.new(score_for_measure, meets_teacher_threshold, meets_student_threshold)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.sufficient_data?(measure:, school:, academic_year:)
|
|
||||||
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
|
|
||||||
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
|
|
||||||
meets_teacher_threshold || meets_student_threshold
|
|
||||||
end
|
|
||||||
|
|
||||||
scope :for_measure, lambda { |measure, school, academic_year|
|
|
||||||
joins(:survey_item)
|
|
||||||
.where('survey_items.measure': measure)
|
|
||||||
.where(school: school, academic_year: academic_year)
|
|
||||||
}
|
|
||||||
scope :for_measures, lambda { |measures, school, academic_year|
|
|
||||||
joins(:survey_item)
|
|
||||||
.where('survey_items.measure': measures)
|
|
||||||
.where(school: school, academic_year: academic_year)
|
|
||||||
}
|
|
||||||
|
|
||||||
scope :teacher_responses_for_measure, lambda { |measure, school, academic_year|
|
|
||||||
for_measure(measure, school, academic_year)
|
|
||||||
.where("survey_items.survey_item_id LIKE 't-%'")
|
|
||||||
}
|
|
||||||
scope :teacher_responses_for_measures, lambda { |measures, school, academic_year|
|
|
||||||
for_measures(measures, school, academic_year)
|
|
||||||
.where("survey_items.survey_item_id LIKE 't-%'")
|
|
||||||
}
|
|
||||||
scope :student_responses_for_measure, lambda { |measure, school, academic_year|
|
|
||||||
for_measure(measure, school, academic_year)
|
|
||||||
.where("survey_items.survey_item_id LIKE 's-%'")
|
|
||||||
}
|
|
||||||
|
|
||||||
scope :student_responses_for_measures, lambda { |measures, school, academic_year|
|
|
||||||
for_measures(measures, school, academic_year)
|
|
||||||
.where("survey_items.survey_item_id LIKE 's-%'")
|
|
||||||
}
|
|
||||||
def self.student_sufficient_data?(measure:, school:, academic_year:)
|
|
||||||
if measure.includes_student_survey_items?
|
|
||||||
student_survey_item_responses = SurveyItemResponse.student_responses_for_measure(measure, school, academic_year)
|
|
||||||
average_number_of_survey_item_responses = student_survey_item_responses.count / measure.student_survey_items.count
|
|
||||||
|
|
||||||
meets_student_threshold = average_number_of_survey_item_responses >= STUDENT_RESPONSE_THRESHOLD
|
|
||||||
end
|
|
||||||
!!meets_student_threshold
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.teacher_sufficient_data?(measure:, school:, academic_year:)
|
|
||||||
if measure.includes_teacher_survey_items?
|
|
||||||
teacher_survey_item_responses = SurveyItemResponse.teacher_responses_for_measure(measure, school, academic_year)
|
|
||||||
average_number_of_survey_item_responses = teacher_survey_item_responses.count / measure.teacher_survey_items.count
|
|
||||||
|
|
||||||
meets_teacher_threshold = average_number_of_survey_item_responses >= TEACHER_RESPONSE_THRESHOLD
|
|
||||||
end
|
|
||||||
!!meets_teacher_threshold
|
|
||||||
end
|
|
||||||
private_class_method :measures_with_sufficient_data
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
class TeacherResponseRate < ResponseRate
|
class TeacherResponseRate
|
||||||
|
include ResponseRate
|
||||||
|
|
||||||
def rate
|
def rate
|
||||||
cap_at_100(super)
|
cap_at_100(super)
|
||||||
end
|
end
|
||||||
|
|
@ -10,12 +12,15 @@ class TeacherResponseRate < ResponseRate
|
||||||
end
|
end
|
||||||
|
|
||||||
def survey_item_count
|
def survey_item_count
|
||||||
@teacher_survey_item_count ||= SurveyItem.teacher_survey_items_for_measures(@subcategory.measures).count
|
@teacher_survey_item_count ||= @subcategory.measures.map { |measure| measure.teacher_survey_items.count }.sum
|
||||||
end
|
end
|
||||||
|
|
||||||
def response_count
|
def response_count
|
||||||
@teacher_response_count ||= SurveyItemResponse.teacher_responses_for_measures(@subcategory.measures, @school,
|
@teacher_response_count ||= @subcategory.measures.map do |measure|
|
||||||
@academic_year).count
|
measure.teacher_survey_items.map do |survey_item|
|
||||||
|
survey_item.survey_item_responses.where(school: @school, academic_year: @academic_year).count
|
||||||
|
end.sum
|
||||||
|
end.sum
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_possible_responses
|
def total_possible_responses
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
class GaugePresenter
|
class GaugePresenter
|
||||||
def initialize(scale:, score:)
|
def initialize(zones:, score:)
|
||||||
@scale = scale
|
@zones = zones
|
||||||
@score = score
|
@score = score
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ class GaugePresenter
|
||||||
end
|
end
|
||||||
|
|
||||||
def key_benchmark_percentage
|
def key_benchmark_percentage
|
||||||
percentage_for @scale.approval_zone.low_benchmark
|
percentage_for @zones.approval_zone.low_benchmark
|
||||||
end
|
end
|
||||||
|
|
||||||
def boundary_percentage_for(zone)
|
def boundary_percentage_for(zone)
|
||||||
|
|
@ -38,31 +38,31 @@ class GaugePresenter
|
||||||
private
|
private
|
||||||
|
|
||||||
def watch_low_boundary
|
def watch_low_boundary
|
||||||
percentage_for @scale.watch_zone.low_benchmark
|
percentage_for @zones.watch_zone.low_benchmark
|
||||||
end
|
end
|
||||||
|
|
||||||
def growth_low_boundary
|
def growth_low_boundary
|
||||||
percentage_for @scale.growth_zone.low_benchmark
|
percentage_for @zones.growth_zone.low_benchmark
|
||||||
end
|
end
|
||||||
|
|
||||||
def approval_low_boundary
|
def approval_low_boundary
|
||||||
percentage_for @scale.approval_zone.low_benchmark
|
percentage_for @zones.approval_zone.low_benchmark
|
||||||
end
|
end
|
||||||
|
|
||||||
def ideal_low_boundary
|
def ideal_low_boundary
|
||||||
percentage_for @scale.ideal_zone.low_benchmark
|
percentage_for @zones.ideal_zone.low_benchmark
|
||||||
end
|
end
|
||||||
|
|
||||||
def zone
|
def zone
|
||||||
@scale.zone_for_score(@score)
|
@zones.zone_for_score(@score)
|
||||||
end
|
end
|
||||||
|
|
||||||
def percentage_for(number)
|
def percentage_for(number)
|
||||||
return nil if number.nil?
|
return nil if number.nil?
|
||||||
|
|
||||||
scale_minimum = @scale.warning_zone.low_benchmark
|
zones_minimum = @zones.warning_zone.low_benchmark
|
||||||
scale_maximum = @scale.ideal_zone.high_benchmark
|
zones_maximum = @zones.ideal_zone.high_benchmark
|
||||||
|
|
||||||
(number - scale_minimum) / (scale_maximum - scale_minimum)
|
(number - zones_minimum) / (zones_maximum - zones_minimum)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class MeasurePresenter
|
||||||
end
|
end
|
||||||
|
|
||||||
def gauge_presenter
|
def gauge_presenter
|
||||||
GaugePresenter.new(scale: scale, score: score_for_measure.average)
|
GaugePresenter.new(zones:, score: score_for_measure.average)
|
||||||
end
|
end
|
||||||
|
|
||||||
def data_item_accordion_id
|
def data_item_accordion_id
|
||||||
|
|
@ -45,11 +45,11 @@ class MeasurePresenter
|
||||||
private
|
private
|
||||||
|
|
||||||
def score_for_measure
|
def score_for_measure
|
||||||
@score ||= SurveyItemResponse.score_for_measure(measure: @measure, academic_year: @academic_year, school: @school)
|
@score ||= @measure.score(school: @school, academic_year: @academic_year)
|
||||||
end
|
end
|
||||||
|
|
||||||
def scale
|
def zones
|
||||||
Scale.new(
|
Zones.new(
|
||||||
watch_low_benchmark: @measure.watch_low_benchmark,
|
watch_low_benchmark: @measure.watch_low_benchmark,
|
||||||
growth_low_benchmark: @measure.growth_low_benchmark,
|
growth_low_benchmark: @measure.growth_low_benchmark,
|
||||||
approval_low_benchmark: @measure.approval_low_benchmark,
|
approval_low_benchmark: @measure.approval_low_benchmark,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
class SubcategoryCardPresenter
|
class SubcategoryCardPresenter
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
def initialize(name:, scale:, score:)
|
def initialize(name:, zones:, score:)
|
||||||
@name = name
|
@name = name
|
||||||
@scale = scale
|
@zones = zones
|
||||||
@score = score
|
@score = score
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -22,6 +22,6 @@ class SubcategoryCardPresenter
|
||||||
private
|
private
|
||||||
|
|
||||||
def zone
|
def zone
|
||||||
@scale.zone_for_score(@score)
|
@zones.zone_for_score(@score)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,15 @@ class SubcategoryPresenter
|
||||||
end
|
end
|
||||||
|
|
||||||
def gauge_presenter
|
def gauge_presenter
|
||||||
GaugePresenter.new(scale:, score: average_score)
|
GaugePresenter.new(zones:, score: average_score)
|
||||||
end
|
end
|
||||||
|
|
||||||
def subcategory_card_presenter
|
def subcategory_card_presenter
|
||||||
SubcategoryCardPresenter.new(name: @subcategory.name, scale:, score: average_score)
|
SubcategoryCardPresenter.new(name: @subcategory.name, zones:, score: average_score)
|
||||||
end
|
end
|
||||||
|
|
||||||
def average_score
|
def average_score
|
||||||
@average_score ||= SurveyItemResponse.score_for_subcategory(subcategory: @subcategory, school: @school,
|
@average_score ||= @subcategory.score(school: @school, academic_year: @academic_year)
|
||||||
academic_year: @academic_year)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def student_response_rate
|
def student_response_rate
|
||||||
|
|
@ -48,7 +47,7 @@ class SubcategoryPresenter
|
||||||
end
|
end
|
||||||
|
|
||||||
def measure_presenters
|
def measure_presenters
|
||||||
@subcategory.measures.includes([:admin_data_items]).sort_by(&:measure_id).map do |measure|
|
@subcategory.measures.sort_by(&:measure_id).map do |measure|
|
||||||
MeasurePresenter.new(measure:, academic_year: @academic_year, school: @school)
|
MeasurePresenter.new(measure:, academic_year: @academic_year, school: @school)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -56,19 +55,17 @@ class SubcategoryPresenter
|
||||||
private
|
private
|
||||||
|
|
||||||
def admin_data_item_count
|
def admin_data_item_count
|
||||||
if @school.is_hs
|
return AdminDataItem.for_measures(@subcategory.measures).count if @school.is_hs
|
||||||
AdminDataItem.for_measures(@subcategory.measures).count
|
|
||||||
else
|
|
||||||
AdminDataItem.non_hs_items_for_measures(@subcategory.measures).count
|
AdminDataItem.non_hs_items_for_measures(@subcategory.measures).count
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def format_a_non_applicable_rate(rate)
|
def format_a_non_applicable_rate(rate)
|
||||||
rate == [0, 0] ? %w[N A] : rate
|
rate == [0, 0] ? %w[N A] : rate
|
||||||
end
|
end
|
||||||
|
|
||||||
def scale
|
def zones
|
||||||
Scale.new(
|
Zones.new(
|
||||||
watch_low_benchmark: measures.map(&:watch_low_benchmark).average,
|
watch_low_benchmark: measures.map(&:watch_low_benchmark).average,
|
||||||
growth_low_benchmark: measures.map(&:growth_low_benchmark).average,
|
growth_low_benchmark: measures.map(&:growth_low_benchmark).average,
|
||||||
approval_low_benchmark: measures.map(&:approval_low_benchmark).average,
|
approval_low_benchmark: measures.map(&:approval_low_benchmark).average,
|
||||||
|
|
|
||||||
|
|
@ -96,12 +96,12 @@ class VarianceChartRowPresenter
|
||||||
end
|
end
|
||||||
|
|
||||||
def zone
|
def zone
|
||||||
scale = Scale.new(
|
zones = Zones.new(
|
||||||
watch_low_benchmark: @measure.watch_low_benchmark,
|
watch_low_benchmark: @measure.watch_low_benchmark,
|
||||||
growth_low_benchmark: @measure.growth_low_benchmark,
|
growth_low_benchmark: @measure.growth_low_benchmark,
|
||||||
approval_low_benchmark: @measure.approval_low_benchmark,
|
approval_low_benchmark: @measure.approval_low_benchmark,
|
||||||
ideal_low_benchmark: @measure.ideal_low_benchmark
|
ideal_low_benchmark: @measure.ideal_low_benchmark
|
||||||
)
|
)
|
||||||
scale.zone_for_score(@score)
|
zones.zone_for_score(@score)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
class Scale
|
class Zones
|
||||||
def initialize(watch_low_benchmark:, growth_low_benchmark:, approval_low_benchmark:, ideal_low_benchmark:)
|
def initialize(watch_low_benchmark:, growth_low_benchmark:, approval_low_benchmark:, ideal_low_benchmark:)
|
||||||
@watch_low_benchmark = watch_low_benchmark
|
@watch_low_benchmark = watch_low_benchmark
|
||||||
@growth_low_benchmark = growth_low_benchmark
|
@growth_low_benchmark = growth_low_benchmark
|
||||||
|
|
@ -34,9 +34,10 @@ class Scale
|
||||||
end
|
end
|
||||||
|
|
||||||
def zone_for_score(score)
|
def zone_for_score(score)
|
||||||
|
return insufficient_data if score.nil?
|
||||||
|
return insufficient_data if score.is_a?(Float) && score.nan?
|
||||||
|
|
||||||
case score
|
case score
|
||||||
when nil
|
|
||||||
insufficient_data
|
|
||||||
when ideal_zone.low_benchmark..ideal_zone.high_benchmark
|
when ideal_zone.low_benchmark..ideal_zone.high_benchmark
|
||||||
ideal_zone
|
ideal_zone
|
||||||
when approval_zone.low_benchmark..approval_zone.high_benchmark
|
when approval_zone.low_benchmark..approval_zone.high_benchmark
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.after_initialize do
|
config.after_initialize do
|
||||||
Bullet.enable = true
|
Bullet.enable = true
|
||||||
Bullet.alert = true
|
Bullet.alert = false
|
||||||
Bullet.bullet_logger = true
|
Bullet.bullet_logger = true
|
||||||
Bullet.console = true
|
Bullet.console = true
|
||||||
# Bullet.growl = true
|
# Bullet.growl = true
|
||||||
|
|
|
||||||
10
db/migrate/20220217123648_create_scales.rb
Normal file
10
db/migrate/20220217123648_create_scales.rb
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
class CreateScales < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
create_table :scales do |t|
|
||||||
|
t.string :scale_id, index: { unique: true }, null: false
|
||||||
|
t.references :measure, null: false, foreign_key: true
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
6
db/migrate/20220217164706_add_scale_to_survey_item.rb
Normal file
6
db/migrate/20220217164706_add_scale_to_survey_item.rb
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddScaleToSurveyItem < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_reference :survey_items, :scale, null: false, foreign_key: true
|
||||||
|
remove_reference :survey_items, :measure, null: false, foreign_key: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
class AddScaleToAdminDataItem < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_reference :admin_data_items, :scale, null: false, foreign_key: true
|
||||||
|
remove_reference :admin_data_items, :measure
|
||||||
|
add_index :admin_data_items, :admin_data_item_id, unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
138
db/schema.rb
138
db/schema.rb
|
|
@ -10,10 +10,8 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
ActiveRecord::Schema[7.0].define(version: 2022_02_17_170442) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
create_table "academic_years", id: :serial, force: :cascade do |t|
|
create_table "academic_years", id: :serial, force: :cascade do |t|
|
||||||
|
|
@ -22,16 +20,18 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "admin_data_items", force: :cascade do |t|
|
create_table "admin_data_items", force: :cascade do |t|
|
||||||
t.integer "measure_id", null: false
|
|
||||||
t.string "admin_data_item_id", null: false
|
t.string "admin_data_item_id", null: false
|
||||||
t.string "description"
|
t.string "description"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.float "watch_low_benchmark"
|
t.float "watch_low_benchmark"
|
||||||
t.float "growth_low_benchmark"
|
t.float "growth_low_benchmark"
|
||||||
t.float "approval_low_benchmark"
|
t.float "approval_low_benchmark"
|
||||||
t.float "ideal_low_benchmark"
|
t.float "ideal_low_benchmark"
|
||||||
t.boolean "hs_only_item", default: false
|
t.boolean "hs_only_item", default: false
|
||||||
|
t.bigint "scale_id", null: false
|
||||||
|
t.index ["admin_data_item_id"], name: "index_admin_data_items_on_admin_data_item_id", unique: true
|
||||||
|
t.index ["scale_id"], name: "index_admin_data_items_on_scale_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "categories", id: :serial, force: :cascade do |t|
|
create_table "categories", id: :serial, force: :cascade do |t|
|
||||||
|
|
@ -39,8 +39,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.integer "sort_index"
|
t.integer "sort_index"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "category_id", null: false
|
t.string "category_id", null: false
|
||||||
t.string "short_description"
|
t.string "short_description"
|
||||||
t.index ["slug"], name: "index_categories_on_slug", unique: true
|
t.index ["slug"], name: "index_categories_on_slug", unique: true
|
||||||
|
|
@ -50,22 +50,22 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.integer "qualtrics_code"
|
t.integer "qualtrics_code"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "legacy_attempts", id: :serial, force: :cascade do |t|
|
create_table "legacy_attempts", id: :serial, force: :cascade do |t|
|
||||||
t.integer "recipient_id"
|
t.integer "recipient_id"
|
||||||
t.integer "schedule_id"
|
t.integer "schedule_id"
|
||||||
t.integer "recipient_schedule_id"
|
t.integer "recipient_schedule_id"
|
||||||
t.datetime "sent_at"
|
t.datetime "sent_at", precision: nil
|
||||||
t.datetime "responded_at"
|
t.datetime "responded_at", precision: nil
|
||||||
t.integer "question_id"
|
t.integer "question_id"
|
||||||
t.integer "translation_id"
|
t.integer "translation_id"
|
||||||
t.integer "answer_index"
|
t.integer "answer_index"
|
||||||
t.integer "open_response_id"
|
t.integer "open_response_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.text "twilio_details"
|
t.text "twilio_details"
|
||||||
t.string "twilio_sid"
|
t.string "twilio_sid"
|
||||||
t.integer "student_id"
|
t.integer "student_id"
|
||||||
|
|
@ -78,8 +78,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.string "external_id"
|
t.string "external_id"
|
||||||
t.integer "parent_category_id"
|
t.integer "parent_category_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.float "benchmark"
|
t.float "benchmark"
|
||||||
t.string "benchmark_description"
|
t.string "benchmark_description"
|
||||||
|
|
@ -90,8 +90,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
create_table "legacy_districts", id: :serial, force: :cascade do |t|
|
create_table "legacy_districts", id: :serial, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.integer "state_id"
|
t.integer "state_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.integer "qualtrics_code"
|
t.integer "qualtrics_code"
|
||||||
t.index ["slug"], name: "index_legacy_districts_on_slug", unique: true
|
t.index ["slug"], name: "index_legacy_districts_on_slug", unique: true
|
||||||
|
|
@ -101,8 +101,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.text "question_ids"
|
t.text "question_ids"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "legacy_questions", id: :serial, force: :cascade do |t|
|
create_table "legacy_questions", id: :serial, force: :cascade do |t|
|
||||||
|
|
@ -113,8 +113,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "option4"
|
t.string "option4"
|
||||||
t.string "option5"
|
t.string "option5"
|
||||||
t.integer "category_id"
|
t.integer "category_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.integer "target_group", default: 0
|
t.integer "target_group", default: 0
|
||||||
t.boolean "for_recipient_students", default: false
|
t.boolean "for_recipient_students", default: false
|
||||||
t.boolean "reverse", default: false
|
t.boolean "reverse", default: false
|
||||||
|
|
@ -126,8 +126,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.text "recipient_ids"
|
t.text "recipient_ids"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.index ["school_id"], name: "index_legacy_recipient_lists_on_school_id"
|
t.index ["school_id"], name: "index_legacy_recipient_lists_on_school_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -136,10 +136,10 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.integer "schedule_id"
|
t.integer "schedule_id"
|
||||||
t.text "upcoming_question_ids"
|
t.text "upcoming_question_ids"
|
||||||
t.text "attempted_question_ids"
|
t.text "attempted_question_ids"
|
||||||
t.datetime "last_attempt_at"
|
t.datetime "last_attempt_at", precision: nil
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.datetime "next_attempt_at"
|
t.datetime "next_attempt_at", precision: nil
|
||||||
t.string "queued_question_ids"
|
t.string "queued_question_ids"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -154,8 +154,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "income"
|
t.string "income"
|
||||||
t.boolean "opted_out", default: false
|
t.boolean "opted_out", default: false
|
||||||
t.integer "school_id"
|
t.integer "school_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.string "email"
|
t.string "email"
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.integer "attempts_count", default: 0
|
t.integer "attempts_count", default: 0
|
||||||
|
|
@ -176,8 +176,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.boolean "random", default: false
|
t.boolean "random", default: false
|
||||||
t.integer "recipient_list_id"
|
t.integer "recipient_list_id"
|
||||||
t.integer "question_list_id"
|
t.integer "question_list_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.integer "time", default: 960
|
t.integer "time", default: 960
|
||||||
t.index ["school_id"], name: "index_legacy_schedules_on_school_id"
|
t.index ["school_id"], name: "index_legacy_schedules_on_school_id"
|
||||||
end
|
end
|
||||||
|
|
@ -188,8 +188,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.integer "attempt_count", default: 0
|
t.integer "attempt_count", default: 0
|
||||||
t.integer "response_count", default: 0
|
t.integer "response_count", default: 0
|
||||||
t.integer "answer_index_total", default: 0
|
t.integer "answer_index_total", default: 0
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.float "nonlikert"
|
t.float "nonlikert"
|
||||||
t.float "zscore"
|
t.float "zscore"
|
||||||
t.string "year"
|
t.string "year"
|
||||||
|
|
@ -207,16 +207,16 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.integer "response_count"
|
t.integer "response_count"
|
||||||
t.float "response_rate"
|
t.float "response_rate"
|
||||||
t.string "year"
|
t.string "year"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.integer "response_total"
|
t.integer "response_total"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "legacy_schools", id: :serial, force: :cascade do |t|
|
create_table "legacy_schools", id: :serial, force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.integer "district_id"
|
t.integer "district_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.integer "student_count"
|
t.integer "student_count"
|
||||||
|
|
@ -233,31 +233,31 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "age"
|
t.string "age"
|
||||||
t.string "ethnicity"
|
t.string "ethnicity"
|
||||||
t.integer "recipient_id"
|
t.integer "recipient_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "legacy_user_schools", id: :serial, force: :cascade do |t|
|
create_table "legacy_user_schools", id: :serial, force: :cascade do |t|
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.integer "school_id"
|
t.integer "school_id"
|
||||||
t.integer "district_id"
|
t.integer "district_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "legacy_users", id: :serial, force: :cascade do |t|
|
create_table "legacy_users", id: :serial, force: :cascade do |t|
|
||||||
t.string "email", default: "", null: false
|
t.string "email", default: "", null: false
|
||||||
t.string "encrypted_password", default: "", null: false
|
t.string "encrypted_password", default: "", null: false
|
||||||
t.string "reset_password_token"
|
t.string "reset_password_token"
|
||||||
t.datetime "reset_password_sent_at"
|
t.datetime "reset_password_sent_at", precision: nil
|
||||||
t.datetime "remember_created_at"
|
t.datetime "remember_created_at", precision: nil
|
||||||
t.integer "sign_in_count", default: 0, null: false
|
t.integer "sign_in_count", default: 0, null: false
|
||||||
t.datetime "current_sign_in_at"
|
t.datetime "current_sign_in_at", precision: nil
|
||||||
t.datetime "last_sign_in_at"
|
t.datetime "last_sign_in_at", precision: nil
|
||||||
t.inet "current_sign_in_ip"
|
t.inet "current_sign_in_ip"
|
||||||
t.inet "last_sign_in_ip"
|
t.inet "last_sign_in_ip"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.index ["email"], name: "index_legacy_users_on_email", unique: true
|
t.index ["email"], name: "index_legacy_users_on_email", unique: true
|
||||||
t.index ["reset_password_token"], name: "index_legacy_users_on_reset_password_token", unique: true
|
t.index ["reset_password_token"], name: "index_legacy_users_on_reset_password_token", unique: true
|
||||||
end
|
end
|
||||||
|
|
@ -267,8 +267,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.integer "subcategory_id", null: false
|
t.integer "subcategory_id", null: false
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["measure_id"], name: "index_measures_on_measure_id"
|
t.index ["measure_id"], name: "index_measures_on_measure_id"
|
||||||
t.index ["subcategory_id"], name: "index_measures_on_subcategory_id"
|
t.index ["subcategory_id"], name: "index_measures_on_subcategory_id"
|
||||||
end
|
end
|
||||||
|
|
@ -278,20 +278,29 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.bigint "academic_year_id", null: false
|
t.bigint "academic_year_id", null: false
|
||||||
t.float "total_students"
|
t.float "total_students"
|
||||||
t.float "total_teachers"
|
t.float "total_teachers"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["academic_year_id"], name: "index_respondents_on_academic_year_id"
|
t.index ["academic_year_id"], name: "index_respondents_on_academic_year_id"
|
||||||
t.index ["school_id"], name: "index_respondents_on_school_id"
|
t.index ["school_id"], name: "index_respondents_on_school_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "scales", force: :cascade do |t|
|
||||||
|
t.string "scale_id", null: false
|
||||||
|
t.bigint "measure_id", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["measure_id"], name: "index_scales_on_measure_id"
|
||||||
|
t.index ["scale_id"], name: "index_scales_on_scale_id", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
create_table "schools", force: :cascade do |t|
|
create_table "schools", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.integer "district_id"
|
t.integer "district_id"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.string "slug"
|
t.string "slug"
|
||||||
t.integer "qualtrics_code"
|
t.integer "qualtrics_code"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.integer "dese_id", null: false
|
t.integer "dese_id", null: false
|
||||||
t.boolean "is_hs", default: false
|
t.boolean "is_hs", default: false
|
||||||
t.index ["dese_id"], name: "index_schools_on_dese_id", unique: true
|
t.index ["dese_id"], name: "index_schools_on_dese_id", unique: true
|
||||||
|
|
@ -301,8 +310,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.integer "category_id"
|
t.integer "category_id"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "subcategory_id", null: false
|
t.string "subcategory_id", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -312,8 +321,8 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
t.integer "survey_item_id", null: false
|
t.integer "survey_item_id", null: false
|
||||||
t.string "response_id", null: false
|
t.string "response_id", null: false
|
||||||
t.integer "academic_year_id", null: false
|
t.integer "academic_year_id", null: false
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["academic_year_id"], name: "index_survey_item_responses_on_academic_year_id"
|
t.index ["academic_year_id"], name: "index_survey_item_responses_on_academic_year_id"
|
||||||
t.index ["response_id"], name: "index_survey_item_responses_on_response_id"
|
t.index ["response_id"], name: "index_survey_item_responses_on_response_id"
|
||||||
t.index ["school_id"], name: "index_survey_item_responses_on_school_id"
|
t.index ["school_id"], name: "index_survey_item_responses_on_school_id"
|
||||||
|
|
@ -321,20 +330,20 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "survey_items", id: :serial, force: :cascade do |t|
|
create_table "survey_items", id: :serial, force: :cascade do |t|
|
||||||
t.integer "measure_id", null: false
|
|
||||||
t.string "survey_item_id", null: false
|
t.string "survey_item_id", null: false
|
||||||
t.string "prompt"
|
t.string "prompt"
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", null: false
|
||||||
t.float "watch_low_benchmark"
|
t.float "watch_low_benchmark"
|
||||||
t.float "growth_low_benchmark"
|
t.float "growth_low_benchmark"
|
||||||
t.float "approval_low_benchmark"
|
t.float "approval_low_benchmark"
|
||||||
t.float "ideal_low_benchmark"
|
t.float "ideal_low_benchmark"
|
||||||
t.index ["measure_id"], name: "index_survey_items_on_measure_id"
|
t.bigint "scale_id", null: false
|
||||||
|
t.index ["scale_id"], name: "index_survey_items_on_scale_id"
|
||||||
t.index ["survey_item_id"], name: "index_survey_items_on_survey_item_id"
|
t.index ["survey_item_id"], name: "index_survey_items_on_survey_item_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_foreign_key "admin_data_items", "measures"
|
add_foreign_key "admin_data_items", "scales"
|
||||||
add_foreign_key "legacy_recipient_lists", "legacy_schools", column: "school_id"
|
add_foreign_key "legacy_recipient_lists", "legacy_schools", column: "school_id"
|
||||||
add_foreign_key "legacy_schedules", "legacy_schools", column: "school_id"
|
add_foreign_key "legacy_schedules", "legacy_schools", column: "school_id"
|
||||||
add_foreign_key "legacy_school_categories", "legacy_categories", column: "category_id"
|
add_foreign_key "legacy_school_categories", "legacy_categories", column: "category_id"
|
||||||
|
|
@ -342,9 +351,10 @@ ActiveRecord::Schema.define(version: 2022_02_11_122234) do
|
||||||
add_foreign_key "measures", "subcategories"
|
add_foreign_key "measures", "subcategories"
|
||||||
add_foreign_key "respondents", "academic_years"
|
add_foreign_key "respondents", "academic_years"
|
||||||
add_foreign_key "respondents", "schools"
|
add_foreign_key "respondents", "schools"
|
||||||
|
add_foreign_key "scales", "measures"
|
||||||
add_foreign_key "subcategories", "categories"
|
add_foreign_key "subcategories", "categories"
|
||||||
add_foreign_key "survey_item_responses", "academic_years"
|
add_foreign_key "survey_item_responses", "academic_years"
|
||||||
add_foreign_key "survey_item_responses", "schools"
|
add_foreign_key "survey_item_responses", "schools"
|
||||||
add_foreign_key "survey_item_responses", "survey_items"
|
add_foreign_key "survey_item_responses", "survey_items"
|
||||||
add_foreign_key "survey_items", "measures"
|
add_foreign_key "survey_items", "scales"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
26
doc/architectural_decision_records/2.md
Normal file
26
doc/architectural_decision_records/2.md
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Application decision record 2
|
||||||
|
|
||||||
|
# Add scale to framework
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Completed
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The calculations needed to be reworked. When calculating a score for a measure, we had looped through all the survey_items_responses for a measure and taken the average for all of them. Doing it that way means student responses are given more weight than teacher responses since the number of students responses will outnumber teacher responses. Another consequence is that survey_items with more questions will be prioritized over ones with fewer questions since they will create more survey item responses.
|
||||||
|
|
||||||
|
Story: #181205114 and #181209931
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Change the calculations so that scores bubble up through the framework hierarchy.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Added scales to framework. Changed calculations to first group based on the most atomic bits of the framework and then
|
||||||
|
average those groupings as we go up the framework. First, likert scores are averaged for
|
||||||
|
all survey item responses in a survey item. Then all the survey items in a scale are
|
||||||
|
averaged. Then student scales in a measure are averaged. And teacher
|
||||||
|
scales in a measure are averaged. The average of student and teacher scales becomes the score for a measure. Then the measures in a
|
||||||
|
subcategory are averaged.
|
||||||
|
|
@ -13,7 +13,7 @@ FactoryBot.define do
|
||||||
|
|
||||||
factory :academic_year do
|
factory :academic_year do
|
||||||
range { '2050-51' }
|
range { '2050-51' }
|
||||||
initialize_with { AcademicYear.find_or_initialize_by(range: range) }
|
initialize_with { AcademicYear.find_or_initialize_by(range:) }
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :category, class: 'Category' do
|
factory :category, class: 'Category' do
|
||||||
|
|
@ -35,9 +35,10 @@ FactoryBot.define do
|
||||||
measures_count { 2 }
|
measures_count { 2 }
|
||||||
end
|
end
|
||||||
after(:create) do |subcategory, evaluator|
|
after(:create) do |subcategory, evaluator|
|
||||||
create_list(:measure, evaluator.measures_count, subcategory: subcategory).each do |measure|
|
create_list(:measure, evaluator.measures_count, subcategory:).each do |measure|
|
||||||
survey_item = create(:teacher_survey_item, measure: measure)
|
scale = create(:scale, measure: measure)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item)
|
survey_item = create(:teacher_survey_item, scale:)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item:)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -54,9 +55,20 @@ FactoryBot.define do
|
||||||
# end
|
# end
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :survey_item do
|
factory :scale do
|
||||||
prompt { 'What do YOU think?' }
|
|
||||||
measure
|
measure
|
||||||
|
scale_id { "A Scale #{rand}" }
|
||||||
|
factory :teacher_scale do
|
||||||
|
scale_id {"t-#{rand}"}
|
||||||
|
end
|
||||||
|
factory :student_scale do
|
||||||
|
scale_id {"s-#{rand}"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :survey_item do
|
||||||
|
scale
|
||||||
|
prompt { 'What do YOU think?' }
|
||||||
factory :teacher_survey_item do
|
factory :teacher_survey_item do
|
||||||
survey_item_id { "t-#{rand}" }
|
survey_item_id { "t-#{rand}" }
|
||||||
watch_low_benchmark { 2.0 }
|
watch_low_benchmark { 2.0 }
|
||||||
|
|
@ -84,7 +96,7 @@ FactoryBot.define do
|
||||||
factory :admin_data_item do
|
factory :admin_data_item do
|
||||||
admin_data_item_id { rand.to_s }
|
admin_data_item_id { rand.to_s }
|
||||||
description { rand.to_s }
|
description { rand.to_s }
|
||||||
measure
|
scale
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :respondent do
|
factory :respondent do
|
||||||
|
|
|
||||||
|
|
@ -123,9 +123,11 @@ describe Seeder do
|
||||||
before do
|
before do
|
||||||
school_culture_category = create(:category, category_id: '2', sort_index: -1)
|
school_culture_category = create(:category, category_id: '2', sort_index: -1)
|
||||||
safety_subcategory = create(:subcategory, subcategory_id: '2A', category: school_culture_category)
|
safety_subcategory = create(:subcategory, subcategory_id: '2A', category: school_culture_category)
|
||||||
student_physical_safety_measure = create(:measure, measure_id: '2A-i', subcategory: safety_subcategory)
|
physical_safety_measure = create(:measure, measure_id: '2A-i', subcategory: safety_subcategory)
|
||||||
create(:survey_item, survey_item_id: 's-phys-q1', measure: student_physical_safety_measure)
|
student_physical_safety_scale = create(:scale, scale_id: 's-phys', measure: physical_safety_measure)
|
||||||
create(:admin_data_item, admin_data_item_id: 'a-phys-i1', measure: student_physical_safety_measure)
|
create(:survey_item, survey_item_id: 's-phys-q1', scale: student_physical_safety_scale)
|
||||||
|
admin_physical_safety_scale = create(:scale, scale_id: 'a-phys', measure: physical_safety_measure)
|
||||||
|
create(:admin_data_item, admin_data_item_id: 'a-phys-i1', scale: admin_physical_safety_scale)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates new objects as necessary' do
|
it 'creates new objects as necessary' do
|
||||||
|
|
@ -133,7 +135,9 @@ describe Seeder do
|
||||||
seeder.seed_sqm_framework sample_sqm_framework_csv
|
seeder.seed_sqm_framework sample_sqm_framework_csv
|
||||||
end.to change { Category.count }.by(4)
|
end.to change { Category.count }.by(4)
|
||||||
.and change { Subcategory.count }.by(15)
|
.and change { Subcategory.count }.by(15)
|
||||||
.and change { Measure.count }.by(31)
|
.and change { Measure.count }.by(31).and change {
|
||||||
|
Scale.count
|
||||||
|
}.by(51)
|
||||||
.and change {
|
.and change {
|
||||||
SurveyItem.count
|
SurveyItem.count
|
||||||
}.by(136)
|
}.by(136)
|
||||||
|
|
@ -174,6 +178,14 @@ describe Seeder do
|
||||||
expect(measure.description).to eq 'This is a measure description.'
|
expect(measure.description).to eq 'This is a measure description.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'updates scale references' do
|
||||||
|
scale = Scale.find_by_scale_id 't-pcom'
|
||||||
|
measure = Measure.find_by_measure_id '1A-iii'
|
||||||
|
survey_item = SurveyItem.find_by_survey_item_id 't-pcom-q1'
|
||||||
|
expect(scale.measure).to eq measure
|
||||||
|
expect(scale.survey_items).to include survey_item
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not overwrite the survey item benchmarks with admin data benchmarks' do
|
it 'does not overwrite the survey item benchmarks with admin data benchmarks' do
|
||||||
survey_item = SurveyItem.find_by_survey_item_id 't-prep-q1'
|
survey_item = SurveyItem.find_by_survey_item_id 't-prep-q1'
|
||||||
expect(survey_item.approval_low_benchmark).to eq 3.5
|
expect(survey_item.approval_low_benchmark).to eq 3.5
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,12 @@ require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe Measure, type: :model do
|
RSpec.describe Measure, type: :model do
|
||||||
let(:measure) { create(:measure) }
|
let(:measure) { create(:measure) }
|
||||||
|
let(:scale) { create(:scale, measure:) }
|
||||||
|
let(:teacher_scale) { create(:teacher_scale, measure:) }
|
||||||
|
let(:student_scale) { create(:student_scale, measure:) }
|
||||||
|
let(:school) { create(:school) }
|
||||||
|
let(:academic_year) { create(:academic_year) }
|
||||||
|
|
||||||
let(:admin_watch_low_benchmark) { 2.0 }
|
let(:admin_watch_low_benchmark) { 2.0 }
|
||||||
let(:admin_growth_low_benchmark) { 3.0 }
|
let(:admin_growth_low_benchmark) { 3.0 }
|
||||||
let(:admin_approval_low_benchmark) { 4.0 }
|
let(:admin_approval_low_benchmark) { 4.0 }
|
||||||
|
|
@ -17,9 +23,10 @@ RSpec.describe Measure, type: :model do
|
||||||
let(:teacher_approval_low_benchmark) { 3.2 }
|
let(:teacher_approval_low_benchmark) { 3.2 }
|
||||||
let(:teacher_ideal_low_benchmark) { 4.2 }
|
let(:teacher_ideal_low_benchmark) { 4.2 }
|
||||||
|
|
||||||
|
describe 'benchmarks' do
|
||||||
context 'when a measure includes only one admin data item' do
|
context 'when a measure includes only one admin data item' do
|
||||||
before do
|
before do
|
||||||
create(:admin_data_item, measure: measure,
|
create(:admin_data_item, scale:,
|
||||||
watch_low_benchmark: admin_watch_low_benchmark,
|
watch_low_benchmark: admin_watch_low_benchmark,
|
||||||
growth_low_benchmark: admin_growth_low_benchmark,
|
growth_low_benchmark: admin_growth_low_benchmark,
|
||||||
approval_low_benchmark: admin_approval_low_benchmark,
|
approval_low_benchmark: admin_approval_low_benchmark,
|
||||||
|
|
@ -36,7 +43,7 @@ RSpec.describe Measure, type: :model do
|
||||||
|
|
||||||
context 'when a measure includes only student survey items' do
|
context 'when a measure includes only student survey items' do
|
||||||
before do
|
before do
|
||||||
create(:student_survey_item, measure: measure,
|
create(:student_survey_item, scale:,
|
||||||
watch_low_benchmark: student_watch_low_benchmark,
|
watch_low_benchmark: student_watch_low_benchmark,
|
||||||
growth_low_benchmark: student_growth_low_benchmark,
|
growth_low_benchmark: student_growth_low_benchmark,
|
||||||
approval_low_benchmark: student_approval_low_benchmark,
|
approval_low_benchmark: student_approval_low_benchmark,
|
||||||
|
|
@ -55,7 +62,7 @@ RSpec.describe Measure, type: :model do
|
||||||
|
|
||||||
context 'when a measure includes only teacher survey items' do
|
context 'when a measure includes only teacher survey items' do
|
||||||
before do
|
before do
|
||||||
create(:teacher_survey_item, measure: measure,
|
create(:teacher_survey_item, scale:,
|
||||||
watch_low_benchmark: teacher_watch_low_benchmark,
|
watch_low_benchmark: teacher_watch_low_benchmark,
|
||||||
growth_low_benchmark: teacher_growth_low_benchmark,
|
growth_low_benchmark: teacher_growth_low_benchmark,
|
||||||
approval_low_benchmark: teacher_approval_low_benchmark,
|
approval_low_benchmark: teacher_approval_low_benchmark,
|
||||||
|
|
@ -74,13 +81,13 @@ RSpec.describe Measure, type: :model do
|
||||||
|
|
||||||
context 'when a measure includes admin data and student survey items' do
|
context 'when a measure includes admin data and student survey items' do
|
||||||
before do
|
before do
|
||||||
create_list(:admin_data_item, 3, measure: measure,
|
create_list(:admin_data_item, 3, scale:,
|
||||||
watch_low_benchmark: admin_watch_low_benchmark,
|
watch_low_benchmark: admin_watch_low_benchmark,
|
||||||
growth_low_benchmark: admin_growth_low_benchmark,
|
growth_low_benchmark: admin_growth_low_benchmark,
|
||||||
approval_low_benchmark: admin_approval_low_benchmark,
|
approval_low_benchmark: admin_approval_low_benchmark,
|
||||||
ideal_low_benchmark: admin_ideal_low_benchmark)
|
ideal_low_benchmark: admin_ideal_low_benchmark)
|
||||||
|
|
||||||
create(:student_survey_item, measure: measure,
|
create(:student_survey_item, scale:,
|
||||||
watch_low_benchmark: student_watch_low_benchmark,
|
watch_low_benchmark: student_watch_low_benchmark,
|
||||||
growth_low_benchmark: student_growth_low_benchmark,
|
growth_low_benchmark: student_growth_low_benchmark,
|
||||||
approval_low_benchmark: student_approval_low_benchmark,
|
approval_low_benchmark: student_approval_low_benchmark,
|
||||||
|
|
@ -92,19 +99,19 @@ RSpec.describe Measure, type: :model do
|
||||||
expect(measure.watch_low_benchmark).to be 1.875
|
expect(measure.watch_low_benchmark).to be 1.875
|
||||||
end
|
end
|
||||||
it 'returns the source as admin and student survey items' do
|
it 'returns the source as admin and student survey items' do
|
||||||
expect(measure.sources).to eq [:admin_data, :student_surveys]
|
expect(measure.sources).to eq %i[admin_data student_surveys]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a measure includes admin data and teacher survey items' do
|
context 'when a measure includes admin data and teacher survey items' do
|
||||||
before do
|
before do
|
||||||
create_list(:admin_data_item, 3, measure: measure,
|
create_list(:admin_data_item, 3, scale:,
|
||||||
watch_low_benchmark: admin_watch_low_benchmark,
|
watch_low_benchmark: admin_watch_low_benchmark,
|
||||||
growth_low_benchmark: admin_growth_low_benchmark,
|
growth_low_benchmark: admin_growth_low_benchmark,
|
||||||
approval_low_benchmark: admin_approval_low_benchmark,
|
approval_low_benchmark: admin_approval_low_benchmark,
|
||||||
ideal_low_benchmark: admin_ideal_low_benchmark)
|
ideal_low_benchmark: admin_ideal_low_benchmark)
|
||||||
|
|
||||||
create(:teacher_survey_item, measure: measure,
|
create(:teacher_survey_item, scale:,
|
||||||
watch_low_benchmark: teacher_watch_low_benchmark,
|
watch_low_benchmark: teacher_watch_low_benchmark,
|
||||||
growth_low_benchmark: teacher_growth_low_benchmark,
|
growth_low_benchmark: teacher_growth_low_benchmark,
|
||||||
approval_low_benchmark: teacher_approval_low_benchmark,
|
approval_low_benchmark: teacher_approval_low_benchmark,
|
||||||
|
|
@ -116,19 +123,19 @@ RSpec.describe Measure, type: :model do
|
||||||
expect(measure.watch_low_benchmark).to be 1.8
|
expect(measure.watch_low_benchmark).to be 1.8
|
||||||
end
|
end
|
||||||
it 'returns the source as admin and teacher survey items' do
|
it 'returns the source as admin and teacher survey items' do
|
||||||
expect(measure.sources).to eq [:admin_data, :teacher_surveys]
|
expect(measure.sources).to eq %i[admin_data teacher_surveys]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a measure includes student and teacher survey items' do
|
context 'when a measure includes student and teacher survey items' do
|
||||||
before do
|
before do
|
||||||
create_list(:student_survey_item, 3, measure: measure,
|
create_list(:student_survey_item, 3, scale:,
|
||||||
watch_low_benchmark: student_watch_low_benchmark,
|
watch_low_benchmark: student_watch_low_benchmark,
|
||||||
growth_low_benchmark: student_growth_low_benchmark,
|
growth_low_benchmark: student_growth_low_benchmark,
|
||||||
approval_low_benchmark: student_approval_low_benchmark,
|
approval_low_benchmark: student_approval_low_benchmark,
|
||||||
ideal_low_benchmark: student_ideal_low_benchmark)
|
ideal_low_benchmark: student_ideal_low_benchmark)
|
||||||
|
|
||||||
create_list(:teacher_survey_item, 3, measure: measure,
|
create_list(:teacher_survey_item, 3, scale:,
|
||||||
watch_low_benchmark: teacher_watch_low_benchmark,
|
watch_low_benchmark: teacher_watch_low_benchmark,
|
||||||
growth_low_benchmark: teacher_growth_low_benchmark,
|
growth_low_benchmark: teacher_growth_low_benchmark,
|
||||||
approval_low_benchmark: teacher_approval_low_benchmark,
|
approval_low_benchmark: teacher_approval_low_benchmark,
|
||||||
|
|
@ -140,24 +147,24 @@ RSpec.describe Measure, type: :model do
|
||||||
expect(measure.watch_low_benchmark).to be 1.35
|
expect(measure.watch_low_benchmark).to be 1.35
|
||||||
end
|
end
|
||||||
it 'returns the source as student and teacher survey items' do
|
it 'returns the source as student and teacher survey items' do
|
||||||
expect(measure.sources).to eq [:student_surveys, :teacher_surveys]
|
expect(measure.sources).to eq %i[student_surveys teacher_surveys]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a measure includes admin data and student and teacher survey items' do
|
context 'when a measure includes admin data and student and teacher survey items' do
|
||||||
before do
|
before do
|
||||||
create_list(:admin_data_item, 3, measure: measure,
|
create_list(:admin_data_item, 3, scale:,
|
||||||
watch_low_benchmark: admin_watch_low_benchmark,
|
watch_low_benchmark: admin_watch_low_benchmark,
|
||||||
growth_low_benchmark: admin_growth_low_benchmark,
|
growth_low_benchmark: admin_growth_low_benchmark,
|
||||||
approval_low_benchmark: admin_approval_low_benchmark,
|
approval_low_benchmark: admin_approval_low_benchmark,
|
||||||
ideal_low_benchmark: admin_ideal_low_benchmark)
|
ideal_low_benchmark: admin_ideal_low_benchmark)
|
||||||
create_list(:student_survey_item, 3, measure: measure,
|
create_list(:student_survey_item, 3, scale:,
|
||||||
watch_low_benchmark: student_watch_low_benchmark,
|
watch_low_benchmark: student_watch_low_benchmark,
|
||||||
growth_low_benchmark: student_growth_low_benchmark,
|
growth_low_benchmark: student_growth_low_benchmark,
|
||||||
approval_low_benchmark: student_approval_low_benchmark,
|
approval_low_benchmark: student_approval_low_benchmark,
|
||||||
ideal_low_benchmark: student_ideal_low_benchmark)
|
ideal_low_benchmark: student_ideal_low_benchmark)
|
||||||
|
|
||||||
create_list(:teacher_survey_item, 3, measure: measure,
|
create_list(:teacher_survey_item, 3, scale:,
|
||||||
watch_low_benchmark: teacher_watch_low_benchmark,
|
watch_low_benchmark: teacher_watch_low_benchmark,
|
||||||
growth_low_benchmark: teacher_growth_low_benchmark,
|
growth_low_benchmark: teacher_growth_low_benchmark,
|
||||||
approval_low_benchmark: teacher_approval_low_benchmark,
|
approval_low_benchmark: teacher_approval_low_benchmark,
|
||||||
|
|
@ -176,7 +183,290 @@ RSpec.describe Measure, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the source as admin student and teacher survey items' do
|
it 'returns the source as admin student and teacher survey items' do
|
||||||
expect(measure.sources).to eq [:admin_data, :student_surveys, :teacher_surveys]
|
expect(measure.sources).to eq %i[admin_data student_surveys teacher_surveys]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.score' do
|
||||||
|
context 'when the measure includes only teacher data' do
|
||||||
|
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
let(:teacher_survey_item_2) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
let(:teacher_survey_item_3) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
|
||||||
|
context "and the number of responses for each of the measure's survey items meets the teacher threshold of 17" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 3)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_2, academic_year:, school:, likert_score: 4)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_3, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 4
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result meets the teacher threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'reports the result does not meeet student threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and the average number of responses across the measure's survey items meets the teacher threshold of 17" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, 19, survey_item: teacher_survey_item_1, academic_year:, school:,
|
||||||
|
likert_score: 3)
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year:, school:,
|
||||||
|
likert_score: 4)
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year:, school:,
|
||||||
|
likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
average_score = 4
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_within(0.001).of(average_score)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and none of the measure's survey items meets the teacher threshold of 17" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_1, academic_year:, school:,
|
||||||
|
likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year:, school:,
|
||||||
|
likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year:, school:,
|
||||||
|
likert_score: rand)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result does not meet the threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and the average number of responses across the measure's survey items does not meet the teacher threshold of 17" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, 18, survey_item: teacher_survey_item_1, academic_year:, school:,
|
||||||
|
likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year:, school:,
|
||||||
|
likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year:, school:,
|
||||||
|
likert_score: rand)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result does not meet the threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the measure includes only student data' do
|
||||||
|
let(:student_survey_item_1) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
let(:student_survey_item_2) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
let(:student_survey_item_3) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
|
||||||
|
context "and the number of responses for each of the measure's survey items meets the student threshold of 196" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_1, academic_year:, school:, likert_score: 3)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_2, academic_year:, school:, likert_score: 4)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_3, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 4
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result meets the student threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be true
|
||||||
|
end
|
||||||
|
it 'notes that the result does not meet the teacher threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and the average number of responses across the measure's survey items meets the student threshold of 196" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, 200, survey_item: student_survey_item_1, academic_year:,
|
||||||
|
school:, likert_score: 3)
|
||||||
|
create_list(:survey_item_response, 195, survey_item: student_survey_item_2, academic_year:,
|
||||||
|
school:, likert_score: 4)
|
||||||
|
create_list(:survey_item_response, 193, survey_item: student_survey_item_3, academic_year:,
|
||||||
|
school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
average_score = 4
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_within(0.001).of(average_score)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and none of the measure's survey items meets the student threshold of 196" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, 195, survey_item: student_survey_item_1, academic_year:,
|
||||||
|
school:, likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 195, survey_item: student_survey_item_2, academic_year:,
|
||||||
|
school:, likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 195, survey_item: student_survey_item_3, academic_year:,
|
||||||
|
school:, likert_score: rand)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result does not meet the threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and the average number of responses across the measure's survey items does not meet the student threshold of 196" do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, 200, survey_item: student_survey_item_1, academic_year:,
|
||||||
|
school:, likert_score: rand)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_2, academic_year:, school:, likert_score: rand)
|
||||||
|
create_list(:survey_item_response, 191, survey_item: student_survey_item_3, academic_year:,
|
||||||
|
school:, likert_score: rand)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result does not meet the threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the measure includes both teacher and student data' do
|
||||||
|
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
let(:student_survey_item_1) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
|
||||||
|
context 'and there is sufficient teacher data and sufficient student data' do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 5)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_1, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result does meet the thresholds' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and a different measure in the same year exists' do
|
||||||
|
before :each do
|
||||||
|
different_measure = create(:measure)
|
||||||
|
different_scale = create(:teacher_scale, measure: different_measure)
|
||||||
|
different_teacher_survey_item = create(:teacher_survey_item, scale: different_scale)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: different_teacher_survey_item, academic_year:, school:, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms the additional measures do not change the scores for the original measure' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and data exists for the same measure but a different school' do
|
||||||
|
before do
|
||||||
|
different_school = create(:school)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school: different_school, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms the data for the different school does not affect the average for the original school' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and data exists for the same measure but a different year' do
|
||||||
|
before do
|
||||||
|
different_year = create(:academic_year, range: '1111-12')
|
||||||
|
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year: different_year, school:, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms the data for the different year does not affect the average for the original year' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and there is sufficient teacher data and insufficient student data' do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 5)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
||||||
|
survey_item: student_survey_item_1, academic_year:, school:, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the teacher survey items' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result meets the teacher threshold but not the student threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be true
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and there is insufficient teacher data and sufficient student data' do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 1)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_1, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the student survey items' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to eq 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result meets the student threshold but not the teacher threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be false
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and there is insufficient teacher data and insufficient student data' do
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
||||||
|
survey_item: student_survey_item_1, academic_year:, school:)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(measure.score(school:, academic_year:).average).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'affirms that the result does not meet either threshold' do
|
||||||
|
expect(measure.score(school:, academic_year:).meets_teacher_threshold?).to be false
|
||||||
|
expect(measure.score(school:, academic_year:).meets_student_threshold?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,16 @@ describe ResponseRate, type: :model do
|
||||||
describe StudentResponseRate do
|
describe StudentResponseRate do
|
||||||
let(:subcategory) { create(:subcategory) }
|
let(:subcategory) { create(:subcategory) }
|
||||||
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
||||||
|
let(:sufficient_scale_1) { create(:scale, measure: sufficient_measure_1) }
|
||||||
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
|
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
|
||||||
|
let(:sufficient_scale_2) { create(:scale, measure: sufficient_measure_2) }
|
||||||
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
||||||
let(:sufficient_teacher_survey_item) { create(:teacher_survey_item, measure: sufficient_measure_1) }
|
let(:insufficient_scale) { create(:scale, measure: insufficient_measure) }
|
||||||
let(:sufficient_student_survey_item_1) { create(:student_survey_item, measure: sufficient_measure_1) }
|
let(:sufficient_teacher_survey_item) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||||
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, measure: insufficient_measure) }
|
let(:sufficient_student_survey_item_1) { create(:student_survey_item, scale: sufficient_scale_1) }
|
||||||
let(:sufficient_student_survey_item_2) { create(:student_survey_item, measure: sufficient_measure_2) }
|
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, scale: insufficient_scale) }
|
||||||
let(:insufficient_student_survey_item) { create(:student_survey_item, measure: insufficient_measure) }
|
let(:sufficient_student_survey_item_2) { create(:student_survey_item, scale: sufficient_scale_2) }
|
||||||
|
let(:insufficient_student_survey_item) { create(:student_survey_item, scale: insufficient_scale) }
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
survey_respondents
|
survey_respondents
|
||||||
|
|
@ -44,14 +47,17 @@ describe ResponseRate, type: :model do
|
||||||
describe TeacherResponseRate do
|
describe TeacherResponseRate do
|
||||||
let(:subcategory) { create(:subcategory) }
|
let(:subcategory) { create(:subcategory) }
|
||||||
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
||||||
|
let(:sufficient_scale_1) { create(:scale, measure: sufficient_measure_1) }
|
||||||
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
|
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
|
||||||
|
let(:sufficient_scale_2) { create(:scale, measure: sufficient_measure_2) }
|
||||||
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
||||||
let(:sufficient_teacher_survey_item_1) { create(:teacher_survey_item, measure: sufficient_measure_1) }
|
let(:insufficient_scale) { create(:scale, measure: insufficient_measure) }
|
||||||
let(:sufficient_teacher_survey_item_2) { create(:teacher_survey_item, measure: sufficient_measure_1) }
|
let(:sufficient_teacher_survey_item_1) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||||
let(:sufficient_teacher_survey_item_3) { create(:teacher_survey_item, measure: sufficient_measure_1) }
|
let(:sufficient_teacher_survey_item_2) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||||
let(:sufficient_student_survey_item_1) { create(:student_survey_item, measure: sufficient_measure_1) }
|
let(:sufficient_teacher_survey_item_3) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||||
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, measure: insufficient_measure) }
|
let(:sufficient_student_survey_item_1) { create(:student_survey_item, scale: sufficient_scale_1) }
|
||||||
let(:insufficient_student_survey_item) { create(:student_survey_item, measure: insufficient_measure) }
|
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, scale: insufficient_scale) }
|
||||||
|
let(:insufficient_student_survey_item) { create(:student_survey_item, scale: insufficient_scale) }
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
survey_respondents
|
survey_respondents
|
||||||
|
|
|
||||||
41
spec/models/scale_spec.rb
Normal file
41
spec/models/scale_spec.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Scale, type: :model do
|
||||||
|
let(:school) { create(:school) }
|
||||||
|
let(:academic_year) { create(:academic_year) }
|
||||||
|
let(:scale) { create(:scale) }
|
||||||
|
|
||||||
|
describe '.score' do
|
||||||
|
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale:) }
|
||||||
|
let(:teacher_survey_item_2) { create(:teacher_survey_item, scale:) }
|
||||||
|
let(:teacher_survey_item_3) { create(:teacher_survey_item, scale:) }
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
create(:survey_item_response,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 3)
|
||||||
|
create(:survey_item_response,
|
||||||
|
survey_item: teacher_survey_item_2, academic_year:, school:, likert_score: 4)
|
||||||
|
create(:survey_item_response,
|
||||||
|
survey_item: teacher_survey_item_3, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
expect(scale.score(school:, academic_year:)).to eq 4
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when other scales exist' do
|
||||||
|
before :each do
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not affect the score for the original scale' do
|
||||||
|
expect(scale.score(school:, academic_year:)).to eq 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
60
spec/models/subcategory_spec.rb
Normal file
60
spec/models/subcategory_spec.rb
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Subcategory, type: :model do
|
||||||
|
let(:school) { create(:school) }
|
||||||
|
let(:academic_year) { create(:academic_year) }
|
||||||
|
let(:subcategory) { create(:subcategory) }
|
||||||
|
let(:measure_1) { create(:measure, subcategory: subcategory) }
|
||||||
|
let(:teacher_scale) { create(:teacher_scale, measure: measure_1) }
|
||||||
|
let(:measure_2) { create(:measure, subcategory: subcategory) }
|
||||||
|
let(:student_scale) { create(:student_scale, measure: measure_2) }
|
||||||
|
|
||||||
|
describe '.score' do
|
||||||
|
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
let(:teacher_survey_item_2) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
let(:teacher_survey_item_3) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||||
|
let(:student_survey_item_1) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
let(:student_survey_item_2) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
let(:student_survey_item_3) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
let(:student_survey_item_4) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
let(:student_survey_item_5) { create(:student_survey_item, scale: student_scale) }
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_1, academic_year:, school:, likert_score: 2)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_2, academic_year:, school:, likert_score: 3)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: teacher_survey_item_3, academic_year:, school:, likert_score: 4)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_1, academic_year:, school:, likert_score: 1)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_2, academic_year:, school:, likert_score: 2)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_3, academic_year:, school:, likert_score: 3)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_4, academic_year:, school:, likert_score: 4)
|
||||||
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
|
survey_item: student_survey_item_5, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the measures' do
|
||||||
|
expect(subcategory.score(school:, academic_year:)).to eq 3
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when other subcategories exist' do
|
||||||
|
before :each do
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not affect the score for the original scale' do
|
||||||
|
expect(subcategory.score(school:, academic_year:)).to eq 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,337 +0,0 @@
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
describe SurveyItemResponse, type: :model do
|
|
||||||
let(:school) { create(:school) }
|
|
||||||
let(:ay) { create(:academic_year) }
|
|
||||||
|
|
||||||
describe '.score_for_measure' do
|
|
||||||
let(:measure) { create(:measure) }
|
|
||||||
|
|
||||||
context 'when the measure includes only teacher data' do
|
|
||||||
let(:teacher_survey_item_1) { create(:teacher_survey_item, measure: measure) }
|
|
||||||
let(:teacher_survey_item_2) { create(:teacher_survey_item, measure: measure) }
|
|
||||||
let(:teacher_survey_item_3) { create(:teacher_survey_item, measure: measure) }
|
|
||||||
|
|
||||||
context "and the number of responses for each of the measure's survey items meets the teacher threshold of 17" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 3)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: teacher_survey_item_2, academic_year: ay, school: school, likert_score: 4)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: teacher_survey_item_3, academic_year: ay, school: school, likert_score: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the survey items' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to eq 4
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result meets the teacher threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'reports the result does not meeet student threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and the average number of responses across the measure's survey items meets the teacher threshold of 17" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, 19, survey_item: teacher_survey_item_1, academic_year: ay, school: school,
|
|
||||||
likert_score: 3)
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year: ay, school: school,
|
|
||||||
likert_score: 4)
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year: ay, school: school,
|
|
||||||
likert_score: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the survey items' do
|
|
||||||
average_score = 3.941
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_within(0.001).of(average_score)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and none of the measure's survey items meets the teacher threshold of 17" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_1, academic_year: ay, school: school,
|
|
||||||
likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year: ay, school: school,
|
|
||||||
likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year: ay, school: school,
|
|
||||||
likert_score: rand)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result does not meet the threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and the average number of responses across the measure's survey items does not meet the teacher threshold of 17" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, 18, survey_item: teacher_survey_item_1, academic_year: ay, school: school,
|
|
||||||
likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_2, academic_year: ay, school: school,
|
|
||||||
likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 16, survey_item: teacher_survey_item_3, academic_year: ay, school: school,
|
|
||||||
likert_score: rand)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result does not meet the threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the measure includes only student data' do
|
|
||||||
let(:student_survey_item_1) { create(:student_survey_item, measure: measure) }
|
|
||||||
let(:student_survey_item_2) { create(:student_survey_item, measure: measure) }
|
|
||||||
let(:student_survey_item_3) { create(:student_survey_item, measure: measure) }
|
|
||||||
|
|
||||||
context "and the number of responses for each of the measure's survey items meets the student threshold of 196" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 3)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: 4)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: student_survey_item_3, academic_year: ay, school: school, likert_score: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the survey items' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to eq 4
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result meets the student threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be true
|
|
||||||
end
|
|
||||||
it 'notes that the result does not meet the teacher threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and the average number of responses across the measure's survey items meets the student threshold of 196" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, 200, survey_item: student_survey_item_1, academic_year: ay,
|
|
||||||
school: school, likert_score: 3)
|
|
||||||
create_list(:survey_item_response, 195, survey_item: student_survey_item_2, academic_year: ay,
|
|
||||||
school: school, likert_score: 4)
|
|
||||||
create_list(:survey_item_response, 193, survey_item: student_survey_item_3, academic_year: ay,
|
|
||||||
school: school, likert_score: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the survey items' do
|
|
||||||
average_score = 3.988
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_within(0.001).of(average_score)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and none of the measure's survey items meets the student threshold of 196" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, 195, survey_item: student_survey_item_1, academic_year: ay,
|
|
||||||
school: school, likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 195, survey_item: student_survey_item_2, academic_year: ay,
|
|
||||||
school: school, likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 195, survey_item: student_survey_item_3, academic_year: ay,
|
|
||||||
school: school, likert_score: rand)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result does not meet the threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and the average number of responses across the measure's survey items does not meet the student threshold of 196" do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, 200, survey_item: student_survey_item_1, academic_year: ay,
|
|
||||||
school: school, likert_score: rand)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: student_survey_item_2, academic_year: ay, school: school, likert_score: rand)
|
|
||||||
create_list(:survey_item_response, 191, survey_item: student_survey_item_3, academic_year: ay,
|
|
||||||
school: school, likert_score: rand)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result does not meet the threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the measure includes both teacher and student data' do
|
|
||||||
let(:teacher_survey_item_1) { create(:teacher_survey_item, measure: measure) }
|
|
||||||
let(:student_survey_item_1) { create(:student_survey_item, measure: measure) }
|
|
||||||
|
|
||||||
context 'and there is sufficient teacher data and sufficient student data' do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 5)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the survey items' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to eq 5
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result does meet the thresholds' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be true
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and there is sufficient teacher data and insufficient student data' do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 5)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the teacher survey items' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to eq 5
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result meets the teacher threshold but not the student threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be true
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and there is insufficient teacher data and sufficient student data' do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: teacher_survey_item_1, academic_year: ay, school: school, likert_score: 1)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
|
||||||
survey_item: student_survey_item_1, academic_year: ay, school: school, likert_score: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average of the likert scores of the student survey items' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to eq 5
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result meets the student threshold but not the teacher threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be false
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and there is insufficient teacher data and insufficient student data' do
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: teacher_survey_item_1, academic_year: ay, school: school)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: student_survey_item_1, academic_year: ay, school: school)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).average).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'affirms that the result does not meet either threshold' do
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_teacher_threshold?).to be false
|
|
||||||
expect(SurveyItemResponse.score_for_measure(measure: measure, school: school,
|
|
||||||
academic_year: ay).meets_student_threshold?).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.score_for_subcategory' do
|
|
||||||
let(:subcategory) { create(:subcategory) }
|
|
||||||
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
|
||||||
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
|
|
||||||
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
|
||||||
let(:sufficient_teacher_survey_item) { create(:teacher_survey_item, measure: sufficient_measure_1) }
|
|
||||||
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, measure: insufficient_measure) }
|
|
||||||
let(:sufficient_student_survey_item) { create(:student_survey_item, measure: sufficient_measure_2) }
|
|
||||||
let(:insufficient_student_survey_item) { create(:student_survey_item, measure: insufficient_measure) }
|
|
||||||
|
|
||||||
before :each do
|
|
||||||
largest_threshold = [SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
|
||||||
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD].max
|
|
||||||
create_list(:survey_item_response, largest_threshold, survey_item: sufficient_teacher_survey_item,
|
|
||||||
academic_year: ay, school: school, likert_score: 1)
|
|
||||||
create_list(:survey_item_response, largest_threshold, survey_item: sufficient_student_survey_item,
|
|
||||||
academic_year: ay, school: school, likert_score: 4)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: insufficient_teacher_survey_item, academic_year: ay, school: school, likert_score: 1)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: insufficient_student_survey_item, academic_year: ay, school: school, likert_score: 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the average score of all survey item responses for measures meeting their respective thresholds' do
|
|
||||||
expect(SurveyItemResponse.score_for_subcategory(subcategory: subcategory, school: school,
|
|
||||||
academic_year: ay)).to eq 2.5
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.responses_for_measure' do
|
|
||||||
let(:subcategory) { create(:subcategory) }
|
|
||||||
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
|
||||||
let(:sufficient_measure_2) { create(:measure, subcategory: subcategory) }
|
|
||||||
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
|
||||||
let(:sufficient_teacher_survey_item) { create(:teacher_survey_item, measure: sufficient_measure_1) }
|
|
||||||
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, measure: insufficient_measure) }
|
|
||||||
let(:sufficient_student_survey_item) { create(:student_survey_item, measure: sufficient_measure_2) }
|
|
||||||
let(:insufficient_student_survey_item) { create(:student_survey_item, measure: insufficient_measure) }
|
|
||||||
|
|
||||||
before :each do
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item,
|
|
||||||
academic_year: ay, school: school, likert_score: 1)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: sufficient_student_survey_item,
|
|
||||||
academic_year: ay, school: school, likert_score: 4)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: insufficient_teacher_survey_item, academic_year: ay, school: school, likert_score: 1)
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
|
||||||
survey_item: insufficient_student_survey_item, academic_year: ay, school: school, likert_score: 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns only responses in a measure that meets the low threshold' do
|
|
||||||
expect(SurveyItemResponse.responses_for_measure(measure: sufficient_measure_1, school: school, academic_year: ay).count).to eq SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD
|
|
||||||
expect(SurveyItemResponse.responses_for_measure(measure: sufficient_measure_2, school: school, academic_year: ay).count).to eq SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD
|
|
||||||
expect(SurveyItemResponse.responses_for_measure(measure: insufficient_measure, school: school, academic_year: ay)).to be nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
38
spec/models/survey_item_spec.rb
Normal file
38
spec/models/survey_item_spec.rb
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
RSpec.describe SurveyItem, type: :model do
|
||||||
|
let(:school) { create(:school) }
|
||||||
|
let(:academic_year) { create(:academic_year) }
|
||||||
|
let(:scale) { create(:scale) }
|
||||||
|
|
||||||
|
describe '.score' do
|
||||||
|
let(:teacher_survey_item) { create(:teacher_survey_item, scale:) }
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
create(:survey_item_response,
|
||||||
|
survey_item: teacher_survey_item, academic_year:, school:, likert_score: 3)
|
||||||
|
create(:survey_item_response,
|
||||||
|
survey_item: teacher_survey_item, academic_year:, school:, likert_score: 4)
|
||||||
|
create(:survey_item_response,
|
||||||
|
survey_item: teacher_survey_item, academic_year:, school:, likert_score: 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the average of the likert scores of the survey items' do
|
||||||
|
expect(teacher_survey_item.score(school:, academic_year:)).to eq 4
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when other scales exist' do
|
||||||
|
before :each do
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
create(:survey_item_response,
|
||||||
|
academic_year:, school:, likert_score: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not affect the score for the original scale' do
|
||||||
|
expect(scale.score(school:, academic_year:)).to eq 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe GaugePresenter do
|
describe GaugePresenter do
|
||||||
let(:scale) do
|
let(:zones) do
|
||||||
Scale.new(
|
Zones.new(
|
||||||
watch_low_benchmark: 1.5,
|
watch_low_benchmark: 1.5,
|
||||||
growth_low_benchmark: 2.5,
|
growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5,
|
approval_low_benchmark: 3.5,
|
||||||
|
|
@ -11,7 +11,7 @@ describe GaugePresenter do
|
||||||
end
|
end
|
||||||
let(:score) { 3 }
|
let(:score) { 3 }
|
||||||
|
|
||||||
let(:gauge_presenter) { GaugePresenter.new(scale: scale, score: score) }
|
let(:gauge_presenter) { GaugePresenter.new(zones: zones, score: score) }
|
||||||
|
|
||||||
it 'returns the key benchmark percentage for the gauge' do
|
it 'returns the key benchmark percentage for the gauge' do
|
||||||
expect(gauge_presenter.key_benchmark_percentage).to eq 0.625
|
expect(gauge_presenter.key_benchmark_percentage).to eq 0.625
|
||||||
|
|
@ -98,8 +98,8 @@ describe GaugePresenter do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there are no benchmarks or score for the gauge' do
|
context 'when there are no benchmarks or score for the gauge' do
|
||||||
let(:scale) do
|
let(:zones) do
|
||||||
Scale.new(
|
Zones.new(
|
||||||
watch_low_benchmark: nil,
|
watch_low_benchmark: nil,
|
||||||
growth_low_benchmark: nil,
|
growth_low_benchmark: nil,
|
||||||
approval_low_benchmark: nil,
|
approval_low_benchmark: nil,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ describe MeasurePresenter do
|
||||||
let(:academic_year) { create(:academic_year, range: '1989-90') }
|
let(:academic_year) { create(:academic_year, range: '1989-90') }
|
||||||
let(:school) { create(:school, name: 'Best School') }
|
let(:school) { create(:school, name: 'Best School') }
|
||||||
let(:measure) { create(:measure, measure_id: 'measure-id') }
|
let(:measure) { create(:measure, measure_id: 'measure-id') }
|
||||||
let(:measure_presenter) { MeasurePresenter.new(measure: measure, academic_year: academic_year, school: school) }
|
let(:teacher_scale) { create(:teacher_scale, measure:) }
|
||||||
|
let(:student_scale) { create(:student_scale, measure:) }
|
||||||
|
let(:admin_scale) { create(:scale, measure:) }
|
||||||
|
let(:measure_presenter) { MeasurePresenter.new(measure:, academic_year:, school:) }
|
||||||
|
|
||||||
it 'returns the id of the measure' do
|
it 'returns the id of the measure' do
|
||||||
expect(measure_presenter.id).to eq 'measure-id'
|
expect(measure_presenter.id).to eq 'measure-id'
|
||||||
|
|
@ -16,13 +19,13 @@ describe MeasurePresenter do
|
||||||
|
|
||||||
context 'when the measure contains only teacher data' do
|
context 'when the measure contains only teacher data' do
|
||||||
before :each do
|
before :each do
|
||||||
survey_item1 = create(:teacher_survey_item, measure: measure, prompt: 'A teacher survey item prompt')
|
survey_item1 = create(:teacher_survey_item, scale: teacher_scale, prompt: 'A teacher survey item prompt')
|
||||||
survey_item2 = create(:teacher_survey_item, measure: measure, prompt: 'Another teacher survey item prompt')
|
survey_item2 = create(:teacher_survey_item, scale: teacher_scale, prompt: 'Another teacher survey item prompt')
|
||||||
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item1,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item1,
|
||||||
academic_year: academic_year, school: school, likert_score: 1)
|
academic_year:, school:, likert_score: 1)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item2,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item2,
|
||||||
academic_year: academic_year, school: school, likert_score: 5)
|
academic_year:, school:, likert_score: 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a gauge presenter that presents the average likert score' do
|
it 'creates a gauge presenter that presents the average likert score' do
|
||||||
|
|
@ -41,10 +44,10 @@ describe MeasurePresenter do
|
||||||
|
|
||||||
context 'when the measure contains both teacher data and admin data' do
|
context 'when the measure contains both teacher data and admin data' do
|
||||||
before :each do
|
before :each do
|
||||||
create(:teacher_survey_item, measure: measure, prompt: 'A teacher survey item prompt')
|
create(:teacher_survey_item, scale: teacher_scale, prompt: 'A teacher survey item prompt')
|
||||||
create(:teacher_survey_item, measure: measure, prompt: 'Another teacher survey item prompt')
|
create(:teacher_survey_item, scale: teacher_scale, prompt: 'Another teacher survey item prompt')
|
||||||
create(:admin_data_item, measure: measure, description: 'An admin data item description')
|
create(:admin_data_item, scale: admin_scale, description: 'An admin data item description')
|
||||||
create(:admin_data_item, measure: measure, description: 'Another admin data item description')
|
create(:admin_data_item, scale: admin_scale, description: 'Another admin data item description')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a list of data item presenters with two elements' do
|
it 'returns a list of data item presenters with two elements' do
|
||||||
|
|
@ -68,13 +71,13 @@ describe MeasurePresenter do
|
||||||
|
|
||||||
context 'when the measure has partial data for teachers and students' do
|
context 'when the measure has partial data for teachers and students' do
|
||||||
before :each do
|
before :each do
|
||||||
teacher_survey_item = create(:teacher_survey_item, measure: measure)
|
teacher_survey_item = create(:teacher_survey_item, scale: teacher_scale)
|
||||||
student_survey_item = create(:student_survey_item, measure: measure)
|
student_survey_item = create(:student_survey_item, scale: student_scale)
|
||||||
|
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
survey_item: teacher_survey_item, academic_year: academic_year, school: school)
|
survey_item: teacher_survey_item, academic_year:, school:)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
||||||
survey_item: student_survey_item, academic_year: academic_year, school: school)
|
survey_item: student_survey_item, academic_year:, school:)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'tracks which parts of the data are sufficient' do
|
it 'tracks which parts of the data are sufficient' do
|
||||||
|
|
@ -91,9 +94,9 @@ describe MeasurePresenter do
|
||||||
|
|
||||||
context 'when the measure has insufficient admin data and insufficient teacher/student data' do
|
context 'when the measure has insufficient admin data and insufficient teacher/student data' do
|
||||||
before :each do
|
before :each do
|
||||||
create(:admin_data_item, measure: measure)
|
create(:admin_data_item, scale: admin_scale)
|
||||||
create(:teacher_survey_item, measure: measure)
|
create(:teacher_survey_item, scale: teacher_scale)
|
||||||
create(:student_survey_item, measure: measure)
|
create(:student_survey_item, scale: student_scale)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'tracks the reason for their insufficiency' do
|
it 'tracks the reason for their insufficiency' do
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe Scale do
|
describe Zones do
|
||||||
describe '#zone_for_score' do
|
describe '#zone_for_score' do
|
||||||
let(:scale) do
|
let(:zones) do
|
||||||
Scale.new watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5,
|
Zones.new watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5,
|
||||||
ideal_low_benchmark: 4.5
|
ideal_low_benchmark: 4.5
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the score is 1.0' do
|
context 'when the score is 1.0' do
|
||||||
it 'returns the warning zone' do
|
it 'returns the warning zone' do
|
||||||
expect(scale.zone_for_score(1.0)).to eq scale.warning_zone
|
expect(zones.zone_for_score(1.0)).to eq zones.warning_zone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the score is 5.0' do
|
context 'when the score is 5.0' do
|
||||||
it 'returns the ideal zone' do
|
it 'returns the ideal zone' do
|
||||||
expect(scale.zone_for_score(5.0)).to eq scale.ideal_zone
|
expect(zones.zone_for_score(5.0)).to eq zones.ideal_zone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the score is right on the benchmark' do
|
context 'when the score is right on the benchmark' do
|
||||||
it 'returns the higher zone' do
|
it 'returns the higher zone' do
|
||||||
expect(scale.zone_for_score(1.5)).to eq scale.watch_zone
|
expect(zones.zone_for_score(1.5)).to eq zones.watch_zone
|
||||||
expect(scale.zone_for_score(2.5)).to eq scale.growth_zone
|
expect(zones.zone_for_score(2.5)).to eq zones.growth_zone
|
||||||
expect(scale.zone_for_score(3.5)).to eq scale.approval_zone
|
expect(zones.zone_for_score(3.5)).to eq zones.approval_zone
|
||||||
expect(scale.zone_for_score(4.5)).to eq scale.ideal_zone
|
expect(zones.zone_for_score(4.5)).to eq zones.ideal_zone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe SubcategoryCardPresenter do
|
describe SubcategoryCardPresenter do
|
||||||
let(:scale) do
|
let(:zones) do
|
||||||
Scale.new(
|
Zones.new(
|
||||||
watch_low_benchmark: 1.5,
|
watch_low_benchmark: 1.5,
|
||||||
growth_low_benchmark: 2.5,
|
growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5,
|
approval_low_benchmark: 3.5,
|
||||||
|
|
@ -10,7 +10,7 @@ describe SubcategoryCardPresenter do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:subcategory_card_presenter) { SubcategoryCardPresenter.new(name: 'Card name', scale: scale, score: score) }
|
let(:subcategory_card_presenter) { SubcategoryCardPresenter.new(name: 'Card name', zones: zones, score: score) }
|
||||||
|
|
||||||
context 'when the given score is in the Warning zone for the given scale' do
|
context 'when the given score is in the Warning zone for the given scale' do
|
||||||
let(:score) { 1 }
|
let(:score) { 1 }
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,11 @@ describe SubcategoryPresenter do
|
||||||
let(:subcategory_presenter) do
|
let(:subcategory_presenter) do
|
||||||
survey_respondents
|
survey_respondents
|
||||||
measure1 = create(:measure, subcategory:)
|
measure1 = create(:measure, subcategory:)
|
||||||
survey_item1 = create(:teacher_survey_item, measure: measure1, watch_low_benchmark: 4, growth_low_benchmark: 4.25,
|
teacher_scale_1 = create(:teacher_scale, measure: measure1)
|
||||||
|
student_scale_1 = create(:student_scale, measure: measure1)
|
||||||
|
survey_item1 = create(:teacher_survey_item, scale: teacher_scale_1, watch_low_benchmark: 4, growth_low_benchmark: 4.25,
|
||||||
approval_low_benchmark: 4.5, ideal_low_benchmark: 4.75)
|
approval_low_benchmark: 4.5, ideal_low_benchmark: 4.75)
|
||||||
survey_item2 = create(:student_survey_item, measure: measure1, watch_low_benchmark: 4, growth_low_benchmark: 4.25,
|
survey_item2 = create(:student_survey_item, scale: student_scale_1, watch_low_benchmark: 4, growth_low_benchmark: 4.25,
|
||||||
approval_low_benchmark: 4.5, ideal_low_benchmark: 4.75)
|
approval_low_benchmark: 4.5, ideal_low_benchmark: 4.75)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item1,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item1,
|
||||||
academic_year:, school:, likert_score: 1)
|
academic_year:, school:, likert_score: 1)
|
||||||
|
|
@ -27,9 +29,12 @@ describe SubcategoryPresenter do
|
||||||
academic_year:, school:, likert_score: 3)
|
academic_year:, school:, likert_score: 3)
|
||||||
|
|
||||||
measure2 = create(:measure, subcategory:)
|
measure2 = create(:measure, subcategory:)
|
||||||
survey_item3 = create(:teacher_survey_item, measure: measure2, watch_low_benchmark: 1.25,
|
teacher_scale_2 = create(:teacher_scale, measure: measure2)
|
||||||
|
student_scale_2 = create(:student_scale, measure: measure2)
|
||||||
|
|
||||||
|
survey_item3 = create(:teacher_survey_item, scale: teacher_scale_2, watch_low_benchmark: 1.25,
|
||||||
growth_low_benchmark: 1.5, approval_low_benchmark: 1.75, ideal_low_benchmark: 2.0)
|
growth_low_benchmark: 1.5, approval_low_benchmark: 1.75, ideal_low_benchmark: 2.0)
|
||||||
survey_item4 = create(:student_survey_item, measure: measure2, watch_low_benchmark: 1.25,
|
survey_item4 = create(:student_survey_item, scale: student_scale_2, watch_low_benchmark: 1.25,
|
||||||
growth_low_benchmark: 1.5, approval_low_benchmark: 1.75, ideal_low_benchmark: 2.0)
|
growth_low_benchmark: 1.5, approval_low_benchmark: 1.75, ideal_low_benchmark: 2.0)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item3,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: survey_item3,
|
||||||
academic_year:, school:, likert_score: 1)
|
academic_year:, school:, likert_score: 1)
|
||||||
|
|
@ -100,8 +105,9 @@ describe SubcategoryPresenter do
|
||||||
context 'and the measure does not include high-school-only admin data items' do
|
context 'and the measure does not include high-school-only admin data items' do
|
||||||
before do
|
before do
|
||||||
measure_of_only_admin_data = create(:measure, subcategory:)
|
measure_of_only_admin_data = create(:measure, subcategory:)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: false)
|
scale_of_only_admin_data = create(:scale, measure: measure_of_only_admin_data)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: false)
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: false)
|
||||||
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: false)
|
||||||
end
|
end
|
||||||
it 'returns the admin collection rate' do
|
it 'returns the admin collection rate' do
|
||||||
expect(subcategory_presenter.admin_collection_rate).to eq [0, 2]
|
expect(subcategory_presenter.admin_collection_rate).to eq [0, 2]
|
||||||
|
|
@ -111,8 +117,9 @@ describe SubcategoryPresenter do
|
||||||
context 'and the measure includes high-school-only items' do
|
context 'and the measure includes high-school-only items' do
|
||||||
before do
|
before do
|
||||||
measure_of_only_admin_data = create(:measure, subcategory:)
|
measure_of_only_admin_data = create(:measure, subcategory:)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: true)
|
scale_of_only_admin_data = create(:scale, measure: measure_of_only_admin_data)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: true)
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: true)
|
||||||
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: true)
|
||||||
end
|
end
|
||||||
it 'returns the admin collection rate' do
|
it 'returns the admin collection rate' do
|
||||||
expect(subcategory_presenter.admin_collection_rate).to eq %w[N A]
|
expect(subcategory_presenter.admin_collection_rate).to eq %w[N A]
|
||||||
|
|
@ -126,8 +133,9 @@ describe SubcategoryPresenter do
|
||||||
school.is_hs = true
|
school.is_hs = true
|
||||||
school.save
|
school.save
|
||||||
measure_of_only_admin_data = create(:measure, subcategory:)
|
measure_of_only_admin_data = create(:measure, subcategory:)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: false)
|
scale_of_only_admin_data = create(:scale, measure: measure_of_only_admin_data)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: false)
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: false)
|
||||||
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: false)
|
||||||
end
|
end
|
||||||
it 'returns the admin collection rate' do
|
it 'returns the admin collection rate' do
|
||||||
expect(subcategory_presenter.admin_collection_rate).to eq [0, 2]
|
expect(subcategory_presenter.admin_collection_rate).to eq [0, 2]
|
||||||
|
|
@ -139,8 +147,9 @@ describe SubcategoryPresenter do
|
||||||
school.is_hs = true
|
school.is_hs = true
|
||||||
school.save
|
school.save
|
||||||
measure_of_only_admin_data = create(:measure, subcategory:)
|
measure_of_only_admin_data = create(:measure, subcategory:)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: true)
|
scale_of_only_admin_data = create(:scale, measure: measure_of_only_admin_data)
|
||||||
create(:admin_data_item, measure: measure_of_only_admin_data, hs_only_item: true)
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: true)
|
||||||
|
create(:admin_data_item, scale: scale_of_only_admin_data, hs_only_item: true)
|
||||||
end
|
end
|
||||||
it 'returns the admin collection rate' do
|
it 'returns the admin collection rate' do
|
||||||
expect(subcategory_presenter.admin_collection_rate).to eq [0, 2]
|
expect(subcategory_presenter.admin_collection_rate).to eq [0, 2]
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,13 @@ describe VarianceChartRowPresenter do
|
||||||
:measure,
|
:measure,
|
||||||
name: 'Some Title'
|
name: 'Some Title'
|
||||||
)
|
)
|
||||||
|
scale = create(:scale, measure:)
|
||||||
|
|
||||||
create(:student_survey_item, measure: measure,
|
create(:student_survey_item, scale:,
|
||||||
watch_low_benchmark: watch_low_benchmark,
|
watch_low_benchmark:,
|
||||||
growth_low_benchmark: growth_low_benchmark,
|
growth_low_benchmark:,
|
||||||
approval_low_benchmark: approval_low_benchmark,
|
approval_low_benchmark:,
|
||||||
ideal_low_benchmark: ideal_low_benchmark)
|
ideal_low_benchmark:)
|
||||||
|
|
||||||
measure
|
measure
|
||||||
end
|
end
|
||||||
|
|
@ -29,7 +30,7 @@ describe VarianceChartRowPresenter do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:presenter) do
|
let(:presenter) do
|
||||||
VarianceChartRowPresenter.new measure: measure, score: score
|
VarianceChartRowPresenter.new measure:, score:
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples_for 'measure_name' do
|
shared_examples_for 'measure_name' do
|
||||||
|
|
@ -155,8 +156,9 @@ describe VarianceChartRowPresenter do
|
||||||
:measure,
|
:measure,
|
||||||
name: 'Some Title'
|
name: 'Some Title'
|
||||||
)
|
)
|
||||||
|
scale_with_admin_data = create(:scale, measure: measure_with_admin_data)
|
||||||
create :admin_data_item,
|
create :admin_data_item,
|
||||||
measure: measure_with_admin_data,
|
scale: scale_with_admin_data,
|
||||||
watch_low_benchmark: watch_low_benchmark,
|
watch_low_benchmark: watch_low_benchmark,
|
||||||
growth_low_benchmark: growth_low_benchmark,
|
growth_low_benchmark: growth_low_benchmark,
|
||||||
approval_low_benchmark: approval_low_benchmark,
|
approval_low_benchmark: approval_low_benchmark,
|
||||||
|
|
@ -172,7 +174,8 @@ describe VarianceChartRowPresenter do
|
||||||
|
|
||||||
context 'when a measure contains teacher survey items' do
|
context 'when a measure contains teacher survey items' do
|
||||||
before :each do
|
before :each do
|
||||||
create :teacher_survey_item, measure: measure
|
scale = create(:scale, measure:)
|
||||||
|
create :teacher_survey_item, scale:
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there are insufficient teacher survey item responses' do
|
context 'when there are insufficient teacher survey item responses' do
|
||||||
|
|
@ -193,7 +196,8 @@ describe VarianceChartRowPresenter do
|
||||||
|
|
||||||
context 'when a measure contains student survey items' do
|
context 'when a measure contains student survey items' do
|
||||||
before :each do
|
before :each do
|
||||||
create :student_survey_item, measure: measure
|
scale = create(:scale, measure:)
|
||||||
|
create :student_survey_item, scale:
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there are insufficient student survey item responses' do
|
context 'when there are insufficient student survey item responses' do
|
||||||
|
|
@ -205,7 +209,8 @@ describe VarianceChartRowPresenter do
|
||||||
|
|
||||||
context 'where there are also admin data items' do
|
context 'where there are also admin data items' do
|
||||||
before :each do
|
before :each do
|
||||||
create :admin_data_item, measure: measure
|
scale = create(:scale, measure:)
|
||||||
|
create :admin_data_item, scale:
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the sources for partial results of administrative data and student survey results' do
|
it 'returns the sources for partial results of administrative data and student survey results' do
|
||||||
|
|
@ -224,12 +229,13 @@ describe VarianceChartRowPresenter do
|
||||||
|
|
||||||
context 'sorting scores' do
|
context 'sorting scores' do
|
||||||
it 'selects a longer bar before a shorter bar for measures in the approval/ideal zones' do
|
it 'selects a longer bar before a shorter bar for measures in the approval/ideal zones' do
|
||||||
|
scale_with_student_survey_items = create(:scale, measure:)
|
||||||
create(:student_survey_item,
|
create(:student_survey_item,
|
||||||
measure: measure,
|
scale: scale_with_student_survey_items,
|
||||||
watch_low_benchmark: watch_low_benchmark,
|
watch_low_benchmark:,
|
||||||
growth_low_benchmark: growth_low_benchmark,
|
growth_low_benchmark:,
|
||||||
approval_low_benchmark: approval_low_benchmark,
|
approval_low_benchmark:,
|
||||||
ideal_low_benchmark: ideal_low_benchmark)
|
ideal_low_benchmark:)
|
||||||
approval_presenter = VarianceChartRowPresenter.new measure: measure, score: Score.new(3.7, true, true)
|
approval_presenter = VarianceChartRowPresenter.new measure: measure, score: Score.new(3.7, true, true)
|
||||||
ideal_presenter = VarianceChartRowPresenter.new measure: measure, score: Score.new(4.4, true, true)
|
ideal_presenter = VarianceChartRowPresenter.new measure: measure, score: Score.new(4.4, true, true)
|
||||||
expect(ideal_presenter <=> approval_presenter).to be < 0
|
expect(ideal_presenter <=> approval_presenter).to be < 0
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,20 @@ describe 'District Admin', js: true do
|
||||||
let(:category) { Category.find_by_name('Teachers & Leadership') }
|
let(:category) { Category.find_by_name('Teachers & Leadership') }
|
||||||
let(:subcategory) { Subcategory.find_by_name('Teachers & The Teaching Environment') }
|
let(:subcategory) { Subcategory.find_by_name('Teachers & The Teaching Environment') }
|
||||||
let(:measures_for_subcategory) { Measure.where(subcategory:) }
|
let(:measures_for_subcategory) { Measure.where(subcategory:) }
|
||||||
let(:survey_items_for_subcategory) { SurveyItem.where(measure: measures_for_subcategory) }
|
let(:scales_for_subcategory) {Scale.where(measure: measures_for_subcategory)}
|
||||||
|
let(:survey_items_for_subcategory) { SurveyItem.where(scale: scales_for_subcategory) }
|
||||||
|
|
||||||
let(:measure_1A_i) { Measure.find_by_measure_id('1A-i') }
|
let(:measure_1A_i) { Measure.find_by_measure_id('1A-i') }
|
||||||
let(:measure_2A_i) { Measure.find_by_measure_id('2A-i') }
|
let(:measure_2A_i) { Measure.find_by_measure_id('2A-i') }
|
||||||
let(:measure_4C_i) { Measure.find_by_measure_id('4C-i') }
|
let(:measure_4C_i) { Measure.find_by_measure_id('4C-i') }
|
||||||
let(:measure_with_no_survey_responses) { Measure.find_by_measure_id('3A-i') }
|
let(:measure_with_no_survey_responses) { Measure.find_by_measure_id('3A-i') }
|
||||||
|
|
||||||
let(:survey_item_1_for_measure_1A_i) { SurveyItem.create measure: measure_1A_i, survey_item_id: rand.to_s }
|
let(:survey_item_1_for_measure_1A_i) { SurveyItem.create scale: measure_1A_i.scales.first, survey_item_id: rand.to_s }
|
||||||
let(:survey_item_2_for_measure_1A_i) { SurveyItem.create measure: measure_1A_i, survey_item_id: rand.to_s }
|
let(:survey_item_2_for_measure_1A_i) { SurveyItem.create scale: measure_1A_i.scales.first, survey_item_id: rand.to_s }
|
||||||
|
|
||||||
let(:survey_items_for_measure_1A_i) { SurveyItem.where(measure: measure_1A_i) }
|
let(:survey_items_for_measure_1A_i) { measure_1A_i.survey_items }
|
||||||
let(:survey_items_for_measure_2A_i) { SurveyItem.where(measure: measure_2A_i) }
|
let(:survey_items_for_measure_2A_i) { measure_2A_i.survey_items }
|
||||||
let(:survey_items_for_measure_4C_i) { SurveyItem.where(measure: measure_4C_i) }
|
let(:survey_items_for_measure_4C_i) { measure_4C_i.survey_items }
|
||||||
|
|
||||||
let(:ay_2020_21) { AcademicYear.find_by_range '2020-21' }
|
let(:ay_2020_21) { AcademicYear.find_by_range '2020-21' }
|
||||||
let(:ay_2019_20) { AcademicYear.find_by_range '2019-20' }
|
let(:ay_2019_20) { AcademicYear.find_by_range '2019-20' }
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ describe 'SQM Application' do
|
||||||
let(:academic_year) { create(:academic_year) }
|
let(:academic_year) { create(:academic_year) }
|
||||||
let(:category) { create(:category) }
|
let(:category) { create(:category) }
|
||||||
let(:measure) { create(:measure) }
|
let(:measure) { create(:measure) }
|
||||||
|
let(:scale) {create(:scale, measure:)}
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
driven_by :rack_test
|
driven_by :rack_test
|
||||||
|
|
@ -26,7 +27,7 @@ describe 'SQM Application' do
|
||||||
|
|
||||||
context 'at least one measure meets its threshold' do
|
context 'at least one measure meets its threshold' do
|
||||||
before :each do
|
before :each do
|
||||||
teacher_survey_item = create(:teacher_survey_item, measure: measure)
|
teacher_survey_item = create(:teacher_survey_item, scale:)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
survey_item: teacher_survey_item, academic_year: academic_year, school: school)
|
survey_item: teacher_survey_item, academic_year: academic_year, school: school)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,31 +6,35 @@ describe 'categories/show' do
|
||||||
school = create(:school, name: 'Best School')
|
school = create(:school, name: 'Best School')
|
||||||
|
|
||||||
category = create(:category, name: 'Some Category', description: 'Some description of the category')
|
category = create(:category, name: 'Some Category', description: 'Some description of the category')
|
||||||
category_presenter = CategoryPresenter.new(category: category)
|
category_presenter = CategoryPresenter.new(category:)
|
||||||
|
|
||||||
subcategory1 = create(:subcategory, category: category, name: 'A subcategory',
|
subcategory1 = create(:subcategory, category:, name: 'A subcategory',
|
||||||
description: 'Some description of the subcategory')
|
description: 'Some description of the subcategory')
|
||||||
subcategory2 = create(:subcategory_with_measures, category: category, name: 'Another subcategory',
|
subcategory2 = create(:subcategory_with_measures, category:, name: 'Another subcategory',
|
||||||
description: 'Another description of the subcategory')
|
description: 'Another description of the subcategory')
|
||||||
|
|
||||||
measure1 = create(:measure, subcategory: subcategory1)
|
measure1 = create(:measure, subcategory: subcategory1)
|
||||||
survey_item1 = create(:student_survey_item, measure: measure1, watch_low_benchmark: 1.5, growth_low_benchmark: 2.5,
|
scale1 = create(:student_scale, measure: measure1)
|
||||||
|
survey_item1 = create(:student_survey_item, scale: scale1, watch_low_benchmark: 1.5, growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item1,
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: survey_item1,
|
||||||
academic_year: academic_year, school: school, likert_score: 1)
|
academic_year:, school:, likert_score: 3)
|
||||||
|
|
||||||
measure2 = create(:measure, name: 'The second measure name', description: 'The second measure description',
|
measure2 = create(:measure, name: 'The second measure name', description: 'The second measure description',
|
||||||
subcategory: subcategory1)
|
subcategory: subcategory2)
|
||||||
student_survey_item = create(:student_survey_item, measure: measure2, prompt: 'Some prompt for student data',
|
scale2 = create(:student_scale, measure: measure2)
|
||||||
|
scale3 = create(:teacher_scale, measure: measure2)
|
||||||
|
student_survey_item = create(:student_survey_item, scale: scale2, prompt: 'Some prompt for student data',
|
||||||
watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
||||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||||
survey_item: student_survey_item, academic_year: academic_year, school: school, likert_score: 5)
|
survey_item: student_survey_item, academic_year:, school:, likert_score: 5)
|
||||||
|
|
||||||
teacher_survey_item = create(:teacher_survey_item, measure: measure2, prompt: 'Some prompt for teacher data')
|
teacher_survey_item = create(:teacher_survey_item, scale: scale3, prompt: 'Some prompt for teacher data')
|
||||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,
|
||||||
survey_item: teacher_survey_item, academic_year: academic_year, school: school, likert_score: 3)
|
survey_item: teacher_survey_item, academic_year:, school:, likert_score: 3)
|
||||||
|
|
||||||
admin_data_item = create(:admin_data_item, measure: measure2, description: 'Some admin data item description',
|
admin_data_scale = create(:scale, measure: measure2)
|
||||||
|
create(:admin_data_item, scale: admin_data_scale, description: 'Some admin data item description',
|
||||||
watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
watch_low_benchmark: 1.5, growth_low_benchmark: 2.5, approval_low_benchmark: 3.5, ideal_low_benchmark: 4.5)
|
||||||
assign :category, category_presenter
|
assign :category, category_presenter
|
||||||
|
|
||||||
|
|
@ -44,45 +48,45 @@ describe 'categories/show' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the category name and description' do
|
it 'renders the category name and description' do
|
||||||
expect(rendered).to match /Some Category/
|
expect(rendered).to match(/Some Category/)
|
||||||
expect(rendered).to match /Some description of the category/
|
expect(rendered).to match(/Some description of the category/)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for each subcategory' do
|
context 'for each subcategory' do
|
||||||
it 'renders the subcategory name' do
|
it 'renders the subcategory name' do
|
||||||
expect(rendered).to match /A subcategory/
|
expect(rendered).to match(/A subcategory/)
|
||||||
expect(rendered).to match /Another subcategory/
|
expect(rendered).to match(/Another subcategory/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the subcategory description' do
|
it 'renders the subcategory description' do
|
||||||
expect(rendered).to match /Some description of the subcategory/
|
expect(rendered).to match(/Some description of the subcategory/)
|
||||||
expect(rendered).to match /Another description of the subcategory/
|
expect(rendered).to match(/Another description of the subcategory/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the zone title and fill color for the gauge graph' do
|
it 'renders the zone title and fill color for the gauge graph' do
|
||||||
expect(rendered).to match /Growth/
|
expect(rendered).to match(/Growth/)
|
||||||
expect(rendered).to match /fill-growth/
|
expect(rendered).to match(/fill-growth/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for each measure' do
|
context 'for each measure' do
|
||||||
it 'renders the measure name' do
|
it 'renders the measure name' do
|
||||||
expect(rendered).to match /The second measure name/
|
expect(rendered).to match(/The second measure name/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the measure description' do
|
it 'renders the measure description' do
|
||||||
expect(rendered).to match /The second measure description/
|
expect(rendered).to match(/The second measure description/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders a gauge graph and the zone title color' do
|
it 'renders a gauge graph and the zone title color' do
|
||||||
expect(rendered).to match /Ideal/
|
expect(rendered).to match(/Approval/)
|
||||||
expect(rendered).to match /fill-ideal/
|
expect(rendered).to match(/fill-approval/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the prompts for survey items and admin data that make up the measure' do
|
it 'renders the prompts for survey items and admin data that make up the measure' do
|
||||||
expect(rendered).to match /Some prompt for student data/
|
expect(rendered).to match(/Some prompt for student data/)
|
||||||
expect(rendered).to match /Some prompt for teacher data/
|
expect(rendered).to match(/Some prompt for teacher data/)
|
||||||
expect(rendered).to match /Some admin data item description/
|
expect(rendered).to match(/Some admin data item description/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ describe 'overview/index' do
|
||||||
|
|
||||||
let(:support_for_teaching) do
|
let(:support_for_teaching) do
|
||||||
measure = create(:measure, name: 'Support For Teaching Development & Growth', measure_id: '1')
|
measure = create(:measure, name: 'Support For Teaching Development & Growth', measure_id: '1')
|
||||||
|
scale = create(:scale, measure:)
|
||||||
create(:student_survey_item,
|
create(:student_survey_item,
|
||||||
measure: measure,
|
scale:,
|
||||||
watch_low_benchmark: 1.5,
|
watch_low_benchmark: 1.5,
|
||||||
growth_low_benchmark: 2.5,
|
growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5,
|
approval_low_benchmark: 3.5,
|
||||||
|
|
@ -16,8 +17,9 @@ describe 'overview/index' do
|
||||||
|
|
||||||
let(:effective_leadership) do
|
let(:effective_leadership) do
|
||||||
measure = create(:measure, name: 'Effective Leadership', measure_id: '2')
|
measure = create(:measure, name: 'Effective Leadership', measure_id: '2')
|
||||||
|
scale = create(:scale, measure:)
|
||||||
create(:teacher_survey_item,
|
create(:teacher_survey_item,
|
||||||
measure: measure,
|
scale:,
|
||||||
watch_low_benchmark: 1.5,
|
watch_low_benchmark: 1.5,
|
||||||
growth_low_benchmark: 2.5,
|
growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5,
|
approval_low_benchmark: 3.5,
|
||||||
|
|
@ -27,8 +29,9 @@ describe 'overview/index' do
|
||||||
|
|
||||||
let(:professional_qualifications) do
|
let(:professional_qualifications) do
|
||||||
measure = create(:measure, name: 'Professional Qualifications', measure_id: '3')
|
measure = create(:measure, name: 'Professional Qualifications', measure_id: '3')
|
||||||
|
scale = create(:scale, measure:)
|
||||||
create(:admin_data_item,
|
create(:admin_data_item,
|
||||||
measure: measure,
|
scale:,
|
||||||
watch_low_benchmark: 1.5,
|
watch_low_benchmark: 1.5,
|
||||||
growth_low_benchmark: 2.5,
|
growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5,
|
approval_low_benchmark: 3.5,
|
||||||
|
|
@ -71,14 +74,15 @@ describe 'overview/index' do
|
||||||
context 'when all the presenters have a non-nil score' do
|
context 'when all the presenters have a non-nil score' do
|
||||||
let(:variance_chart_row_presenters) do
|
let(:variance_chart_row_presenters) do
|
||||||
measure = create(:measure, name: 'Display Me', measure_id: 'display-me')
|
measure = create(:measure, name: 'Display Me', measure_id: 'display-me')
|
||||||
|
scale = create(:scale, measure:)
|
||||||
create(:student_survey_item,
|
create(:student_survey_item,
|
||||||
measure: measure,
|
scale:,
|
||||||
watch_low_benchmark: 1.5,
|
watch_low_benchmark: 1.5,
|
||||||
growth_low_benchmark: 2.5,
|
growth_low_benchmark: 2.5,
|
||||||
approval_low_benchmark: 3.5,
|
approval_low_benchmark: 3.5,
|
||||||
ideal_low_benchmark: 4.5)
|
ideal_low_benchmark: 4.5)
|
||||||
[
|
[
|
||||||
VarianceChartRowPresenter.new(measure: measure,
|
VarianceChartRowPresenter.new(measure:,
|
||||||
score: Score.new(rand))
|
score: Score.new(rand))
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,17 @@ describe 'overview/_variance_chart.html.erb' do
|
||||||
|
|
||||||
let(:survey_items1) { [create(:student_survey_item)] }
|
let(:survey_items1) { [create(:student_survey_item)] }
|
||||||
let(:survey_items2) { [create(:student_survey_item)] }
|
let(:survey_items2) { [create(:student_survey_item)] }
|
||||||
let(:higher_scoring_measure) { create(:measure, survey_items: survey_items1) }
|
let(:higher_scoring_measure) do
|
||||||
let(:lower_scoring_measure) { create(:measure, survey_items: survey_items2) }
|
measure = create(:measure)
|
||||||
|
create(:scale, measure:, survey_items: survey_items1)
|
||||||
|
measure
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:lower_scoring_measure) do
|
||||||
|
measure = create(:measure)
|
||||||
|
create(:scale, measure:, survey_items: survey_items2)
|
||||||
|
measure
|
||||||
|
end
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
presenters = [
|
presenters = [
|
||||||
|
|
@ -15,7 +24,7 @@ describe 'overview/_variance_chart.html.erb' do
|
||||||
VarianceChartRowPresenter.new(measure: higher_scoring_measure, score: Score.new(5))
|
VarianceChartRowPresenter.new(measure: higher_scoring_measure, score: Score.new(5))
|
||||||
]
|
]
|
||||||
|
|
||||||
render partial: 'variance_chart', locals: { presenters: presenters }
|
render partial: 'variance_chart', locals: { presenters: }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'displays higher scoring measures above lower scoring measures' do
|
it 'displays higher scoring measures above lower scoring measures' do
|
||||||
|
|
@ -41,7 +50,7 @@ describe 'overview/_variance_chart.html.erb' do
|
||||||
VarianceChartRowPresenter.new(measure: another_measure_lacking_score, score: Score.new(nil))
|
VarianceChartRowPresenter.new(measure: another_measure_lacking_score, score: Score.new(nil))
|
||||||
]
|
]
|
||||||
|
|
||||||
render partial: 'variance_chart', locals: { presenters: presenters }
|
render partial: 'variance_chart', locals: { presenters: }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "displays the text 'insufficient data' for an empty dataset" do
|
it "displays the text 'insufficient data' for an empty dataset" do
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue