Set a minimum threshold of 10 survey item responses to calculate scores per survey item

rpp-main
rebuilt 3 years ago
parent d888cdff3a
commit aa3a67406b

@ -24,11 +24,15 @@ class Measure < ActiveRecord::Base
@student_survey_items ||= survey_items.student_survey_items @student_survey_items ||= survey_items.student_survey_items
end end
def student_survey_items_by_survey_type(school:, academic_year:) def student_survey_items_with_sufficient_responses(school:, academic_year:)
survey = Survey.where(school:, academic_year:).first SurveyItem.where(id: SurveyItem.joins('inner join survey_item_responses on survey_item_responses.survey_item_id = survey_items.id')
return student_survey_items.short_form_items if survey.form == 'short' .student_survey_items
.where("survey_item_responses.school": school,
student_survey_items "survey_item_responses.academic_year": academic_year,
"survey_item_responses.survey_item_id": survey_items.student_survey_items)
.group('survey_items.id')
.having('count(*) >= 10')
.count.keys)
end end
def teacher_scales def teacher_scales
@ -244,7 +248,7 @@ class Measure < ActiveRecord::Base
def student_average(school:, academic_year:) def student_average(school:, academic_year:)
@student_average ||= Hash.new do |memo, (school, academic_year)| @student_average ||= Hash.new do |memo, (school, academic_year)|
survey_items = student_survey_items_by_survey_type(school:, academic_year:) survey_items = student_survey_items_with_sufficient_responses(school:, academic_year:)
memo[[school, academic_year]] = collect_survey_item_average(survey_items:, school:, academic_year:) memo[[school, academic_year]] = collect_survey_item_average(survey_items:, school:, academic_year:)
end end
@student_average[[school, academic_year]] @student_average[[school, academic_year]]

@ -194,7 +194,9 @@ namespace :one_off do
end end
desc 'delete errant response' desc 'delete errant response'
task delete_response: :environment do task delete_responses: :environment do
SurveyItemResponse.where(response_id: 'R_diYAw7qOj4W1UZ3').delete_all SurveyItemResponse.where(response_id: 'R_diYAw7qOj4W1UZ3').delete_all
SurveyItemResponse.where(response_id: 'R_27fKhVfyeKGMF5q').delete_all
SurveyItemResponse.where(response_id: 'R_2cjPX1Ngxr2Hc4c').delete_all
end end
end end

@ -294,6 +294,46 @@ RSpec.describe Measure, type: :model do
let(:short_form_student_survey_item_2) { create(:student_survey_item, scale: student_scale, on_short_form: true) } let(:short_form_student_survey_item_2) { create(:student_survey_item, scale: student_scale, on_short_form: true) }
let(:short_form_student_survey_item_3) { create(:student_survey_item, scale: student_scale, on_short_form: true) } let(:short_form_student_survey_item_3) { create(:student_survey_item, scale: student_scale, on_short_form: true) }
context "and the number of responses for each of the measure's survey items does not meet the student threshold " do
before :each do
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 - 1,
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 'it does not return an average score' do
expect(measure.score(school:, academic_year:).average).to eq nil
end
end
context 'and one survey item has sufficient responses but other items do not meet the 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)
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
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 'it does not return an average score' do
expect(measure.score(school:, academic_year:).average).to eq 3
end
end
context 'and two survey items have sufficient responses but other items do not meet the 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)
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 'it does not return an average score' do
expect(measure.score(school:, academic_year:).average).to eq 3.5
end
end
context "and the number of responses for each of the measure's survey items meets the student threshold " do context "and the number of responses for each of the measure's survey items meets the student threshold " do
before :each do before :each do
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD,
@ -316,22 +356,6 @@ RSpec.describe Measure, type: :model do
end end
end end
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, 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
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 " do context "and none of the measure's survey items meets the student threshold " do
before :each do before :each do
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_1, academic_year:, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1, survey_item: student_survey_item_1, academic_year:,
@ -375,6 +399,18 @@ RSpec.describe Measure, type: :model do
let(:teacher_survey_item_1) { create(:teacher_survey_item, scale: teacher_scale) } let(:teacher_survey_item_1) { create(:teacher_survey_item, scale: teacher_scale) }
let(:student_survey_item_1) { create(:student_survey_item, scale: student_scale) } let(:student_survey_item_1) { create(:student_survey_item, scale: student_scale) }
context 'and there is sufficient teacher data but 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: 3)
create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD - 1,
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 3
end
end
context 'and there is sufficient teacher data and sufficient student data' do context 'and there is sufficient teacher data and sufficient student data' do
before :each do before :each do
create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD,

@ -129,10 +129,10 @@ describe GroupedBarColumnPresenter do
end end
context 'when more than one year exists' do context 'when more than one year exists' do
before do before do
create(:survey_item_response, survey_item: student_survey_item_for_composite_measure, school:, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_for_composite_measure, school:,
academic_year: another_academic_year, likert_score: 5) academic_year: another_academic_year, likert_score: 5)
create(:survey_item_response, survey_item: student_survey_item_for_composite_measure, school:, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item_for_composite_measure, school:,
academic_year: another_academic_year, likert_score: 3) academic_year: another_academic_year, likert_score: 3)
end end
it 'returns independent scores for each year of data' do it 'returns independent scores for each year of data' do
expect(all_data_presenter.score(0).average).to eq 4.5 expect(all_data_presenter.score(0).average).to eq 4.5
@ -205,10 +205,10 @@ describe GroupedBarColumnPresenter do
context 'when there is more than one years worth of data to show' do context 'when there is more than one years worth of data to show' do
before do before do
create(:survey_item_response, survey_item: student_survey_item, school:, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item, school:,
academic_year: another_academic_year, likert_score: 3) academic_year: another_academic_year, likert_score: 3)
create(:survey_item_response, survey_item: student_survey_item, school:, create_list(:survey_item_response, SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD, survey_item: student_survey_item, school:,
academic_year: another_academic_year, likert_score: 4) academic_year: another_academic_year, likert_score: 4)
end end
it 'returns only bars that have a numeric score' do it 'returns only bars that have a numeric score' do
@ -305,8 +305,8 @@ describe GroupedBarColumnPresenter do
end end
context 'when there are enough responses to calculate a score' do context 'when there are enough responses to calculate a score' do
before do before do
create(:survey_item_response, survey_item: teacher_survey_item, school:, create(:survey_item_response, survey_item: teacher_survey_item, school:,
academic_year:) academic_year:)
end end
it 'indicates it should show the insufficient data message' do it 'indicates it should show the insufficient data message' do

Loading…
Cancel
Save