mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
Change the sufficiency threshold from a static number of minimum responses to a minimum response rate of 25 percent
This commit is contained in:
parent
d4df7cbc06
commit
2a2777745a
20 changed files with 180 additions and 138 deletions
|
|
@ -27,3 +27,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Bump ruby version to 3.1.0
|
||||
- Add previous year data.
|
||||
- Add scale to framework. Calculations for scores bubble up through the framework.
|
||||
- Change the threshold for sufficiency from a static number of responses to a response rate; from a minimum threshold of 17 teacher responses per survey item in a measure to 25 percent response rate in a subcategory and a minimum of 196 student responses per survey item in a measure to 25 percent response rate in a subcategory.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ class SqmApplicationController < ApplicationController
|
|||
@schools = School.includes([:district]).where(district: @district).order(:name)
|
||||
@academic_year = AcademicYear.find_by_range params[:year]
|
||||
@academic_years = AcademicYear.all.order(range: :desc)
|
||||
@has_empty_dataset = Measure.all.all? do |measure| measure.none_meet_threshold? school: @school, academic_year: @academic_year end
|
||||
@has_empty_dataset = Measure.all.all? do |measure|
|
||||
measure.none_meet_threshold? school: @school, academic_year: @academic_year
|
||||
end
|
||||
end
|
||||
|
||||
def district_slug
|
||||
|
|
|
|||
|
|
@ -83,19 +83,13 @@ class Measure < ActiveRecord::Base
|
|||
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
|
||||
subcategory.student_response_rate(school:, academic_year:).meets_student_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
|
||||
subcategory.teacher_response_rate(school:, academic_year:).meets_teacher_threshold?
|
||||
end
|
||||
|
||||
def sufficient_data?(school:, academic_year:)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
module ResponseRate
|
||||
TEACHER_RATE_THRESHOLD = 0.25
|
||||
STUDENT_RATE_THRESHOLD = 0.25
|
||||
|
||||
def initialize(subcategory:, school:, academic_year:)
|
||||
@subcategory = subcategory
|
||||
@school = school
|
||||
|
|
@ -14,4 +17,12 @@ module ResponseRate
|
|||
|
||||
(average_responses_per_survey_item / total_possible_responses.to_f * 100).round
|
||||
end
|
||||
|
||||
def meets_student_threshold?
|
||||
rate >= STUDENT_RATE_THRESHOLD * 100
|
||||
end
|
||||
|
||||
def meets_teacher_threshold?
|
||||
rate >= TEACHER_RATE_THRESHOLD * 100
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ class StudentResponseRate
|
|||
private
|
||||
|
||||
def survey_item_count
|
||||
@student_survey_item_count ||= @subcategory.measures.map { |measure| measure.student_survey_items.count }.sum
|
||||
@survey_item_count ||= @subcategory.measures.map { |measure| measure.student_survey_items.count }.sum
|
||||
end
|
||||
|
||||
def response_count
|
||||
@student_response_count ||= @subcategory.measures.map do |measure|
|
||||
@response_count ||= @subcategory.measures.map do |measure|
|
||||
measure.student_survey_items.map do |survey_item|
|
||||
survey_item.survey_item_responses.where(school: @school, academic_year: @academic_year).count
|
||||
end.sum
|
||||
|
|
@ -16,7 +16,7 @@ class StudentResponseRate
|
|||
end
|
||||
|
||||
def total_possible_responses
|
||||
@total_possible_student_responses ||= begin
|
||||
@total_possible_responses ||= begin
|
||||
total_responses = Respondent.where(school: @school, academic_year: @academic_year).first
|
||||
return 0 unless total_responses.present?
|
||||
|
||||
|
|
|
|||
|
|
@ -10,4 +10,20 @@ class Subcategory < ActiveRecord::Base
|
|||
scores = scores.reject(&:nil?)
|
||||
scores.average
|
||||
end
|
||||
|
||||
def student_response_rate(school:, academic_year:)
|
||||
@student_response_rate ||= Hash.new do |memo|
|
||||
memo[[school, academic_year]] = StudentResponseRate.new(subcategory: self, school:, academic_year:)
|
||||
end
|
||||
|
||||
@student_response_rate[[school, academic_year]]
|
||||
end
|
||||
|
||||
def teacher_response_rate(school:, academic_year:)
|
||||
@teacher_response_rate ||= Hash.new do |memo|
|
||||
memo[[school, academic_year]] = TeacherResponseRate.new(subcategory: self, school:, academic_year:)
|
||||
end
|
||||
|
||||
@teacher_response_rate[[school, academic_year]]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
class SurveyItemResponse < ActiveRecord::Base
|
||||
TEACHER_RESPONSE_THRESHOLD = 17
|
||||
STUDENT_RESPONSE_THRESHOLD = 196
|
||||
TEACHER_RESPONSE_THRESHOLD = 2
|
||||
STUDENT_RESPONSE_THRESHOLD = 2
|
||||
|
||||
belongs_to :academic_year
|
||||
belongs_to :school
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ class TeacherResponseRate
|
|||
end
|
||||
|
||||
def survey_item_count
|
||||
@teacher_survey_item_count ||= @subcategory.measures.map { |measure| measure.teacher_survey_items.count }.sum
|
||||
@survey_item_count ||= @subcategory.measures.map { |measure| measure.teacher_survey_items.count }.sum
|
||||
end
|
||||
|
||||
def response_count
|
||||
@teacher_response_count ||= @subcategory.measures.map do |measure|
|
||||
@response_count ||= @subcategory.measures.map do |measure|
|
||||
measure.teacher_survey_items.map do |survey_item|
|
||||
survey_item.survey_item_responses.where(school: @school, academic_year: @academic_year).count
|
||||
end.sum
|
||||
|
|
@ -24,7 +24,7 @@ class TeacherResponseRate
|
|||
end
|
||||
|
||||
def total_possible_responses
|
||||
@total_possible_teacher_responses ||= begin
|
||||
@total_possible_responses ||= begin
|
||||
total_responses = Respondent.where(school: @school, academic_year: @academic_year).first
|
||||
return 0 unless total_responses.present?
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@ class SubcategoryPresenter
|
|||
@subcategory = subcategory
|
||||
@academic_year = academic_year
|
||||
@school = school
|
||||
@student_response_rate = StudentResponseRate.new(subcategory: @subcategory, school: @school,
|
||||
academic_year: @academic_year)
|
||||
@teacher_response_rate = TeacherResponseRate.new(subcategory: @subcategory, school: @school,
|
||||
academic_year: @academic_year)
|
||||
end
|
||||
|
||||
def id
|
||||
|
|
@ -34,11 +30,11 @@ class SubcategoryPresenter
|
|||
end
|
||||
|
||||
def student_response_rate
|
||||
@student_response_rate.rate
|
||||
@subcategory.student_response_rate(school: @school, academic_year: @academic_year).rate
|
||||
end
|
||||
|
||||
def teacher_response_rate
|
||||
@teacher_response_rate.rate
|
||||
@subcategory.teacher_response_rate(school: @school, academic_year: @academic_year).rate
|
||||
end
|
||||
|
||||
def admin_collection_rate
|
||||
|
|
|
|||
19
doc/architectural_decision_records/3.md
Normal file
19
doc/architectural_decision_records/3.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Decision record 3
|
||||
|
||||
# Change the response rate threshold from a static number to a response rate percentage
|
||||
|
||||
## Status
|
||||
|
||||
Completed
|
||||
|
||||
## Context
|
||||
|
||||
We do not show responses if there is insufficient data. We only show a graph if it's statistically meaningful. Previously, the minimum number of responses was set to 17 per teacher survey item and 196 per student survey item. This was calculated at the measure level.
|
||||
|
||||
## Decision
|
||||
|
||||
We have changed the minumim threshold to be a 25 percent response rate at the subcategory level.
|
||||
|
||||
## Consequences
|
||||
|
||||
This story, in combination with the story for marking short-form only schools, means that small population elementary schools will be able to see the responses visualized on the dashboard where before, that data would have been filtered out.
|
||||
|
|
@ -36,7 +36,7 @@ FactoryBot.define do
|
|||
end
|
||||
after(:create) do |subcategory, evaluator|
|
||||
create_list(:measure, evaluator.measures_count, subcategory:).each do |measure|
|
||||
scale = create(:scale, measure: measure)
|
||||
scale = create(:scale, measure:)
|
||||
survey_item = create(:teacher_survey_item, scale:)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item:)
|
||||
end
|
||||
|
|
@ -59,10 +59,10 @@ FactoryBot.define do
|
|||
measure
|
||||
scale_id { "A Scale #{rand}" }
|
||||
factory :teacher_scale do
|
||||
scale_id {"t-#{rand}"}
|
||||
scale_id { "t-#{rand}" }
|
||||
end
|
||||
factory :student_scale do
|
||||
scale_id {"s-#{rand}"}
|
||||
scale_id { "s-#{rand}" }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -102,5 +102,7 @@ FactoryBot.define do
|
|||
factory :respondent do
|
||||
school
|
||||
academic_year
|
||||
total_students { SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD * 4 }
|
||||
total_teachers { SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD * 4 }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
module Legacy
|
||||
RSpec.describe Student, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
end
|
||||
|
|
@ -23,6 +23,10 @@ RSpec.describe Measure, type: :model do
|
|||
let(:teacher_approval_low_benchmark) { 3.2 }
|
||||
let(:teacher_ideal_low_benchmark) { 4.2 }
|
||||
|
||||
before do
|
||||
create(:respondent, school:, academic_year:)
|
||||
create(:respondent, school:, academic_year:)
|
||||
end
|
||||
describe 'benchmarks' do
|
||||
context 'when a measure includes only one admin data item' do
|
||||
before do
|
||||
|
|
@ -194,7 +198,7 @@ RSpec.describe Measure, type: :model do
|
|||
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
|
||||
context "and the number of responses for each of the measure's survey items meets the teacher threshold " 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)
|
||||
|
|
@ -217,14 +221,14 @@ RSpec.describe Measure, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "and the average number of responses across the measure's survey items meets the teacher threshold of 17" do
|
||||
context "and the average number of responses across the measure's survey items meets the teacher threshold " 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)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD + 1, 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 - 1, 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
|
||||
|
|
@ -233,14 +237,14 @@ RSpec.describe Measure, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "and none of the measure's survey items meets the teacher threshold of 17" do
|
||||
context "and none of the measure's survey items meets the teacher threshold " 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)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, survey_item: teacher_survey_item_1, academic_year:, school:,
|
||||
likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, survey_item: teacher_survey_item_2, academic_year:, school:,
|
||||
likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, survey_item: teacher_survey_item_3, academic_year:, school:,
|
||||
likert_score: rand)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
|
|
@ -252,14 +256,14 @@ RSpec.describe Measure, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "and the average number of responses across the measure's survey items does not meet the teacher threshold of 17" do
|
||||
context "and the average number of responses across the measure's survey items does not meet the teacher threshold " 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)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: teacher_survey_item_1, academic_year:, school:,
|
||||
likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, survey_item: teacher_survey_item_2, academic_year:, school:,
|
||||
likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD - 1, survey_item: teacher_survey_item_3, academic_year:, school:,
|
||||
likert_score: rand)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
|
|
@ -277,7 +281,7 @@ RSpec.describe Measure, type: :model do
|
|||
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
|
||||
context "and the number of responses for each of the measure's survey items meets the student threshold " 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)
|
||||
|
|
@ -299,14 +303,14 @@ RSpec.describe Measure, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "and the average number of responses across the measure's survey items meets the student threshold of 196" do
|
||||
context "and the average number of responses across the measure's survey items meets the student threshold " 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)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD + 1, 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 - 1, 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
|
||||
|
|
@ -315,14 +319,14 @@ RSpec.describe Measure, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "and none of the measure's survey items meets the student threshold of 196" do
|
||||
context "and none of the measure's survey items meets the student threshold " 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)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_1, academic_year:,
|
||||
school:, likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_2, academic_year:,
|
||||
school:, likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_3, academic_year:,
|
||||
school:, likert_score: rand)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
|
|
@ -334,14 +338,14 @@ RSpec.describe Measure, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context "and the average number of responses across the measure's survey items does not meet the student threshold of 196" do
|
||||
context "and the average number of responses across the measure's survey items does not meet the student threshold " 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,
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_1, academic_year:,
|
||||
school:, likert_score: rand)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
|
||||
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)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_3, academic_year:,
|
||||
school:, likert_score: rand)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
|
|
|
|||
|
|
@ -2,103 +2,86 @@ require 'rails_helper'
|
|||
|
||||
describe ResponseRate, type: :model do
|
||||
let(:school) { create(:school) }
|
||||
let(:ay) { create(:academic_year) }
|
||||
let(:academic_year) { create(:academic_year) }
|
||||
let(:survey_respondents) do
|
||||
create(:respondent, school: school, total_students: SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||
total_teachers: SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, academic_year: ay)
|
||||
create(:respondent, school:, academic_year:)
|
||||
end
|
||||
|
||||
describe StudentResponseRate do
|
||||
let(:subcategory) { create(:subcategory) }
|
||||
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
||||
let(:sufficient_measure_1) { create(:measure, 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:) }
|
||||
let(:sufficient_scale_2) { create(:scale, measure: sufficient_measure_2) }
|
||||
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
||||
let(:insufficient_scale) { create(:scale, measure: insufficient_measure) }
|
||||
let(:sufficient_teacher_survey_item) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||
let(:sufficient_student_survey_item_1) { create(:student_survey_item, scale: sufficient_scale_1) }
|
||||
let(:insufficient_teacher_survey_item) { create(:teacher_survey_item, scale: insufficient_scale) }
|
||||
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
|
||||
survey_respondents
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item,
|
||||
academic_year: ay, school: school, likert_score: 1)
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: sufficient_student_survey_item_1,
|
||||
academic_year: ay, school: school, likert_score: 4)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD + 1, survey_item: sufficient_student_survey_item_2,
|
||||
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)
|
||||
academic_year:, school:, likert_score: 4)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: sufficient_student_survey_item_2,
|
||||
academic_year:, school:, likert_score: 4)
|
||||
end
|
||||
|
||||
context 'when the average number of student responses per question in a subcategory is equal to the student response threshold' do
|
||||
it 'returns 100 percent' do
|
||||
expect(StudentResponseRate.new(subcategory: subcategory, school: school,
|
||||
academic_year: ay).rate).to eq 100
|
||||
expect(StudentResponseRate.new(subcategory:, school:,
|
||||
academic_year:).rate).to eq 25
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe TeacherResponseRate do
|
||||
let(:subcategory) { create(:subcategory) }
|
||||
let(:sufficient_measure_1) { create(:measure, subcategory: subcategory) }
|
||||
let(:sufficient_measure_1) { create(:measure, 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:) }
|
||||
let(:sufficient_scale_2) { create(:scale, measure: sufficient_measure_2) }
|
||||
let(:insufficient_measure) { create(:measure, subcategory: subcategory) }
|
||||
let(:insufficient_scale) { create(:scale, measure: insufficient_measure) }
|
||||
let(:sufficient_teacher_survey_item_1) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||
let(:sufficient_teacher_survey_item_2) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||
let(:sufficient_teacher_survey_item_3) { create(:teacher_survey_item, scale: sufficient_scale_1) }
|
||||
let(:sufficient_student_survey_item_1) { create(:student_survey_item, scale: sufficient_scale_1) }
|
||||
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
|
||||
survey_respondents
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item_1,
|
||||
academic_year: ay, school: school, likert_score: 1)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD + 1, survey_item: sufficient_teacher_survey_item_2,
|
||||
academic_year: ay, school: school, likert_score: 1)
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: sufficient_teacher_survey_item_2,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: sufficient_student_survey_item_1,
|
||||
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)
|
||||
academic_year:, school:, likert_score: 4)
|
||||
end
|
||||
|
||||
context 'when the average number of teacher responses per question in a subcategory is equal to the total possible responses' do
|
||||
it 'returns 100 percent' do
|
||||
expect(TeacherResponseRate.new(subcategory: subcategory, school: school,
|
||||
academic_year: ay).rate).to eq 100
|
||||
context 'when the average number of teacher responses per question in a subcategory is at the threshold' do
|
||||
it 'returns 25 percent' do
|
||||
expect(TeacherResponseRate.new(subcategory:, school:,
|
||||
academic_year:).rate).to eq 25
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the average number of teacher responses is 77.9, the response rate averages up to 78 percent' do
|
||||
context 'when the teacher response rate is not a whole number. eg 29.166%' do
|
||||
before do
|
||||
create_list(:survey_item_response, 2, survey_item: sufficient_teacher_survey_item_3,
|
||||
academic_year: ay, school: school, likert_score: 1)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD + 1, survey_item: sufficient_teacher_survey_item_3,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
end
|
||||
it 'returns 10 percent' do
|
||||
expect(TeacherResponseRate.new(subcategory: subcategory, school: school,
|
||||
academic_year: ay).rate).to eq 78
|
||||
it 'it will return the nearest whole number' do
|
||||
expect(TeacherResponseRate.new(subcategory:, school:,
|
||||
academic_year:).rate).to eq 29
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the average number of teacher responses is greater than the total possible responses' do
|
||||
before do
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD + 1, survey_item: sufficient_teacher_survey_item_3,
|
||||
academic_year: ay, school: school, likert_score: 1)
|
||||
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD * 11, survey_item: sufficient_teacher_survey_item_3,
|
||||
academic_year:, school:, likert_score: 1)
|
||||
end
|
||||
it 'returns 100 percent' do
|
||||
expect(TeacherResponseRate.new(subcategory: subcategory, school: school,
|
||||
academic_year: ay).rate).to eq 100
|
||||
expect(TeacherResponseRate.new(subcategory:, school:,
|
||||
academic_year:).rate).to eq 100
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ 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(:measure_1) { create(:measure, subcategory:) }
|
||||
let(:teacher_scale) { create(:teacher_scale, measure: measure_1) }
|
||||
let(:measure_2) { create(:measure, subcategory: subcategory) }
|
||||
let(:measure_2) { create(:measure, subcategory:) }
|
||||
let(:student_scale) { create(:student_scale, measure: measure_2) }
|
||||
before do
|
||||
create(:respondent, school:, academic_year:)
|
||||
end
|
||||
|
||||
describe '.score' do
|
||||
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale: teacher_scale) }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ describe MeasurePresenter do
|
|||
let(:student_scale) { create(:student_scale, measure:) }
|
||||
let(:admin_scale) { create(:scale, measure:) }
|
||||
let(:measure_presenter) { MeasurePresenter.new(measure:, academic_year:, school:) }
|
||||
before do
|
||||
create(:respondent, school:, academic_year:)
|
||||
end
|
||||
|
||||
it 'returns the id of the measure' do
|
||||
expect(measure_presenter.id).to eq 'measure-id'
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ describe SubcategoryPresenter do
|
|||
create(:subcategory, name: 'A great subcategory', subcategory_id: 'A', description: 'A great description')
|
||||
end
|
||||
let(:survey_respondents) do
|
||||
create(:respondent, school:, total_students: SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
|
||||
total_teachers: 10.0, academic_year:)
|
||||
create(:respondent, school:, academic_year:)
|
||||
end
|
||||
let(:subcategory_presenter) do
|
||||
survey_respondents
|
||||
|
|
@ -68,11 +67,11 @@ describe SubcategoryPresenter do
|
|||
end
|
||||
|
||||
it 'returns the student response rate' do
|
||||
expect(subcategory_presenter.student_response_rate).to eq 100.0
|
||||
expect(subcategory_presenter.student_response_rate).to eq 25
|
||||
end
|
||||
|
||||
it 'returns the teacher response rate' do
|
||||
expect(subcategory_presenter.teacher_response_rate).to eq 100
|
||||
expect(subcategory_presenter.teacher_response_rate).to eq 50
|
||||
end
|
||||
|
||||
it 'returns the admin collection rate' do
|
||||
|
|
|
|||
|
|
@ -9,30 +9,36 @@ describe 'District Admin', js: true do
|
|||
let(:category) { Category.find_by_name('Teachers & Leadership') }
|
||||
let(:subcategory) { Subcategory.find_by_name('Teachers & The Teaching Environment') }
|
||||
let(:measures_for_subcategory) { Measure.where(subcategory:) }
|
||||
let(:scales_for_subcategory) {Scale.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_2A_i) { Measure.find_by_measure_id('2A-i') }
|
||||
let(:measure_2A_ii) { Measure.find_by_measure_id('2A-ii') }
|
||||
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(: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 scale: measure_1A_i.scales.first, survey_item_id: rand.to_s }
|
||||
|
||||
let(:survey_items_for_measure_1A_i) { measure_1A_i.survey_items }
|
||||
let(:survey_items_for_measure_2A_i) { measure_2A_i.survey_items }
|
||||
let(:survey_items_for_measure_2A_ii) { measure_2A_ii.survey_items }
|
||||
let(:survey_items_for_measure_4C_i) { measure_4C_i.survey_items }
|
||||
|
||||
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' }
|
||||
|
||||
let(:username) { 'winchester' }
|
||||
let(:password) { 'winchester!' }
|
||||
let(:respondents) do
|
||||
respondents = Respondent.where(school:).first
|
||||
respondents.total_students = 8
|
||||
respondents.total_teachers = 8
|
||||
respondents.save
|
||||
end
|
||||
|
||||
before :each do
|
||||
Rails.application.load_seed
|
||||
|
||||
respondents
|
||||
survey_item_responses = []
|
||||
|
||||
survey_items_for_measure_1A_i.each do |survey_item|
|
||||
|
|
@ -49,6 +55,13 @@ describe 'District Admin', js: true do
|
|||
end
|
||||
end
|
||||
|
||||
survey_items_for_measure_2A_ii.each do |survey_item|
|
||||
SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do
|
||||
survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2020_21,
|
||||
school:, survey_item:, likert_score: 5)
|
||||
end
|
||||
end
|
||||
|
||||
survey_items_for_measure_4C_i.each do |survey_item|
|
||||
SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do
|
||||
survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2020_21,
|
||||
|
|
@ -57,7 +70,7 @@ describe 'District Admin', js: true do
|
|||
end
|
||||
|
||||
survey_items_for_subcategory.each do |survey_item|
|
||||
200.times do
|
||||
2.times do
|
||||
survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2020_21,
|
||||
school:, survey_item:, likert_score: 4)
|
||||
end
|
||||
|
|
@ -108,6 +121,7 @@ end
|
|||
|
||||
def district_admin_sees_student_physical_safety
|
||||
expect(page).to have_text('Student Physical Safety')
|
||||
|
||||
expect(page).to have_css("[data-for-measure-id='2A-i'][width='40.0%'][x='60%']")
|
||||
end
|
||||
|
||||
|
|
@ -159,7 +173,7 @@ def district_admin_sees_overview_content
|
|||
district_admin_sees_student_physical_safety
|
||||
district_admin_sees_problem_solving_emphasis
|
||||
|
||||
page.assert_selector('.measure-row-bar', count: 5)
|
||||
page.assert_selector('.measure-row-bar', count: 6)
|
||||
end
|
||||
|
||||
def district_admin_sees_browse_content
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ describe 'SQM Application' do
|
|||
before :each do
|
||||
driven_by :rack_test
|
||||
page.driver.browser.basic_authorize(username, password)
|
||||
create(:respondent, school:, academic_year:)
|
||||
end
|
||||
|
||||
context 'when no measures meet their threshold' do
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ describe 'categories/show' do
|
|||
|
||||
subcategory1 = create(:subcategory, category:, name: 'A subcategory',
|
||||
description: 'Some description of the subcategory')
|
||||
subcategory2 = create(:subcategory_with_measures, category:, name: 'Another subcategory',
|
||||
description: 'Another description of the subcategory')
|
||||
subcategory2 = create(:subcategory, category:, name: 'Another subcategory',
|
||||
description: 'Another description of the subcategory')
|
||||
|
||||
measure1 = create(:measure, subcategory: subcategory1)
|
||||
scale1 = create(:student_scale, measure: measure1)
|
||||
|
|
@ -44,6 +44,7 @@ describe 'categories/show' do
|
|||
assign :academic_year, academic_year
|
||||
assign :academic_years, [academic_year]
|
||||
|
||||
create(:respondent, school:, academic_year:)
|
||||
render
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue