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

mciea-main
rebuilt 3 years ago
parent 982f216c6c
commit 30e006ee0d

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

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